From 34e44f92a193291a4a7303cd6f3e0b96e79ab080 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 6 Dec 2010 23:24:39 -0500 Subject: [PATCH 01/35] freetdm: OPENZAP-121 - ftmod_sangoma_ss7 compile error --- .../freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c index 4a9c863b12..8a24f971ed 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c @@ -1976,7 +1976,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-route"); + strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[0].name, "self-rt"); g_ftdm_sngss7_data.cfg.mtpRoute[0].id = 0; g_ftdm_sngss7_data.cfg.mtpRoute[0].dpc = spc; From 9350fb96265961fd87c1bcecdb4e0123cf77234f Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 7 Dec 2010 00:19:49 -0600 Subject: [PATCH 02/35] skypopen: added a second timer on read from Skype client (timer_read_srv), so not to depend anymore from select on that socket --- src/mod/endpoints/mod_skypopen/mod_skypopen.c | 20 +++++++++++++++++++ src/mod/endpoints/mod_skypopen/skypopen.h | 5 +++-- .../mod_skypopen/skypopen_protocol.c | 10 ++++++++-- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.c b/src/mod/endpoints/mod_skypopen/mod_skypopen.c index 1263e5f81a..65c1b120fd 100644 --- a/src/mod/endpoints/mod_skypopen/mod_skypopen.c +++ b/src/mod/endpoints/mod_skypopen/mod_skypopen.c @@ -526,6 +526,10 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session) switch_core_timer_destroy(&tech_pvt->timer_read); } + if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { + switch_core_timer_destroy(&tech_pvt->timer_read_srv); + } + if (tech_pvt->timer_write.timer_interface && tech_pvt->timer_write.timer_interface->timer_next) { switch_core_timer_destroy(&tech_pvt->timer_write); } @@ -1121,6 +1125,9 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) { switch_core_timer_sync(&tech_pvt->timer_read); } + if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { + switch_core_timer_sync(&tech_pvt->timer_read_srv); + } switch_mutex_unlock(tech_pvt->mutex_audio_srv); } @@ -1146,6 +1153,9 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) { switch_core_timer_sync(&tech_pvt->timer_read); } + if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { + switch_core_timer_sync(&tech_pvt->timer_read_srv); + } switch_mutex_unlock(tech_pvt->mutex_audio_srv); } @@ -1168,6 +1178,9 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) { switch_core_timer_sync(&tech_pvt->timer_read); } + if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { + switch_core_timer_sync(&tech_pvt->timer_read_srv); + } switch_mutex_unlock(tech_pvt->mutex_audio_srv); } @@ -2168,6 +2181,13 @@ int start_audio_threads(private_t *tech_pvt) switch_core_timer_sync(&tech_pvt->timer_read); + if (switch_core_timer_init(&tech_pvt->timer_read_srv, "soft", MS_SKYPOPEN, SAMPLES_PER_FRAME, skypopen_module_pool) != SWITCH_STATUS_SUCCESS) { + ERRORA("setup timer failed\n", SKYPOPEN_P_LOG); + return SWITCH_STATUS_FALSE; + } + + switch_core_timer_sync(&tech_pvt->timer_read_srv); + if (switch_core_timer_init(&tech_pvt->timer_write, "soft", MS_SKYPOPEN, SAMPLES_PER_FRAME, skypopen_module_pool) != SWITCH_STATUS_SUCCESS) { ERRORA("setup timer failed\n", SKYPOPEN_P_LOG); return SWITCH_STATUS_FALSE; diff --git a/src/mod/endpoints/mod_skypopen/skypopen.h b/src/mod/endpoints/mod_skypopen/skypopen.h index 4ff2b012c6..2f1c8e48e9 100644 --- a/src/mod/endpoints/mod_skypopen/skypopen.h +++ b/src/mod/endpoints/mod_skypopen/skypopen.h @@ -76,8 +76,8 @@ #define SAMPLERATE_SKYPOPEN 16000 #define MS_SKYPOPEN 20 -#define SAMPLES_PER_FRAME SAMPLERATE_SKYPOPEN/(1000/MS_SKYPOPEN) -#define BYTES_PER_FRAME SAMPLES_PER_FRAME * sizeof(short) +#define SAMPLES_PER_FRAME (SAMPLERATE_SKYPOPEN/(1000/MS_SKYPOPEN)) +#define BYTES_PER_FRAME (SAMPLES_PER_FRAME * sizeof(short)) #ifdef SKYPOPEN_C_VER #ifdef MODSKYPOPEN_C_VER @@ -341,6 +341,7 @@ struct private_object { chat_t chats[MAX_CHATS]; uint32_t report_incoming_chatmessages; switch_timer_t timer_read; + switch_timer_t timer_read_srv; switch_timer_t timer_write; int begin_to_write; int begin_to_read; diff --git a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c index ef06bfac1e..391a23caaf 100644 --- a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c +++ b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c @@ -547,6 +547,9 @@ int skypopen_signaling_read(private_t *tech_pvt) if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) { switch_core_timer_sync(&tech_pvt->timer_read); } + if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { + switch_core_timer_sync(&tech_pvt->timer_read_srv); + } switch_mutex_unlock(tech_pvt->mutex_audio_srv); } @@ -878,7 +881,7 @@ void *skypopen_do_tcp_srv_thread_func(void *obj) || tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPOPEN_STATE_UP)) { unsigned int fdselect; - int rt; + int rt=1; fd_set fs; struct timeval to; int nospace; @@ -891,7 +894,10 @@ void *skypopen_do_tcp_srv_thread_func(void *obj) to.tv_usec = MS_SKYPOPEN * 1000 * 3; to.tv_sec = 0; - rt = select(fdselect + 1, &fs, NULL, NULL, &to); + if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { + switch_core_timer_next(&tech_pvt->timer_read_srv); + } + //rt = select(fdselect + 1, &fs, NULL, NULL, &to); if (rt > 0) { if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) { From 673fcb6572401d909a44f0a0d4bda9ee819a9027 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 7 Dec 2010 09:44:38 -0500 Subject: [PATCH 03/35] freetdm: ftmod_r2 - set MF dumps for outgoing calls too --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 46 +++++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 0348c8b57e..2048d27d4b 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -56,7 +56,10 @@ typedef enum { FTDM_R2_RUNNING = (1 << 0), } ftdm_r2_flag_t; -/* private call information stored in ftdmchan->call_data void* ptr */ +/* private call information stored in ftdmchan->call_data void* ptr, + * remember that each time you add a new member to this structure + * most likely you want to clear it in ft_r2_clean_call function + * */ #define R2CALL(ftdmchan) ((ftdm_r2_call_t*)((ftdmchan)->call_data)) typedef struct ftdm_r2_call_t { openr2_chan_t *r2chan; @@ -322,8 +325,20 @@ static openr2_call_disconnect_cause_t ftdm_r2_ftdm_cause_to_openr2_cause(ftdm_ch static void ft_r2_clean_call(ftdm_r2_call_t *call) { openr2_chan_t *r2chan = call->r2chan; - memset(call, 0, sizeof(*call)); + + /* Do not memset call structure, that clears values we do not want to clear, + * like the log name set in on_call_log_created() */ call->r2chan = r2chan; + call->accepted = 0; + call->answer_pending = 0; + call->disconnect_rcvd = 0; + call->ftdm_call_started = 0; + call->protocol_error = 0; + call->chanstate = FTDM_CHANNEL_STATE_DOWN; + call->dnis_index = 0; + call->ani_index = 0; + call->name[0] = 0; + call->txdrops = 0; } static void ft_r2_accept_call(ftdm_channel_t *ftdmchan) @@ -367,6 +382,12 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN; ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DIALING); + /* start io dump */ + if (r2data->mf_dump_size) { + ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_INPUT_DUMP, &r2data->mf_dump_size); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_OUTPUT_DUMP, &r2data->mf_dump_size); + } + callstatus = openr2_chan_make_call(R2CALL(ftdmchan)->r2chan, ftdmchan->caller_data.cid_num.digits, ftdmchan->caller_data.dnis.digits, @@ -382,6 +403,7 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) ftdm_channel_state2str(ftdmchan->state)); return FTDM_BREAK; } + return FTDM_SUCCESS; } @@ -414,7 +436,7 @@ static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_channel_sig_status) } /* always called from the monitor thread */ -static void ftdm_r2_on_call_init(openr2_chan_t *r2chan, const char *logname) +static void ftdm_r2_on_call_init(openr2_chan_t *r2chan) { ftdm_r2_call_t *r2call; ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); @@ -447,8 +469,6 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan, const char *logname) ft_r2_clean_call(ftdmchan->call_data); r2call = R2CALL(ftdmchan); - snprintf(r2call->logname, sizeof(r2call->logname), "%s", logname); - /* start io dump */ if (r2data->mf_dump_size) { ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_INPUT_DUMP, &r2data->mf_dump_size); @@ -459,6 +479,7 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan, const char *logname) ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); } +static void dump_mf(openr2_chan_t *r2chan); /* only called for incoming calls when the ANI, DNIS etc is complete and the user has to decide either to accept or reject the call */ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis, openr2_calling_party_category_t category) { @@ -468,6 +489,8 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons 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); + dump_mf(r2chan); + /* 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); @@ -759,6 +782,16 @@ static void ftdm_r2_on_ani_digit_received(openr2_chan_t *r2chan, char digit) R2CALL(ftdmchan)->ani_index = collected_len; } +static void ftdm_r2_on_billing_pulse(openr2_chan_t *r2chan) {} + +static void ftdm_r2_on_call_log_created(openr2_chan_t *r2chan, const char *logname) +{ + ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); + ftdm_r2_call_t *r2call = R2CALL(ftdmchan); + /* this is used when dumping I/O for debugging */ + snprintf(r2call->logname, sizeof(r2call->logname), "%s", logname); +} + static openr2_event_interface_t ftdm_r2_event_iface = { /* .on_call_init */ ftdm_r2_on_call_init, /* .on_call_offered */ ftdm_r2_on_call_offered, @@ -779,7 +812,8 @@ static openr2_event_interface_t ftdm_r2_event_iface = { /* .on_ani_digit_received */ ftdm_r2_on_ani_digit_received, /* so far we do nothing with billing pulses */ - /* .on_billing_pulse_received */ NULL, + /* .on_billing_pulse_received */ ftdm_r2_on_billing_pulse, + /* .on_call_log_created */ ftdm_r2_on_call_log_created, }; static int ftdm_r2_io_set_cas(openr2_chan_t *r2chan, int cas) From d4f512083f14b0ff7058df292a16424be758d3ac Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Tue, 7 Dec 2010 13:58:44 -0200 Subject: [PATCH 04/35] freetdm: ftmod_r2 - added cast to properly malloc io dump buffer on win64 --- libs/freetdm/src/ftdm_io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 3b46394709..3e4cce676d 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -163,7 +163,7 @@ static ftdm_status_t start_chan_io_dump(ftdm_channel_t *chan, ftdm_io_dump_t *du return FTDM_FAIL; } memset(dump, 0, sizeof(*dump)); - dump->buffer = ftdm_malloc(size); + dump->buffer = ftdm_malloc((uint32_t)size); if (!dump->buffer) { return FTDM_FAIL; } @@ -2814,7 +2814,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co GOTO_STATUS(done, FTDM_FAIL); } dump_chan_io_to_file(ftdmchan, &ftdmchan->rxdump, obj); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %zd to file %p\n", ftdmchan->rxdump.size, obj); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %d to file %p\n", ftdmchan->rxdump.size, obj); GOTO_STATUS(done, FTDM_SUCCESS); } break; From 5d288a9a4f3feee2eb2bcb536a6a131309d2c71d Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Tue, 7 Dec 2010 14:18:38 -0200 Subject: [PATCH 05/35] freetdm: fix testsangomaboost compilation --- libs/freetdm/src/testsangomaboost.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/freetdm/src/testsangomaboost.c b/libs/freetdm/src/testsangomaboost.c index 85b5332635..84ff287830 100644 --- a/libs/freetdm/src/testsangomaboost.c +++ b/libs/freetdm/src/testsangomaboost.c @@ -49,7 +49,9 @@ #include #include #ifdef __linux__ +#ifndef __USE_BSD #define __USE_BSD +#endif #include #endif #include "freetdm.h" From b4cb165115eec01a83cd2ce9c00cb1b8cefd5e20 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 7 Dec 2010 11:33:51 -0500 Subject: [PATCH 06/35] freetdm:Changes to transmit facilityStr in PROGRESS and ALERT messages --- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c | 8 ++++++-- .../ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c | 3 +-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c index 08b14a08ce..752ac40641 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c @@ -341,6 +341,7 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ memset(&cnStEvnt, 0, sizeof(cnStEvnt)); set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); + set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, signal_data->dchan_id, sngisdn_info->ces)) { @@ -366,6 +367,7 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind memset(&cnStEvnt, 0, sizeof(cnStEvnt)); set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); + set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending ALERT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); @@ -424,6 +426,7 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan) } set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); + set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) { @@ -522,7 +525,8 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan) memset(&discEvnt, 0, sizeof(discEvnt)); - /* Fill discEvnt here */ + /* Fill discEvnt here */ + /* TODO move this to set_cause_ie function */ discEvnt.causeDgn[0].eh.pres = PRSNT_NODEF; discEvnt.causeDgn[0].location.pres = PRSNT_NODEF; discEvnt.causeDgn[0].location.val = IN_LOC_PRIVNETLU; @@ -559,7 +563,7 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare) memset(&relEvnt, 0, sizeof(relEvnt)); - /* Fill discEvnt here */ + /* Fill relEvnt here */ relEvnt.causeDgn[0].eh.pres = PRSNT_NODEF; relEvnt.causeDgn[0].location.pres = PRSNT_NODEF; relEvnt.causeDgn[0].location.val = IN_LOC_PRIVNETLU; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index 42bcd1e20a..565781aa41 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -560,9 +560,8 @@ ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t *data_len) { ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - - if (caller_data->raw_data_len > 0 && caller_data->raw_data[0] == SNGISDN_Q931_FACILITY_IE_ID) { + if (caller_data->raw_data_len > 0 && caller_data->raw_data[0] == SNGISDN_Q931_FACILITY_IE_ID) { *data_len = caller_data->raw_data[1]; memcpy(data, &caller_data->raw_data[2], *data_len); return FTDM_SUCCESS; From a40f92674f8fc7c07d531c5d6d11688c4b2aec05 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 7 Dec 2010 11:42:36 -0500 Subject: [PATCH 07/35] Fix for compile error --- .../ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index 16b22a5da1..086354a993 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -328,8 +328,6 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; ISDN_FUNC_TRACE_ENTER(__FUNCTION__); From 6a36b8f33faa20d4c4b1aa516feb0c6bf30be429 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 7 Dec 2010 09:59:56 -0500 Subject: [PATCH 08/35] freetdm: isdn stack and testsangomaboost warning fix --- .../ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c | 2 -- libs/freetdm/src/testsangomaboost.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index 16b22a5da1..086354a993 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -328,8 +328,6 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; ISDN_FUNC_TRACE_ENTER(__FUNCTION__); diff --git a/libs/freetdm/src/testsangomaboost.c b/libs/freetdm/src/testsangomaboost.c index 85b5332635..61b7c47ddd 100644 --- a/libs/freetdm/src/testsangomaboost.c +++ b/libs/freetdm/src/testsangomaboost.c @@ -48,7 +48,7 @@ #include #include #include -#ifdef __linux__ +#if defined(__linux__) && !defined(__USE_BSD) #define __USE_BSD #include #endif From 60cb91b042cf62186a9f967ab668dfc6c919f6ae Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Tue, 7 Dec 2010 20:06:48 +0100 Subject: [PATCH 09/35] freetdm: ftmod_libpri + ftmod_zt: some DAHDI drivers return an error of ELAST (500) on read()/write() to indicate there are events pending. Fixup zt_read() to handle this case correctly and rework ftmod_libpri's read wrapper function to not fail when the read function returns zero bytes. NOTE: zt_write() has not been changed (some better way to handle these events is needed then) This should fix these log messages: [WARNING] ftdm_io.c:3561 [s1c16][1:16] raw I/O read filed [CRIT] lpwrap_pri.c:125 span 1 D-READ FAIL! [] [CRIT] lpwrap_pri.c:157 span 1 D-WRITE FAIL! [] [ERR] ftmod_libpri.c:131 Short write: -1/6 (Unknown error 500) Signed-off-by: Stefan Knoblich --- .../src/ftmod/ftmod_libpri/lpwrap_pri.c | 17 +++++++------ libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 25 ++++++++++++++----- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c index de4fa2b232..fbe6ca0822 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c @@ -134,17 +134,18 @@ static int __pri_lpwrap_read(struct pri *pri, void *buf, int buflen) spri->errs = 0; res = (int)len; - memset(&((unsigned char*)buf)[res], 0, 2); - res += 2; - + if (res > 0) { + memset(&((unsigned char*)buf)[res], 0, 2); + res += 2; #ifdef IODEBUG - { - char bb[2048] = { 0 }; + { + char bb[2048] = { 0 }; - print_hex_bytes(buf, res - 2, bb, sizeof(bb)); - ftdm_log(FTDM_LOG_DEBUG, "READ %d\n", res - 2); - } + print_hex_bytes(buf, res - 2, bb, sizeof(bb)); + ftdm_log(FTDM_LOG_DEBUG, "READ %d\n", res - 2); + } #endif + } return res; } diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index 9247edc72e..7320934a49 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -35,6 +35,11 @@ #include "private/ftdm_core.h" #include "ftmod_zt.h" +/* used by dahdi to indicate there is no data available, but events to read */ +#ifndef ELAST +#define ELAST 500 +#endif + /** * \brief Zaptel globals */ @@ -1081,7 +1086,6 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) } return FTDM_FAIL; - } /** @@ -1100,12 +1104,19 @@ static FIO_READ_FUNCTION(zt_read) if ((r = read(ftdmchan->sockfd, data, *datalen)) > 0) { break; } - ftdm_sleep(10); - if (r == 0) { - errs--; + else if (r == 0) { + ftdm_sleep(10); + if (errs) errs--; + } + else { + if (errno == EAGAIN || errno == EINTR) + continue; + if (errno == ELAST) + break; + + ftdm_log(FTDM_LOG_ERROR, "read failed: %s\n", strerror(errno)); } } - if (r > 0) { *datalen = r; if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) { @@ -1113,7 +1124,9 @@ static FIO_READ_FUNCTION(zt_read) } return FTDM_SUCCESS; } - + else if (errno == ELAST) { + return FTDM_SUCCESS; + } return r == 0 ? FTDM_TIMEOUT : FTDM_FAIL; } From 10885336264f64ad8b737b313aeb70089cd6e57b Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Tue, 7 Dec 2010 18:14:03 -0200 Subject: [PATCH 10/35] freetdm: removed dump_mf() debug call from ftmod_r2 and added a comment to ftdm_io --- libs/freetdm/src/ftdm_io.c | 2 ++ libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index cde3c245cf..13c0652901 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -163,6 +163,8 @@ static ftdm_status_t start_chan_io_dump(ftdm_channel_t *chan, ftdm_io_dump_t *du return FTDM_FAIL; } memset(dump, 0, sizeof(*dump)); + /* on 64bits, we get a weird number if we don't cast to uint here + * which is what size_t will be anyway */ dump->buffer = ftdm_malloc((uint32_t)size); if (!dump->buffer) { return FTDM_FAIL; diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 2048d27d4b..30221e149d 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -489,8 +489,6 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons 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); - dump_mf(r2chan); - /* 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); From d25cb0282b1d6db944cd27eb7e87de484eab8225 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Tue, 7 Dec 2010 20:33:23 -0200 Subject: [PATCH 11/35] freetdm: ftmod_r2 - fixed complation warnings on windows --- libs/freetdm/src/ftdm_io.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 13c0652901..b7f8d7ee26 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -102,7 +102,7 @@ static void write_chan_io_dump(ftdm_io_dump_t *dump, char *dataptr, int dlen) if (dlen > avail) { int diff = dlen - avail; - ftdm_assert(diff < dump->size, "Very small buffer or very big IO chunk!\n"); + ftdm_assert(diff < (int)dump->size, "Very small buffer or very big IO chunk!\n"); /* write only what we can and the rest at the beginning of the buffer */ memcpy(&dump->buffer[windex], dataptr, avail); @@ -116,7 +116,7 @@ static void write_chan_io_dump(ftdm_io_dump_t *dump, char *dataptr, int dlen) windex += dlen; } - if (windex == dump->size) { + if (windex == (int)dump->size) { /*ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "wrapping around dump buffer %p\n", dump);*/ windex = 0; dump->wrapped = 1; @@ -3398,8 +3398,8 @@ 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) { - int dlen = (int) *datalen; - if (write(ftdmchan->fds[FTDM_READ_TRACE_INDEX], data, dlen) != dlen) { + ftdm_size_t dlen = *datalen; + if ((ftdm_size_t)write(ftdmchan->fds[FTDM_READ_TRACE_INDEX], data, dlen) != dlen) { ftdm_log(FTDM_LOG_WARNING, "Raw input trace failed to write all of the %zd bytes\n", dlen); } } @@ -3409,8 +3409,8 @@ static FIO_READ_FUNCTION(ftdm_raw_read) } if (status == FTDM_SUCCESS) { - int dlen = (int) *datalen; - size_t rc = 0; + ftdm_size_t dlen = *datalen; + ftdm_size_t rc = 0; write_chan_io_dump(&ftdmchan->rxdump, data, dlen); From 37cdd5b93466811988b6a413165d579a9fa548f0 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 7 Dec 2010 18:31:32 -0500 Subject: [PATCH 12/35] freetdm: more analog changes to attempt to make the state transitions more similar to other signaling modules --- libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c | 5 +++-- .../src/ftmod/ftmod_analog_em/ftmod_analog_em.c | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c index 95002e3e70..f07f48b0d6 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c @@ -491,9 +491,10 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) ftdm_channel_command(ftdmchan, FTDM_COMMAND_GENERATE_RING_OFF, NULL); } - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && + if (ftdmchan->type == FTDM_CHAN_TYPE_FXS && + ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && (ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE - || ftdmchan->last_state >= FTDM_CHANNEL_STATE_RING)) { + || ftdmchan->last_state == FTDM_CHANNEL_STATE_RING)) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); } else { ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING; diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c index 199bba43a3..886c4a8fec 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c @@ -329,8 +329,8 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) { if (state_counter > 500) { if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && - (ftdmchan->last_state == FTDM_CHANNEL_STATE_RING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE - || ftdmchan->last_state >= FTDM_CHANNEL_STATE_IDLE)) { + (ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE + || ftdmchan->last_state == FTDM_CHANNEL_STATE_RING)) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); } else { ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING; @@ -340,7 +340,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) } break; case FTDM_CHANNEL_STATE_UP: - case FTDM_CHANNEL_STATE_IDLE: + case FTDM_CHANNEL_STATE_RING: { ftdm_sleep(interval); continue; @@ -386,7 +386,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) ftdm_channel_use(ftdmchan); } break; - case FTDM_CHANNEL_STATE_IDLE: + case FTDM_CHANNEL_STATE_RING: { ftdm_channel_use(ftdmchan); @@ -421,7 +421,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) ftdm_channel_command(ftdmchan, FTDM_COMMAND_WINK, NULL); } break; - case FTDM_CHANNEL_STATE_RING: + case FTDM_CHANNEL_STATE_RINGING: { ftdm_buffer_zero(dt_buffer); teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]); @@ -477,7 +477,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) > analog_data->max_dialstr))) { ftdm_log(FTDM_LOG_DEBUG, "Number obtained [%s]\n", dtmf); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING); last_digit = 0; collecting = 0; } From 72bcc01b1d975c6d2667cd4762addcff50f1b140 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Tue, 7 Dec 2010 22:32:38 -0600 Subject: [PATCH 13/35] FS-2210 Add support for auto completion for uuid_simplify --- .../applications/mod_commands/mod_commands.c | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index c7edfd5420..eacde59949 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2491,24 +2491,47 @@ SWITCH_STANDARD_API(uuid_display_function) #define SIMPLIFY_SYNTAX "" SWITCH_STANDARD_API(uuid_simplify_function) { + char *mydata = NULL, *argv[2] = { 0 }; + int argc = 0; + switch_status_t status = SWITCH_STATUS_FALSE; if (zstr(cmd)) { - stream->write_function(stream, "-USAGE: %s\n", SIMPLIFY_SYNTAX); - } else { + goto error; + } + + mydata = strdup(cmd); + switch_assert(mydata); + + argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + + if (argc < 1) { + goto error; + } + if (argv[0]) { switch_core_session_message_t msg = { 0 }; switch_core_session_t *lsession = NULL; msg.message_id = SWITCH_MESSAGE_INDICATE_SIMPLIFY; - msg.string_arg = cmd; + msg.string_arg = argv[0]; msg.from = __FILE__; - if ((lsession = switch_core_session_locate(cmd))) { + if ((lsession = switch_core_session_locate(argv[0]))) { status = switch_core_session_receive_message(lsession, &msg); switch_core_session_rwunlock(lsession); } + goto ok; + } else { + goto error; } + error: + stream->write_function(stream, "-USAGE: %s\n", SIMPLIFY_SYNTAX); + switch_safe_free(mydata); + return SWITCH_STATUS_SUCCESS; + ok: + switch_safe_free(mydata); + if (status == SWITCH_STATUS_SUCCESS) { stream->write_function(stream, "+OK Success\n"); } else { @@ -4853,6 +4876,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add uuid_session_heartbeat ::console::list_uuid"); switch_console_set_complete("add uuid_setvar_multi ::console::list_uuid"); switch_console_set_complete("add uuid_setvar ::console::list_uuid"); + switch_console_set_complete("add uuid_simplify ::console::list_uuid"); switch_console_set_complete("add uuid_transfer ::console::list_uuid"); switch_console_set_complete("add uuid_dual_transfer ::console::list_uuid"); switch_console_set_complete("add version"); From 32e28540db33d19109d32247d2395bb749cacf1b Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 8 Dec 2010 06:22:46 -0500 Subject: [PATCH 14/35] freetdm: ftmod_wanpipe - implement tx and rx flush command --- .../freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index c8b8868acd..0bafa40bdd 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -756,6 +756,16 @@ static FIO_COMMAND_FUNCTION(wanpipe_command) err = sangoma_flush_bufs(ftdmchan->sockfd, &tdm_api); } break; + case FTDM_COMMAND_FLUSH_RX_BUFFERS: + { + err = sangoma_flush_rx_bufs(ftdmchan->sockfd, &tdm_api); + } + case FTDM_COMMAND_FLUSH_TX_BUFFERS: + break; + { + err = sangoma_flush_tx_bufs(ftdmchan->sockfd, &tdm_api); + } + break; case FTDM_COMMAND_FLUSH_IOSTATS: { err = sangoma_flush_stats(ftdmchan->sockfd, &tdm_api); @@ -775,12 +785,13 @@ static FIO_COMMAND_FUNCTION(wanpipe_command) } break; default: + err = FTDM_NOTIMPL; break; }; if (err) { snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno)); - return FTDM_FAIL; + return err; } From 71a902d258cbea2302faf75b3bfa058567c49200 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 8 Dec 2010 09:09:14 -0500 Subject: [PATCH 15/35] freetdm: Added core rx and tx drops Added sig_write callback ftmod_r2 - Added IO stats flag during call setup - Disable user read and writes during call setup --- libs/freetdm/src/ftdm_io.c | 61 +++++++++++++-- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 75 ++++++++++++++++--- libs/freetdm/src/include/private/ftdm_core.h | 3 + libs/freetdm/src/include/private/ftdm_types.h | 3 + 4 files changed, 127 insertions(+), 15 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index b7f8d7ee26..3206ee4313 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2254,7 +2254,7 @@ static ftdm_status_t call_hangup(ftdm_channel_t *chan, const char *file, const c } else { /* the signaling stack did not touch the state, * core is responsible from clearing flags and stuff */ - ftdm_channel_done(chan); + ftdm_channel_close(&chan); } return FTDM_SUCCESS; } @@ -2557,8 +2557,14 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdm_span_send_signal(ftdmchan->span, &sigmsg); } + if (ftdmchan->txdrops || ftdmchan->rxdrops) { + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n", + ftdmchan->txdrops, ftdmchan->rxdrops); + } + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n"); + ftdm_mutex_unlock(ftdmchan->mutex); return FTDM_SUCCESS; @@ -3385,6 +3391,16 @@ skipdebug: static FIO_WRITE_FUNCTION(ftdm_raw_write) { int dlen = (int) *datalen; + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TX_DISABLED)) { + ftdmchan->txdrops++; + if (ftdmchan->txdrops <= 10) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "cannot write in channel with tx disabled\n"); + } + if (ftdmchan->txdrops == 10) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Too many tx drops, not printing anymore\n"); + } + return FTDM_FAIL; + } if (ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] > -1) { if ((write(ftdmchan->fds[FTDM_WRITE_TRACE_INDEX], data, dlen)) != dlen) { ftdm_log(FTDM_LOG_WARNING, "Raw output trace failed to write all of the %zd bytes\n", dlen); @@ -3557,6 +3573,18 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data goto done; } + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED)) { + ftdmchan->rxdrops++; + if (ftdmchan->rxdrops <= 10) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "cannot read from channel with rx disabled\n"); + } + if (ftdmchan->rxdrops == 10) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "too many rx drops, not logging anymore\n"); + } + status = FTDM_FAIL; + goto done; + } + status = ftdm_raw_read(ftdmchan, data, datalen); if (status != FTDM_SUCCESS) { @@ -3756,7 +3784,7 @@ done: FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t datasize, ftdm_size_t *datalen) { - ftdm_status_t status = FTDM_FAIL; + ftdm_status_t status = FTDM_SUCCESS; fio_codec_t codec_func = NULL; ftdm_size_t max = datasize; unsigned int i = 0; @@ -3764,22 +3792,28 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel on write!\n"); ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "null I/O on write!\n"); + ftdm_channel_lock(ftdmchan); + if (!ftdmchan->buffer_delay && ((ftdmchan->dtmf_buffer && ftdm_buffer_inuse(ftdmchan->dtmf_buffer)) || (ftdmchan->fsk_buffer && ftdm_buffer_inuse(ftdmchan->fsk_buffer)))) { /* read size writing DTMF ATM */ - return FTDM_SUCCESS; + goto done; } if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "cannot write in channel not open\n"); snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "channel not open"); - return FTDM_FAIL; + status = FTDM_FAIL; + goto done; } if (!ftdmchan->fio->write) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "write method not implemented\n"); snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "method not implemented"); - return FTDM_FAIL; + status = FTDM_FAIL; + goto done; } if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) { @@ -3796,10 +3830,13 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat if (codec_func) { status = codec_func(data, max, datalen); } else { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Do not know how to handle transcoding from %d to %d\n", + ftdmchan->effective_codec, ftdmchan->native_codec); snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!"); status = FTDM_FAIL; + goto done; } - } + } if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_USE_TX_GAIN) && (ftdmchan->native_codec == FTDM_CODEC_ALAW || ftdmchan->native_codec == FTDM_CODEC_ULAW)) { @@ -3809,8 +3846,20 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat } } + if (ftdmchan->span->sig_write) { + status = ftdmchan->span->sig_write(ftdmchan, data, datalen); + if (status == FTDM_BREAK) { + /* signaling module decided to drop user frame */ + status = FTDM_SUCCESS; + goto done; + } + } + status = ftdm_raw_write(ftdmchan, data, datalen); +done: + ftdm_channel_unlock(ftdmchan); + return status; } diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 30221e149d..21f7a1202c 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -73,7 +73,6 @@ typedef struct ftdm_r2_call_t { ftdm_size_t ani_index; char logname[255]; char name[10]; - unsigned long txdrops; } ftdm_r2_call_t; /* this is just used as place holder in the stack when configuring the span to avoid using bunch of locals */ @@ -129,6 +128,12 @@ typedef struct ftdm_r2_data_s { uint64_t total_loops; /* number of loops per 10ms increment from 0-9ms, 10-19ms .. 100ms and above */ uint64_t loops[11]; + /* Total number of sleeps performed so far */ + uint64_t total_sleeps; + /* number of sleeps per 10ms increment from 0-9ms, 10-19ms .. 100ms and above */ + uint64_t sleeps[11]; + /* max time spent in ms sleeping in a single loop */ + int32_t sleepmax; /* LWP */ uint32_t monitor_thread_id; /* Logging directory */ @@ -338,7 +343,6 @@ static void ft_r2_clean_call(ftdm_r2_call_t *call) call->dnis_index = 0; call->ani_index = 0; call->name[0] = 0; - call->txdrops = 0; } static void ft_r2_accept_call(ftdm_channel_t *ftdmchan) @@ -404,6 +408,10 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) return FTDM_BREAK; } + ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_TX_BUFFERS, NULL); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_RX_BUFFERS, NULL); + return FTDM_SUCCESS; } @@ -477,6 +485,9 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan) R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN; ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); + ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_TX_BUFFERS, NULL); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_RX_BUFFERS, NULL); } static void dump_mf(openr2_chan_t *r2chan); @@ -556,6 +567,11 @@ static void ftdm_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t m /* at this point the MF signaling has ended and there is no point on keep reading */ openr2_chan_disable_read(r2chan); + + /* at this point we are no longer responsible for reading and writing, + * we are not interested in the stats anymore */ + ftdm_channel_clear_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS); + R2CALL(ftdmchan)->accepted = 1; @@ -1335,7 +1351,6 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) /* value and key are the same so just free one of them */ snprintf(r2call->name, sizeof(r2call->name), "chancall%d", i); hashtable_insert(spanpvt->r2calls, (void *)r2call->name, r2call, HASHTABLE_FLAG_FREE_VALUE); - } r2data->mf_dump_size = r2conf.mf_dump_size; r2data->flags = 0; @@ -1347,6 +1362,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) span->start = ftdm_r2_start; span->stop = ftdm_r2_stop; span->sig_read = NULL; + span->sig_write = NULL; /* let the core set the states, we just read them */ span->get_channel_sig_status = ftdm_r2_get_channel_sig_status; @@ -1544,10 +1560,7 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) /* finished call for good */ case FTDM_CHANNEL_STATE_DOWN: { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call is down\n"); - if (R2CALL(ftdmchan)->txdrops) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "dropped %d tx packets\n", R2CALL(ftdmchan)->txdrops); - } + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "R2 Call is down\n"); openr2_chan_disable_read(r2chan); ret = 1; } @@ -1587,8 +1600,9 @@ static void ftdm_r2_state_advance_all(ftdm_channel_t *ftdmchan) static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) { - openr2_chan_t *r2chan; + openr2_chan_t *r2chan = NULL; ftdm_channel_t *ftdmchan = NULL; + ftdm_r2_call_t *call = NULL; ftdm_status_t status; ftdm_span_t *span = (ftdm_span_t *) obj; ftdm_r2_data_t *r2data = span->signal_data; @@ -1662,6 +1676,19 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) continue; } + ms = ((start.tv_sec - end.tv_sec) * 1000) + + ((( 1000000 + start.tv_usec - end.tv_usec) / 1000) - 1000); + if (ms < 0) { + ms = 0; + } + if (ms > r2data->sleepmax) { + r2data->sleepmax = ms; + } + index = (ms / 15); + index = (index > 10) ? 10 : index; + r2data->sleeps[index]++; + r2data->total_sleeps++; + /* this main loop takes care of MF and CAS signaling during call setup and tear down * for every single channel in the span, do not perform blocking operations here! */ chaniter = ftdm_span_get_chan_iterator(span, chaniter); @@ -1670,13 +1697,26 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) ftdm_mutex_lock(ftdmchan->mutex); + call = R2CALL(ftdmchan); + + /* This let knows the core and io signaling hooks know that + * read/writes come from us and should be allowed */ + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED); + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TX_DISABLED); + ftdm_r2_state_advance_all(ftdmchan); - r2chan = R2CALL(ftdmchan)->r2chan; + r2chan = call->r2chan; openr2_chan_process_signaling(r2chan); ftdm_r2_state_advance_all(ftdmchan); + if (!call->accepted) { + /* if the call is not accepted we do not want users reading */ + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED); + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_TX_DISABLED); + } + ftdm_mutex_unlock(ftdmchan->mutex); } /* deliver the actual events to the user now without any channel locking */ @@ -1886,6 +1926,8 @@ static FIO_API_FUNCTION(ftdm_r2_api) stream->write_function(stream, "-ERR invalid span. No R2 signal data in span.\n"); goto done; } + stream->write_function(stream, "-- Working --\n"); + stream->write_function(stream, "Total loops: %llu\n", r2data->total_loops); range = 0; for (i = 0; i < ftdm_array_len(r2data->loops); i++) { pct = 100*(float)r2data->loops[i]/r2data->total_loops; @@ -1897,6 +1939,21 @@ static FIO_API_FUNCTION(ftdm_r2_api) range += 10; } stream->write_function(stream, "\n"); + + stream->write_function(stream, "-- Sleeping --\n"); + stream->write_function(stream, "Total sleeps: %llu\n", r2data->total_sleeps); + range = 0; + for (i = 0; i < ftdm_array_len(r2data->sleeps); i++) { + pct = 100*(float)r2data->sleeps[i]/r2data->total_sleeps; + if ((i + 1) == ftdm_array_len(r2data->sleeps)) { + stream->write_function(stream, ">= %dms: %llu - %.03lf%%\n", range, r2data->sleeps[i], pct); + } else { + stream->write_function(stream, "%d-%dms: %llu - %.03lf%%\n", range, range + 14, r2data->sleeps[i], pct); + } + range += 15; + } + stream->write_function(stream, "\n"); + stream->write_function(stream, "+OK.\n"); goto done; } else { diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index f1058d8e48..a1e1c02439 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -477,6 +477,8 @@ struct ftdm_channel { ftdm_dtmf_debug_t dtmfdbg; ftdm_io_dump_t rxdump; ftdm_io_dump_t txdump; + int32_t txdrops; + int32_t rxdrops; }; struct ftdm_span { @@ -509,6 +511,7 @@ struct ftdm_span { ftdm_span_start_t start; ftdm_span_stop_t stop; ftdm_channel_sig_read_t sig_read; + ftdm_channel_sig_write_t sig_write; /* Private I/O data per span. Do not touch unless you are an I/O module */ void *io_data; char *type; diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index db1428c962..9c6260cdef 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -264,6 +264,8 @@ typedef enum { FTDM_CHANNEL_IN_ALARM = (1 << 27), FTDM_CHANNEL_SIG_UP = (1 << 28), FTDM_CHANNEL_USER_HANGUP = (1 << 29), + FTDM_CHANNEL_RX_DISABLED = (1 << 30), + FTDM_CHANNEL_TX_DISABLED = (1 << 31), } ftdm_channel_flag_t; #if defined(__cplusplus) && defined(WIN32) // fix C2676 @@ -380,6 +382,7 @@ typedef struct ftdm_fsk_modulator ftdm_fsk_modulator_t; typedef ftdm_status_t (*ftdm_span_start_t)(ftdm_span_t *span); typedef ftdm_status_t (*ftdm_span_stop_t)(ftdm_span_t *span); typedef ftdm_status_t (*ftdm_channel_sig_read_t)(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t size); +typedef ftdm_status_t (*ftdm_channel_sig_write_t)(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t size); typedef enum { FTDM_ITERATOR_VARS = 1, From 15d18e7a15a80b6aa6f60ccc8c9fd49bf38659d0 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 8 Dec 2010 10:45:45 -0500 Subject: [PATCH 16/35] freetdm: ftmod_r2 - Fixed input size for tx and rx dumping ftmod_r2 - Set tx queue to 4 only ftmod_wanpipe - Fixed stats warnings --- libs/freetdm/src/ftdm_io.c | 16 +++++------ libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 23 +++++++++------ .../src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 28 +++++++++++++------ 3 files changed, 41 insertions(+), 26 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 3206ee4313..cdd734ba3c 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -163,9 +163,7 @@ static ftdm_status_t start_chan_io_dump(ftdm_channel_t *chan, ftdm_io_dump_t *du return FTDM_FAIL; } memset(dump, 0, sizeof(*dump)); - /* on 64bits, we get a weird number if we don't cast to uint here - * which is what size_t will be anyway */ - dump->buffer = ftdm_malloc((uint32_t)size); + dump->buffer = ftdm_malloc(size); if (!dump->buffer) { return FTDM_FAIL; } @@ -350,7 +348,7 @@ static __inline__ void *ftdm_std_malloc(void *pool, ftdm_size_t size) { void *ptr = malloc(size); pool = NULL; /* fix warning */ - ftdm_assert_return(ptr != NULL, NULL, "Out of memory"); + ftdm_assert_return(ptr != NULL, NULL, "Out of memory\n"); return ptr; } @@ -358,7 +356,7 @@ static __inline__ void *ftdm_std_calloc(void *pool, ftdm_size_t elements, ftdm_s { void *ptr = calloc(elements, size); pool = NULL; - ftdm_assert_return(ptr != NULL, NULL, "Out of memory"); + ftdm_assert_return(ptr != NULL, NULL, "Out of memory\n"); return ptr; } @@ -366,7 +364,7 @@ static __inline__ void *ftdm_std_realloc(void *pool, void *buff, ftdm_size_t siz { buff = realloc(buff, size); pool = NULL; - ftdm_assert_return(buff != NULL, NULL, "Out of memory"); + ftdm_assert_return(buff != NULL, NULL, "Out of memory\n"); return buff; } @@ -2764,7 +2762,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co GOTO_STATUS(done, FTDM_FAIL); } if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, size) != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable input dump\n"); + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to enable input dump of size %zd\n", size); GOTO_STATUS(done, FTDM_FAIL); } ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled input dump with size %zd\n", size); @@ -2794,7 +2792,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co GOTO_STATUS(done, FTDM_FAIL); } if (start_chan_io_dump(ftdmchan, &ftdmchan->txdump, size) != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable output dump\n"); + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to enable output dump of size %d\n", size); GOTO_STATUS(done, FTDM_FAIL); } ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled output dump with size %zd\n", size); @@ -3847,7 +3845,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat } if (ftdmchan->span->sig_write) { - status = ftdmchan->span->sig_write(ftdmchan, data, datalen); + status = ftdmchan->span->sig_write(ftdmchan, data, *datalen); if (status == FTDM_BREAK) { /* signaling module decided to drop user frame */ status = FTDM_SUCCESS; diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 21f7a1202c..2a95b01fe9 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -91,7 +91,7 @@ typedef struct ft_r2_conf_s { int32_t max_dnis; int32_t mfback_timeout; int32_t metering_pulse_timeout; - int32_t mf_dump_size; + ftdm_size_t mf_dump_size; /* booleans */ int immediate_accept; @@ -121,7 +121,7 @@ typedef struct ftdm_r2_data_s { /* whether accept the call when offered, or wait until the user decides to accept */ int accept_on_offer:1; /* Size of multi-frequency (or any media) dumps used during protocol errors */ - int32_t mf_dump_size; + ftdm_size_t mf_dump_size; /* max time spent in ms doing real work in a single loop */ int32_t jobmax; /* Total number of loops performed so far */ @@ -473,7 +473,6 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan) memset(ftdmchan->caller_data.dnis.digits, 0, sizeof(ftdmchan->caller_data.collected)); memset(ftdmchan->caller_data.ani.digits, 0, sizeof(ftdmchan->caller_data.collected)); - /* clean the call data structure but keep the R2 processing flag on! */ ft_r2_clean_call(ftdmchan->call_data); r2call = R2CALL(ftdmchan); @@ -1120,6 +1119,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) { unsigned int i = 0; int conf_failure = 0; + int intval = 0; const char *var = NULL, *val = NULL; const char *log_level = "notice,warning,error"; /* default loglevel, if none is read from conf */ ftdm_r2_data_t *r2data = NULL; @@ -1226,11 +1226,12 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) r2conf.advanced_protocol_file = (char *)val; ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with advanced protocol file %s\n", span->name, val); } else if (!strcasecmp(var, "mf_dump_size")) { - r2conf.mf_dump_size = atoi(val); - if (r2conf.mf_dump_size < 0) { + intval = atoi(val); + if (intval < 0) { r2conf.mf_dump_size = FTDM_IO_DUMP_DEFAULT_BUFF_SIZE; ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with default mf_dump_size = %d bytes\n", span->name, r2conf.mf_dump_size); } else { + r2conf.mf_dump_size = intval; ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with mf_dump_size = %d bytes\n", span->name, r2conf.mf_dump_size); } } else if (!strcasecmp(var, "allow_collect_calls")) { @@ -1612,6 +1613,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) int index = 0; struct timeval start, end; ftdm_iterator_t *chaniter = NULL; + uint32_t txqueue_size = 4; short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count); #ifdef __linux__ @@ -1620,18 +1622,23 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) ftdm_log(FTDM_LOG_DEBUG, "OpenR2 monitor thread %lu started.\n", r2data->monitor_thread_id); r2chan = NULL; - for (i = 1; i <= span->chan_count; i++) { - r2chan = R2CALL(span->channels[i])->r2chan; + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (i = 1; chaniter; chaniter = ftdm_iterator_next(chaniter), i++) { + ftdmchan = ftdm_iterator_current(chaniter); + r2chan = R2CALL(ftdmchan)->r2chan; openr2_chan_set_span_id(r2chan, span->span_id); openr2_chan_set_idle(r2chan); openr2_chan_process_cas_signaling(r2chan); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &txqueue_size); } memset(&start, 0, sizeof(start)); memset(&end, 0, sizeof(end)); - chaniter = ftdm_span_get_chan_iterator(span, NULL); while (ftdm_running() && ftdm_test_flag(r2data, FTDM_R2_RUNNING)) { res = gettimeofday(&end, NULL); + if (res) { + ftdm_log(FTDM_LOG_CRIT, "Failure gettimeofday [%s]\n", strerror(errno)); + } if (start.tv_sec) { ms = ((end.tv_sec - start.tv_sec) * 1000) + ((( 1000000 + end.tv_usec - start.tv_usec) / 1000) - 1000); diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index 0bafa40bdd..1c0baa731f 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -760,8 +760,8 @@ static FIO_COMMAND_FUNCTION(wanpipe_command) { err = sangoma_flush_rx_bufs(ftdmchan->sockfd, &tdm_api); } - case FTDM_COMMAND_FLUSH_TX_BUFFERS: break; + case FTDM_COMMAND_FLUSH_TX_BUFFERS: { err = sangoma_flush_tx_bufs(ftdmchan->sockfd, &tdm_api); } @@ -806,20 +806,17 @@ static void wanpipe_write_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_tx_hdr_t *t /* we don't test for 80% full in tx since is typically full for voice channels, should we test tx 80% full for D-channels? */ if (ftdmchan->iostats.tx.queue_len >= ftdmchan->iostats.tx.queue_size) { - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Tx Queue Full (%d/%d)\n", - ftdmchan->iostats.tx.queue_len, ftdmchan->iostats.tx.queue_size); ftdm_set_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL); } else if (ftdm_test_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL)){ - ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Tx Queue no longer full (%d/%d)\n", - ftdmchan->iostats.tx.queue_len, ftdmchan->iostats.tx.queue_size); ftdm_clear_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL); } if (ftdmchan->iostats.tx.idle_packets < tx_stats->wp_api_tx_hdr_number_of_frames_in_queue) { ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets; - /* HDLC channels do not always transmit, so its ok for drivers to fill with idle */ - if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx idle: %d\n", ftdmchan->iostats.tx.idle_packets); + /* HDLC channels do not always transmit, so its ok for drivers to fill with idle + * also do not report idle warning when we just started transmitting */ + if (ftdmchan->iostats.tx.packets && FTDM_IS_VOICE_CHANNEL(ftdmchan)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx idle: %d\n", ftdmchan->iostats.tx.idle_packets); } } @@ -942,7 +939,9 @@ static FIO_READ_FUNCTION(wanpipe_read) */ static FIO_WRITE_FUNCTION(wanpipe_write) { - int bsent; + int bsent = 0; + int err = 0; + ftdm_time_t ms = 0; wp_tdm_api_tx_hdr_t hdrframe; /* Do we even need the headerframe here? on windows, we don't even pass it to the driver */ @@ -950,6 +949,17 @@ static FIO_WRITE_FUNCTION(wanpipe_write) if (*datalen == 0) { return FTDM_SUCCESS; } + + if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS) && !ftdmchan->iostats.tx.packets) { + wanpipe_tdm_api_t tdm_api; + memset(&tdm_api, 0, sizeof(tdm_api)); + /* if this is the first write ever, flush the tx first to have clean stats */ + err = sangoma_flush_tx_bufs(ftdmchan->sockfd, &tdm_api); + if (err) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to flush on first write\n"); + } + } + bsent = sangoma_writemsg_tdm(ftdmchan->sockfd, &hdrframe, (int)sizeof(hdrframe), data, (unsigned short)(*datalen),0); /* should we be checking if bsent == *datalen here? */ From d6583acd3bd4992798092b32cd07679b3d6f18bf Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 8 Dec 2010 11:57:24 -0500 Subject: [PATCH 17/35] freetdm: mod_freetdm - fix progress media state for R2 signaling ftmod_r2 - Do not set the state to DIALING unless openr2_chan_make_call succeeds --- libs/freetdm/mod_freetdm/mod_freetdm.c | 11 ++++++++++- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 10 ++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index ca16e8bc71..7ea6bb6d37 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2033,7 +2033,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal) break; case FTDM_SIGEVENT_PROGRESS: - case FTDM_SIGEVENT_PROGRESS_MEDIA: { if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { channel = switch_core_session_get_channel(session); @@ -2043,6 +2042,16 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal) } break; + case FTDM_SIGEVENT_PROGRESS_MEDIA: + { + if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { + channel = switch_core_session_get_channel(session); + switch_channel_mark_pre_answered(channel); + switch_core_session_rwunlock(session); + } + } + break; + case FTDM_SIGEVENT_UP: { if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 2a95b01fe9..02860189b9 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -382,9 +382,6 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) } ft_r2_clean_call(ftdmchan->call_data); - R2CALL(ftdmchan)->ftdm_call_started = 1; - R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DIALING); /* start io dump */ if (r2data->mf_dump_size) { @@ -395,7 +392,7 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) callstatus = openr2_chan_make_call(R2CALL(ftdmchan)->r2chan, ftdmchan->caller_data.cid_num.digits, ftdmchan->caller_data.dnis.digits, - OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER); + r2data->category); if (callstatus) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to make call in R2 channel, openr2_chan_make_call failed\n"); @@ -408,6 +405,10 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) return FTDM_BREAK; } + R2CALL(ftdmchan)->ftdm_call_started = 1; + R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN; + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DIALING); + ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS); ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_TX_BUFFERS, NULL); ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_RX_BUFFERS, NULL); @@ -1354,6 +1355,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) hashtable_insert(spanpvt->r2calls, (void *)r2call->name, r2call, HASHTABLE_FLAG_FREE_VALUE); } r2data->mf_dump_size = r2conf.mf_dump_size; + r2data->category = r2conf.category; r2data->flags = 0; spanpvt->r2context = r2data->r2context; From de23c6d375cef19961bcc82b9c3f79d32a95190f Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 8 Dec 2010 12:01:13 -0500 Subject: [PATCH 18/35] freetdm: ftmod_r2 - Remove buggy collision check --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 02860189b9..fa0479d48b 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -399,12 +399,6 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) return FTDM_FAIL; } - if (ftdmchan->state != FTDM_CHANNEL_STATE_DIALING) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Collision after call attempt, try another channel, new state = %s\n", - ftdm_channel_state2str(ftdmchan->state)); - return FTDM_BREAK; - } - R2CALL(ftdmchan)->ftdm_call_started = 1; R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN; ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DIALING); From 972500fcc93f816e0a70fa7b64da6636607167e4 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Wed, 8 Dec 2010 12:36:26 -0500 Subject: [PATCH 19/35] return failure from make if build failed --- Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.am b/Makefile.am index aeb31eca01..e701494a2e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -90,6 +90,8 @@ $(RECURSIVE_TARGETS): fi; \ if test -z "$$fail" ; then \ cd $(top_builddir)/build && $(MAKE) $(AM_MAKEFLAGS) $$target || exit 1; \ + else \ + exit 1; \ fi ; CORE_CFLAGS = `$(switch_builddir)/libs/apr/apr-1-config --cflags --cppflags --includes` From e6250bcb9493aae8a3e8afdf1502c8417b110072 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 8 Dec 2010 13:15:26 -0500 Subject: [PATCH 20/35] freetdm: ftmod_r2 - Add protocol error recovery timer --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 40 ++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index fa0479d48b..166a914100 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -138,6 +138,8 @@ typedef struct ftdm_r2_data_s { uint32_t monitor_thread_id; /* Logging directory */ char logdir[512]; + /* scheduling context */ + ftdm_sched_t *sched; } ftdm_r2_data_t; /* one element per span will be stored in g_mod_data_hash global var to keep track of them @@ -145,6 +147,7 @@ typedef struct ftdm_r2_data_s { typedef struct ftdm_r2_span_pvt_s { openr2_context_t *r2context; /* r2 context allocated for this span */ ftdm_hash_t *r2calls; /* hash table of allocated call data per channel for this span */ + ftdm_sched_t *sched; /* schedule for the span */ } ftdm_r2_span_pvt_t; /* span monitor thread */ @@ -312,6 +315,7 @@ static openr2_call_disconnect_cause_t ftdm_r2_ftdm_cause_to_openr2_cause(ftdm_ch case FTDM_CAUSE_NETWORK_OUT_OF_ORDER: case FTDM_CAUSE_SERVICE_UNAVAILABLE: + case FTDM_CAUSE_PROTOCOL_ERROR: return OR2_CAUSE_OUT_OF_ORDER; case FTDM_CAUSE_NO_ANSWER: @@ -644,6 +648,20 @@ static void ftdm_r2_on_os_error(openr2_chan_t *r2chan, int errorcode) ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "OS error: %s\n", strerror(errorcode)); } +static void ftdm_r2_recover_from_protocol_error(void *data) +{ + openr2_chan_t *r2chan = data; + ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); + ftdm_channel_lock(ftdmchan); + if (ftdmchan->state != FTDM_CHANNEL_STATE_HANGUP) { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Recovering from protocol error but state is %s!\n", ftdm_channel_state2str(ftdmchan->state)); + goto done; + } + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); +done: + ftdm_channel_unlock(ftdmchan); +} + static void ftdm_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_error_t reason) { ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); @@ -1115,6 +1133,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) unsigned int i = 0; int conf_failure = 0; int intval = 0; + char schedname[255]; const char *var = NULL, *val = NULL; const char *log_level = "notice,warning,error"; /* default loglevel, if none is read from conf */ ftdm_r2_data_t *r2data = NULL; @@ -1374,6 +1393,11 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) /* use signals queue */ ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE); + /* setup the scheduler */ + snprintf(schedname, sizeof(schedname), "ftmod_r2_%s", span->name); + ftdm_assert(ftdm_sched_create(&r2data->sched, schedname) == FTDM_SUCCESS, "Failed to create schedule!\n"); + spanpvt->sched = r2data->sched; + return FTDM_SUCCESS; fail: @@ -1396,6 +1420,7 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) ftdm_sigmsg_t sigev; int ret; openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan; + ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; memset(&sigev, 0, sizeof(sigev)); sigev.chan_id = ftdmchan->chan_id; @@ -1526,7 +1551,9 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) openr2_chan_disconnect_call(r2chan, OR2_CAUSE_NORMAL_CLEARING); } else { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Clearing call due to protocol error\n"); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + /* do not set to down yet, give some time for recovery */ + ftdm_sched_timer(r2data->sched, "protocolerr_recover", 100, + ftdm_r2_recover_from_protocol_error, r2chan, NULL); } } break; @@ -1650,6 +1677,11 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) r2data->total_loops++; } + /* run any span timers */ + ftdm_sched_run(r2data->sched); + + /* deliver the actual channel events to the user now without any channel locking */ + ftdm_span_trigger_signals(span); #ifndef WIN32 /* figure out what event to poll each channel for. POLLPRI when the channel is down, * POLLPRI|POLLIN|POLLOUT otherwise */ @@ -1669,6 +1701,9 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) status = ftdm_span_poll_event(span, waitms, NULL); #endif + /* run any span timers */ + ftdm_sched_run(r2data->sched); + res = gettimeofday(&start, NULL); if (res) { ftdm_log(FTDM_LOG_CRIT, "Failure gettimeofday [%s]\n", strerror(errno)); @@ -1722,8 +1757,6 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) ftdm_mutex_unlock(ftdmchan->mutex); } - /* deliver the actual events to the user now without any channel locking */ - ftdm_span_trigger_signals(span); } chaniter = ftdm_span_get_chan_iterator(span, chaniter); @@ -2046,6 +2079,7 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_r2_destroy) spanpvt = val; openr2_context_delete(spanpvt->r2context); hashtable_destroy(spanpvt->r2calls); + ftdm_sched_destroy(&spanpvt->sched); } } hashtable_destroy(g_mod_data_hash); From 68cad2aa950472b209350febcf76c0d4f9c5ee99 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Wed, 8 Dec 2010 19:25:44 -0200 Subject: [PATCH 21/35] freetdm: ftmod_r2 - use freetdm logical channel id to set r2chan's id --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 2a95b01fe9..cfe3ae6cd0 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -1328,7 +1328,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) } for (i = 1; (i <= span->chan_count) && (i <= FTDM_MAX_CHANNELS_SPAN); i++) { - r2chan = openr2_chan_new_from_fd(r2data->r2context, span->channels[i], span->channels[i]->physical_chan_id); + r2chan = openr2_chan_new_from_fd(r2data->r2context, span->channels[i], span->channels[i]->chan_id); if (!r2chan) { snprintf(span->last_error, sizeof(span->last_error), "Cannot create all openr2 channels for span."); goto fail; From 315441d219fa3accb4ad159e3e33226523b59cdd Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 8 Dec 2010 14:30:47 -0500 Subject: [PATCH 22/35] freetdm: ftmod_r2 - handle race on protocol error --- libs/freetdm/src/ftdm_io.c | 6 +- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 111 +++++++++++---------- 2 files changed, 61 insertions(+), 56 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index cdd734ba3c..66164871c6 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -133,14 +133,16 @@ static void dump_chan_io_to_file(ftdm_channel_t *fchan, ftdm_io_dump_t *dump, FI if (dump->wrapped) { rc = fwrite(&dump->buffer[dump->windex], 1, towrite, file); if (rc != towrite) { - ftdm_log_chan(fchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite); + ftdm_log_chan(fchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in io dump buffer\n", + rc, towrite, strerror(errno)); } } if (dump->windex) { towrite = dump->windex; rc = fwrite(&dump->buffer[0], 1, towrite, file); if (rc != towrite) { - ftdm_log_chan(fchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite); + ftdm_log_chan(fchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in io dump buffer: %s\n", + rc, towrite, strerror(errno)); } } dump->windex = 0; diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 81f1754537..ab85d2b4d6 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -73,6 +73,7 @@ typedef struct ftdm_r2_call_t { ftdm_size_t ani_index; char logname[255]; char name[10]; + ftdm_timer_id_t protocol_error_recovery_timer; } ftdm_r2_call_t; /* this is just used as place holder in the stack when configuring the span to avoid using bunch of locals */ @@ -334,7 +335,7 @@ static openr2_call_disconnect_cause_t ftdm_r2_ftdm_cause_to_openr2_cause(ftdm_ch static void ft_r2_clean_call(ftdm_r2_call_t *call) { openr2_chan_t *r2chan = call->r2chan; - + /* Do not memset call structure, that clears values we do not want to clear, * like the log name set in on_call_log_created() */ call->r2chan = r2chan; @@ -347,6 +348,7 @@ static void ft_r2_clean_call(ftdm_r2_call_t *call) call->dnis_index = 0; call->ani_index = 0; call->name[0] = 0; + call->protocol_error_recovery_timer = 0; } static void ft_r2_accept_call(ftdm_channel_t *ftdmchan) @@ -451,6 +453,18 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan) ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Received request to start call\n"); + if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP) { + r2call = R2CALL(ftdmchan); + if (r2call->protocol_error) { + /* we had a protocol error and we were giving some recovery time, cancel the recovery timer now + * that is obvious that the other side recovered */ + ftdm_sched_cancel_timer(r2data->sched, r2call->protocol_error_recovery_timer); + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Cancelled protocol error recovery timer\n"); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + ftdm_r2_state_advance_all(ftdmchan); + } + } + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) { ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Cannot start call when channel is in use (state = %s)\n", ftdm_channel_state2str(ftdmchan->state)); return; @@ -658,6 +672,7 @@ static void ftdm_r2_recover_from_protocol_error(void *data) goto done; } ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + ftdm_r2_state_advance_all(ftdmchan); done: ftdm_channel_unlock(ftdmchan); } @@ -960,36 +975,37 @@ static int ftdm_r2_io_setup(openr2_chan_t *r2chan) static int ftdm_r2_io_get_oob_event(openr2_chan_t *r2chan, openr2_oob_event_t *event) { - ftdm_status_t status; - ftdm_event_t *fevent = NULL; - ftdm_channel_t *ftdmchan = openr2_chan_get_fd(r2chan); + ftdm_status_t status; + ftdm_event_t *fevent = NULL; + ftdm_channel_t *ftdmchan = openr2_chan_get_fd(r2chan); - *event = OR2_OOB_EVENT_NONE; - status = ftdm_channel_read_event(ftdmchan, &fevent); - if (status != FTDM_SUCCESS) { + *event = OR2_OOB_EVENT_NONE; + + status = ftdm_channel_read_event(ftdmchan, &fevent); + + if (status != FTDM_SUCCESS) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "failed to retrieve freetdm event!\n"); - return -1; - } - if (fevent->e_type != FTDM_EVENT_OOB) - return 0; - switch (fevent->enum_id) { - case FTDM_OOB_CAS_BITS_CHANGE: - { - *event = OR2_OOB_EVENT_CAS_CHANGE; - } - break; - case FTDM_OOB_ALARM_TRAP: - { - *event = OR2_OOB_EVENT_ALARM_ON; - } - break; - case FTDM_OOB_ALARM_CLEAR: - { - *event = OR2_OOB_EVENT_ALARM_OFF; - } - break; + return -1; } - return 0; + + switch (fevent->enum_id) { + case FTDM_OOB_CAS_BITS_CHANGE: + { + *event = OR2_OOB_EVENT_CAS_CHANGE; + } + break; + case FTDM_OOB_ALARM_TRAP: + { + *event = OR2_OOB_EVENT_ALARM_ON; + } + break; + case FTDM_OOB_ALARM_CLEAR: + { + *event = OR2_OOB_EVENT_ALARM_OFF; + } + break; + } + return 0; } static openr2_io_interface_t ftdm_r2_io_iface = { @@ -1419,7 +1435,8 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) { ftdm_sigmsg_t sigev; int ret; - openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan; + ftdm_r2_call_t *r2call = R2CALL(ftdmchan); + openr2_chan_t *r2chan = r2call->r2chan; ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; memset(&sigev, 0, sizeof(sigev)); @@ -1435,10 +1452,10 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) * to complete (the processing is media-bound) * */ if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE) - && (R2CALL(ftdmchan)->chanstate != ftdmchan->state)) { + && (r2call->chanstate != ftdmchan->state)) { ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Executing state handler for %s\n", ftdm_channel_state2str(ftdmchan->state)); - R2CALL(ftdmchan)->chanstate = ftdmchan->state; + r2call->chanstate = ftdmchan->state; if (IS_ACCEPTING_PENDING(ftdmchan)) { /* @@ -1487,13 +1504,8 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) /* notify the user about the new call */ sigev.event_id = FTDM_SIGEVENT_START; - if (ftdm_span_send_signal(ftdmchan->span, &sigev) != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Failed to handle call offered\n"); - openr2_chan_disconnect_call(r2chan, OR2_CAUSE_OUT_OF_ORDER); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - break; - } - R2CALL(ftdmchan)->ftdm_call_started = 1; + ftdm_span_send_signal(ftdmchan->span, &sigev); + r2call->ftdm_call_started = 1; break; @@ -1502,7 +1514,7 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: { if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - if (!R2CALL(ftdmchan)->accepted) { + if (!r2call->accepted) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Accepting call\n"); ft_r2_accept_call(ftdmchan); } @@ -1522,11 +1534,11 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call was answered\n"); if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - if (!R2CALL(ftdmchan)->accepted) { + if (!r2call->accepted) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call has not been accepted, need to accept first\n"); // the answering will be done in the on_call_accepted handler ft_r2_accept_call(ftdmchan); - R2CALL(ftdmchan)->answer_pending = 1; + r2call->answer_pending = 1; } else { ft_r2_answer_call(ftdmchan); } @@ -1541,19 +1553,19 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) /* just got hangup */ case FTDM_CHANNEL_STATE_HANGUP: { - if (!R2CALL(ftdmchan)->disconnect_rcvd) { + if (!r2call->disconnect_rcvd) { openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan); ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause)); /* this will disconnect the call, but need to wait for the call end before moving to DOWN */ openr2_chan_disconnect_call(r2chan, disconnect_cause); - } else if (!R2CALL(ftdmchan)->protocol_error) { + } else if (!r2call->protocol_error) { /* just ack the hangup, on_call_end will be called by openr2 right after */ openr2_chan_disconnect_call(r2chan, OR2_CAUSE_NORMAL_CLEARING); } else { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Clearing call due to protocol error\n"); /* do not set to down yet, give some time for recovery */ ftdm_sched_timer(r2data->sched, "protocolerr_recover", 100, - ftdm_r2_recover_from_protocol_error, r2chan, NULL); + ftdm_r2_recover_from_protocol_error, r2chan, &r2call->protocol_error_recovery_timer); } } break; @@ -1561,7 +1573,7 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) case FTDM_CHANNEL_STATE_TERMINATING: { /* if the call has not been started yet we must go to HANGUP right here */ - if (!R2CALL(ftdmchan)->ftdm_call_started) { + if (!r2call->ftdm_call_started) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); } else { openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan); @@ -1573,19 +1585,10 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) } break; - /* just got hangup from the freetdm side due to abnormal failure */ - case FTDM_CHANNEL_STATE_CANCEL: - { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Unable to receive call\n"); - openr2_chan_disconnect_call(r2chan, OR2_CAUSE_OUT_OF_ORDER); - } - break; - /* finished call for good */ case FTDM_CHANNEL_STATE_DOWN: { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "R2 Call is down\n"); - openr2_chan_disable_read(r2chan); ret = 1; } break; From 18299684bf953f6cc635938a2084bb333ab275ac Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 8 Dec 2010 14:50:40 -0500 Subject: [PATCH 23/35] freetdm: added core command to print channels by flag --- libs/freetdm/src/ftdm_io.c | 61 +++++++++++++++++++ libs/freetdm/src/include/private/ftdm_types.h | 1 + 2 files changed, 62 insertions(+) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 66164871c6..758681fdd5 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -4073,6 +4073,52 @@ static struct { ftdm_io_interface_t *pika_interface; } interfaces; +static void print_channels_by_flag(ftdm_stream_handle_t *stream, uint32_t flag, int not, int *count) +{ + ftdm_hash_iterator_t *i = NULL; + ftdm_span_t *span; + ftdm_channel_t *fchan = NULL; + ftdm_iterator_t *citer = NULL; + ftdm_iterator_t *curr = NULL; + const void *key = NULL; + void *val = NULL; + + *count = 0; + + ftdm_mutex_lock(globals.mutex); + + for (i = hashtable_first(globals.span_hash); i; i = hashtable_next(i)) { + hashtable_this(i, &key, NULL, &val); + if (!key || !val) { + break; + } + span = val; + citer = ftdm_span_get_chan_iterator(span, NULL); + if (!citer) { + continue; + } + for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) { + fchan = ftdm_iterator_current(curr); + if (not && !ftdm_test_flag(fchan, flag)) { + stream->write_function(stream, "[s%dc%d][%d:%d] has not flag %d\n", + fchan->span_id, fchan->chan_id, + fchan->physical_span_id, fchan->physical_chan_id, + flag); + (*count)++; + } else if (!not && ftdm_test_flag(fchan, flag)) { + stream->write_function(stream, "[s%dc%d][%d:%d] has flag %d\n", + fchan->span_id, fchan->chan_id, + fchan->physical_span_id, fchan->physical_chan_id, + flag); + (*count)++; + } + } + ftdm_iterator_free(citer); + } + + ftdm_mutex_unlock(globals.mutex); +} + static void print_channels_by_state(ftdm_stream_handle_t *stream, ftdm_channel_state_t state, int not, int *count) { ftdm_hash_iterator_t *i = NULL; @@ -4125,6 +4171,8 @@ static char *handle_core_command(const char *cmd) int not = 0; char *argv[10] = { 0 }; char *state = NULL; + char *flag = NULL; + uint32_t flagval = 0; ftdm_channel_state_t i = FTDM_CHANNEL_STATE_INVALID; ftdm_stream_handle_t stream = { 0 }; @@ -4159,6 +4207,19 @@ static char *handle_core_command(const char *cmd) } print_channels_by_state(&stream, i, not, &count); stream.write_function(&stream, "\nTotal channels %s %s: %d\n", not ? "not in state" : "in state", ftdm_channel_state2str(i), count); + } else if (!strcasecmp(argv[0], "flag")) { + if (argc < 2) { + stream.write_function(&stream, "core state command requires an argument\n"); + goto done; + } + flag = argv[1]; + if (argv[1][0] == '!') { + not = 1; + flag++; + } + flagval = atoi(flag); + print_channels_by_flag(&stream, flagval, not, &count); + stream.write_function(&stream, "\nTotal channels %s %s: %d\n", not ? "without flag" : "with flag", flagval, count); } else { stream.write_function(&stream, "invalid core command %s\n", argv[0]); } diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index 9c6260cdef..df747021b2 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -266,6 +266,7 @@ typedef enum { FTDM_CHANNEL_USER_HANGUP = (1 << 29), FTDM_CHANNEL_RX_DISABLED = (1 << 30), FTDM_CHANNEL_TX_DISABLED = (1 << 31), + /* ok, when we reach 32, we need to move to uint64_t all the flag stuff */ } ftdm_channel_flag_t; #if defined(__cplusplus) && defined(WIN32) // fix C2676 From 997151838426d4f2de8c6f81a836fd0323cad17d Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 8 Dec 2010 13:59:56 -0600 Subject: [PATCH 24/35] VS2010 add missing files freetdm --- .../mod_freetdm/mod_freetdm.2010.vcxproj | 217 ++++++++++++++++++ .../mod_freetdm.2010.vcxproj.filters | 14 ++ 2 files changed, 231 insertions(+) create mode 100644 libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj create mode 100644 libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj.filters diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj new file mode 100644 index 0000000000..ec69333410 --- /dev/null +++ b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj @@ -0,0 +1,217 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + mod_freetdm + {FE3540C5-3303-46E0-A69E-D92F775687F1} + mod_freetdm + Win32Proj + + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(PlatformName)\$(Configuration)\mod\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(PlatformName)\$(Configuration)\mod\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(PlatformName)\$(Configuration)\mod\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(PlatformName)\$(Configuration)\mod\ + $(Platform)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + true + ProgramDatabase + + + FreeSwitchCore.lib;%(AdditionalDependencies) + ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) + true + $(OutDir)$(TargetName).pdb + Windows + false + + + $(OutDir)mod_freetdm.lib + MachineX86 + + + + + ../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + true + ProgramDatabase + + + FreeSwitchCore.lib;%(AdditionalDependencies) + ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) + true + $(OutDir)$(TargetName).pdb + Windows + true + true + UseLinkTimeCodeGeneration + false + + + $(OutDir)mod_freetdm.lib + MachineX86 + + + + + X64 + + + Disabled + ../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + true + ProgramDatabase + + + FreeSwitchCore.lib;%(AdditionalDependencies) + ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) + true + $(OutDir)$(TargetName).pdb + Windows + false + + + $(OutDir)mod_freetdm.lib + MachineX64 + + + + + X64 + + + ../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + true + ProgramDatabase + + + FreeSwitchCore.lib;%(AdditionalDependencies) + ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) + true + $(OutDir)$(TargetName).pdb + Windows + true + true + UseLinkTimeCodeGeneration + false + + + $(OutDir)mod_freetdm.lib + MachineX64 + + + + + + + + {93b8812c-3ec4-4f78-8970-ffbfc99e167d} + false + + + + + + \ No newline at end of file diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj.filters b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj.filters new file mode 100644 index 0000000000..92ac5ead47 --- /dev/null +++ b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file From 648a124c3f777bd79635ddf8e1d57b6c4c741cfc Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 8 Dec 2010 15:12:10 -0500 Subject: [PATCH 25/35] freetdm: improve core flag command --- libs/freetdm/src/ftdm_io.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 758681fdd5..249d8580b5 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -4073,7 +4073,7 @@ static struct { ftdm_io_interface_t *pika_interface; } interfaces; -static void print_channels_by_flag(ftdm_stream_handle_t *stream, uint32_t flag, int not, int *count) +static void print_channels_by_flag(ftdm_stream_handle_t *stream, int32_t flagval, int not, int *count) { ftdm_hash_iterator_t *i = NULL; ftdm_span_t *span; @@ -4082,6 +4082,7 @@ static void print_channels_by_flag(ftdm_stream_handle_t *stream, uint32_t flag, ftdm_iterator_t *curr = NULL; const void *key = NULL; void *val = NULL; + uint32_t flag = (1 << flagval); *count = 0; @@ -4103,13 +4104,13 @@ static void print_channels_by_flag(ftdm_stream_handle_t *stream, uint32_t flag, stream->write_function(stream, "[s%dc%d][%d:%d] has not flag %d\n", fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, - flag); + flagval); (*count)++; } else if (!not && ftdm_test_flag(fchan, flag)) { stream->write_function(stream, "[s%dc%d][%d:%d] has flag %d\n", fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, - flag); + flagval); (*count)++; } } @@ -4219,7 +4220,7 @@ static char *handle_core_command(const char *cmd) } flagval = atoi(flag); print_channels_by_flag(&stream, flagval, not, &count); - stream.write_function(&stream, "\nTotal channels %s %s: %d\n", not ? "without flag" : "with flag", flagval, count); + stream.write_function(&stream, "\nTotal channels %s %d: %d\n", not ? "without flag" : "with flag", flagval, count); } else { stream.write_function(&stream, "invalid core command %s\n", argv[0]); } From 14113f23b187bd1d25122544033b52c94d0ad905 Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Wed, 8 Dec 2010 13:33:34 -0800 Subject: [PATCH 26/35] Update ChangeLog through Dec 7 --- docs/ChangeLog | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/ChangeLog b/docs/ChangeLog index 6037c14ec7..96066b6e8c 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -32,6 +32,7 @@ freeswitch (1.0.7) config: default example to resolve some issues with SCA in cases where host and ip are mixed causing the phone to be confused. (r:0279261b) config: Fix phrase files, still missing a sound file (r:6741f350/FS-2742) config: Disallow global-intercept and group-intercept can intercept an outbound call in default dialplan (r:890871ba/FS-2777) + config: fix single domain assumption in default config to be more portable *cough* bkw *cough* (r:f987903e) core: Add RTCP support (FSRTP-14) core: handle some errors on missing db handle conditions core: add ... and shutdown as a fail-safe when no modules are loaded @@ -134,6 +135,16 @@ freeswitch (1.0.7) core: Better handling of progress and answering to prevent sip profile from locking up at higher volumes (r:04e57577/FS-2801) core: ACL for IPv6 address and swigall to boot (r:db91f0e8/FS-2842) core: add intercept_unanswered_only var akin to intercept_unbridged_only (r:68f18efe) + core: switch_odbc_handle_exec_string duplication SQLExecute (r:8b0e7d24/FS-2880) + core: Fix timeout while bridge is waiting for CF_BRIDGED flag (r:2572621b/FS-2368) + core: don't parse events for b legs from a leg thread in case they are using a monolothic python script as a group_confirm exec over socket to send it messages while the call is ringing (r:ed5266d3) + core: add new function to check when messages need parsing to improve performance on parsing messages during originate (r:8b0421ff) + core: run execute_on_answer on_media _on_ring apps async (r:ef4a4ed0) + core: add switch_ivr_insert_file to insert one file into another at an arbitrary sample point (r:82394b37) + core: Slow reload cause calls to hang (r:1ba98b02/FS-2852) + core: Application intercept causes FS to stop processing calls (r:12fc65f7/FS-2872) + core: fix edge cases for endless loop in sql thread (r:5d7c09ed) + core: prevent race while changing codecs mid call (r:7aa72b67) lang: Improve French phrase files (FSCONFIG-23) libapr: Fix issue where after a bridge with a member, uuid of Agent is set to single quote character ' (r:3fee704d/FS-2738) libdingaling: fix race on shutdown causing crash (FSMOD-47) @@ -151,6 +162,7 @@ freeswitch (1.0.7) libesl: Fix SEGV when using serialize function without any arguments (r:910729b5/ESL-44) libesl: fix leak-on-error in esl_connect_timeout() (r:4263d60e) libesl: Call close on connection handle if the connection fails (r:413dcc4c/ESL-50) + libesl: allow fs_cli -x to have args up to 1024 chars (was 256) (r:7039ba47) libfreetdm: implemented freetdm config nodes and ss7 initial configuration libfreetdm: fix codec for CAS signaling (r:b76e7f18) libfreetdm: freetdm: ss7- added support for incoming group blocks, started adding support for ansi (r:c219a73c) @@ -189,7 +201,8 @@ freeswitch (1.0.7) mod_callcenter: Fix invalid update of agent field (r:426a448f/FS-2738) mod_callcenter: Allow to get queue info via api (r:70d592ae) mod_callcenter: Fix bad return type so it compile on archlinux, thx bougyman (r:3a475986) - mod_callcenter: Make callcenter_config agent get return the value of the item requested. Also added queue param max-wait-time-with-no-agent-time-reached: If the max-wai-time-with-no-agent is already reached for the queue, then new caller can wait for x ammount of second before it kicked out of the queue rather than get rejected automaticly. (r:81a03869) + mod_callcenter: Make callcenter_config agent get return the value of the item requested. Also added queue param max-wait-time-with-no-agent-time-reached: If the max-wai-time-with-no-agent is already reached for the queue, then new caller can wait for x amount of second before it kicked out of the queue rather than get rejected automatically. (r:81a03869) + mod_callcenter: Add new event socket agent-offering. Plus some documentation and better handling of bad agent type -- FS-2869 (r:80174cf3/FS-2869) mod_cidlookup: null xml is bad (r:095815f8) mod_cid_lookup: honor skipcitystate when using whitepages (r:a66654de/FSMOD-53) mod_commands: make break uuid_break and add cascade flag @@ -205,6 +218,8 @@ freeswitch (1.0.7) mod_commands: ***BEHAVIOUR CHANGE*** reloadacl, load , reload will now explicitly call reloadxml (r:42c9df72) mod_commands: add nat_map usage (r:7577b8aa) mod_commands: add escaping empty strings to sql_escape (r:7bd0a5a6/FS-2833) + mod_commands: add uuid_fileman : <-- same vals as the callbacks in js and lua to control the currently playing file of a channel from the cli or ESL (for the people who were ignoring me on the conference call so I decided to implement it instead of try to explain it ) (r:c4369fc8) + mod_commands: FS-2210 Add support for auto completion for uuid_simplify (r:72bcc01b/FS-2210) mod_conference: Fix reporting of volume up/down (MODAPP-419) mod_conference: add last talking time per member to conference xml list mod_conference: add terminate-on-silence conference param @@ -221,6 +236,8 @@ freeswitch (1.0.7) mod_dingaling: make dingaling work with google voice inbound too (r:4ee68141) mod_dingaling: Fix crash when testing the new gv-dingaling with around 24 concurrent calls (r:73e1ec5e/FSCORE-667) mod_dingaling: Fix NULL pointer (r:e3eff816/FS-1103) + mod_dingaling: fix leak in chat_send (r:eb109a85) + mod_dingaling: use the login as message source when not in component mode. (chat_send) (r:58c28aab) mod_directory: Add variable directory_search_order to allow to search by first name by default is set to "first_name" (r:163ca31f) mod_distributor: Add mod_distributor to VS2010 - not built by default (r:bac79ba1) mod_dptools: add eavesdrop_enable_dtmf chan var (r:596c0012) @@ -279,8 +296,10 @@ freeswitch (1.0.7) mod_freetdm: lock the channel when placing call (r:705dd237) mod_freetdm: created cmake files for freetdm (r:fc55997b) mod_freetdm: ss7 - added support to control mtp2, mtp3, and isup timers via freetdm.conf.xml (r:4455d581) + mod_freetdm: made ftmod_r2 use FTDM_SPAN_USE_SIGNALS_QUEUE and properly send FTDM_SIGEVENT_SIGSTATUS_CHANGED (r:af5f0a4a) mod_gsmopen: copy from branch mod_gsmopen: fix FS-2793, compilation stops (r:355c0dbb/FS-2793) + mod_gsmopen: retry serial initialization if failed, zeroing audio buffers, slower retry on soundcard busy (EAGAIN) (r:c7aefe93) mod_hash: free all hashtables on shutdown (r:e76d7d92) mod_hash: remove unneeded initializer (r:10d468a6) mod_hash: begin working on remote support (r:c5ad49da) @@ -324,6 +343,7 @@ freeswitch (1.0.7) mod_lua: Added SAF_ROUTING_EXEC flag to lua app, so it can be run inline (r:7d5ca1c0) mod_managed: Added wrapper for switch_event_bind for .net (r:a5f07a80/MODLANG-165) mod_managed: add additional support (r:5be58aac) + mod_managed: add mono 2.8 patch file see FS-2774 (r:6a948bd9/FS-2774) mod_mp4v: MP4V-ES passthru for washibechi on IRC mod_mp4: New module. Supports playback of MP4 files. Depends on libmp4v2 (originally compiled against v1.6.1) mod_nibblebill: free allocated mem at shutdown; free properly if using custom_sql @@ -472,6 +492,14 @@ freeswitch (1.0.7) mod_sofia: fix missing name and potential segfault in gateway status (r:40ac860a) mod_sofia: Add missing RTP info for early SDP in bypass media (r:10119e9e/FS-2824) mod_sofia: add manual_rtp_bugs to profile and chan var and 3 new RTP bugs SEND_LINEAR_TIMESTAMPS|START_SEQ_AT_ZERO|NEVER_SEND_MARKER (r:b278dd23) + mod_sofia: apparently some sip device vendors did not read the RFC (who knew?) adding verbose_sdp=true var to add needless a= lines for standard iana codecs that explicitly do not require them (r:6c4f49a8) + mod_sofia: Fix registering a gateway, sofia always places a Via header with ext-sip-ip, even if this gateway is local (r:cf398e1a/FS-535) + mod_sofia: add presence-probe-on-register sofia param to send a probe on register instead of presence to deal with some broken phones and add some general improvements to allow multi homed presence (r:14394994) + mod_sofia: Fix issue when fs_path is used so we pick the correct media IP in our outbound invite this was soemthing that wouldn't work correctly over ATT on the iphone. (r:a669f76f) + mod_sofia: Default T38 Options (r:92f43440/FS-2892) + mod_sofia: Fix wrong IP in VIA and contact HEADER for MESSAGE method while fs run in private network (r:59ea4a1b/FS-2886) + mod_sofia: SIP-header History-Info might exist multiple times, but only last header is exposed as a channel variable (r:8cf15012/FS-2881) + mod_sofia: Add support to reboot Yealink phone remotely (r:fdc31908/FS-2897) mod_spandsp: initial checkin of mod_fax/mod_voipcodecs merge into mod_spandsp (r:fa9a59a8) mod_spandsp: rework of new mod_spandsp to have functions broken up into different c files (r:65400642) mod_spandsp: improve duplicate digit detection and add 'min_dup_digit_spacing_ms' channel variable for use with the dtmf detector (r:eab4f246/FSMOD-45) @@ -508,6 +536,8 @@ freeswitch (1.0.7) mod_xml_cdr: fix minor memory leaks and config bug (r:19253d83/MODEVENT-62) mod_xml_rpc: Fix crash if unauthorized XML RPC is attempted (r:9835395c/FS-184) scripts: added honeypot.pl and blacklist.pl which add extra SIP security options (r:b6a81ba7) + scripts: do simple verification to make sure we are getting IP addresses from VoIP abuse blacklist (r:b0049160) + scripts: add_user - cmd line utility that lets admin create new users very easily. (r:ec8f2c2b) sofia-sip: fix null derefernce segfault in soa (r:f356c5e6) sofia-sip: extend timeout for session expires on short timeouts to be 90% of timeout instead of 1/3 to handle devices that do not refresh in time such as polycom (r:a7f48928/SFSIP-212) tools: Add fs_encode tool (r:89b17601) From 5aba96e382793c2c4440a658f7c1797b6c8c2809 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 8 Dec 2010 20:38:16 -0600 Subject: [PATCH 27/35] FS-2910 --- src/switch_odbc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/switch_odbc.c b/src/switch_odbc.c index a1c476e4a1..5a88ba7690 100644 --- a/src/switch_odbc.c +++ b/src/switch_odbc.c @@ -160,11 +160,6 @@ static int db_is_up(switch_odbc_handle_t *handle) strcpy((char *) sql, "select 1"); } - if (stmt) { - SQLFreeHandle(SQL_HANDLE_STMT, stmt); - stmt = NULL; - } - if (SQLAllocHandle(SQL_HANDLE_STMT, handle->con, &stmt) != SQL_SUCCESS) { code = __LINE__; goto error; @@ -229,6 +224,11 @@ static int db_is_up(switch_odbc_handle_t *handle) goto done; } + if (stmt) { + SQLFreeHandle(SQL_HANDLE_STMT, stmt); + stmt = NULL; + } + switch_safe_free(err_str); switch_yield(1000000); goto top; From 515e0ad175bbf5ec847669b3bd50fd46c9bdeea8 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 8 Dec 2010 23:04:29 -0500 Subject: [PATCH 28/35] freetdm: fix testsangomaboost --- libs/freetdm/src/testsangomaboost.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/freetdm/src/testsangomaboost.c b/libs/freetdm/src/testsangomaboost.c index e9042eef17..01e5a6be22 100644 --- a/libs/freetdm/src/testsangomaboost.c +++ b/libs/freetdm/src/testsangomaboost.c @@ -52,7 +52,6 @@ #define __USE_BSD #endif #include -#endif #include "freetdm.h" From 499eafb2e02f7d5359dc7d09aa635c7f4dbd3c69 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 9 Dec 2010 07:19:31 -0500 Subject: [PATCH 29/35] freetdm: check for dump enabled before writing to file --- libs/freetdm/src/ftdm_io.c | 19 +++++++++++++++++-- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 5 +++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 249d8580b5..ef290964d4 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -128,8 +128,15 @@ static void write_chan_io_dump(ftdm_io_dump_t *dump, char *dataptr, int dlen) static void dump_chan_io_to_file(ftdm_channel_t *fchan, ftdm_io_dump_t *dump, FILE *file) { /* write the saved audio buffer */ - size_t rc = 0; - size_t towrite = dump->size - dump->windex; + ftdm_size_t rc = 0; + ftdm_size_t towrite = 0; + + if (!dump->buffer) { + return; + } + + towrite = dump->size - dump->windex; + if (dump->wrapped) { rc = fwrite(&dump->buffer[dump->windex], 1, towrite, file); if (rc != towrite) { @@ -2821,6 +2828,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co if (!obj) { GOTO_STATUS(done, FTDM_FAIL); } + if (!ftdmchan->rxdump.buffer) { + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Not dumped input to file %p, input dump is not enabled\n", obj); + GOTO_STATUS(done, FTDM_FAIL); + } dump_chan_io_to_file(ftdmchan, &ftdmchan->rxdump, obj); ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %d to file %p\n", ftdmchan->rxdump.size, obj); GOTO_STATUS(done, FTDM_SUCCESS); @@ -2833,6 +2844,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co if (!obj) { GOTO_STATUS(done, FTDM_FAIL); } + if (!ftdmchan->txdump.buffer) { + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Not dumped output to file %p, output dump is not enabled\n", obj); + GOTO_STATUS(done, FTDM_FAIL); + } dump_chan_io_to_file(ftdmchan, &ftdmchan->txdump, obj); ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %zd to file %p\n", ftdmchan->txdump.size, obj); GOTO_STATUS(done, FTDM_SUCCESS); diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index ab85d2b4d6..37070c45a1 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -29,6 +29,11 @@ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Contributors: + * + * Arnaldo Pereira + * */ #ifdef __linux__ From 3c747978f4b1dc395846e90f613fbf2acb6324db Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 9 Dec 2010 13:20:05 -0500 Subject: [PATCH 30/35] freetdm: support for call variables --- libs/freetdm/mod_freetdm/mod_freetdm.c | 42 +++-- libs/freetdm/src/ftdm_io.c | 129 ++++++++++++++- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 31 +++- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 8 +- .../ftmod_sangoma_isdn_stack_hndl.c | 9 +- .../ftmod_sangoma_isdn_stack_out.c | 26 ++- .../ftmod_sangoma_isdn_support.c | 151 ++++++++++++++++-- .../ftmod_sangoma_ss7_handle.c | 4 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 42 ++--- libs/freetdm/src/include/freetdm.h | 57 ++++++- libs/freetdm/src/include/private/ftdm_core.h | 1 + 11 files changed, 428 insertions(+), 72 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 7ea6bb6d37..38197bb2f0 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -429,7 +429,7 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) assert(tech_pvt->ftdmchan != NULL); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel)); - + ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROCEED); return SWITCH_STATUS_SUCCESS; } @@ -1329,7 +1329,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi char *v = h->name + FREETDM_VAR_PREFIX_LEN; if (!zstr(v)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s=%s to channel %d:%d\n", v, h->value, span_id, chan_id); - ftdm_channel_add_var(ftdmchan, v, h->value); + ftdm_call_add_var(&caller_data, v, h->value); } } } @@ -1528,6 +1528,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chanid); switch_channel_set_variable_printf(channel, "freetdm_bearer_capability", "%d", channel_caller_data->bearer_capability); switch_channel_set_variable_printf(channel, "freetdm_bearer_layer1", "%d", channel_caller_data->bearer_layer1); + if (globals.sip_headers) { switch_channel_set_variable(channel, "sip_h_X-FreeTDM-SpanName", ftdm_channel_get_span_name(sigmsg->channel)); switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-SpanNumber", "%d", spanid); @@ -1561,8 +1562,18 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session ftdm_channel_get_current_var(curr, &var_name, &var_value); snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name); switch_channel_set_variable_printf(channel, name, "%s", var_value); + } + + /* Add any call variable to the dial plan */ + iter = ftdm_call_get_var_iterator(channel_caller_data, iter); + for (curr = iter ; curr; curr = ftdm_iterator_next(curr)) { + ftdm_call_get_current_var(curr, &var_name, &var_value); + snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name); + switch_channel_set_variable_printf(channel, name, "%s", var_value); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s=%s\n", name, var_value); } ftdm_iterator_free(iter); + switch_channel_set_state(channel, CS_INIT); if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { @@ -1661,11 +1672,11 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) ftdm_status_t status; uint32_t spanid; uint32_t chanid; - ftdm_caller_data_t *callerdata; + ftdm_caller_data_t *caller_data; spanid = ftdm_channel_get_span_id(sigmsg->channel); chanid = ftdm_channel_get_id(sigmsg->channel); - callerdata = ftdm_channel_get_caller_data(sigmsg->channel); + caller_data = ftdm_channel_get_caller_data(sigmsg->channel); ftdm_log(FTDM_LOG_DEBUG, "got FXO sig %d:%d [%s]\n", spanid, chanid, ftdm_signal_event2str(sigmsg->event_id)); @@ -1688,7 +1699,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) switch_set_flag_locked(tech_pvt, TFLAG_DEAD); ftdm_channel_clear_token(sigmsg->channel, 0); channel = switch_core_session_get_channel(session); - switch_channel_hangup(channel, callerdata->hangup_cause); + switch_channel_hangup(channel, caller_data->hangup_cause); ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session)); switch_core_session_rwunlock(session); } @@ -1712,8 +1723,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) } } break; - case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; - + case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; + default: { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n", @@ -1767,7 +1778,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal) } } break; - case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; + case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; + case FTDM_SIGEVENT_STOP: { private_t *tech_pvt = NULL; @@ -1991,8 +2003,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal) } break; - case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; - + case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; + /* on DNIS received from the R2 forward side, return status == FTDM_BREAK to stop requesting DNIS */ case FTDM_SIGEVENT_COLLECTED_DIGIT: { @@ -2104,14 +2116,14 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) switch(sigmsg->event_id) { case FTDM_SIGEVENT_START: { - ftdm_channel_add_var(sigmsg->channel, "screening_ind", ftdm_screening2str(caller_data->screen)); - ftdm_channel_add_var(sigmsg->channel, "presentation_ind", ftdm_presentation2str(caller_data->pres)); + ftdm_call_add_var(caller_data, "screening_ind", ftdm_screening2str(caller_data->screen)); + ftdm_call_add_var(caller_data, "presentation_ind", ftdm_presentation2str(caller_data->pres)); return ftdm_channel_from_event(sigmsg, &session); } break; - case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; - + case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; + case FTDM_SIGEVENT_STOP: case FTDM_SIGEVENT_RESTART: { @@ -2176,7 +2188,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) } break; case FTDM_SIGEVENT_PROCEED: - case FTDM_SIGEVENT_MSG: + case FTDM_SIGEVENT_FACILITY: /* FS does not have handlers for these messages, so ignore them for now */ break; default: diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index ef290964d4..7355c8497c 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -61,6 +61,8 @@ struct tm *localtime_r(const time_t *clock, struct tm *result); 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 int time_is_init = 0; static void time_init(void) @@ -1893,7 +1895,9 @@ static ftdm_status_t ftdm_channel_reset(ftdm_channel_t *ftdmchan) if (!ftdmchan->dtmf_off) { 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)) { @@ -2432,6 +2436,27 @@ done: return FTDM_SUCCESS; } +FT_DECLARE(ftdm_status_t) _ftdm_channel_call_send_msg(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_sigmsg_t *sigmsg) +{ + ftdm_status_t status = FTDM_FAIL; + ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel"); +#ifdef __WINDOWS__ + UNREFERENCED_PARAMETER(file); + UNREFERENCED_PARAMETER(func); + UNREFERENCED_PARAMETER(line); +#endif + + ftdm_channel_lock(ftdmchan); + if (ftdmchan->span->send_msg) { + status = ftdmchan->span->send_msg(ftdmchan, sigmsg); + } else { + status = FTDM_NOTIMPL; + ftdm_log(FTDM_LOG_ERROR, "send_msg method not implemented in this span!\n"); + } + ftdm_channel_unlock(ftdmchan); + return status; +} + FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan) { ftdm_status_t status = FTDM_FAIL; @@ -3878,6 +3903,100 @@ done: return status; } +FT_DECLARE(void) ftdm_call_clear_data(ftdm_caller_data_t *caller_data) +{ + ftdm_call_clear_vars(caller_data); + memset(caller_data.raw_data, 0, sizeof(raw_data)); + caller_data->raw_data_len = 0; + return; +} + +FT_DECLARE(ftdm_status_t) ftdm_call_clear_vars(ftdm_caller_data_t *caller_data) +{ + if (caller_data->variables) { + hashtable_destroy(caller_data->variables); + } + caller_data->variables = NULL; + return FTDM_SUCCESS; +} + +FT_DECLARE(ftdm_status_t) ftdm_call_remove_var(ftdm_caller_data_t *caller_data, const char *var_name) +{ + if (caller_data->variables) { + hashtable_remove(caller_data->variables, (void *)var_name); + } + + return FTDM_SUCCESS; +} + + +FT_DECLARE(ftdm_status_t) ftdm_call_add_var(ftdm_caller_data_t *caller_data, const char *var_name, const char *value) +{ + char *t_name = 0, *t_val = 0; + + if (!var_name || !value) { + return FTDM_FAIL; + } + + if (!caller_data->variables) { + /* initialize on first use */ + caller_data->variables = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); + ftdm_assert_return(caller_data->variables, FTDM_FAIL, "Failed to create hash table\n"); + } + + t_name = ftdm_strdup(var_name); + t_val = ftdm_strdup(value); + hashtable_insert(caller_data->variables, t_name, t_val, HASHTABLE_FLAG_FREE_KEY | HASHTABLE_FLAG_FREE_VALUE); + return FTDM_SUCCESS; +} + +FT_DECLARE(const char *) ftdm_call_get_var(ftdm_caller_data_t *caller_data, const char *var_name) +{ + const char *var = NULL; + + if (!caller_data->variables || !var_name) { + return NULL; + } + + var = (const char *)hashtable_search(((struct hashtable*)caller_data->variables), (void *)var_name); + return var; +} + +FT_DECLARE(ftdm_iterator_t *) ftdm_call_get_var_iterator(const ftdm_caller_data_t *caller_data, ftdm_iterator_t *iter) +{ + ftdm_hash_iterator_t *hashiter = NULL; + hashiter = caller_data->variables == NULL ? NULL : hashtable_first(caller_data->variables); + + if (hashiter == NULL) { + return NULL; + } + + if (!(iter = get_iterator(FTDM_ITERATOR_VARS, iter))) { + return NULL; + } + iter->pvt.hashiter = hashiter; + return iter; +} + +FT_DECLARE(ftdm_status_t) ftdm_call_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val) +{ + const void *key = NULL; + void *val = NULL; + + *var_name = NULL; + *var_val = NULL; + + ftdm_assert_return(iter && (iter->type == FTDM_ITERATOR_VARS) && iter->pvt.hashiter, FTDM_FAIL, "Cannot get variable from invalid iterator!\n"); + + hashtable_this(iter->pvt.hashiter, &key, NULL, &val); + + *var_name = key; + *var_val = val; + + return FTDM_SUCCESS; +} + + static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan) { ftdm_channel_lock(ftdmchan); @@ -3924,6 +4043,7 @@ done: return status; } + FT_DECLARE(const char *) ftdm_channel_get_var(ftdm_channel_t *ftdmchan, const char *var_name) { const char *var = NULL; @@ -5157,7 +5277,11 @@ FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *na static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) { - return span->signal_cb(sigmsg); + ftdm_status_t status = span->signal_cb(sigmsg); + if (sigmsg->channel) { + ftdm_call_clear_data(&(sigmsg->channel->caller_data)); + } + return status; } static ftdm_status_t ftdm_span_queue_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) @@ -5261,6 +5385,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t } done: + if (sigmsg->channel) { ftdm_mutex_unlock(sigmsg->channel->mutex); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index 03b5a5fb1d..96f1a2b430 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -626,8 +626,11 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) case FTDM_CHANNEL_STATE_GET_CALLERID: { if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) { + /* By default, we do not send a progress indicator in the proceed */ + ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID}; + sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED); - sngisdn_snd_proceed(ftdmchan); + sngisdn_snd_proceed(ftdmchan, prog_ind); } /* Wait in this state until we get FACILITY msg */ } @@ -666,8 +669,11 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) ftdm_span_send_signal(ftdmchan->span, &sigev); } else { if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) { + /* By default, we do not send a progress indicator in the proceed */ + ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID}; + sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED); - sngisdn_snd_proceed(ftdmchan); + sngisdn_snd_proceed(ftdmchan, prog_ind); } } } @@ -851,6 +857,26 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) return; } +static FIO_CHANNEL_SEND_MSG_FUNCTION(ftdm_sangoma_isdn_send_msg) +{ + ftdm_status_t status = FTDM_FAIL; + + switch (sigmsg->event_id) { + case FTDM_SIGEVENT_RESTART: + /* TODO: Send a channel restart here */ + /* Implement me */ + break; + case FTDM_SIGEVENT_FACILITY: + sngisdn_snd_fac_req(ftdmchan); + break; + default: + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Unsupported signalling msg requested\n"); + status = FTDM_BREAK; + } + ftdm_call_clear_data(&ftdmchan->caller_data); + return status; +} + static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_isdn_outgoing_call) { sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; @@ -1030,6 +1056,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) span->stop = ftdm_sangoma_isdn_stop; span->signal_type = FTDM_SIGTYPE_ISDN; span->outgoing_call = ftdm_sangoma_isdn_outgoing_call; + span->send_msg = ftdm_sangoma_isdn_send_msg; span->channel_request = NULL; span->signal_cb = sig_cb; span->get_channel_sig_status = ftdm_sangoma_isdn_get_chan_sig_status; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index b9ab3395ae..f15eff9200 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -363,7 +363,7 @@ void stack_pst_init(Pst *pst); /* Outbound Call Control functions */ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan); void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan); -void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan); +void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind); void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind); void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind); void sngisdn_snd_connect(ftdm_channel_t *ftdmchan); @@ -436,6 +436,7 @@ void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...); void sngisdn_rcv_sng_assert(char *message); ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); +ftdm_status_t get_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb); ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb); ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *display); @@ -443,16 +444,17 @@ ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *us ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad); ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd); ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr); -ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t data_len); +ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t data_len); ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); +ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb); ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb); ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt); ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad); ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind); ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr); -ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t *data_len); +ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t *data_len); uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index 086354a993..cb9f6d33e1 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -123,12 +123,9 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) break; } -#if 0 - /* Export ftdmchan variables here if we need to */ - ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1"); -#endif /* Fill in call information */ get_calling_num(ftdmchan, &conEvnt->cgPtyNmb); + get_calling_num2(ftdmchan, &conEvnt->cgPtyNmb2); get_called_num(ftdmchan, &conEvnt->cdPtyNmb); get_redir_num(ftdmchan, &conEvnt->redirNmb); get_calling_subaddr(ftdmchan, &conEvnt->cgPtySad); @@ -757,14 +754,14 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) { ftdm_sigmsg_t sigev; if (facEvnt->facElmt.facStr.pres) { - get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len); + get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len-2); } memset(&sigev, 0, sizeof(sigev)); sigev.chan_id = ftdmchan->chan_id; sigev.span_id = ftdmchan->span_id; sigev.channel = ftdmchan; - sigev.event_id = FTDM_SIGEVENT_MSG; + sigev.event_id = FTDM_SIGEVENT_FACILITY; ftdm_span_send_signal(ftdmchan->span, &sigev); } break; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c index 38bbdb6968..297c59c3b7 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c @@ -128,6 +128,7 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) set_called_num(ftdmchan, &conEvnt.cdPtyNmb); set_calling_num(ftdmchan, &conEvnt.cgPtyNmb); + set_calling_num2(ftdmchan, &conEvnt.cgPtyNmb2); set_calling_subaddr(ftdmchan, &conEvnt.cgPtySad); set_redir_num(ftdmchan, &conEvnt.redirNmb); set_calling_name(ftdmchan, &conEvnt); @@ -262,10 +263,9 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan) } -void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan) +void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind) { CnStEvnt cnStEvnt; - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; @@ -310,7 +310,9 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan) cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id; } + set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); + ftdm_call_clear_data(&ftdmchan->caller_data); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROCEED (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); @@ -343,6 +345,7 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ memset(&cnStEvnt, 0, sizeof(cnStEvnt)); set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); + ftdm_call_clear_data(&ftdmchan->caller_data); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, signal_data->dchan_id, sngisdn_info->ces)) { @@ -369,6 +372,7 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); + ftdm_call_clear_data(&ftdmchan->caller_data); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending ALERT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); @@ -428,6 +432,7 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan) set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); + ftdm_call_clear_data(&ftdmchan->caller_data); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) { @@ -450,10 +455,17 @@ void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan) memset(&facEvnt, 0, sizeof(facEvnt)); - set_facility_ie_str(ftdmchan, &facEvnt.facElmt.facStr.val[2], (ftdm_size_t*)&facEvnt.facElmt.facStr.len); + if (set_facility_ie_str(ftdmchan, &facEvnt.facElmt.facStr.val[2], (uint8_t*)&facEvnt.facElmt.facStr.len) != FTDM_SUCCESS) { + /* No point in sending a FACILITY message if there is no Facility IE to transmit */ + return; + } + ftdm_call_clear_data(&ftdmchan->caller_data); + facEvnt.facElmt.eh.pres = PRSNT_NODEF; + facEvnt.facElmt.facStr.pres = PRSNT_NODEF; facEvnt.facElmt.facStr.val[0] = 0x1C; - facEvnt.facElmt.facStr.val[1] = facEvnt.facElmt.facStr.len; + facEvnt.facElmt.facStr.val[1] = (uint8_t)facEvnt.facElmt.facStr.len; + facEvnt.facElmt.facStr.len +=2; /* Need to include the size of identifier + len */ ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending FACILITY (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); @@ -481,6 +493,8 @@ void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan) //ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending INFO REQ\n"); + ftdm_call_clear_data(&ftdmchan->caller_data); + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending INFO REQ (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, signal_data->dchan_id, sngisdn_info->ces); if (sng_isdn_con_status(signal_data->cc_id, 0, 0, &cnStEvnt, MI_INFO, signal_data->dchan_id, sngisdn_info->ces)) { @@ -501,6 +515,8 @@ void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan) memset(&staEvnt, 0, sizeof(StaEvnt)); + ftdm_call_clear_data(&ftdmchan->caller_data); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Status ENQ on suId:%d suInstId:%u spInstId:%d dchan:%d ces:%d\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); if (sng_isdn_status_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &staEvnt, MI_STATENQ)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused Status ENQ request\n"); @@ -539,6 +555,7 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan) discEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT; set_facility_ie(ftdmchan, &discEvnt.facilityStr); + ftdm_call_clear_data(&ftdmchan->caller_data); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); if (sng_isdn_disc_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &discEvnt)) { @@ -585,6 +602,7 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare) } set_facility_ie(ftdmchan, &relEvnt.facilityStr); + ftdm_call_clear_data(&ftdmchan->caller_data); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RELEASE/RELEASE COMPLETE (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, suInstId, spInstId); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index fae25c9ad6..76d11d6d34 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -185,6 +185,39 @@ ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) return FTDM_SUCCESS; } +ftdm_status_t get_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) +{ + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; + if (cgPtyNmb->eh.pres != PRSNT_NODEF) { + return FTDM_FAIL; + } + + if (cgPtyNmb->screenInd.pres == PRSNT_NODEF) { + ftdm_call_add_var(caller_data, "isdn.cg_pty2.screen_ind", ftdm_screening2str(cgPtyNmb->screenInd.val)); + } + + if (cgPtyNmb->presInd0.pres == PRSNT_NODEF) { + ftdm_call_add_var(caller_data, "isdn.cg_pty2.presentation_ind", ftdm_presentation2str(cgPtyNmb->presInd0.val)); + } + + if (cgPtyNmb->nmbPlanId.pres == PRSNT_NODEF) { + ftdm_call_add_var(caller_data, "isdn.cg_pty2.npi", ftdm_npi2str(cgPtyNmb->nmbPlanId.val)); + } + + if (cgPtyNmb->typeNmb1.pres == PRSNT_NODEF) { + ftdm_call_add_var(caller_data, "isdn.cg_pty2.ton", ftdm_ton2str(cgPtyNmb->typeNmb1.val)); + } + + if (cgPtyNmb->nmbDigits.pres == PRSNT_NODEF) { + char digits_string [32]; + memcpy(digits_string, (const char*)cgPtyNmb->nmbDigits.val, cgPtyNmb->nmbDigits.len); + digits_string[cgPtyNmb->nmbDigits.len] = '\0'; + ftdm_call_add_var(caller_data, "isdn.cg_pty2.digits", digits_string); + } + memcpy(&caller_data->ani, &caller_data->cid_num, sizeof(caller_data->ani)); + return FTDM_SUCCESS; +} + ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb) { ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; @@ -278,7 +311,7 @@ ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad) memcpy(subaddress, (char*)cgPtySad->sadInfo.val, cgPtySad->sadInfo.len); subaddress[cgPtySad->sadInfo.len] = '\0'; - ftdm_channel_add_var(ftdmchan, "isdn.calling_subaddr", subaddress); + ftdm_call_add_var(&ftdmchan->caller_data, "isdn.calling_subaddr", subaddress); return FTDM_SUCCESS; } @@ -291,17 +324,16 @@ ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr return get_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, facilityStr->facilityStr.len); } -ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t data_len) +ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t data_len) { ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) { - if (data_len > sizeof(caller_data->raw_data)-2) { - ftdm_log(FTDM_LOG_CRIT, "Length of Facility IE exceeds maximum length\n"); - return FTDM_FAIL; - } - + /* size of facilityStr->facilityStr.len is a uint8_t so no need to check + for overflow here as facilityStr->facilityStr.len will always be smaller + than sizeof(caller_data->raw_data) */ + memset(caller_data->raw_data, 0, sizeof(caller_data->raw_data)); /* Always include Facility IE identifier + len so this can be used as a sanity check by the user */ caller_data->raw_data[0] = SNGISDN_Q931_FACILITY_IE_ID; @@ -348,7 +380,7 @@ ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd) val = SNGISDN_PROGIND_DESCR_INVALID; break; } - ftdm_channel_add_var(ftdmchan, "isdn.prog_ind.descr", ftdm_sngisdn_progind_descr2str(val)); + ftdm_call_add_var(&ftdmchan->caller_data, "isdn.prog_ind.descr", ftdm_sngisdn_progind_descr2str(val)); } if (progInd->location.pres) { @@ -379,7 +411,7 @@ ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd) val = SNGISDN_PROGIND_LOC_INVALID; break; } - ftdm_channel_add_var(ftdmchan, "isdn.prog_ind.loc", ftdm_sngisdn_progind_loc2str(val)); + ftdm_call_add_var(&ftdmchan->caller_data, "isdn.prog_ind.loc", ftdm_sngisdn_progind_loc2str(val)); } return FTDM_SUCCESS; } @@ -423,6 +455,89 @@ ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) return FTDM_SUCCESS; } +ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) +{ + const char* string = NULL; + uint8_t len,val; + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; + + string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.digits"); + if ((string == NULL) || !(*string)) { + return FTDM_FAIL; + } + + cgPtyNmb->eh.pres = PRSNT_NODEF; + + len = strlen(string); + cgPtyNmb->nmbDigits.len = len; + + cgPtyNmb->nmbDigits.pres = PRSNT_NODEF; + memcpy(cgPtyNmb->nmbDigits.val, string, len); + + /* Screening Indicator */ + cgPtyNmb->screenInd.pres = PRSNT_NODEF; + + val = FTDM_SCREENING_INVALID; + string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.screening_ind"); + if ((string != NULL) && (*string)) { + val = ftdm_str2ftdm_screening(string); + } + + /* isdn.cg_pty2.screen_ind does not exist or we could not parse its value */ + if (val == FTDM_SCREENING_INVALID) { + /* default to caller data screening ind */ + cgPtyNmb->screenInd.val = caller_data->screen; + } else { + cgPtyNmb->screenInd.val = val; + } + + /* Presentation Indicator */ + cgPtyNmb->presInd0.pres = PRSNT_NODEF; + + val = FTDM_PRES_INVALID; + string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.presentation_ind"); + if ((string != NULL) && (*string)) { + val = ftdm_str2ftdm_presentation(string); + } + + if (val == FTDM_PRES_INVALID) { + cgPtyNmb->presInd0.val = caller_data->pres; + } else { + cgPtyNmb->presInd0.val = val; + } + + /* Numbering Plan Indicator */ + cgPtyNmb->nmbPlanId.pres = PRSNT_NODEF; + + val = FTDM_NPI_INVALID; + string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.npi"); + if ((string != NULL) && (*string)) { + val = ftdm_str2ftdm_npi(string); + } + + if (val == FTDM_NPI_INVALID) { + cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan; + } else { + cgPtyNmb->nmbPlanId.val = val; + } + + cgPtyNmb->typeNmb1.pres = PRSNT_NODEF; + + /* Type of Number */ + val = FTDM_TON_INVALID; + string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.ton"); + if ((string != NULL) && (*string)) { + val = ftdm_str2ftdm_ton(string); + } + + if (val == FTDM_TON_INVALID) { + cgPtyNmb->typeNmb1.val = caller_data->cid_num.type; + } else { + cgPtyNmb->typeNmb1.val = val; + } + return FTDM_SUCCESS; +} + ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb) { ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; @@ -544,7 +659,7 @@ ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt) ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad) { const char* clg_subaddr = NULL; - clg_subaddr = ftdm_channel_get_var(ftdmchan, "isdn.calling_subaddr"); + clg_subaddr = ftdm_call_get_var(&ftdmchan->caller_data, "isdn.calling_subaddr"); if ((clg_subaddr != NULL) && (*clg_subaddr)) { unsigned len = strlen (clg_subaddr); cgPtySad->eh.pres = PRSNT_NODEF; @@ -565,7 +680,7 @@ ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad) ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr) { ftdm_status_t status; - status = set_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, (ftdm_size_t*)&facilityStr->facilityStr.len); + status = set_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, (uint8_t*)&(facilityStr->facilityStr.len)); if (status == FTDM_SUCCESS) { facilityStr->eh.pres = PRSNT_NODEF; facilityStr->facilityStr.pres = PRSNT_NODEF; @@ -573,13 +688,15 @@ ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr return status; } -ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t *data_len) +ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t *data_len) { + int len; ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; if (caller_data->raw_data_len > 0 && caller_data->raw_data[0] == SNGISDN_Q931_FACILITY_IE_ID) { - *data_len = caller_data->raw_data[1]; - memcpy(data, &caller_data->raw_data[2], *data_len); + len = caller_data->raw_data[1]; + memcpy(data, &caller_data->raw_data[2], len); + *data_len = len; return FTDM_SUCCESS; } return FTDM_FAIL; @@ -591,7 +708,7 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s int descr = prog_ind.descr; int loc = prog_ind.loc; - str = ftdm_channel_get_var(ftdmchan, "isdn.prog_ind.descr"); + str = ftdm_call_get_var(&ftdmchan->caller_data, "isdn.prog_ind.descr"); if (str && *str) { /* User wants to override progress indicator */ descr = ftdm_str2ftdm_sngisdn_progind_descr(str); @@ -602,8 +719,8 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s return FTDM_SUCCESS; } - str = ftdm_channel_get_var(ftdmchan, "isdn.prog_ind.loc"); - if (str && *str) { + str = ftdm_call_get_var(&ftdmchan->caller_data, "isdn.prog_ind.loc"); + if (str && *str) { loc = ftdm_str2ftdm_sngisdn_progind_loc(str); } if (loc == SNGISDN_PROGIND_LOC_INVALID) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c index 72e4bacf52..7517ee42a0 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c @@ -211,10 +211,10 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* add any special variables for the dialplan */ sprintf(nadi, "%d", siConEvnt->cgPtyNum.natAddrInd.val); - ftdm_channel_add_var(ftdmchan, "ss7_clg_nadi", nadi); + ftdm_call_add_var(&ftdmchan->caller_data, "ss7_clg_nadi", nadi); sprintf(nadi, "%d", siConEvnt->cdPtyNum.natAddrInd.val); - ftdm_channel_add_var(ftdmchan, "ss7_cld_nadi", nadi); + ftdm_call_add_var(&ftdmchan->caller_data, "ss7_cld_nadi", nadi); /* check if a COT test is requested */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c index 008265b9a4..ec8d7df12a 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c @@ -187,7 +187,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum); /* check if the user would like a custom NADI value for the calling Pty Num */ - clg_nadi = ftdm_channel_get_var(ftdmchan, "ss7_clg_nadi"); + clg_nadi = ftdm_call_get_var(&ftdmchan->caller_data, "ss7_clg_nadi"); if ((clg_nadi != NULL) && (*clg_nadi)) { SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling NADI value \"%s\"\n", clg_nadi); iam.cgPtyNum.natAddrInd.val = atoi(clg_nadi); @@ -196,7 +196,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLG, using \"%d\"\n", iam.cgPtyNum.natAddrInd.val); } - cld_nadi = ftdm_channel_get_var(ftdmchan, "ss7_cld_nadi"); + cld_nadi = ftdm_call_get_var(&ftdmchan->caller_data, "ss7_cld_nadi"); if ((cld_nadi != NULL) && (*cld_nadi)) { SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called NADI value \"%s\"\n", cld_nadi); iam.cdPtyNum.natAddrInd.val = atoi(cld_nadi); @@ -206,7 +206,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) } /* check if the user would like us to send a clg_sub-address */ - clg_subAddr = ftdm_channel_get_var(ftdmchan, "ss7_clg_subaddr"); + clg_subAddr = ftdm_call_get_var(&ftdmchan->caller_data, "ss7_clg_subaddr"); if ((clg_subAddr != NULL) && (*clg_subAddr)) { SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling Sub-Address value \"%s\"\n", clg_subAddr); @@ -245,7 +245,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) } /* check if the user would like us to send a cld_sub-address */ - cld_subAddr = ftdm_channel_get_var(ftdmchan, "ss7_cld_subaddr"); + cld_subAddr = ftdm_call_get_var(&ftdmchan->caller_data, "ss7_cld_subaddr"); if ((cld_subAddr != NULL) && (*cld_subAddr)) { SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called Sub-Address value \"%s\"\n", cld_subAddr); @@ -298,7 +298,8 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) iam.cgPtyNum.natAddrInd.val, ftdmchan->caller_data.dnis.digits, iam.cdPtyNum.natAddrInd.val); - + + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -379,7 +380,7 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) ADDRCMPLT); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ACM\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -403,7 +404,7 @@ void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan) 5); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ANM\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -438,7 +439,7 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan) SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx REL cause=%d \n", sngss7_info->circuit->cic, ftdmchan->caller_data.hangup_cause ); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -461,7 +462,7 @@ void ft_to_sngss7_rlc (ftdm_channel_t * ftdmchan) &rlc); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RLC\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -482,7 +483,7 @@ void ft_to_sngss7_rsc (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -503,7 +504,7 @@ void ft_to_sngss7_rsca (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC-RLC\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -524,7 +525,7 @@ void ft_to_sngss7_blo (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLO\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -545,7 +546,7 @@ void ft_to_sngss7_bla (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLA\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -567,7 +568,7 @@ ft_to_sngss7_ubl (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBL\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -588,7 +589,7 @@ void ft_to_sngss7_uba (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBA\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -609,7 +610,7 @@ void ft_to_sngss7_lpa (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx LPA\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -654,6 +655,7 @@ void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan) sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->rx_grs.range)); + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -686,7 +688,8 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan) sngss7_info->circuit->cic, sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->tx_grs.range)); - + + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -735,7 +738,7 @@ void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan) /* clean out the saved data */ memset(&sngss7_span->rx_cgb, 0x0, sizeof(sngss7_group_data_t)); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -785,6 +788,7 @@ void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan) /* clean out the saved data */ memset(&sngss7_span->rx_cgu, 0x0, sizeof(sngss7_group_data_t)); + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -835,6 +839,7 @@ void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan) /* clean out the saved data */ memset(&sngss7_span->tx_cgb, 0x0, sizeof(sngss7_group_data_t)); + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -885,6 +890,7 @@ void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan) /* clean out the saved data */ memset(&sngss7_span->tx_cgu, 0x0, sizeof(sngss7_group_data_t)); + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 41e7f50ed8..4ee6ff5f52 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -272,6 +272,8 @@ typedef struct { uint8_t plan; } ftdm_number_t; +typedef void * ftdm_variable_container_t; + /*! \brief Caller information */ typedef struct ftdm_caller_data { char cid_date[8]; /*!< Caller ID date */ @@ -286,12 +288,13 @@ typedef struct ftdm_caller_data { char collected[25]; /*!< Collected digits so far */ int hangup_cause; /*!< Hangup cause */ char raw_data[1024]; /*!< Protocol specific raw caller data */ - uint32_t raw_data_len; /* !< Raw data length */ + uint32_t raw_data_len; /*!< Raw data length */ /* these 2 are undocumented right now, only used by boost: */ /* bearer capability */ ftdm_bearer_cap_t bearer_capability; /* user information layer 1 protocol */ ftdm_user_layer1_prot_t bearer_layer1; + ftdm_variable_container_t variables; /*!variables and caller_data->raw_data. + * */ +FT_DECLARE(void) ftdm_call_clear_data(ftdm_caller_data_t *caller_data); + /*! \brief Get the span pointer associated to the channel */ FT_DECLARE(ftdm_span_t *) ftdm_channel_get_span(const ftdm_channel_t *ftdmchan); diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index a1e1c02439..deabafd537 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -503,6 +503,7 @@ struct ftdm_span { teletone_multi_tone_t tone_finder[FTDM_TONEMAP_INVALID+1]; ftdm_channel_t *channels[FTDM_MAX_CHANNELS_SPAN+1]; fio_channel_outgoing_call_t outgoing_call; + fio_channel_send_msg_t send_msg; fio_channel_set_sig_status_t set_channel_sig_status; fio_channel_get_sig_status_t get_channel_sig_status; fio_span_set_sig_status_t set_span_sig_status; From 5ab19aaa23dac4771baadd1f2a2b874c8c630154 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 9 Dec 2010 13:47:40 -0500 Subject: [PATCH 31/35] freetdm: fix compilation --- libs/freetdm/src/ftdm_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 7355c8497c..605f13c0bc 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -3906,7 +3906,7 @@ done: FT_DECLARE(void) ftdm_call_clear_data(ftdm_caller_data_t *caller_data) { ftdm_call_clear_vars(caller_data); - memset(caller_data.raw_data, 0, sizeof(raw_data)); + memset(&caller_data->raw_data, 0, sizeof(caller_data->raw_data)); caller_data->raw_data_len = 0; return; } From fced79a4933560500a5710af3c48019da700948b Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 9 Dec 2010 17:13:34 -0500 Subject: [PATCH 32/35] fix not handling disconnect when in RINGING state --- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index cb9f6d33e1..fb65d20cab 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -407,6 +407,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) } break; case FTDM_CHANNEL_STATE_RING: + case FTDM_CHANNEL_STATE_RINGING: case FTDM_CHANNEL_STATE_PROCEED: case FTDM_CHANNEL_STATE_PROGRESS: case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: @@ -447,6 +448,7 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event) ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_RING: + case FTDM_CHANNEL_STATE_RINGING: case FTDM_CHANNEL_STATE_DIALING: case FTDM_CHANNEL_STATE_PROCEED: case FTDM_CHANNEL_STATE_PROGRESS: @@ -537,6 +539,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: case FTDM_CHANNEL_STATE_UP: case FTDM_CHANNEL_STATE_RING: + case FTDM_CHANNEL_STATE_RINGING: /* If we previously had a glare on this channel, this RELEASE could be for the previous call. Confirm whether call_data has not changed while we were waiting for ftdmchan->mutex by comparing suInstId's */ @@ -881,6 +884,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) break; case FTDM_CHANNEL_STATE_PROCEED: case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_RINGING: case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Remote switch expecting OVERLAP receive, but we are already PROCEEDING\n"); sngisdn_snd_disconnect(ftdmchan); @@ -899,6 +903,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_PROCEED: case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_RINGING: /* T310 timer has expired */ ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val; ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T310 Timer expired, hanging up call\n"); @@ -935,6 +940,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) break; case 9: /* Remote switch is in "Incoming call proceeding" state */ switch (ftdmchan->state) { + case FTDM_CHANNEL_STATE_RINGING: case FTDM_CHANNEL_STATE_PROGRESS: case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: case FTDM_CHANNEL_STATE_GET_CALLERID: From 86c484c134ca46edd572c3b46c6480ac9011292b Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 9 Dec 2010 18:01:31 -0500 Subject: [PATCH 33/35] freetdm: added support for skip states, used by sangoma_isdn module --- libs/freetdm/src/ftdm_io.c | 40 +++++++++---------- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 1 + libs/freetdm/src/include/private/ftdm_types.h | 3 ++ 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 605f13c0bc..eaa25e3da5 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2213,31 +2213,31 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char goto done; } -#ifndef FREETDM_SKIP_SIG_STATES - /* We will fail RFC's if we not skip states, but some modules apart from ftmod_sangoma_isdn - * expect the call to always to go PROGRESS and PROGRESS MEDIA state before going to UP, so - * remove this only in netborder branch for now while we update the sig modules */ + if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_SKIP_STATES)) { + /* We will fail RFC's if we not skip states, but some modules apart from ftmod_sangoma_isdn + * expect the call to always to go PROGRESS and PROGRESS MEDIA state before going to UP, so + * use FTDM_SPAN_USE_SKIP_STATESfor now while we update the sig modules */ - if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) { - ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1); - } + if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) { + ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1); + } - /* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */ - if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n"); - goto done; - } + /* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */ + if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n"); + goto done; + } - if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS_MEDIA) { - ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1); - } + if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS_MEDIA) { + ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1); + } - /* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */ - if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to UP\n"); - goto done; + /* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */ + if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to UP\n"); + goto done; + } } -#endif ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 1); done: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index 96f1a2b430..e20d3ae7e0 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -1067,6 +1067,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE); ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE); ftdm_set_flag(span, FTDM_SPAN_USE_PROCEED_STATE); + ftdm_set_flag(span, FTDM_SPAN_USE_SKIP_STATES); if (span->trunk_type == FTDM_TRUNK_BRI_PTMP || span->trunk_type == FTDM_TRUNK_BRI) { diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index df747021b2..313044abc4 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -184,6 +184,9 @@ typedef enum { FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 10), /* If this flag is set, channel will be moved to proceed state when calls goes to routing */ FTDM_SPAN_USE_PROCEED_STATE = (1 << 11), + /* If this flag is set, the signalling module supports jumping directly to state up, without + going through PROGRESS/PROGRESS_MEDIA */ + FTDM_SPAN_USE_SKIP_STATES = (1 << 12), } ftdm_span_flag_t; /*! \brief Channel supported features */ From 002181e143e5c56c554abeeb37c7611dcdad8536 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 10 Dec 2010 06:52:04 -0500 Subject: [PATCH 34/35] freetdm: fix serious mem leak in R2 module iterator usage --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 34 ++++++++++++++-------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 37070c45a1..e95a74bc25 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -1644,6 +1644,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) int index = 0; struct timeval start, end; ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *citer = NULL; uint32_t txqueue_size = 4; short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count); @@ -1654,8 +1655,12 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) ftdm_log(FTDM_LOG_DEBUG, "OpenR2 monitor thread %lu started.\n", r2data->monitor_thread_id); r2chan = NULL; chaniter = ftdm_span_get_chan_iterator(span, NULL); - for (i = 1; chaniter; chaniter = ftdm_iterator_next(chaniter), i++) { - ftdmchan = ftdm_iterator_current(chaniter); + if (!chaniter) { + ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); + goto done; + } + for (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) { + ftdmchan = ftdm_iterator_current(citer); r2chan = R2CALL(ftdmchan)->r2chan; openr2_chan_set_span_id(r2chan, span->span_id); openr2_chan_set_idle(r2chan); @@ -1694,9 +1699,13 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) /* figure out what event to poll each channel for. POLLPRI when the channel is down, * POLLPRI|POLLIN|POLLOUT otherwise */ memset(poll_events, 0, sizeof(short)*span->chan_count); - chaniter = ftdm_span_get_chan_iterator(span, chaniter); - for (i = 0; chaniter; chaniter = ftdm_iterator_next(chaniter), i++) { - ftdmchan = ftdm_iterator_current(chaniter); + citer = ftdm_span_get_chan_iterator(span, chaniter); + if (!citer) { + ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); + goto done; + } + for (i = 0; citer; citer = ftdm_iterator_next(citer), i++) { + ftdmchan = ftdm_iterator_current(citer); r2chan = R2CALL(ftdmchan)->r2chan; poll_events[i] = POLLPRI; if (openr2_chan_get_read_enabled(r2chan)) { @@ -1737,9 +1746,9 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) /* this main loop takes care of MF and CAS signaling during call setup and tear down * for every single channel in the span, do not perform blocking operations here! */ - chaniter = ftdm_span_get_chan_iterator(span, chaniter); - for ( ; chaniter; chaniter = ftdm_iterator_next(chaniter)) { - ftdmchan = ftdm_iterator_current(chaniter); + citer = ftdm_span_get_chan_iterator(span, chaniter); + for ( ; citer; citer = ftdm_iterator_next(citer)) { + ftdmchan = ftdm_iterator_current(citer); ftdm_mutex_lock(ftdmchan->mutex); @@ -1766,10 +1775,11 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) ftdm_mutex_unlock(ftdmchan->mutex); } } - - chaniter = ftdm_span_get_chan_iterator(span, chaniter); - for ( ; chaniter; chaniter = ftdm_iterator_next(chaniter)) { - ftdmchan = ftdm_iterator_current(chaniter); + +done: + citer = ftdm_span_get_chan_iterator(span, chaniter); + for ( ; citer; citer = ftdm_iterator_next(citer)) { + ftdmchan = ftdm_iterator_current(citer); r2chan = R2CALL(ftdmchan)->r2chan; openr2_chan_set_blocked(r2chan); } From 8c057921f3e5c889cd148e461ffb67932dd78fbb Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 10 Dec 2010 08:32:36 -0500 Subject: [PATCH 35/35] ftmod_wanpipe - fix idle frame stats --- libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index 1c0baa731f..e1b6658945 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -811,13 +811,14 @@ static void wanpipe_write_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_tx_hdr_t *t ftdm_clear_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL); } - if (ftdmchan->iostats.tx.idle_packets < tx_stats->wp_api_tx_hdr_number_of_frames_in_queue) { - ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets; + if (ftdmchan->iostats.tx.idle_packets < tx_stats->wp_api_tx_hdr_tx_idle_packets) { /* HDLC channels do not always transmit, so its ok for drivers to fill with idle * also do not report idle warning when we just started transmitting */ if (ftdmchan->iostats.tx.packets && FTDM_IS_VOICE_CHANNEL(ftdmchan)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx idle: %d\n", ftdmchan->iostats.tx.idle_packets); + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx idle changed from %d to %d\n", + ftdmchan->iostats.tx.idle_packets, tx_stats->wp_api_tx_hdr_tx_idle_packets); } + ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets; } if (!ftdmchan->iostats.tx.packets) { @@ -941,7 +942,6 @@ static FIO_WRITE_FUNCTION(wanpipe_write) { int bsent = 0; int err = 0; - ftdm_time_t ms = 0; wp_tdm_api_tx_hdr_t hdrframe; /* Do we even need the headerframe here? on windows, we don't even pass it to the driver */