mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-23 20:51:58 +00:00
Merge branch 'master' into netborder
Conflicts: libs/freetdm/src/testsangomaboost.c
This commit is contained in:
@@ -1177,7 +1177,6 @@ ESL_DECLARE(esl_status_t) esl_send_recv_timed(esl_handle_t *handle, const char *
|
||||
return ESL_FAIL;
|
||||
}
|
||||
|
||||
esl_event_safe_destroy(&handle->last_event);
|
||||
esl_event_safe_destroy(&handle->last_sr_event);
|
||||
|
||||
*handle->last_sr_reply = '\0';
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#! /bin/sh
|
||||
./configure "$@" --with-pic
|
||||
|
||||
srcpath=$(dirname $0 2>/dev/null ) || srcpath="."
|
||||
$srcpath/configure "$@" --with-pic
|
||||
|
||||
@@ -119,10 +119,8 @@ Global
|
||||
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.ActiveCfg = Release|x64
|
||||
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.Build.0 = Release|x64
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.Build.0 = Release|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|x64
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>FreeSwitchCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>FreeSwitch.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
@@ -127,7 +127,7 @@
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>FreeSwitchCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>FreeSwitch.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
|
||||
+64
-12
@@ -57,11 +57,14 @@ struct tm *localtime_r(const time_t *clock, struct tm *result);
|
||||
#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
|
||||
#define FTDM_READ_TRACE_INDEX 0
|
||||
#define FTDM_WRITE_TRACE_INDEX 1
|
||||
#define MAX_CALLIDS 6000
|
||||
|
||||
ftdm_time_t time_last_throttle_log = 0;
|
||||
ftdm_time_t time_current_throttle_log = 0;
|
||||
|
||||
static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter);
|
||||
static ftdm_status_t ftdm_call_set_call_id(ftdm_caller_data_t *caller_data);
|
||||
static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data);
|
||||
|
||||
static int time_is_init = 0;
|
||||
|
||||
@@ -235,6 +238,10 @@ static struct {
|
||||
ftdm_span_t *spans;
|
||||
ftdm_group_t *groups;
|
||||
cpu_monitor_t cpu_monitor;
|
||||
|
||||
ftdm_caller_data_t *call_ids[MAX_CALLIDS+1];
|
||||
ftdm_mutex_t *call_id_mutex;
|
||||
uint32_t last_call_id;
|
||||
} globals;
|
||||
|
||||
enum ftdm_enum_cpu_alarm_action_flags
|
||||
@@ -1896,8 +1903,6 @@ static ftdm_status_t ftdm_channel_reset(ftdm_channel_t *ftdmchan)
|
||||
ftdmchan->dtmf_off = FTDM_DEFAULT_DTMF_OFF;
|
||||
}
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
|
||||
memset(ftdmchan->dtmf_hangup_buf, '\0', ftdmchan->span->dtmf_hangup_len);
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE)) {
|
||||
@@ -2483,6 +2488,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char
|
||||
|
||||
ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 100);
|
||||
|
||||
ftdm_call_set_call_id(&ftdmchan->caller_data);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
|
||||
return status;
|
||||
@@ -2545,9 +2551,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
||||
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel can't be done!\n");
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
|
||||
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_INUSE);
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_WINK);
|
||||
@@ -2587,7 +2590,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
||||
sigmsg.channel = ftdmchan;
|
||||
sigmsg.event_id = FTDM_SIGEVENT_RELEASED;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigmsg);
|
||||
}
|
||||
ftdm_call_clear_call_id(&ftdmchan->caller_data);
|
||||
}
|
||||
|
||||
if (ftdmchan->txdrops || ftdmchan->rxdrops) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n",
|
||||
@@ -2595,8 +2599,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
||||
}
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n");
|
||||
|
||||
|
||||
memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
@@ -3455,7 +3458,7 @@ static FIO_READ_FUNCTION(ftdm_raw_read)
|
||||
ftdm_status_t status = ftdmchan->fio->read(ftdmchan, data, datalen);
|
||||
if (status == FTDM_SUCCESS && ftdmchan->fds[FTDM_READ_TRACE_INDEX] > -1) {
|
||||
ftdm_size_t dlen = *datalen;
|
||||
if ((ftdm_size_t)write(ftdmchan->fds[FTDM_READ_TRACE_INDEX], data, dlen) != dlen) {
|
||||
if ((ftdm_size_t)write(ftdmchan->fds[FTDM_READ_TRACE_INDEX], data, (int)dlen) != dlen) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Raw input trace failed to write all of the %zd bytes\n", dlen);
|
||||
}
|
||||
}
|
||||
@@ -3468,7 +3471,7 @@ static FIO_READ_FUNCTION(ftdm_raw_read)
|
||||
ftdm_size_t dlen = *datalen;
|
||||
ftdm_size_t rc = 0;
|
||||
|
||||
write_chan_io_dump(&ftdmchan->rxdump, data, dlen);
|
||||
write_chan_io_dump(&ftdmchan->rxdump, data, (int)dlen);
|
||||
|
||||
/* if dtmf debug is enabled and initialized, write there too */
|
||||
if (ftdmchan->dtmfdbg.file) {
|
||||
@@ -5336,7 +5339,7 @@ static void execute_safety_hangup(void *data)
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
||||
{
|
||||
if (sigmsg->channel) {
|
||||
ftdm_mutex_lock(sigmsg->channel->mutex);
|
||||
ftdm_mutex_lock(sigmsg->channel->mutex);
|
||||
}
|
||||
|
||||
/* some core things to do on special events */
|
||||
@@ -5355,6 +5358,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
||||
|
||||
case FTDM_SIGEVENT_START:
|
||||
{
|
||||
ftdm_call_set_call_id(&sigmsg->channel->caller_data);
|
||||
ftdm_set_echocancel_call_begin(sigmsg->channel);
|
||||
if (sigmsg->channel->dtmfdbg.requested) {
|
||||
ftdm_channel_command(sigmsg->channel, FTDM_COMMAND_ENABLE_DEBUG_DTMF, NULL);
|
||||
@@ -5384,7 +5388,10 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (sigmsg->channel) {
|
||||
sigmsg->call_id = sigmsg->channel->caller_data.call_id;
|
||||
}
|
||||
/* if the signaling module uses a queue for signaling notifications, then enqueue it */
|
||||
if (ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) {
|
||||
ftdm_span_queue_signal(span, sigmsg);
|
||||
@@ -5493,6 +5500,8 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
|
||||
ftdm_mutex_create(&globals.mutex);
|
||||
ftdm_mutex_create(&globals.span_mutex);
|
||||
ftdm_mutex_create(&globals.group_mutex);
|
||||
ftdm_mutex_create(&globals.call_id_mutex);
|
||||
|
||||
ftdm_sched_global_init();
|
||||
if (ftdm_sched_create(&globals.timingsched, "freetdm-master") != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to create master timing schedule context\n");
|
||||
@@ -5502,6 +5511,7 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to run master timing schedule context\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
globals.running = 1;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
@@ -5605,6 +5615,7 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
|
||||
ftdm_mutex_destroy(&globals.mutex);
|
||||
ftdm_mutex_destroy(&globals.span_mutex);
|
||||
ftdm_mutex_destroy(&globals.group_mutex);
|
||||
ftdm_mutex_destroy(&globals.call_id_mutex);
|
||||
|
||||
memset(&globals, 0, sizeof(globals));
|
||||
return FTDM_SUCCESS;
|
||||
@@ -5963,6 +5974,47 @@ FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan)
|
||||
return stream.data;
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdm_call_set_call_id(ftdm_caller_data_t *caller_data)
|
||||
{
|
||||
uint32_t current_call_id;
|
||||
ftdm_assert_return(!caller_data->call_id, FTDM_FAIL, "Overwriting non-cleared call-id");
|
||||
|
||||
ftdm_mutex_lock(globals.call_id_mutex);
|
||||
current_call_id = globals.last_call_id;
|
||||
|
||||
do {
|
||||
if (++current_call_id > MAX_CALLIDS) {
|
||||
current_call_id = 1;
|
||||
}
|
||||
if (globals.call_ids[current_call_id] != NULL) {
|
||||
continue;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
globals.last_call_id = current_call_id;
|
||||
caller_data->call_id = current_call_id;
|
||||
|
||||
globals.call_ids[current_call_id] = caller_data;
|
||||
ftdm_mutex_unlock(globals.call_id_mutex);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data)
|
||||
{
|
||||
ftdm_assert_return((caller_data->call_id && caller_data->call_id <= MAX_CALLIDS), FTDM_FAIL, "Clearing call with invalid call-id\n");
|
||||
ftdm_mutex_lock(globals.call_id_mutex);
|
||||
if (globals.call_ids[caller_data->call_id]) {
|
||||
caller_data->call_id = 0;
|
||||
globals.call_ids[caller_data->call_id] = NULL;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_CRIT, "call-id did not exist %u\n", caller_data->call_id);
|
||||
}
|
||||
ftdm_mutex_unlock(globals.call_id_mutex);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
|
||||
@@ -515,13 +515,20 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons
|
||||
ftdm_r2_data_t *r2data = ftdmchan->span->signal_data;
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Call offered with ANI = %s, DNIS = %s, Category = (%d)\n", ani, dnis, category);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
|
||||
/* nothing went wrong during call setup, MF has ended, we can and must disable the MF dump */
|
||||
if (r2data->mf_dump_size) {
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL);
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL);
|
||||
}
|
||||
|
||||
/* check if this is a collect call and if we should accept it */
|
||||
if (!r2data->allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Rejecting collect call\n");
|
||||
openr2_chan_disconnect_call(r2chan, OR2_CAUSE_COLLECT_CALL_REJECTED);
|
||||
} else {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -900,7 +907,7 @@ static int ftdm_r2_io_write(openr2_chan_t *r2chan, const void *buf, int size)
|
||||
if (FTDM_FAIL == status) {
|
||||
return -1;
|
||||
}
|
||||
return outsize;
|
||||
return (int)outsize;
|
||||
}
|
||||
|
||||
static int ftdm_r2_io_read(openr2_chan_t *r2chan, const void *buf, int size)
|
||||
@@ -911,7 +918,7 @@ static int ftdm_r2_io_read(openr2_chan_t *r2chan, const void *buf, int size)
|
||||
if (FTDM_FAIL == status) {
|
||||
return -1;
|
||||
}
|
||||
return outsize;
|
||||
return (int)outsize;
|
||||
}
|
||||
|
||||
static int ftdm_r2_io_wait(openr2_chan_t *r2chan, int *flags, int block)
|
||||
@@ -993,6 +1000,10 @@ static int ftdm_r2_io_get_oob_event(openr2_chan_t *r2chan, openr2_oob_event_t *e
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fevent->e_type != FTDM_EVENT_OOB) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (fevent->enum_id) {
|
||||
case FTDM_OOB_CAS_BITS_CHANGE:
|
||||
{
|
||||
@@ -1598,6 +1609,13 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
|
||||
}
|
||||
break;
|
||||
|
||||
/* INDICATE_RINGING doesn't apply to MFC/R2. maybe we could generate a tone */
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
{
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "RINGING indicated, ignoring it as it doesn't apply to MFC/R2\n");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Unhandled channel state change: %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
@@ -502,6 +502,8 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
/**************************************************************************/
|
||||
case FTDM_CHANNEL_STATE_COLLECT: /* IAM received but wating on digits */
|
||||
|
||||
isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
|
||||
|
||||
if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
|
||||
SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
|
||||
break;
|
||||
@@ -521,8 +523,8 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
/*now go to the RING state */
|
||||
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
|
||||
} else if (i >= g_ftdm_sngss7_data.min_digits) {
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, g_ftdm_sngss7_data.min_digits);
|
||||
} else if (i >= isup_intf->min_digits) {
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, isup_intf->min_digits);
|
||||
|
||||
/*now go to the RING state */
|
||||
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
@@ -532,7 +534,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) {
|
||||
SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n",
|
||||
i,
|
||||
g_ftdm_sngss7_data.min_digits,
|
||||
isup_intf->min_digits,
|
||||
ftdmchan->caller_data.dnis.digits);
|
||||
|
||||
/* start ISUP t35 */
|
||||
@@ -1520,9 +1522,6 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init)
|
||||
/* initalize the global gen_config flag */
|
||||
g_ftdm_sngss7_data.gen_config = 0;
|
||||
|
||||
/* min. number of digitis to wait for */
|
||||
g_ftdm_sngss7_data.min_digits = 7;
|
||||
|
||||
/* function trace initizalation */
|
||||
g_ftdm_sngss7_data.function_trace = 1;
|
||||
g_ftdm_sngss7_data.function_trace_level = 7;
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
/******************************************************************************/
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
#define MAX_NAME_LEN 10
|
||||
#define MAX_NAME_LEN 25
|
||||
#define MAX_PATH 255
|
||||
|
||||
#define MAX_CIC_LENGTH 5
|
||||
@@ -224,6 +224,7 @@ typedef struct sng_isup_intf {
|
||||
uint32_t isap;
|
||||
uint32_t clg_nadi;
|
||||
uint32_t cld_nadi;
|
||||
uint32_t min_digits;
|
||||
uint16_t t4;
|
||||
uint32_t t10;
|
||||
uint32_t t11;
|
||||
@@ -326,7 +327,6 @@ typedef struct sng_ss7_cfg {
|
||||
typedef struct ftdm_sngss7_data {
|
||||
sng_ss7_cfg_t cfg;
|
||||
int gen_config;
|
||||
int min_digits;
|
||||
int function_trace;
|
||||
int function_trace_level;
|
||||
int message_trace;
|
||||
|
||||
@@ -142,7 +142,7 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
|
||||
|
||||
if (!strcasecmp(var, "ch_map")) {
|
||||
/**********************************************************************/
|
||||
strcpy(isupCkt.ch_map, val);
|
||||
strncpy(isupCkt.ch_map, val, MAX_CIC_MAP_LENGTH-1);
|
||||
SS7_DEBUG("\tFound channel map \"%s\"\n", isupCkt.ch_map);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(var, "typeCntrl")) {
|
||||
@@ -393,7 +393,7 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset)
|
||||
for (i = 0; i < num_parms; i++) {
|
||||
/**********************************************************************/
|
||||
if (!strcasecmp(parm->var, "name")) {
|
||||
strcpy((char *)mtpLinkSet.name, parm->val);
|
||||
strncpy((char *)mtpLinkSet.name, parm->val, MAX_NAME_LEN-1);
|
||||
SS7_DEBUG("\tFound an \"mtp_linkset\" named = %s\n", mtpLinkSet.name);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "apc")) {
|
||||
@@ -508,7 +508,7 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *
|
||||
/* try to match the parameter to what we expect */
|
||||
/**********************************************************************/
|
||||
if (!strcasecmp(parm->var, "name")) {
|
||||
strcpy((char *)mtpLink->name, parm->val);
|
||||
strncpy((char *)mtpLink->name, parm->val, MAX_NAME_LEN-1);
|
||||
SS7_DEBUG("\tFound an \"mtp_link\" named = %s\n", mtpLink->name);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "span")) {
|
||||
@@ -827,7 +827,7 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route)
|
||||
/* try to match the parameter to what we expect */
|
||||
/**********************************************************************/
|
||||
if (!strcasecmp(parm->var, "name")) {
|
||||
strcpy((char *)mtpRoute.name, parm->val);
|
||||
strncpy((char *)mtpRoute.name, parm->val, MAX_NAME_LEN-1);
|
||||
SS7_DEBUG("\tFound an \"mtp_route\" named = %s\n", mtpRoute.name);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "dpc")) {
|
||||
@@ -999,7 +999,7 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
|
||||
/* try to match the parameter to what we expect */
|
||||
/**********************************************************************/
|
||||
if (!strcasecmp(parm->var, "name")) {
|
||||
strcpy((char *)sng_isup.name, parm->val);
|
||||
strncpy((char *)sng_isup.name, parm->val, MAX_NAME_LEN-1);
|
||||
SS7_DEBUG("\tFound an \"isup_interface\" named = %s\n", sng_isup.name);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "spc")) {
|
||||
@@ -1047,6 +1047,11 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
|
||||
SS7_DEBUG("\tFound MTP3 Route = %s\n", parm->val);
|
||||
}
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "min_digits")) {
|
||||
sng_isup.min_digits = atoi(parm->val);
|
||||
|
||||
SS7_DEBUG("\tFound min_digits = %d\n", sng_isup.min_digits);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "ssf")) {
|
||||
if (!strcasecmp(parm->val, "nat")) {
|
||||
sng_isup.ssf = SSF_NAT;
|
||||
@@ -1067,8 +1072,8 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "license")) {
|
||||
/**********************************************************************/
|
||||
strcpy(g_ftdm_sngss7_data.cfg.license, parm->val);
|
||||
strcpy(g_ftdm_sngss7_data.cfg.signature, parm->val);
|
||||
strncpy(g_ftdm_sngss7_data.cfg.license, parm->val, MAX_PATH-1);
|
||||
strncpy(g_ftdm_sngss7_data.cfg.signature, parm->val, MAX_PATH-1);
|
||||
strcat(g_ftdm_sngss7_data.cfg.signature, ".sig");
|
||||
SS7_DEBUG("\tFound license file = %s\n", g_ftdm_sngss7_data.cfg.license);
|
||||
SS7_DEBUG("\tFound signature file = %s\n", g_ftdm_sngss7_data.cfg.signature);
|
||||
@@ -1304,6 +1309,13 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
|
||||
sng_isup.clg_nadi = 0x03;
|
||||
}
|
||||
|
||||
/* check if the user requested min_digits value */
|
||||
if (sng_isup.min_digits == 0) {
|
||||
/* default to 7 */
|
||||
sng_isup.min_digits = 7;
|
||||
}
|
||||
|
||||
|
||||
/* trickle down the SPC to all sub entities */
|
||||
linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].linkSetId;
|
||||
|
||||
@@ -1359,7 +1371,7 @@ static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink)
|
||||
}
|
||||
|
||||
/* fill in the information */
|
||||
strcpy((char *)g_ftdm_sngss7_data.cfg.mtpLink[i].name, (char *)mtpLink->name);
|
||||
strncpy((char *)g_ftdm_sngss7_data.cfg.mtpLink[i].name, (char *)mtpLink->name, MAX_NAME_LEN-1);
|
||||
|
||||
g_ftdm_sngss7_data.cfg.mtpLink[i].id = mtpLink->id;
|
||||
|
||||
@@ -1521,7 +1533,7 @@ static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet)
|
||||
{
|
||||
int i = mtpLinkSet->id;
|
||||
|
||||
strcpy((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[i].name, (char *)mtpLinkSet->name);
|
||||
strncpy((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[i].name, (char *)mtpLinkSet->name, MAX_NAME_LEN-1);
|
||||
|
||||
g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id = mtpLinkSet->id;
|
||||
g_ftdm_sngss7_data.cfg.mtpLinkSet[i].apc = mtpLinkSet->apc;
|
||||
@@ -1559,7 +1571,7 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route)
|
||||
SS7_DEBUG("found existing mtp3_route, id is = %d\n", mtp3_route->id);
|
||||
}
|
||||
|
||||
strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, (char *)mtp3_route->name);
|
||||
strncpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, (char *)mtp3_route->name, MAX_NAME_LEN-1);
|
||||
|
||||
g_ftdm_sngss7_data.cfg.mtpRoute[i].id = mtp3_route->id;
|
||||
g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc = mtp3_route->dpc;
|
||||
@@ -1693,7 +1705,7 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup)
|
||||
SS7_DEBUG("found existing isup interface, id is = %d\n", sng_isup->id);
|
||||
}
|
||||
|
||||
strcpy((char *)g_ftdm_sngss7_data.cfg.isupIntf[i].name, (char *)sng_isup->name);
|
||||
strncpy((char *)g_ftdm_sngss7_data.cfg.isupIntf[i].name, (char *)sng_isup->name, MAX_NAME_LEN-1);
|
||||
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].id = sng_isup->id;
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].mtpRouteId = sng_isup->mtpRouteId;
|
||||
@@ -1705,6 +1717,7 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup)
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].isap = sng_isup->isap;
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].cld_nadi = sng_isup->cld_nadi;
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].clg_nadi = sng_isup->clg_nadi;
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].min_digits = sng_isup->min_digits;
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].options = sng_isup->options;
|
||||
if (sng_isup->t4 != 0) {
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].t4 = sng_isup->t4;
|
||||
@@ -1976,7 +1989,7 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[0].name, "self-rt");
|
||||
strncpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[0].name, "self-route", MAX_NAME_LEN-1);
|
||||
|
||||
g_ftdm_sngss7_data.cfg.mtpRoute[0].id = 0;
|
||||
g_ftdm_sngss7_data.cfg.mtpRoute[0].dpc = spc;
|
||||
@@ -2230,7 +2243,7 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot)
|
||||
int lower;
|
||||
int upper;
|
||||
char tmp[5]; /*KONRAD FIX ME*/
|
||||
char new_ch_map[MAX_CIC_LENGTH];
|
||||
char new_ch_map[MAX_CIC_MAP_LENGTH];
|
||||
|
||||
memset(&tmp[0], '\0', sizeof(tmp));
|
||||
memset(&new_ch_map[0], '\0', sizeof(new_ch_map));
|
||||
@@ -2337,7 +2350,9 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot)
|
||||
/* the the rest of ch_map to new_ch_map */
|
||||
strncat(new_ch_map, &ch_map[x], strlen(&ch_map[x]));
|
||||
|
||||
|
||||
/* set the new cic map to ch_map*/
|
||||
memset(ch_map, '\0', sizeof(ch_map));
|
||||
strcpy(ch_map, new_ch_map);
|
||||
|
||||
} else if (ch_map[x] == ',') {
|
||||
@@ -2345,16 +2360,21 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot)
|
||||
x++;
|
||||
|
||||
/* copy the rest of the list to new_ch_map */
|
||||
memset(new_ch_map, '\0', sizeof(new_ch_map));
|
||||
strcpy(new_ch_map, &ch_map[x]);
|
||||
|
||||
/* copy the new_ch_map over the old one */
|
||||
memset(ch_map, '\0', sizeof(ch_map));
|
||||
strcpy(ch_map, new_ch_map);
|
||||
|
||||
} else if (ch_map[x] == '\0') {
|
||||
|
||||
/* we're at the end of the string...copy the rest of the list to new_ch_map */
|
||||
memset(new_ch_map, '\0', sizeof(new_ch_map));
|
||||
strcpy(new_ch_map, &ch_map[x]);
|
||||
|
||||
/* set the new cic map to ch_map*/
|
||||
memset(ch_map, '\0', sizeof(ch_map));
|
||||
strcpy(ch_map, new_ch_map);
|
||||
} else {
|
||||
/* nothing to do */
|
||||
|
||||
@@ -295,6 +295,11 @@ typedef struct ftdm_caller_data {
|
||||
/* user information layer 1 protocol */
|
||||
ftdm_user_layer1_prot_t bearer_layer1;
|
||||
ftdm_variable_container_t variables; /*!<variables attached to this call */
|
||||
/* We need call_id inside caller_data for the user to be able to retrieve
|
||||
* the call_id when ftdm_channel_call_place is called. This is the only time
|
||||
* that the user can use caller_data.call_id to obtain the call_id. The user
|
||||
* should use the call_id from sigmsg otherwise */
|
||||
uint32_t call_id; /*!< Unique call ID for this call */
|
||||
} ftdm_caller_data_t;
|
||||
|
||||
/*! \brief Tone type */
|
||||
@@ -381,9 +386,10 @@ struct ftdm_sigmsg {
|
||||
ftdm_channel_t *channel; /*!< Related channel */
|
||||
uint32_t chan_id; /*!< easy access to chan id */
|
||||
uint32_t span_id; /*!< easy access to span_id */
|
||||
ftdm_signaling_status_t sigstatus; /*!< Signaling status (valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED) */
|
||||
ftdm_signaling_status_t sigstatus; /*!< Signaling status (valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED) */
|
||||
void *raw_data; /*!< Message specific data if any */
|
||||
uint32_t raw_data_len; /*!< Data len in case is needed */
|
||||
uint32_t call_id; /*!< unique call id for this call */
|
||||
};
|
||||
|
||||
/*! \brief Crash policy
|
||||
|
||||
@@ -52,11 +52,9 @@
|
||||
#if defined(__linux__) && !defined(__USE_BSD)
|
||||
#define __USE_BSD
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "freetdm.h"
|
||||
|
||||
|
||||
|
||||
@@ -39,8 +39,9 @@
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
@INSERT_MATH_HEADER@
|
||||
#if !defined(SPANDSP_NO_TIFF)
|
||||
#include <tiffio.h>
|
||||
|
||||
#endif
|
||||
#include <spandsp/telephony.h>
|
||||
#include <spandsp/fast_convert.h>
|
||||
#include <spandsp/logging.h>
|
||||
|
||||
+382
-85
@@ -27,6 +27,7 @@
|
||||
*/
|
||||
#include "stfu.h"
|
||||
|
||||
//#define DB_JB 1
|
||||
#ifdef _MSC_VER
|
||||
/* warning C4706: assignment within conditional expression*/
|
||||
#pragma warning(disable: 4706)
|
||||
@@ -35,9 +36,12 @@
|
||||
struct stfu_queue {
|
||||
struct stfu_frame *array;
|
||||
struct stfu_frame int_frame;
|
||||
uint32_t real_array_size;
|
||||
uint32_t array_size;
|
||||
uint32_t array_len;
|
||||
uint32_t wr_len;
|
||||
uint32_t last_index;
|
||||
int32_t last_jitter;
|
||||
};
|
||||
typedef struct stfu_queue stfu_queue_t;
|
||||
|
||||
@@ -48,27 +52,72 @@ struct stfu_instance {
|
||||
struct stfu_queue *out_queue;
|
||||
struct stfu_frame *last_frame;
|
||||
uint32_t cur_ts;
|
||||
uint32_t cur_seq;
|
||||
uint32_t last_wr_ts;
|
||||
uint32_t last_wr_seq;
|
||||
uint32_t last_rd_ts;
|
||||
uint32_t interval;
|
||||
uint32_t samples_per_packet;
|
||||
uint32_t samples_per_second;
|
||||
uint32_t miss_count;
|
||||
uint32_t max_plc;
|
||||
uint32_t qlen;
|
||||
uint32_t max_qlen;
|
||||
uint32_t orig_qlen;
|
||||
uint32_t packet_count;
|
||||
uint32_t consecutive_good_count;
|
||||
uint32_t consecutive_bad_count;
|
||||
uint32_t period_good_count;
|
||||
uint32_t period_bad_count;
|
||||
uint32_t period_packet_in_count;
|
||||
uint32_t period_packet_out_count;
|
||||
uint32_t period_missing_count;
|
||||
uint32_t period_need_range;
|
||||
uint32_t period_need_range_avg;
|
||||
uint32_t period_clean_count;
|
||||
|
||||
uint32_t session_clean_count;
|
||||
uint32_t session_missing_count;
|
||||
|
||||
uint32_t session_packet_in_count;
|
||||
uint32_t session_packet_out_count;
|
||||
|
||||
uint32_t sync;
|
||||
|
||||
|
||||
int32_t ts_diff;
|
||||
int32_t last_ts_diff;
|
||||
int32_t same_ts;
|
||||
|
||||
uint32_t last_seq;
|
||||
|
||||
uint32_t period_time;
|
||||
uint32_t decrement_time;
|
||||
|
||||
uint32_t plc_len;
|
||||
|
||||
stfu_n_call_me_t callback;
|
||||
void *udata;
|
||||
};
|
||||
|
||||
static void stfu_n_reset_counters(stfu_instance_t *i);
|
||||
|
||||
static stfu_status_t stfu_n_resize_aqueue(stfu_queue_t *queue, uint32_t qlen)
|
||||
{
|
||||
unsigned char *m;
|
||||
|
||||
if (qlen <= queue->array_size) {
|
||||
return STFU_IT_FAILED;;
|
||||
if (qlen <= queue->real_array_size) {
|
||||
queue->array_size = qlen;
|
||||
if (queue->array_len > qlen) {
|
||||
queue->array_len = qlen;
|
||||
}
|
||||
} else {
|
||||
m = realloc(queue->array, qlen * sizeof(struct stfu_frame));
|
||||
assert(m);
|
||||
memset(m + queue->array_size * sizeof(struct stfu_frame), 0, (qlen * sizeof(struct stfu_frame)) - (queue->array_size * sizeof(struct stfu_frame)));
|
||||
queue->array = (struct stfu_frame *) m;
|
||||
queue->real_array_size = queue->array_size = qlen;
|
||||
}
|
||||
|
||||
m = realloc(queue->array, qlen * sizeof(struct stfu_frame));
|
||||
assert(m);
|
||||
memset(m + queue->array_size, 0, qlen * sizeof(struct stfu_frame) - queue->array_size);
|
||||
queue->array = (struct stfu_frame *) m;
|
||||
queue->array_size = qlen;
|
||||
return STFU_IT_WORKED;
|
||||
}
|
||||
|
||||
@@ -77,8 +126,16 @@ static void stfu_n_init_aqueue(stfu_queue_t *queue, uint32_t qlen)
|
||||
queue->array = calloc(qlen, sizeof(struct stfu_frame));
|
||||
assert(queue->array != NULL);
|
||||
memset(queue->array, 0, sizeof(struct stfu_frame) * qlen);
|
||||
queue->array_size = qlen;
|
||||
queue->real_array_size = queue->array_size = qlen;
|
||||
queue->int_frame.plc = 1;
|
||||
memset(queue->int_frame.data, 255, sizeof(queue->int_frame.data));
|
||||
}
|
||||
|
||||
|
||||
void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata)
|
||||
{
|
||||
i->callback = callback;
|
||||
i->udata = udata;
|
||||
}
|
||||
|
||||
void stfu_n_destroy(stfu_instance_t **i)
|
||||
@@ -97,24 +154,40 @@ void stfu_n_destroy(stfu_instance_t **i)
|
||||
void stfu_n_report(stfu_instance_t *i, stfu_report_t *r)
|
||||
{
|
||||
assert(i);
|
||||
r->in_len = i->in_queue->array_len;
|
||||
r->in_size = i->in_queue->array_size;
|
||||
r->out_len = i->out_queue->array_len;
|
||||
r->out_size = i->out_queue->array_size;
|
||||
r->qlen = i->qlen;
|
||||
r->packet_in_count = i->period_packet_in_count;
|
||||
r->clean_count = i->period_clean_count;
|
||||
r->consecutive_good_count = i->consecutive_good_count;
|
||||
r->consecutive_bad_count = i->consecutive_bad_count;
|
||||
}
|
||||
|
||||
stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen)
|
||||
{
|
||||
stfu_status_t s;
|
||||
|
||||
if (i->qlen == i->max_qlen) {
|
||||
return STFU_IT_FAILED;
|
||||
}
|
||||
|
||||
if (i->max_qlen && qlen > i->max_qlen) {
|
||||
if (i->qlen < i->max_qlen) {
|
||||
qlen = i->max_qlen;
|
||||
} else {
|
||||
return STFU_IT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if ((s = stfu_n_resize_aqueue(&i->a_queue, qlen)) == STFU_IT_WORKED) {
|
||||
s = stfu_n_resize_aqueue(&i->b_queue, qlen);
|
||||
i->qlen = qlen;
|
||||
i->max_plc = 5;
|
||||
i->last_frame = NULL;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_plc)
|
||||
stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_per_packet, uint32_t samples_per_second)
|
||||
{
|
||||
struct stfu_instance *i;
|
||||
|
||||
@@ -123,82 +196,172 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_plc)
|
||||
return NULL;
|
||||
}
|
||||
memset(i, 0, sizeof(*i));
|
||||
i->qlen = qlen;
|
||||
i->max_qlen = max_qlen;
|
||||
i->orig_qlen = qlen;
|
||||
i->samples_per_packet = samples_per_packet;
|
||||
|
||||
stfu_n_init_aqueue(&i->a_queue, qlen);
|
||||
stfu_n_init_aqueue(&i->b_queue, qlen);
|
||||
i->in_queue = &i->a_queue;
|
||||
i->out_queue = &i->b_queue;
|
||||
|
||||
i->max_plc = i->qlen / 2;
|
||||
|
||||
if (max_plc) {
|
||||
i->max_plc = max_plc;
|
||||
} else {
|
||||
i->max_plc = qlen / 2;
|
||||
}
|
||||
i->samples_per_second = samples_per_second ? samples_per_second : 8000;
|
||||
|
||||
i->period_time = ((i->samples_per_second * 20) / i->samples_per_packet);
|
||||
i->decrement_time = ((i->samples_per_second * 15) / i->samples_per_packet);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void stfu_n_reset_counters(stfu_instance_t *i)
|
||||
{
|
||||
#ifdef DB_JB
|
||||
printf("COUNTER RESET........\n");
|
||||
#endif
|
||||
|
||||
if (i->callback) {
|
||||
i->callback(i, i->udata);
|
||||
}
|
||||
|
||||
i->consecutive_good_count = 0;
|
||||
i->consecutive_bad_count = 0;
|
||||
i->period_good_count = 0;
|
||||
i->period_clean_count = 0;
|
||||
i->period_bad_count = 0;
|
||||
i->period_packet_in_count = 0;
|
||||
i->period_packet_out_count = 0;
|
||||
i->period_missing_count = 0;
|
||||
i->period_need_range = 0;
|
||||
i->period_need_range_avg = 0;
|
||||
}
|
||||
|
||||
void stfu_n_reset(stfu_instance_t *i)
|
||||
{
|
||||
#ifdef DB_JB
|
||||
printf("RESET\n");
|
||||
#endif
|
||||
i->in_queue = &i->a_queue;
|
||||
i->out_queue = &i->b_queue;
|
||||
i->in_queue->array_len = 0;
|
||||
i->out_queue->array_len = 0;
|
||||
i->out_queue->wr_len = 0;
|
||||
i->last_frame = NULL;
|
||||
i->miss_count = 0;
|
||||
|
||||
i->in_queue->last_jitter = 0;
|
||||
i->out_queue->last_jitter = 0;
|
||||
|
||||
stfu_n_reset_counters(i);
|
||||
|
||||
i->last_seq = 0;
|
||||
|
||||
i->cur_ts = 0;
|
||||
i->cur_seq = 0;
|
||||
i->last_wr_ts = 0;
|
||||
i->miss_count = 0;
|
||||
i->interval = 0;
|
||||
i->last_wr_seq = 0;
|
||||
i->last_rd_ts = 0;
|
||||
i->miss_count = 0;
|
||||
i->packet_count = 0;
|
||||
}
|
||||
|
||||
static int32_t stfu_n_measure_interval(stfu_queue_t *queue)
|
||||
stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets)
|
||||
{
|
||||
uint32_t index;
|
||||
int32_t d, most = 0, last = 0, this, track[STFU_MAX_TRACK] = {0};
|
||||
|
||||
for(index = 0; index < queue->array_len; index++) {
|
||||
this = queue->array[index].ts;
|
||||
if (last) {
|
||||
if (packets > i->qlen) {
|
||||
stfu_n_reset(i);
|
||||
} else {
|
||||
i->sync = packets;
|
||||
}
|
||||
|
||||
if ((d = this - last) > 0 && d / 10 < STFU_MAX_TRACK) {
|
||||
track[(d/10)]++;
|
||||
}
|
||||
}
|
||||
|
||||
last = this;
|
||||
}
|
||||
|
||||
for(index = 0; index < STFU_MAX_TRACK; index++) {
|
||||
if (track[index] > track[most]) {
|
||||
most = index;
|
||||
}
|
||||
}
|
||||
|
||||
return most * 10;
|
||||
return STFU_IT_WORKED;
|
||||
}
|
||||
|
||||
static int16_t stfu_n_process(stfu_instance_t *i, stfu_queue_t *queue)
|
||||
{
|
||||
if (!i->interval && !(i->interval = stfu_n_measure_interval(queue))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, int last)
|
||||
stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uint32_t pt, void *data, size_t datalen, int last)
|
||||
{
|
||||
uint32_t index;
|
||||
stfu_frame_t *frame;
|
||||
size_t cplen = 0;
|
||||
int good_seq = 0, good_ts = 0;
|
||||
|
||||
if (!i->samples_per_packet && ts && i->last_rd_ts) {
|
||||
i->ts_diff = ts - i->last_rd_ts;
|
||||
|
||||
if (i->last_ts_diff == i->ts_diff) {
|
||||
if (++i->same_ts == 5) {
|
||||
i->samples_per_packet = i->ts_diff;
|
||||
}
|
||||
} else {
|
||||
i->same_ts = 0;
|
||||
}
|
||||
|
||||
i->last_ts_diff = i->ts_diff;
|
||||
|
||||
if (!i->samples_per_packet) {
|
||||
i->last_rd_ts = ts;
|
||||
return STFU_IT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (seq && seq == i->last_seq + 1) {
|
||||
good_seq = 1;
|
||||
}
|
||||
|
||||
if (ts && ts == i->last_rd_ts + i->samples_per_packet) {
|
||||
good_ts = 1;
|
||||
}
|
||||
|
||||
|
||||
if (good_seq || good_ts) {
|
||||
i->period_clean_count++;
|
||||
i->session_clean_count++;
|
||||
}
|
||||
|
||||
i->period_packet_in_count++;
|
||||
i->session_packet_in_count++;
|
||||
|
||||
if (i->session_packet_in_count == 150) {
|
||||
return STFU_IT_WORKED;
|
||||
}
|
||||
|
||||
i->period_need_range_avg = i->period_need_range / (i->period_missing_count || 1);
|
||||
|
||||
if (i->period_missing_count > i->qlen * 2) {
|
||||
stfu_n_resize(i, i->qlen + 1);
|
||||
stfu_n_reset_counters(i);
|
||||
}
|
||||
|
||||
if (i->qlen > i->orig_qlen && (i->consecutive_good_count > i->decrement_time || i->period_clean_count > i->decrement_time)) {
|
||||
stfu_n_resize(i, i->qlen - 1);
|
||||
stfu_n_reset_counters(i);
|
||||
stfu_n_sync(i, i->qlen);
|
||||
}
|
||||
|
||||
if ((i->period_packet_in_count > i->period_time)) {
|
||||
i->period_packet_in_count = 0;
|
||||
|
||||
if (i->period_missing_count == 0 && i->qlen > i->orig_qlen) {
|
||||
stfu_n_resize(i, i->qlen - 1);
|
||||
stfu_n_sync(i, i->qlen);
|
||||
}
|
||||
|
||||
stfu_n_reset_counters(i);
|
||||
}
|
||||
|
||||
#ifdef DB_JB
|
||||
printf("%u i=%u/%u - g:%u/%u c:%u/%u b:%u - %u/%u - %u %d\n",
|
||||
i->qlen, i->period_packet_in_count, i->period_time, i->consecutive_good_count,
|
||||
i->decrement_time, i->period_clean_count, i->decrement_time, i->consecutive_bad_count,
|
||||
seq, ts,
|
||||
i->period_missing_count, i->period_need_range_avg);
|
||||
#endif
|
||||
|
||||
|
||||
if (last || i->in_queue->array_len == i->in_queue->array_size) {
|
||||
stfu_queue_t *other_queue;
|
||||
|
||||
if (i->out_queue->wr_len < i->out_queue->array_len) {
|
||||
return STFU_IT_FAILED;
|
||||
}
|
||||
|
||||
other_queue = i->in_queue;
|
||||
i->in_queue = i->out_queue;
|
||||
i->out_queue = other_queue;
|
||||
@@ -207,57 +370,92 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void
|
||||
i->out_queue->wr_len = 0;
|
||||
i->last_frame = NULL;
|
||||
i->miss_count = 0;
|
||||
|
||||
if (stfu_n_process(i, i->out_queue) < 0) {
|
||||
if (i->in_queue->array_len == i->in_queue->array_size && i->out_queue->array_len == i->out_queue->array_size) {
|
||||
stfu_n_resize(i, i->out_queue->array_size * 2);
|
||||
}
|
||||
//return STFU_IT_FAILED;
|
||||
}
|
||||
for(index = 0; index < i->out_queue->array_len; index++) {
|
||||
i->out_queue->array[index].was_read = 0;
|
||||
}
|
||||
}
|
||||
i->in_queue->last_index = 0;
|
||||
i->out_queue->last_index = 0;
|
||||
i->out_queue->last_jitter = 0;
|
||||
}
|
||||
|
||||
if (last) {
|
||||
return STFU_IM_DONE;
|
||||
}
|
||||
|
||||
index = i->in_queue->array_len++;
|
||||
for(index = 0; index < i->out_queue->array_size; index++) {
|
||||
if (i->in_queue->array[index].was_read) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
index = i->in_queue->array_len++;
|
||||
|
||||
frame = &i->in_queue->array[index];
|
||||
|
||||
if ((cplen = datalen) > sizeof(frame->data)) {
|
||||
cplen = sizeof(frame->data);
|
||||
}
|
||||
|
||||
i->last_seq = seq;
|
||||
i->last_rd_ts = ts;
|
||||
i->packet_count++;
|
||||
|
||||
memcpy(frame->data, data, cplen);
|
||||
|
||||
frame->pt = pt;
|
||||
frame->ts = ts;
|
||||
frame->seq = seq;
|
||||
frame->dlen = cplen;
|
||||
frame->was_read = 0;
|
||||
|
||||
return STFU_IT_WORKED;
|
||||
}
|
||||
|
||||
static int stfu_n_find_frame(stfu_queue_t *queue, uint32_t ts, stfu_frame_t **r_frame, uint32_t *index)
|
||||
static int stfu_n_find_any_frame(stfu_instance_t *in, stfu_frame_t **r_frame)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
stfu_frame_t *frame = NULL;
|
||||
stfu_queue_t *queue;
|
||||
|
||||
assert(r_frame);
|
||||
|
||||
*r_frame = NULL;
|
||||
|
||||
for (queue = in->out_queue ; queue && queue != in->in_queue ; queue = in->in_queue) {
|
||||
|
||||
for(i = 0; i < queue->real_array_size; i++) {
|
||||
frame = &queue->array[i];
|
||||
if (!frame->was_read) {
|
||||
*r_frame = frame;
|
||||
queue->last_index = i;
|
||||
frame->was_read = 1;
|
||||
in->period_packet_out_count++;
|
||||
in->session_packet_out_count++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t ts, uint32_t seq, stfu_frame_t **r_frame)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
stfu_frame_t *frame = NULL;
|
||||
|
||||
assert(r_frame);
|
||||
assert(index);
|
||||
|
||||
*r_frame = NULL;
|
||||
|
||||
for(i = 0; i < queue->array_len; i++) {
|
||||
for(i = 0; i < queue->real_array_size; i++) {
|
||||
frame = &queue->array[i];
|
||||
|
||||
if (frame->ts == ts) {
|
||||
if ((seq && frame->seq == seq) || frame->ts == ts) {
|
||||
*r_frame = frame;
|
||||
*index = i;
|
||||
queue->last_index = i;
|
||||
frame->was_read = 1;
|
||||
in->period_packet_out_count++;
|
||||
in->session_packet_out_count++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -267,40 +465,139 @@ static int stfu_n_find_frame(stfu_queue_t *queue, uint32_t ts, stfu_frame_t **r_
|
||||
|
||||
stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
|
||||
{
|
||||
uint32_t index;
|
||||
stfu_frame_t *rframe = NULL;
|
||||
|
||||
if (((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) {
|
||||
int found = 0;
|
||||
|
||||
if (!i->samples_per_packet || ((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (i->cur_ts == 0) {
|
||||
i->cur_ts = i->out_queue->array[0].ts;
|
||||
} else {
|
||||
i->cur_ts += i->interval;
|
||||
i->cur_ts += i->samples_per_packet;
|
||||
}
|
||||
|
||||
if (i->cur_seq == 0) {
|
||||
i->cur_seq = i->out_queue->array[0].seq;
|
||||
} else {
|
||||
i->cur_seq++;
|
||||
}
|
||||
|
||||
if (stfu_n_find_frame(i->out_queue, i->cur_ts, &rframe, &index) || stfu_n_find_frame(i->in_queue, i->cur_ts, &rframe, &index)) {
|
||||
if (!(found = stfu_n_find_frame(i, i->out_queue, i->cur_ts, i->cur_seq, &rframe))) {
|
||||
found = stfu_n_find_frame(i, i->in_queue, i->cur_ts, i->cur_seq, &rframe);
|
||||
}
|
||||
|
||||
if (!found && i->sync) {
|
||||
#ifdef DB_JB
|
||||
printf("SYNC %u\n", i->sync);
|
||||
#endif
|
||||
if ((found = stfu_n_find_any_frame(i, &rframe))) {
|
||||
i->cur_seq = rframe->seq;
|
||||
i->cur_ts = rframe->ts;
|
||||
}
|
||||
i->sync--;
|
||||
}
|
||||
|
||||
|
||||
if (!found && i->samples_per_packet) {
|
||||
#ifdef DB_JB
|
||||
int y;
|
||||
stfu_frame_t *frame = NULL;
|
||||
#endif
|
||||
int32_t delay = i->last_rd_ts - i->cur_ts;
|
||||
uint32_t need = abs(i->last_rd_ts - i->cur_ts) / i->samples_per_packet;
|
||||
|
||||
|
||||
i->period_missing_count++;
|
||||
i->session_missing_count++;
|
||||
i->period_need_range += need;
|
||||
|
||||
#ifdef DB_JB
|
||||
printf("MISSING %u %u %u %u %d %u %d\n", i->cur_seq, i->cur_ts, i->packet_count, i->last_rd_ts, delay, i->qlen, need);
|
||||
#endif
|
||||
|
||||
if (i->packet_count > i->orig_qlen * 100 && delay > 0 && need > i->qlen && need < (i->qlen + 5)) {
|
||||
i->packet_count = 0;
|
||||
}
|
||||
|
||||
#ifdef DB_JB
|
||||
for(y = 0; y < i->out_queue->array_size; y++) {
|
||||
if ((y % 5) == 0) printf("\n");
|
||||
frame = &i->out_queue->array[y];
|
||||
printf("%u:%u\t", frame->seq, frame->ts);
|
||||
}
|
||||
printf("\n\n");
|
||||
|
||||
|
||||
for(y = 0; y < i->in_queue->array_size; y++) {
|
||||
if ((y % 5) == 0) printf("\n");
|
||||
frame = &i->in_queue->array[y];
|
||||
printf("%u:%u\t", frame->seq, frame->ts);
|
||||
}
|
||||
printf("\n\n");
|
||||
#endif
|
||||
|
||||
if (delay < 0) {
|
||||
stfu_n_reset(i);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DB_JB
|
||||
if (found) {
|
||||
printf("O: %u:%u %u\n", rframe->seq, rframe->seq, rframe->plc);
|
||||
assert(found && rframe->seq);
|
||||
} else {
|
||||
printf("DATA: %u %u %d %s %d\n", i->packet_count, i->consecutive_good_count, i->out_queue->last_jitter, found ? "found" : "not found", i->qlen);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (found) {
|
||||
i->consecutive_good_count++;
|
||||
i->period_good_count++;
|
||||
i->consecutive_bad_count = 0;
|
||||
} else {
|
||||
i->consecutive_bad_count++;
|
||||
i->period_bad_count++;
|
||||
i->consecutive_good_count = 0;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
i->last_frame = rframe;
|
||||
i->out_queue->wr_len++;
|
||||
i->last_wr_ts = rframe->ts;
|
||||
i->last_wr_seq = rframe->seq;
|
||||
i->miss_count = 0;
|
||||
if (rframe->dlen) {
|
||||
i->plc_len = rframe->dlen;
|
||||
}
|
||||
} else {
|
||||
i->last_wr_ts = i->cur_ts;
|
||||
i->last_wr_seq = i->cur_seq;
|
||||
rframe = &i->out_queue->int_frame;
|
||||
|
||||
if (i->last_frame && i->last_frame != rframe) {
|
||||
rframe->dlen = i->last_frame->dlen;
|
||||
rframe->dlen = i->plc_len;
|
||||
|
||||
if (i->last_frame) {
|
||||
/* poor man's plc.. Copy the last frame, but we flag it so you can use a better one if you wish */
|
||||
memcpy(rframe->data, i->last_frame->data, rframe->dlen);
|
||||
if (i->miss_count) {
|
||||
memset(rframe->data, 255, rframe->dlen);
|
||||
} else {
|
||||
memcpy(rframe->data, i->last_frame->data, rframe->dlen);
|
||||
}
|
||||
}
|
||||
|
||||
rframe->ts = i->cur_ts;
|
||||
|
||||
if (++i->miss_count > i->max_plc) {
|
||||
i->out_queue->wr_len = i->out_queue->array_size;
|
||||
i->cur_ts = 0;
|
||||
i->miss_count++;
|
||||
|
||||
#ifdef DB_JB
|
||||
printf("PLC %d %d %ld %u %u\n", i->miss_count, rframe->plc, rframe->dlen, rframe->seq, rframe->ts);
|
||||
#endif
|
||||
|
||||
if (i->miss_count > i->max_plc) {
|
||||
stfu_n_reset(i);
|
||||
rframe = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-8
@@ -75,6 +75,7 @@ typedef enum {
|
||||
struct stfu_frame {
|
||||
uint32_t ts;
|
||||
uint32_t pt;
|
||||
uint32_t seq;
|
||||
uint8_t data[STFU_DATALEN];
|
||||
size_t dlen;
|
||||
uint8_t was_read;
|
||||
@@ -86,24 +87,27 @@ struct stfu_instance;
|
||||
typedef struct stfu_instance stfu_instance_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t in_len;
|
||||
uint32_t in_size;
|
||||
uint32_t out_len;
|
||||
uint32_t out_size;
|
||||
|
||||
uint32_t qlen;
|
||||
uint32_t packet_in_count;
|
||||
uint32_t clean_count;
|
||||
uint32_t consecutive_good_count;
|
||||
uint32_t consecutive_bad_count;
|
||||
} stfu_report_t;
|
||||
|
||||
typedef void (*stfu_n_call_me_t)(stfu_instance_t *i, void *);
|
||||
|
||||
void stfu_n_report(stfu_instance_t *i, stfu_report_t *r);
|
||||
void stfu_n_destroy(stfu_instance_t **i);
|
||||
stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_plc);
|
||||
stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_per_packet, uint32_t samples_per_second);
|
||||
stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen);
|
||||
stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, int last);
|
||||
stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uint32_t pt, void *data, size_t datalen, int last);
|
||||
stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i);
|
||||
void stfu_n_reset(stfu_instance_t *i);
|
||||
stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets);
|
||||
void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata);
|
||||
|
||||
#define stfu_im_done(i) stfu_n_add_data(i, 0, NULL, 0, 1)
|
||||
#define stfu_n_eat(i,t,p,d,l) stfu_n_add_data(i, t, p, d, l, 0)
|
||||
#define stfu_n_eat(i,t,s,p,d,l) stfu_n_add_data(i, t, s, p, d, l, 0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user