From 7e2ef3a55cdd77148941772f8170b72dc3b6c651 Mon Sep 17 00:00:00 2001 From: Nenad Corbic Date: Sun, 18 Dec 2011 23:02:59 -0500 Subject: [PATCH 01/34] freetdm: The remote hangup logic that waits for 3sec for FS to hanup up before hanging up the freetdm channel by force seems to have a memory leak. I have increased the timeout to 30sec and made the print statement WARNING level. --- 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 731b9f88ef..8b179ccf05 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -52,7 +52,7 @@ struct tm *localtime_r(const time_t *clock, struct tm *result); #endif -#define FORCE_HANGUP_TIMER 3000 +#define FORCE_HANGUP_TIMER 30000 #define SPAN_PENDING_CHANS_QUEUE_SIZE 1000 #define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000 #define FTDM_READ_TRACE_INDEX 0 @@ -5455,7 +5455,7 @@ static void execute_safety_hangup(void *data) ftdm_channel_lock(fchan); fchan->hangup_timer = 0; if (fchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan(fchan, FTDM_LOG_NOTICE, "Forcing hangup since the user did not confirmed our hangup after %dms\n", FORCE_HANGUP_TIMER); + ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Forcing hangup since the user did not confirmed our hangup after %dms\n", FORCE_HANGUP_TIMER); _ftdm_channel_call_hangup_nl(__FILE__, __FUNCTION__, __LINE__, fchan, NULL); } else { ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Not performing safety hangup, channel state is %s\n", ftdm_channel_state2str(fchan->state)); From b6ca6c5b1da2d577d6ae95cbf0ce445ed59f2043 Mon Sep 17 00:00:00 2001 From: Nenad Corbic Date: Mon, 19 Dec 2011 02:27:38 -0500 Subject: [PATCH 02/34] freetdm: Added sng_cc_resource_check() On SIG Down we must not fail a call instead try hunting for another. The only time we can fail the call and not bother hunting is if sng_cc_resource_check fails. Took out configuration retry as the config code is now fixed in sng_ss7 library. Transaction id fix. Unit Tested: NSG UP -- start full load kill NSG NSG UP again on full load make sure it comes up fine. --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c | 9 +++---- .../ftmod_sangoma_ss7_main.c | 25 +++++++++++-------- .../ftmod_sangoma_ss7_main.h | 6 +++++ 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c index 25510e8c7a..327ca40f05 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c @@ -77,9 +77,9 @@ int ft_to_sngss7_cfg_all(void) int ret = 0; /* check if we have done gen_config already */ - if (!(g_ftdm_sngss7_data.gen_config)) { + if (g_ftdm_sngss7_data.gen_config == SNG_GEN_CFG_STATUS_INIT) { /* update the global gen_config so we don't do it again */ - g_ftdm_sngss7_data.gen_config = 1; + g_ftdm_sngss7_data.gen_config = SNG_GEN_CFG_STATUS_PENDING; /* start of by checking if the license and sig file are valid */ if (sng_validate_license(g_ftdm_sngss7_data.cfg.license, @@ -209,13 +209,12 @@ int ft_to_sngss7_cfg_all(void) } } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) */ - g_ftdm_sngss7_data.gen_config = 2; + g_ftdm_sngss7_data.gen_config = SNG_GEN_CFG_STATUS_DONE; } /* if (!(g_ftdm_sngss7_data.gen_config)) */ - /* FIXME: Please change number 2 to an ENUM that is more explanatory */ - if (g_ftdm_sngss7_data.gen_config != 2) { + if (g_ftdm_sngss7_data.gen_config != SNG_GEN_CFG_STATUS_DONE) { SS7_CRITICAL("General configuration FAILED!\n"); return 1; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index f6c61162b1..c963ea7cb7 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -1653,8 +1653,10 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call) /* check if the channel sig state is UP */ if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { - SS7_ERROR_CHAN(ftdmchan, "Requested channel sig state is down, cancelling call!%s\n", " "); - goto outgoing_fail; + SS7_ERROR_CHAN(ftdmchan, "Requested channel sig state is down, skipping channell!%s\n", " "); + /* Sig state will be down due to a block. + Right action is to hunt for another call */ + goto outgoing_break; } /* check if there is a remote block */ @@ -1679,6 +1681,14 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call) goto outgoing_break; } + + /* This is a gracefull stack resource check. + Removing this function will cause unpredictable + ungracefule errors. */ + if (sng_cc_resource_check()) { + goto outgoing_fail; + } + /* check the state of the channel */ switch (ftdmchan->state){ /**************************************************************************/ @@ -1873,7 +1883,6 @@ static ftdm_status_t ftdm_sangoma_ss7_stop(ftdm_span_t * span) static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config) { sngss7_span_data_t *ss7_span_info; - int sngss7_retry_cnt=5; ftdm_log (FTDM_LOG_INFO, "Configuring ftmod_sangoma_ss7 span = %s(%d)...\n", span->name, @@ -1923,20 +1932,14 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config) /* parse the configuration and apply to the global config structure */ if (ftmod_ss7_parse_xml(ftdm_parameters, span)) { ftdm_log (FTDM_LOG_CRIT, "Failed to parse configuration!\n"); - ftdm_sleep (1000); + ftdm_sleep (100); return FTDM_FAIL; } /* configure libsngss7 */ -try_cfg_again: if (ft_to_sngss7_cfg_all()) { - if (sngss7_retry_cnt--) { - ftdm_sleep (500); - ftdm_log (FTDM_LOG_DEBUG, "Failed to configure LibSngSS7 - retrying!\n"); - goto try_cfg_again; - } ftdm_log (FTDM_LOG_CRIT, "Failed to configure LibSngSS7!\n"); - ftdm_sleep (1000); + ftdm_sleep (100); return FTDM_FAIL; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index bb02d7e3ed..78210d50fb 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -116,6 +116,12 @@ typedef enum { SNG_CALLING = 2 } sng_addr_type_t; +typedef enum { + SNG_GEN_CFG_STATUS_INIT = 0, + SNG_GEN_CFG_STATUS_PENDING = 1, + SNG_GEN_CFG_STATUS_DONE = 2 +} nsg_gen_cfg_type_t; + typedef struct sng_mtp2_error_type { int init; char sng_type[MAX_NAME_LEN]; From 8eeb37a81b57226053caf9c2d151de721e4f6308 Mon Sep 17 00:00:00 2001 From: William Adam Date: Wed, 21 Dec 2011 14:56:03 -0500 Subject: [PATCH 03/34] Fixed bug#2215 - SPIROU transparent IAM max size 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 f1c6625b85..f7d0171f93 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 @@ -1923,7 +1923,7 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span) SS7_DEBUG("Found transparent_iam %d\n", sng_ccSpan.transparent_iam); #endif } else if (!strcasecmp(parm->var, "transparent_iam_max_size")) { - sng_ccSpan.transparent_iam_max_size = ftdm_true(parm->val); + sng_ccSpan.transparent_iam_max_size = atoi(parm->val); SS7_DEBUG("Found transparent_iam_max_size %d\n", sng_ccSpan.transparent_iam_max_size); } else if (!strcasecmp(parm->var, "cpg_on_progress_media")) { sng_ccSpan.cpg_on_progress_media = ftdm_true(parm->val); From 5ac80d39399a366ee72aa80cbd2e12aa100016c1 Mon Sep 17 00:00:00 2001 From: James Zhang Date: Thu, 19 Jan 2012 16:31:52 -0500 Subject: [PATCH 04/34] FreeTDM: fixing redirect information outgoing call bug --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c | 11 +++++++++++ .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c | 4 ++++ 2 files changed, 15 insertions(+) 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 0497955059..0bed14c2e6 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 @@ -252,8 +252,19 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ sprintf(var, "%d", sngss7_info->circuit->cic); sngss7_add_var(sngss7_info, "ss7_cic", var); + + if (siConEvnt->orgPteCde.eh.pres) { + sprintf(var, "%d",(uint32_t)siConEvnt->orgPteCde.sigPointCode.val); + sngss7_add_var(sngss7_info, "ss7_opc", var); + SS7_DEBUG_CHAN(ftdmchan, " OPC = d%\n", (uint32_t)siConEvnt->orgPteCde.sigPointCode.val); + } else { + SS7_DEBUG_CHAN(ftdmchan, "No OPC information in IAM%s\n", " "); + } + + /* original code, should be removed after review. sprintf(var, "%d", g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].spc ); sngss7_add_var(sngss7_info, "ss7_opc", var); + */ if (siConEvnt->callRef.callId.pres) { /* %x expect an unsigned int so as callId is a U32, casting to uint32_t diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c index 3230292675..59777b048b 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c @@ -585,6 +585,7 @@ ftdm_status_t copy_redirgInfo_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *r val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdinfo_indicator"); if (!ftdm_strlen_zero(val)) { redirInfo->redirInd.val = atoi(val); + redirInfo->redirInd.pres = 1; bProceed = 1; } else { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Information on Redirection Indicator\n"); @@ -593,6 +594,7 @@ ftdm_status_t copy_redirgInfo_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *r val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdinfo_orig"); if (!ftdm_strlen_zero(val)) { redirInfo->origRedirReas.val = atoi(val); + redirInfo->origRedirReas.pres = 1; bProceed = 1; } else { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Information on Original Reasons\n"); @@ -601,6 +603,7 @@ ftdm_status_t copy_redirgInfo_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *r val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdinfo_count"); if (!ftdm_strlen_zero(val)) { redirInfo->redirCnt.val = atoi(val); + redirInfo->redirCnt.pres= 1; bProceed = 1; } else { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Information on Redirection Count\n"); @@ -609,6 +612,7 @@ ftdm_status_t copy_redirgInfo_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *r val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdinfo_reason"); if (!ftdm_strlen_zero(val)) { redirInfo->redirReas.val = atoi(val); + redirInfo->redirReas.pres = 1; bProceed = 1; } else { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Information on Redirection Reasons\n"); From 63ecf4e9091c1a9f2fd18d5ce324375275162739 Mon Sep 17 00:00:00 2001 From: James Zhang Date: Thu, 19 Jan 2012 16:55:15 -0500 Subject: [PATCH 05/34] FreeTDM: remove the portion of opc fix --- .../ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c | 10 ---------- 1 file changed, 10 deletions(-) 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 0bed14c2e6..a4d16b7dd2 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 @@ -253,18 +253,8 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ sngss7_add_var(sngss7_info, "ss7_cic", var); - if (siConEvnt->orgPteCde.eh.pres) { - sprintf(var, "%d",(uint32_t)siConEvnt->orgPteCde.sigPointCode.val); - sngss7_add_var(sngss7_info, "ss7_opc", var); - SS7_DEBUG_CHAN(ftdmchan, " OPC = d%\n", (uint32_t)siConEvnt->orgPteCde.sigPointCode.val); - } else { - SS7_DEBUG_CHAN(ftdmchan, "No OPC information in IAM%s\n", " "); - } - - /* original code, should be removed after review. sprintf(var, "%d", g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].spc ); sngss7_add_var(sngss7_info, "ss7_opc", var); - */ if (siConEvnt->callRef.callId.pres) { /* %x expect an unsigned int so as callId is a U32, casting to uint32_t From 8d1d930085d9a594bff424d01ca5f9f8c33fbd72 Mon Sep 17 00:00:00 2001 From: James Zhang Date: Thu, 19 Jan 2012 18:04:03 -0500 Subject: [PATCH 06/34] FreeTDM: fixing OPC bug using local SPC - take the DPC of the link and set it as OPC in x-header - this is what the user want's to have --- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a4d16b7dd2..9c3bd65426 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 @@ -253,7 +253,7 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ sngss7_add_var(sngss7_info, "ss7_cic", var); - sprintf(var, "%d", g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].spc ); + sprintf(var, "%d", g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].dpc ); sngss7_add_var(sngss7_info, "ss7_opc", var); if (siConEvnt->callRef.callId.pres) { From 34c8e58ae1a500d0fd1855b88c4ce86f317fc03f Mon Sep 17 00:00:00 2001 From: James Zhang Date: Wed, 25 Jan 2012 16:00:20 -0500 Subject: [PATCH 07/34] FreeTDM: location value in REL message set to 0x04 - only available to SPIROU --- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 4 ++++ 1 file changed, 4 insertions(+) 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 fbfab15d1e..4b5f82f52d 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 @@ -259,7 +259,11 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan) rel.causeDgn.eh.pres = PRSNT_NODEF; rel.causeDgn.location.pres = PRSNT_NODEF; +#ifdef SANGOMA_SPIROU + rel.causeDgn.location.val = 0x04; +#else rel.causeDgn.location.val = 0x01; +#endif rel.causeDgn.cdeStand.pres = PRSNT_NODEF; rel.causeDgn.cdeStand.val = 0x00; rel.causeDgn.recommend.pres = NOTPRSNT; From 28e27248e5d86ef553973dc39827bd099d2db853 Mon Sep 17 00:00:00 2001 From: James Zhang Date: Wed, 25 Jan 2012 18:00:41 -0500 Subject: [PATCH 08/34] FreeTDM: remove the previous commit - hardcode does not work in this matter --- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 4 ---- 1 file changed, 4 deletions(-) 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 4b5f82f52d..fbfab15d1e 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 @@ -259,11 +259,7 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan) rel.causeDgn.eh.pres = PRSNT_NODEF; rel.causeDgn.location.pres = PRSNT_NODEF; -#ifdef SANGOMA_SPIROU - rel.causeDgn.location.val = 0x04; -#else rel.causeDgn.location.val = 0x01; -#endif rel.causeDgn.cdeStand.pres = PRSNT_NODEF; rel.causeDgn.cdeStand.val = 0x00; rel.causeDgn.recommend.pres = NOTPRSNT; From 90f538c0a0e08197f9add62131f1a5ee9a3522c0 Mon Sep 17 00:00:00 2001 From: James Zhang Date: Thu, 26 Jan 2012 11:19:41 -0500 Subject: [PATCH 09/34] FreeTDM: Fixing issues of SPIROU - redirect number in Transparent IAM - redirect information in Transparent IAM - called party number in Transparent IAM - adding incoming uuid to x-header to check loop calls --- libs/freetdm/mod_freetdm/mod_freetdm.c | 23 ++++++++++++++++++- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 9 ++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 003be91b17..e694a0f8fa 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -115,6 +115,8 @@ struct private_object { ftdm_channel_t *ftdmchan; uint32_t write_error; uint32_t read_error; + char network_peer_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1]; + }; /* private data attached to FTDM channels (only FXS for now) */ @@ -1246,6 +1248,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi int argc = 0; const char *var; const char *dest_num = NULL, *callerid_num = NULL; + const char *network_peer_uuid = NULL; ftdm_hunting_scheme_t hunting; ftdm_usrmsg_t usrmsg; @@ -1336,6 +1339,9 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi if (session && globals.sip_headers) { switch_channel_t *channel = switch_core_session_get_channel(session); const char *sipvar; + + network_peer_uuid = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-TransUUID"); + sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CallerName"); if (sipvar) { ftdm_set_string(caller_data.cid_name, sipvar); @@ -1592,6 +1598,20 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi goto fail; } + if (network_peer_uuid) { + switch_core_session_t *network_peer = switch_core_session_locate(network_peer_uuid); + if (network_peer) { + const char *my_uuid = switch_core_session_get_uuid(*new_session); + private_t *peer_private = switch_core_session_get_private(network_peer); + switch_set_string(tech_pvt->network_peer_uuid, network_peer_uuid); + switch_set_string(peer_private->network_peer_uuid, my_uuid); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Session %s is network-bridged with %s\n", my_uuid, network_peer_uuid); + + switch_core_session_rwunlock(network_peer); + } + } + caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); caller_profile->destination_number = switch_core_strdup(caller_profile->pool, switch_str_nil(dest_num)); caller_profile->caller_id_number = switch_core_strdup(caller_profile->pool, switch_str_nil(callerid_num)); @@ -1617,7 +1637,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi } else { cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; } - goto fail; + goto fail; } return SWITCH_CAUSE_SUCCESS; @@ -1746,6 +1766,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session 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-TransUUID", "%s",switch_core_session_get_uuid(session)); switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-SpanNumber", "%d", spanid); switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ChanNumber", "%d", chanid); 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 fbfab15d1e..0c8cf3832a 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 @@ -58,6 +58,15 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) if (sngss7_info->circuit->transparent_iam && sngss7_retrieve_iam(ftdmchan, &iam) == FTDM_SUCCESS) { SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Transparent)\n", sngss7_info->circuit->cic); + + /* Called Number information */ + copy_cdPtyNum_to_sngss7(ftdmchan, &iam.cdPtyNum); + + /* Redirecting Number */ + copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum); + + /* Redirecting Information */ + copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo); } else { /* Nature of Connection Indicators */ copy_natConInd_to_sngss7(ftdmchan, &iam.natConInd); From 1b964054de8aa60299c9ffc29647ccbcd457d44f Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 26 Jan 2012 15:21:51 -0500 Subject: [PATCH 10/34] freetdm: Add new queue for ss7 clone messages, all incoming messages are queued now --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c | 18 ++++++++++++++++++ .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h | 1 + .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 3 +++ 3 files changed, 22 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index c963ea7cb7..ebee2c382d 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -511,6 +511,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev { sngss7_chan_data_t *sngss7_info = NULL; ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *event_clone = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(sngss7_event->circuit, &sngss7_info, &ftdmchan)) { @@ -521,6 +522,22 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev /* now that we have the right channel ... put a lock on it so no-one else can use it */ ftdm_channel_lock(ftdmchan); + if (sngss7_info->event_queue) { + if (sngss7_event->event_id == SNGSS7_CON_IND_EVENT) { + /* this is the first event in a call, flush the event queue */ + while ((event_clone = ftdm_queue_dequeue(sngss7_info->event_queue))) { + SS7_WARN("Discarding clone event from past call for circuit = %d!\n", sngss7_event->circuit); + ftdm_safe_free(event_clone); + } + } + /* clone the event and save it for later usage */ + event_clone = ftdm_calloc(1, sizeof(*sngss7_event)); + if (event_clone) { + memcpy(clone, sngss7_event, sizeof(*sngss7_event)); + ftdm_queue_enqueue(sngss7_info->event_queue, clone); + } + } + /* while there's a state change present on this channel process it */ ftdm_channel_advance_states(ftdmchan); @@ -576,6 +593,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev break; /**************************************************************************/ case (SNGSS7_SSP_STA_CFM_EVENT): + SS7_ERROR("dazed and confused ... hu?!\n"); break; /**************************************************************************/ default: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index 78210d50fb..2a1ca1749e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -485,6 +485,7 @@ typedef struct sngss7_chan_data { sngss7_group_data_t rx_gra; sngss7_group_data_t tx_grs; sngss7_group_data_t ucic; + ftdm_queue_t *event_queue; } sngss7_chan_data_t; #define SNGSS7_RX_GRS_PENDING (1 << 0) 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 f7d0171f93..d7732cce6c 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 @@ -2925,6 +2925,9 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan) /* prepare the global info sturcture */ ss7_info = ftdm_calloc(1, sizeof(sngss7_chan_data_t)); ss7_info->ftdmchan = NULL; + if (ftdm_queue_create(&ss7_info->event_queue, SNGSS7_EVENT_QUEUE_SIZE) != FTDM_SUCCESS) { + SS7_CRITICAL("Failed to create ss7 cic event queue\n"); + } ss7_info->circuit = &g_ftdm_sngss7_data.cfg.isupCkt[x]; g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info; From 98d566b29c5ebc43834c27c8859d042b69ef94ba Mon Sep 17 00:00:00 2001 From: James Zhang Date: Thu, 26 Jan 2012 16:39:43 -0500 Subject: [PATCH 11/34] FreeTDM: adding variable ss7_rel_loc for REL location indicator (to support SPIROU) --- libs/freetdm/mod_freetdm/mod_freetdm.c | 11 +++++++++++ .../ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 11 ++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index e694a0f8fa..1ecf1fe7ef 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -506,6 +506,9 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session) int chan_id = 0; const char *name = NULL; + ftdm_usrmsg_t usrmsg; + memset(&usrmsg, 0, sizeof(ftdm_usrmsg_t)); + channel = switch_core_session_get_channel(session); assert(channel != NULL); @@ -574,11 +577,19 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session) case FTDM_CHAN_TYPE_CAS: case FTDM_CHAN_TYPE_B: { + const char *sipvar; ftdm_call_cause_t hcause = switch_channel_get_cause_q850(channel); if (hcause < 1 || hcause > 127) { hcause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER; } + sipvar = switch_channel_get_variable(channel, "ss7_rel_loc"); + if (sipvar) { + ftdm_usrmsg_add_var(&usrmsg, "ss7_rel_loc", sipvar); + } + /* ftdm_channel_call_hangup_with_cause(tech_pvt->ftdmchan, hcause); + */ + ftdm_channel_call_hangup_with_cause_ex(tech_pvt->ftdmchan, hcause, &usrmsg); } break; default: 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 0c8cf3832a..f73fd871b4 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 @@ -259,6 +259,7 @@ void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan) /******************************************************************************/ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan) { + const char *loc_ind = NULL; SS7_FUNC_TRACE_ENTER (__FUNCTION__); sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; @@ -268,7 +269,15 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan) rel.causeDgn.eh.pres = PRSNT_NODEF; rel.causeDgn.location.pres = PRSNT_NODEF; - rel.causeDgn.location.val = 0x01; + + loc_ind = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rel_loc"); + if (!ftdm_strlen_zero(loc_ind)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied location indicator in REL, value \"%s\"\n", loc_ind); + rel.causeDgn.location.val = atoi(loc_ind); + } else { + rel.causeDgn.location.val = 0x01; + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied location indicator in REL, using 0x01\"%s\"\n", ""); + } rel.causeDgn.cdeStand.pres = PRSNT_NODEF; rel.causeDgn.cdeStand.val = 0x00; rel.causeDgn.recommend.pres = NOTPRSNT; From a1a1af579b9b6cbf7349c5e39b8d51a260eb443f Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 26 Jan 2012 16:50:38 -0500 Subject: [PATCH 12/34] freetdm: Implement SS7 transparent IAM functionality using the event clones queue --- libs/freetdm/mod_freetdm/mod_freetdm.c | 17 ++++++ .../ftmod_sangoma_ss7_main.c | 15 ++++- .../ftmod_sangoma_ss7_main.h | 1 + .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 55 ++++++++++++++++++- 4 files changed, 86 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 003be91b17..204e5a894f 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1603,6 +1603,23 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi hunt_data.tech_pvt = tech_pvt; caller_data.priv = &hunt_data; + if (session + && (var = channel_get_variable(session, var_event, FREETDM_VAR_PREFIX "native_sigbridge")) + && switch_true(var) + && switch_core_session_compare(*new_session, session)) { + char sigbridge_peer[255]; + private_t *peer_pvt = switch_core_session_get_private(session); + switch_channel_t *peer_chan = switch_core_session_get_channel(session); + switch_channel_t *our_chan = switch_core_session_get_channel(*new_session); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, + "Bridging native signaling of channel %s to channel %s\n", + switch_channel_get_name(peer_chan), switch_channel_get_name(our_chan)); + snprintf(sigbridge_peer, sizeof(sigbridge_peer), "%u:%u", + ftdm_channel_get_span_id(peer_pvt->ftdmchan), ftdm_channel_get_id(peer_pvt->ftdmchan)); + ftdm_usrmsg_add_var(&usrmsg, "sigbridge_peer", sigbridge_peer); + } + + if ((status = ftdm_call_place_ex(&caller_data, &hunting, &usrmsg)) != FTDM_SUCCESS) { if (tech_pvt->read_codec.implementation) { switch_core_codec_destroy(&tech_pvt->read_codec); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index ebee2c382d..bcb518ff9d 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -526,7 +526,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev if (sngss7_event->event_id == SNGSS7_CON_IND_EVENT) { /* this is the first event in a call, flush the event queue */ while ((event_clone = ftdm_queue_dequeue(sngss7_info->event_queue))) { - SS7_WARN("Discarding clone event from past call for circuit = %d!\n", sngss7_event->circuit); + SS7_WARN("[CIC:%d]Discarding clone event from past call!\n", sngss7_info->circuit->cic); ftdm_safe_free(event_clone); } } @@ -1076,6 +1076,19 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OPEN)) { ftdm_channel_t *close_chan = ftdmchan; + + /* detach native bridging if needed (only the outbound leg is responsible for that) + Inbound leg was responsible of flushing its queue of events, but peer attach/detach + is left as an outbound leg responsibility + */ + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { + sngss7_chan_data_t *peer_info = sngss7_info->peer_data; + sngss7_info->peer_data = NULL; + if (peer_info) { + peer_info->peer_data = NULL; + } + } + /* close the channel */ SS7_DEBUG_CHAN(ftdmchan,"FTDM Channel Close %s\n", ""); ftdm_channel_close (&close_chan); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index 2a1ca1749e..2fc6f740c7 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -486,6 +486,7 @@ typedef struct sngss7_chan_data { sngss7_group_data_t tx_grs; sngss7_group_data_t ucic; ftdm_queue_t *event_queue; + struct sngss7_chan_data *peer_data; } sngss7_chan_data_t; #define SNGSS7_RX_GRS_PENDING (1 << 0) 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 fbfab15d1e..eda03715f3 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 @@ -44,6 +44,7 @@ /* FUNCTIONS ******************************************************************/ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) { + const char *var = NULL; SiConEvnt iam; sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;; @@ -55,7 +56,59 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) memset (&iam, 0x0, sizeof (iam)); - if (sngss7_info->circuit->transparent_iam && + var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "sigbridge_peer"); + if (!ftdm_strlen_zero(var)) { + ftdm_status_t status = FTDM_SUCCESS; + int rc = 0; + ftdm_span_t *peer_span = NULL; + ftdm_channel_t *peer_chan = NULL; + sngss7_chan_data_t *peer_info = NULL; + unsigned peer_span_id = 0; + unsigned peer_chan_id = 0; + rc = sscanf(var, "%u:%u", &peer_span_id, &peer_chan_id); + if (rc != 2) { + SS7_ERROR_CHAN(ftdmchan, "Failed to parse sigbridge_peer string '%s'\n", var); + } else { + status = ftdm_span_find(peer_span_id, &peer_span); + if (status != FTDM_SUCCESS || !peer_span) { + SS7_ERROR_CHAN(ftdmchan, "Failed to find peer span for channel id '%u:%u'\n", peer_span_id, peer_chan_id); + } else if (peer_span->signal_type != FTDM_SIGTYPE_SS7) { + SS7_ERROR_CHAN(ftdmchan, "Peer channel %d:%d has different signaling type %d'\n", + peer_span_id, peer_chan_id, peer_span->signal_type); + } else { + if (peer_chan_id > (FTDM_MAX_CHANNELS_SPAN+1) || !(peer_chan = peer_span->channels[peer_chan_id])) { + SS7_ERROR_CHAN(ftdmchan, "Invalid peer channel id '%u:%u'\n", peer_span_id, peer_chan_id); + } else { + sngss7_event_data_t *event_clone = NULL; + peer_info = peer_chan->call_data; + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Starting native bridge with peer CIC %d\n", + sngss7_info->circuit->cic, peer_info->circuit->cic); + /* make each one of us aware of the native bridge */ + peer_info->peer_data = sngss7_info; + sngss7_info->peer_data = peer_info; + /* flush our own queue */ + while ((event_clone = ftdm_queue_dequeue(sngss7_info->event_queue))) { + SS7_WARN("[CIC:%d]Discarding clone event from past call!\n", sngss7_info->circuit->cic); + ftdm_safe_free(event_clone); + } + } + } + } + } + + if (sngss7_info->peer_data) { + sngss7_event_data_t *event_clone = ftdm_queue_dequeue(sngss7_info->peer_data->event_queue); + /* Retrieve IAM from our peer */ + if (!event_clone) { + SS7_ERROR_CHAN(ftdmchan, "No event clone in peer queue!%s\n", ""); + } else if (event_clone->event_id != SNGSS7_CON_IND_EVENT) { + /* first message in the queue should ALWAYS be an IAM */ + SS7_ERROR_CHAN(ftdmchan, "Invalid initial peer message type '%d'\n", event_clone->event_id); + } else { + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged)\n", sngss7_info->circuit->cic); + memcpy(&iam, &event_clone->event.siConEvnt, sizeof(iam)); + } + } else if (sngss7_info->circuit->transparent_iam && sngss7_retrieve_iam(ftdmchan, &iam) == FTDM_SUCCESS) { SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Transparent)\n", sngss7_info->circuit->cic); } else { From b4e8d5b6086ddf861760db21686ad4344f470356 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 26 Jan 2012 17:22:45 -0500 Subject: [PATCH 13/34] freetdm: Fix incorrect variable name leading to segfault --- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index bcb518ff9d..96b662bdbb 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -533,8 +533,8 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev /* clone the event and save it for later usage */ event_clone = ftdm_calloc(1, sizeof(*sngss7_event)); if (event_clone) { - memcpy(clone, sngss7_event, sizeof(*sngss7_event)); - ftdm_queue_enqueue(sngss7_info->event_queue, clone); + memcpy(event_clone, sngss7_event, sizeof(*sngss7_event)); + ftdm_queue_enqueue(sngss7_info->event_queue, event_clone); } } From 95baef882153eef83885022024ef5c07251b3a79 Mon Sep 17 00:00:00 2001 From: James Zhang Date: Thu, 26 Jan 2012 17:37:35 -0500 Subject: [PATCH 14/34] FreeTDM: patch SPIROU requests - adding freetdm_iam_loc_pres variable to disable LOC in transparent IAM - confirming freetdm_bearer_capability is working properly --- libs/freetdm/mod_freetdm/mod_freetdm.c | 4 ++++ .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 3 +++ .../ftmod_sangoma_ss7_support.c | 22 ++++++++++++++----- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 1ecf1fe7ef..c2712621da 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1523,9 +1523,13 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi caller_data.pres = FTDM_PRES_RESTRICTED; } + if ((var = channel_get_variable(session, var_event, "freetdm_iam_loc_pres"))) { + ftdm_usrmsg_add_var(&usrmsg, "iam_loc_pres", var); + } if ((var = channel_get_variable(session, var_event, "freetdm_bearer_capability"))) { caller_data.bearer_capability = (uint8_t)atoi(var); } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "freetdm_bearer_capability is set to %s \n", var ); if ((var = channel_get_variable(session, var_event, "freetdm_bearer_layer1"))) { caller_data.bearer_layer1 = (uint8_t)atoi(var); 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 f73fd871b4..a5311e9afc 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 @@ -67,6 +67,9 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) /* Redirecting Information */ copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo); + + /* Location Number information */ + copy_locPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum1); } else { /* Nature of Connection Indicators */ copy_natConInd_to_sngss7(ftdmchan, &iam.natConInd); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c index 59777b048b..957649fa21 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c @@ -243,15 +243,25 @@ ftdm_status_t copy_locPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *loc { const char *val = NULL; const char *loc_nadi = NULL; + int pres_val = PRSNT_NODEF; sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - locPtyNum->eh.pres = PRSNT_NODEF; - locPtyNum->natAddrInd.pres = PRSNT_NODEF; + + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "iam_loc_pres"); + if (!ftdm_strlen_zero(val)) { + if (!strcasecmp(val, "false")) { + pres_val = NOTPRSNT; + } + } + + + locPtyNum->eh.pres = pres_val; + locPtyNum->natAddrInd.pres = pres_val; locPtyNum->natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].loc_nadi; - locPtyNum->scrnInd.pres = PRSNT_NODEF; + locPtyNum->scrnInd.pres = pres_val; val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_loc_screen_ind"); if (!ftdm_strlen_zero(val)) { locPtyNum->scrnInd.val = atoi(val); @@ -260,7 +270,7 @@ ftdm_status_t copy_locPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *loc } ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Location Reference Code Screening Ind %d\n", locPtyNum->scrnInd.val); - locPtyNum->presRest.pres = PRSNT_NODEF; + locPtyNum->presRest.pres = pres_val; val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_pres_ind"); if (!ftdm_strlen_zero(val)) { locPtyNum->presRest.val = atoi(val); @@ -269,10 +279,10 @@ ftdm_status_t copy_locPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *loc } ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Number Presentation Ind %d\n", locPtyNum->presRest.val); - locPtyNum->numPlan.pres = PRSNT_NODEF; + locPtyNum->numPlan.pres = pres_val; locPtyNum->numPlan.val = 0x01; - locPtyNum->niInd.pres = PRSNT_NODEF; + locPtyNum->niInd.pres = pres_val; locPtyNum->niInd.val = 0x00; /* check if the user would like a custom NADI value for the Location Reference */ From 3235fa079a26142e8c499441b08660254dfee55c Mon Sep 17 00:00:00 2001 From: James Zhang Date: Thu, 26 Jan 2012 18:00:34 -0500 Subject: [PATCH 15/34] FreeTDM: fix for SPIROU - adding freetdm_iam_fwd_ind_isdn_access_ind (value must be 0 or 1) to modify forward call indicator's ISDN access indicator value in transparent IAM --- libs/freetdm/mod_freetdm/mod_freetdm.c | 5 ++++- .../ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 3 +++ .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c | 10 +++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index c2712621da..cdcb8ca1e0 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1523,13 +1523,16 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi caller_data.pres = FTDM_PRES_RESTRICTED; } + if ((var = channel_get_variable(session, var_event, "freetdm_iam_fwd_ind_isdn_access_ind"))) { + ftdm_usrmsg_add_var(&usrmsg, "iam_fwd_ind_isdn_access_ind", var); + } + if ((var = channel_get_variable(session, var_event, "freetdm_iam_loc_pres"))) { ftdm_usrmsg_add_var(&usrmsg, "iam_loc_pres", var); } if ((var = channel_get_variable(session, var_event, "freetdm_bearer_capability"))) { caller_data.bearer_capability = (uint8_t)atoi(var); } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "freetdm_bearer_capability is set to %s \n", var ); if ((var = channel_get_variable(session, var_event, "freetdm_bearer_layer1"))) { caller_data.bearer_layer1 = (uint8_t)atoi(var); 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 a5311e9afc..d25b3342f0 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 @@ -70,6 +70,9 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) /* Location Number information */ copy_locPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum1); + + /* Forward Call Indicators */ + copy_fwdCallInd_to_sngss7(ftdmchan, &iam.fwdCallInd); } else { /* Nature of Connection Indicators */ copy_natConInd_to_sngss7(ftdmchan, &iam.natConInd); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c index 957649fa21..c25597cd40 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c @@ -763,6 +763,8 @@ ftdm_status_t copy_natConInd_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *na ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd) { + const char *val = NULL; + int acc_val = ISDNACC_ISDN; sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; fwdCallInd->eh.pres = PRSNT_NODEF; @@ -779,7 +781,13 @@ ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd * fwdCallInd->isdnUsrPrtPrfInd.pres = PRSNT_NODEF; fwdCallInd->isdnUsrPrtPrfInd.val = PREF_PREFAW; fwdCallInd->isdnAccInd.pres = PRSNT_NODEF; - fwdCallInd->isdnAccInd.val = ISDNACC_ISDN; + + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "iam_fwd_ind_isdn_access_ind"); + if (!ftdm_strlen_zero(val)) { + acc_val = (int)atoi(val); + } + + fwdCallInd->isdnAccInd.val = acc_val; fwdCallInd->sccpMethInd.pres = PRSNT_NODEF; fwdCallInd->sccpMethInd.val = SCCPMTH_NOIND; From 977b546f9a420a7cc4699cabb12223744ffc93b4 Mon Sep 17 00:00:00 2001 From: James Zhang Date: Thu, 26 Jan 2012 18:52:27 -0500 Subject: [PATCH 16/34] FreeTDM: reuse sip_h_X-FreeTDM-LOC = NULL to indicate disable LOC --- libs/freetdm/mod_freetdm/mod_freetdm.c | 3 --- .../ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c | 9 ++------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index cdcb8ca1e0..9d15ad8eec 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1527,9 +1527,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi ftdm_usrmsg_add_var(&usrmsg, "iam_fwd_ind_isdn_access_ind", var); } - if ((var = channel_get_variable(session, var_event, "freetdm_iam_loc_pres"))) { - ftdm_usrmsg_add_var(&usrmsg, "iam_loc_pres", var); - } if ((var = channel_get_variable(session, var_event, "freetdm_bearer_capability"))) { caller_data.bearer_capability = (uint8_t)atoi(var); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c index c25597cd40..fde1278b15 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c @@ -248,15 +248,10 @@ ftdm_status_t copy_locPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *loc sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "iam_loc_pres"); - if (!ftdm_strlen_zero(val)) { - if (!strcasecmp(val, "false")) { - pres_val = NOTPRSNT; - } + if (!strcasecmp(caller_data->loc.digits, "NULL")) { + pres_val = NOTPRSNT; } - locPtyNum->eh.pres = pres_val; locPtyNum->natAddrInd.pres = pres_val; locPtyNum->natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].loc_nadi; From 71c3cf365aa724eed3429ffc736674bf1c77cd4a Mon Sep 17 00:00:00 2001 From: James Zhang Date: Thu, 26 Jan 2012 19:25:04 -0500 Subject: [PATCH 17/34] FreeTDM: adding sip_h_X-FreeTDM-RDNIS-Presentation in redirecting number to give the ability to change RDNIS Presentation value for Transparent IAM --- .../ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c index fde1278b15..2088f240b6 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c @@ -444,6 +444,13 @@ ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *red return FTDM_FAIL; } } else { + + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_pres_ind"); + if (!ftdm_strlen_zero(val)) { + redirgNum->presRest.val = atoi(val); + } + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Address Presentation Restricted Ind:%d\n", redirgNum->presRest.val); + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Number\n"); return FTDM_SUCCESS; } From 23a328389b6bbfa905501ca907de6e2cf91a700e Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 26 Jan 2012 22:44:19 -0500 Subject: [PATCH 18/34] freetdm: Initial attempt to bridge natively SS7 signaling between 2 channels --- libs/freetdm/src/ftdm_io.c | 71 +++- .../ftmod_sangoma_ss7_main.c | 397 +++++++++++++++++- .../ftmod_sangoma_ss7_main.h | 7 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 61 ++- libs/freetdm/src/include/private/ftdm_core.h | 6 + libs/freetdm/src/include/private/ftdm_types.h | 2 + 6 files changed, 491 insertions(+), 53 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 8b179ccf05..6ebe5fc161 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -53,8 +53,6 @@ struct tm *localtime_r(const time_t *clock, struct tm *result); #endif #define FORCE_HANGUP_TIMER 30000 -#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000 -#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000 #define FTDM_READ_TRACE_INDEX 0 #define FTDM_WRITE_TRACE_INDEX 1 #define MAX_CALLIDS 6000 @@ -2201,6 +2199,12 @@ static ftdm_status_t _ftdm_channel_call_hangup_nl(const char *file, const char * { ftdm_status_t status = FTDM_SUCCESS; + if (ftdm_test_flag(chan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { + ftdm_log_chan_ex(chan, file, func, line, FTDM_LOG_LEVEL_DEBUG, + "Ignoring hangup in channel in state %s (native bridge enabled)\n", ftdm_channel_state2str(chan->state)); + goto done; + } + if (chan->state != FTDM_CHANNEL_STATE_DOWN) { if (chan->state == FTDM_CHANNEL_STATE_HANGUP) { /* make user's life easier, and just ignore double hangup requests */ @@ -2227,6 +2231,8 @@ static ftdm_status_t _ftdm_channel_call_hangup_nl(const char *file, const char * ftdm_channel_close(&chan); } } + +done: return status; } @@ -2322,6 +2328,15 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch ftdm_channel_lock(ftdmchan); + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { + ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, + "Ignoring indication %s in channel in state %s (native bridge enabled)\n", + ftdm_channel_indication2str(indication), + ftdm_channel_state2str(ftdmchan->state)); + status = FTDM_SUCCESS; + goto done; + } + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IND_ACK_PENDING)) { ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "Cannot indicate %s in channel with indication %s still pending in state %s\n", ftdm_channel_indication2str(indication), @@ -2422,10 +2437,50 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func return FTDM_SUCCESS; } +FT_DECLARE(ftdm_status_t) ftdm_get_channel_from_string(const char *string_id, ftdm_span_t **out_span, ftdm_channel_t **out_channel) +{ + ftdm_status_t status = FTDM_SUCCESS; + int rc = 0; + ftdm_span_t *span = NULL; + ftdm_channel_t *ftdmchan = NULL; + unsigned span_id = 0; + unsigned chan_id = 0; + + *out_span = NULL; + *out_channel = NULL; + + rc = sscanf(string_id, "%u:%u", &span_id, &chan_id); + if (rc != 2) { + ftdm_log(FTDM_LOG_ERROR, "Failed to parse channel id string '%s'\n", string_id); + status = FTDM_EINVAL; + goto done; + } + + status = ftdm_span_find(span_id, &span); + if (status != FTDM_SUCCESS || !span) { + ftdm_log(FTDM_LOG_ERROR, "Failed to find span for channel id string '%s'\n", string_id); + status = FTDM_EINVAL; + goto done; + } + + if (chan_id > (FTDM_MAX_CHANNELS_SPAN+1) || !(ftdmchan = span->channels[chan_id])) { + ftdm_log(FTDM_LOG_ERROR, "Invalid channel id string '%s'\n", string_id); + status = FTDM_EINVAL; + goto done; + } + + status = FTDM_SUCCESS; + *out_span = span; + *out_channel = ftdmchan; +done: + return status; +} + /* this function MUST be called with the channel lock held with lock recursivity of 1 exactly, * and the caller must be aware we might unlock the channel for a brief period of time and then lock it again */ static ftdm_status_t _ftdm_channel_call_place_nl(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg) { + const char *var = NULL; ftdm_status_t status = FTDM_FAIL; ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel"); @@ -2461,6 +2516,17 @@ static ftdm_status_t _ftdm_channel_call_place_nl(const char *file, const char *f ftdm_set_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED); ftdm_call_set_call_id(ftdmchan, &ftdmchan->caller_data); + var = ftdm_usrmsg_get_var(usrmsg, "sigbridge_peer"); + if (var) { + ftdm_span_t *peer_span = NULL; + ftdm_channel_t *peer_chan = NULL; + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "enabling native signaling bridge!\n"); + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE); + ftdm_get_channel_from_string(var, &peer_span, &peer_chan); + if (peer_chan) { + ftdm_set_flag(peer_chan, FTDM_CHANNEL_NATIVE_SIGBRIDGE); + } + } /* if the signaling stack left the channel in state down on success, is expecting us to move to DIALING */ if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN) { @@ -2662,6 +2728,7 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_ANSWERED); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_USER_HANGUP); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA); + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE); ftdm_mutex_lock(ftdmchan->pre_buffer_mutex); ftdm_buffer_destroy(&ftdmchan->pre_buffer); ftdmchan->pre_buffer_size = 0; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 96b662bdbb..dddb0b2bef 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -55,6 +55,7 @@ ftdm_sngss7_data_t g_ftdm_sngss7_data; /* PROTOTYPES *****************************************************************/ static void *ftdm_sangoma_ss7_run (ftdm_thread_t * me, void *obj); static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event); +static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, sngss7_event_data_t *sngss7_event); static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span); static ftdm_status_t ftdm_sangoma_ss7_start (ftdm_span_t * span); @@ -338,9 +339,10 @@ static void handle_hw_alarm(ftdm_event_t *e) /* MONITIOR THREADS ***********************************************************/ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) { - ftdm_interrupt_t *ftdm_sangoma_ss7_int[2]; + ftdm_interrupt_t *ftdm_sangoma_ss7_int[3]; ftdm_span_t *ftdmspan = (ftdm_span_t *) obj; ftdm_channel_t *ftdmchan = NULL; + ftdm_channel_t *peerchan = NULL; ftdm_event_t *event = NULL; sngss7_event_data_t *sngss7_event = NULL; sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data; @@ -365,6 +367,12 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) goto ftdm_sangoma_ss7_run_exit; } + /* get an interrupt queue for this span for peer channel events */ + if (ftdm_queue_get_interrupt (sngss7_span->peer_chans, &ftdm_sangoma_ss7_int[2]) != FTDM_SUCCESS) { + SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for peer channel events queue!\n", ftdmspan->span_id); + goto ftdm_sangoma_ss7_run_exit; + } + while (ftdm_running () && !(ftdm_test_flag (ftdmspan, FTDM_SPAN_STOP_THREAD))) { int x = 0; if (b_alarm_test) { @@ -395,7 +403,7 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) } /* check the channel state queue for an event*/ - switch ((ftdm_interrupt_multiple_wait(ftdm_sangoma_ss7_int, 2, 100))) { + switch ((ftdm_interrupt_multiple_wait(ftdm_sangoma_ss7_int, ftdm_array_len(ftdm_sangoma_ss7_int), 100))) { /**********************************************************************/ case FTDM_SUCCESS: /* process all pending state changes */ @@ -412,6 +420,31 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) ftdm_mutex_unlock (ftdmchan->mutex); } + /* clean out all peer pending channel events */ + while ((peerchan = ftdm_queue_dequeue (sngss7_span->peer_chans))) { + /* note that the channels being dequeued here may not belong to this span + they may belong to just about any other span that one of our channels + happens to be bridged to */ + sngss7_chan_data_t *peer_info = peerchan->call_data; + sngss7_chan_data_t *chan_info = peer_info->peer_data; + ftdmchan = chan_info->ftdmchan; + + /* + if there is any state changes at all, those will be done in the opposite channel + to peerchan (where the original event was received), therefore we must lock ftdmchan, + but do not need to lock peerchan as we only read its event queue, which is already + locked when dequeueing */ + ftdm_channel_lock(ftdmchan); + + /* clean out all pending stack events in the peer channel */ + while ((sngss7_event = ftdm_queue_dequeue(peer_info->event_queue))) { + ftdm_sangoma_ss7_process_peer_stack_event(ftdmchan, sngss7_event); + ftdm_safe_free(sngss7_event); + } + + ftdm_channel_lock(ftdmchan); + } + /* clean out all pending stack events */ while ((sngss7_event = ftdm_queue_dequeue(sngss7_span->event_queue))) { ftdm_sangoma_ss7_process_stack_event(sngss7_event); @@ -522,24 +555,60 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev /* now that we have the right channel ... put a lock on it so no-one else can use it */ ftdm_channel_lock(ftdmchan); - if (sngss7_info->event_queue) { - if (sngss7_event->event_id == SNGSS7_CON_IND_EVENT) { - /* this is the first event in a call, flush the event queue */ - while ((event_clone = ftdm_queue_dequeue(sngss7_info->event_queue))) { - SS7_WARN("[CIC:%d]Discarding clone event from past call!\n", sngss7_info->circuit->cic); - ftdm_safe_free(event_clone); - } - } - /* clone the event and save it for later usage */ - event_clone = ftdm_calloc(1, sizeof(*sngss7_event)); - if (event_clone) { - memcpy(event_clone, sngss7_event, sizeof(*sngss7_event)); - ftdm_queue_enqueue(sngss7_info->event_queue, event_clone); + /* while there's a state change present on this channel process it */ + ftdm_channel_advance_states(ftdmchan); + + if (sngss7_event->event_id == SNGSS7_CON_IND_EVENT) { + /* this is the first event in a call, flush the event queue */ + while ((event_clone = ftdm_queue_dequeue(sngss7_info->event_queue))) { + SS7_WARN("[CIC:%d]Discarding clone event from past call!\n", sngss7_info->circuit->cic); + ftdm_safe_free(event_clone); } } - /* while there's a state change present on this channel process it */ - ftdm_channel_advance_states(ftdmchan); + /* clone the event and save it for later usage */ + event_clone = ftdm_calloc(1, sizeof(*sngss7_event)); + if (event_clone) { + memcpy(event_clone, sngss7_event, sizeof(*sngss7_event)); + ftdm_queue_enqueue(sngss7_info->event_queue, event_clone); + if (sngss7_info->peer_data) { + sngss7_span_data_t *sngss7_peer_span = (sngss7_span_data_t *)sngss7_info->peer_data->ftdmchan->span->signal_data; + /* we already have a peer attached, wake him up */ + ftdm_queue_enqueue(sngss7_peer_span->peer_chans, sngss7_info->ftdmchan); + } + } + + /* we could test for sngss7_info->peer_data too, bit this flag is set earlier, the earlier we know the better */ + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { + /* most messages are simply relayed in sig bridge mode, except for hangup which requires state changing */ + switch (sngss7_event->event_id) { + case SNGSS7_REL_IND_EVENT: + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + break; + case SNGSS7_REL_CFM_EVENT: + { + ftdm_channel_t *peer_chan = sngss7_info->peer_data->ftdmchan; + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + if (peer_chan) { + /* we need to unlock our chan or we risk deadlock */ + ftdm_channel_advance_states(ftdmchan); + ftdm_channel_unlock(ftdmchan); + + ftdm_channel_lock(peer_chan); + if (peer_chan->state != FTDM_CHANNEL_STATE_DOWN) { + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + } + ftdm_channel_unlock(peer_chan); + + ftdm_channel_lock(ftdmchan); + } + } + break; + default: + break; + } + goto done; + } /* figure out the type of event and send it to the right handler */ switch (sngss7_event->event_id) { @@ -602,6 +671,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev /**************************************************************************/ } +done: /* while there's a state change present on this channel process it */ ftdm_channel_advance_states(ftdmchan); @@ -610,8 +680,290 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev } +FTDM_ENUM_NAMES(SNG_EVENT_TYPE_NAMES, SNG_EVENT_TYPE_STRINGS) +FTDM_STR2ENUM(ftdm_str2sngss7_event, ftdm_sngss7_event2str, sng_event_type_t, SNG_EVENT_TYPE_NAMES, SNGSS7_INVALID_EVENT) +static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, sngss7_event_data_t *sngss7_event) +{ + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + + if (ftdmchan->state < FTDM_CHANNEL_STATE_UP) { + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); + ftdm_channel_advance_states(ftdmchan); + } + + SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]Relaying message %s from bridged peer\n", + sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id)); + + switch (sngss7_event->event_id) { + + case (SNGSS7_CON_IND_EVENT): + SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]Rx IAM (bridged)??\n", sngss7_info->circuit->cic); + break; + + case (SNGSS7_CON_CFM_EVENT): + /* send the ANM request to LibSngSS7 */ + sng_cc_con_response(1, + sngss7_info->suInstId, + sngss7_info->spInstId, + sngss7_info->circuit->id, + &sngss7_event->event.siConEvnt, + 5); + + SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Tx peer ANM\n", sngss7_info->circuit->cic); + break; + + case (SNGSS7_CON_STA_EVENT): + switch (sngss7_event->evntType) { + /**************************************************************************/ + case (ADDRCMPLT): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer ACM\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (MODIFY): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer MODIFY\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (MODCMPLT): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer MODIFY-COMPLETE\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (MODREJ): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer MODIFY-REJECT\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (PROGRESS): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CPG\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (FRWDTRSFR): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer FOT\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (INFORMATION): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer INF\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (INFORMATREQ): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer INR\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (SUBSADDR): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer SAM\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (EXIT): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer EXIT\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (NETRESMGT): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer NRM\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (IDENTREQ): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer IDR\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (IDENTRSP): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer IRS\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (MALCLLPRNT): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer MALICIOUS CALL\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (CHARGE): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CRG\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (TRFFCHGE): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CRG-TARIFF\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (CHARGEACK): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CRG-ACK\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (CALLOFFMSG): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CALL-OFFER\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (LOOPPRVNT): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer LOP\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (TECT_TIMEOUT): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer ECT-Timeout\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (RINGSEND): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer RINGING-SEND\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (CALLCLEAR): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CALL-LINE Clear\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (PRERELEASE): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer PRI\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (APPTRANSPORT): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer APM\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (OPERATOR): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer OPERATOR\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (METPULSE): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer METERING-PULSE\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (CLGPTCLR): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CALLING_PARTY_CLEAR\n", sngss7_info->circuit->cic); + break; + /**************************************************************************/ + case (SUBDIRNUM): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer SUB-DIR\n", sngss7_info->circuit->cic); + break; +#ifdef SANGOMA_SPIROU + case (CHARGE_ACK): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer TXA\n", sngss7_info->circuit->cic); + break; + case (CHARGE_UNIT): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer ITX\n", sngss7_info->circuit->cic); + break; +#endif + /**************************************************************************/ + default: + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer Unknown Msg %d\n", sngss7_info->circuit->cic, sngss7_event->evntType); + break; + /**************************************************************************/ + } + sng_cc_con_status (1, + sngss7_info->suInstId, + sngss7_info->spInstId, + sngss7_info->circuit->id, + &sngss7_event->event.siCnStEvnt, + sngss7_event->evntType); + + break; + /**************************************************************************/ + case (SNGSS7_REL_IND_EVENT): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer REL cause=%d\n", sngss7_info->circuit->cic, sngss7_event->event.siRelEvnt.causeDgn.causeVal.val); + + //handle_rel_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siRelEvnt); + sng_cc_rel_request (1, + sngss7_info->suInstId, + sngss7_info->spInstId, + sngss7_info->circuit->id, + &sngss7_event->event.siRelEvnt); + break; + + /**************************************************************************/ + case (SNGSS7_REL_CFM_EVENT): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer RLC\n", sngss7_info->circuit->cic); + sng_cc_rel_response (1, + sngss7_info->suInstId, + sngss7_info->spInstId, + sngss7_info->circuit->id, + &sngss7_event->event.siRelEvnt); + //handle_rel_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siRelEvnt); + break; + + /**************************************************************************/ + case (SNGSS7_DAT_IND_EVENT): + //handle_dat_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siInfoEvnt); + break; + /**************************************************************************/ + case (SNGSS7_FAC_IND_EVENT): + //handle_fac_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType, &sngss7_event->event.siFacEvnt); + break; + /**************************************************************************/ + case (SNGSS7_FAC_CFM_EVENT): + //handle_fac_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType, &sngss7_event->event.siFacEvnt); + break; + /**************************************************************************/ + case (SNGSS7_UMSG_IND_EVENT): + //handle_umsg_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit); + break; + /**************************************************************************/ + case (SNGSS7_STA_IND_EVENT): + //handle_sta_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->globalFlg, sngss7_event->evntType, &sngss7_event->event.siStaEvnt); + break; + /**************************************************************************/ + case (SNGSS7_SUSP_IND_EVENT): + //handle_susp_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siSuspEvnt); + break; + /**************************************************************************/ + case (SNGSS7_RESM_IND_EVENT): + //handle_resm_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siResmEvnt); + break; + /**************************************************************************/ + case (SNGSS7_SSP_STA_CFM_EVENT): + SS7_ERROR("dazed and confused ... hu?!\n"); + break; + /**************************************************************************/ + default: + SS7_ERROR("Unknown Event Id!\n"); + break; + /**************************************************************************/ + } + +} + +static ftdm_status_t ftdm_sangoma_ss7_native_bridge_state_change(ftdm_channel_t *ftdmchan); +static ftdm_status_t ftdm_sangoma_ss7_native_bridge_state_change(ftdm_channel_t *ftdmchan) +{ + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + + ftdm_channel_complete_state(ftdmchan); + + switch (ftdmchan->state) { + + case FTDM_CHANNEL_STATE_DOWN: + { + /* both peers come here after the channel processing the RLC moves the pair to DOWN */ + ftdm_channel_t *close_chan = ftdmchan; + + /* detach native bridging if needed (only the outbound leg is responsible for that to avoid races or messy locks) */ + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { + sngss7_chan_data_t *peer_info = sngss7_info->peer_data; + sngss7_info->peer_data = NULL; + if (peer_info) { + peer_info->peer_data = NULL; + } + } + + /* close the channel */ + ftdm_channel_close (&close_chan); + } + break; + + case FTDM_CHANNEL_STATE_UP: + { + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { + sngss7_send_signal(sngss7_info, FTDM_SIGEVENT_UP); + } + } + break; + + case FTDM_CHANNEL_STATE_TERMINATING: + { + /* when receiving REL we move to TERMINATING and notify the user that the bridge is ending */ + sngss7_send_signal(sngss7_info, FTDM_SIGEVENT_STOP); + } + break; + + default: + break; + } + + return FTDM_SUCCESS; +} + /******************************************************************************/ -ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) +ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan) { sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; sng_isup_inf_t *isup_intf = NULL; @@ -623,6 +975,9 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) sngss7_info->ckt_flags, sngss7_info->blk_flags); + if (sngss7_info->peer_data) { + return ftdm_sangoma_ss7_native_bridge_state_change(ftdmchan); + } /*check what state we are supposed to be in */ switch (ftdmchan->state) { @@ -1940,6 +2295,12 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config) return FTDM_FAIL; } + /* create an peer channel queue for this span */ + if ((ftdm_queue_create(&(ss7_span_info)->peer_chans, SPAN_PENDING_CHANS_QUEUE_SIZE)) != FTDM_SUCCESS) { + SS7_CRITICAL("Unable to create peer chans queue!\n"); + return FTDM_FAIL; + } + /*setup the span structure with the info so far */ g_ftdm_sngss7_data.sig_cb = sig_cb; span->start = ftdm_sangoma_ss7_start; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index 2fc6f740c7..7404a8e55d 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -81,8 +81,12 @@ typedef enum { SNGSS7_STA_IND_EVENT, SNGSS7_SUSP_IND_EVENT, SNGSS7_RESM_IND_EVENT, - SNGSS7_SSP_STA_CFM_EVENT + SNGSS7_SSP_STA_CFM_EVENT, + SNGSS7_INVALID_EVENT, } sng_event_type_t; +#define SNG_EVENT_TYPE_STRINGS "CON_IND", "CON_CFM", "CON_STA", "REL_IND", "REL_CFM", "DAT_IND", "FAC_IND", \ + "FAC_CFM", "UMSG_IND", "STA_IND", "SUSP_IND", "RESM_IND", "SSP_STA_CFM", "INVALID" +FTDM_STR2ENUM_P(ftdm_str2sngss7_event, ftdm_sngss7_event2str, sng_event_type_t) typedef enum { SNG_BIT_A = (1 << 0), @@ -500,6 +504,7 @@ typedef struct sngss7_span_data { sngss7_group_data_t rx_cgu; sngss7_group_data_t tx_cgu; ftdm_queue_t *event_queue; + ftdm_queue_t *peer_chans; } sngss7_span_data_t; typedef struct sngss7_event_data 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 eda03715f3..96ec5afae9 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 @@ -58,45 +58,39 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "sigbridge_peer"); if (!ftdm_strlen_zero(var)) { - ftdm_status_t status = FTDM_SUCCESS; - int rc = 0; ftdm_span_t *peer_span = NULL; ftdm_channel_t *peer_chan = NULL; sngss7_chan_data_t *peer_info = NULL; - unsigned peer_span_id = 0; - unsigned peer_chan_id = 0; - rc = sscanf(var, "%u:%u", &peer_span_id, &peer_chan_id); - if (rc != 2) { - SS7_ERROR_CHAN(ftdmchan, "Failed to parse sigbridge_peer string '%s'\n", var); + + ftdm_get_channel_from_string(var, &peer_span, &peer_chan); + if (!peer_chan) { + SS7_ERROR_CHAN(ftdmchan, "Failed to find sigbridge peer from string '%s'\n", var); } else { - status = ftdm_span_find(peer_span_id, &peer_span); - if (status != FTDM_SUCCESS || !peer_span) { - SS7_ERROR_CHAN(ftdmchan, "Failed to find peer span for channel id '%u:%u'\n", peer_span_id, peer_chan_id); - } else if (peer_span->signal_type != FTDM_SIGTYPE_SS7) { - SS7_ERROR_CHAN(ftdmchan, "Peer channel %d:%d has different signaling type %d'\n", - peer_span_id, peer_chan_id, peer_span->signal_type); + if (peer_span->signal_type != FTDM_SIGTYPE_SS7) { + SS7_ERROR_CHAN(ftdmchan, "Peer channel '%s' has different signaling type %d'\n", + var, peer_span->signal_type); } else { - if (peer_chan_id > (FTDM_MAX_CHANNELS_SPAN+1) || !(peer_chan = peer_span->channels[peer_chan_id])) { - SS7_ERROR_CHAN(ftdmchan, "Invalid peer channel id '%u:%u'\n", peer_span_id, peer_chan_id); - } else { - sngss7_event_data_t *event_clone = NULL; - peer_info = peer_chan->call_data; - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Starting native bridge with peer CIC %d\n", - sngss7_info->circuit->cic, peer_info->circuit->cic); - /* make each one of us aware of the native bridge */ - peer_info->peer_data = sngss7_info; - sngss7_info->peer_data = peer_info; - /* flush our own queue */ - while ((event_clone = ftdm_queue_dequeue(sngss7_info->event_queue))) { - SS7_WARN("[CIC:%d]Discarding clone event from past call!\n", sngss7_info->circuit->cic); - ftdm_safe_free(event_clone); - } + sngss7_event_data_t *event_clone = NULL; + peer_info = peer_chan->call_data; + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Starting native bridge with peer CIC %d\n", + sngss7_info->circuit->cic, peer_info->circuit->cic); + /* make each one of us aware of the native bridge */ + peer_info->peer_data = sngss7_info; + sngss7_info->peer_data = peer_info; + /* flush our own queue */ + while ((event_clone = ftdm_queue_dequeue(sngss7_info->event_queue))) { + SS7_WARN("[CIC:%d]Discarding clone event from past call!\n", sngss7_info->circuit->cic); + ftdm_safe_free(event_clone); } + /* go up until release comes, note that state processing is done different and much simpler when there is a peer */ + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); + ftdm_channel_advance_states(ftdmchan); } } } if (sngss7_info->peer_data) { + sngss7_span_data_t *span_data = ftdmchan->span->signal_data; sngss7_event_data_t *event_clone = ftdm_queue_dequeue(sngss7_info->peer_data->event_queue); /* Retrieve IAM from our peer */ if (!event_clone) { @@ -108,6 +102,9 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged)\n", sngss7_info->circuit->cic); memcpy(&iam, &event_clone->event.siConEvnt, sizeof(iam)); } + /* since this is the first time we dequeue an event from the peer, make sure our main thread process any other events, + this will trigger the interrupt in our span peer_chans queue which will wake up our main thread if it is sleeping */ + ftdm_queue_enqueue(span_data->peer_chans, sngss7_info->peer_data->ftdmchan); } else if (sngss7_info->circuit->transparent_iam && sngss7_retrieve_iam(ftdmchan, &iam) == FTDM_SUCCESS) { SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Transparent)\n", sngss7_info->circuit->cic); @@ -322,10 +319,10 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan) /* send the REL request to LibSngSS7 */ sng_cc_rel_request (1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &rel); + sngss7_info->suInstId, + sngss7_info->spInstId, + sngss7_info->circuit->id, + &rel); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx REL cause=%d \n", sngss7_info->circuit->cic, diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index f27be789e2..4150480297 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -130,6 +130,9 @@ extern "C" { #endif +#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000 +#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000 + #define GOTO_STATUS(label,st) status = st; goto label ; #define ftdm_copy_string(x,y,z) strncpy(x, y, z - 1) @@ -686,6 +689,9 @@ FT_DECLARE(ftdm_status_t) ftdm_sigmsg_remove_var(ftdm_sigmsg_t *sigmsg, const ch */ FT_DECLARE(ftdm_status_t) ftdm_sigmsg_set_raw_data(ftdm_sigmsg_t *sigmsg, void *data, ftdm_size_t datalen); +/*! \brief Retrieve a span and channel data structure from a string in the format 'span_id:chan_id'*/ +FT_DECLARE(ftdm_status_t) ftdm_get_channel_from_string(const char *string_id, ftdm_span_t **out_span, ftdm_channel_t **out_channel); + /*! \brief Assert condition */ diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index 6df25fe4d2..17e273c425 100755 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -265,6 +265,8 @@ typedef enum { #define FTDM_CHANNEL_BLOCKING (1ULL << 35) /*!< Media is digital */ #define FTDM_CHANNEL_DIGITAL_MEDIA (1ULL << 36) +/*!< Native signaling bridge is enabled */ +#define FTDM_CHANNEL_NATIVE_SIGBRIDGE (1ULL << 37) #include "ftdm_state.h" From f2cdb8c6c75039f431ea51964f0542a73f56fde3 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 26 Jan 2012 23:31:29 -0500 Subject: [PATCH 19/34] freetdm: Fixes for native signaling bridge (now tested, and works for basic call flows) - Fix typo when unlocking channel that resulted in deadlock - Defer clearing of the peer data until it is completely safe (next call) --- libs/freetdm/src/ftdm_state.c | 5 ++++ .../ftmod_sangoma_ss7_main.c | 24 +++++++------------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/libs/freetdm/src/ftdm_state.c b/libs/freetdm/src/ftdm_state.c index 6572ab75a4..30ef3ce478 100644 --- a/libs/freetdm/src/ftdm_state.c +++ b/libs/freetdm/src/ftdm_state.c @@ -263,6 +263,9 @@ static ftdm_status_t ftdm_core_set_state(const char *file, const char *func, int } } + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { + goto perform_state_change; + } if (ftdmchan->span->state_map) { ok = ftdm_parse_state_map(ftdmchan, state, ftdmchan->span->state_map); @@ -354,6 +357,8 @@ end: goto done; } +perform_state_change: + ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Changed state from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state)); ftdmchan->last_state = ftdmchan->state; ftdmchan->state = state; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index dddb0b2bef..968e557acc 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -441,8 +441,8 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) ftdm_sangoma_ss7_process_peer_stack_event(ftdmchan, sngss7_event); ftdm_safe_free(sngss7_event); } - - ftdm_channel_lock(ftdmchan); + + ftdm_channel_unlock(ftdmchan); } /* clean out all pending stack events */ @@ -564,6 +564,8 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev SS7_WARN("[CIC:%d]Discarding clone event from past call!\n", sngss7_info->circuit->cic); ftdm_safe_free(event_clone); } + /* clear the peer if any */ + sngss7_info->peer_data = NULL; } /* clone the event and save it for later usage */ @@ -596,7 +598,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev ftdm_channel_lock(peer_chan); if (peer_chan->state != FTDM_CHANNEL_STATE_DOWN) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + ftdm_set_state(peer_chan, FTDM_CHANNEL_STATE_DOWN); } ftdm_channel_unlock(peer_chan); @@ -923,19 +925,7 @@ static ftdm_status_t ftdm_sangoma_ss7_native_bridge_state_change(ftdm_channel_t case FTDM_CHANNEL_STATE_DOWN: { - /* both peers come here after the channel processing the RLC moves the pair to DOWN */ ftdm_channel_t *close_chan = ftdmchan; - - /* detach native bridging if needed (only the outbound leg is responsible for that to avoid races or messy locks) */ - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sngss7_chan_data_t *peer_info = sngss7_info->peer_data; - sngss7_info->peer_data = NULL; - if (peer_info) { - peer_info->peer_data = NULL; - } - } - - /* close the channel */ ftdm_channel_close (&close_chan); } break; @@ -975,6 +965,10 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan) sngss7_info->ckt_flags, sngss7_info->blk_flags); + if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) { + sngss7_info->peer_data = NULL; + } + if (sngss7_info->peer_data) { return ftdm_sangoma_ss7_native_bridge_state_change(ftdmchan); } From 1aa4f87b6acd16a3a75f84f611af189725a696eb Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 26 Jan 2012 23:51:21 -0500 Subject: [PATCH 20/34] freetdm: Tweaks to SS7 native bridge feature - Enable native bridge also when receiving the UUID via SIP header - Remove some debug CRIT messages and set a more proper log level --- libs/freetdm/mod_freetdm/mod_freetdm.c | 38 ++++++++++++------- libs/freetdm/src/ftdm_io.c | 1 - .../ftmod_sangoma_ss7_main.c | 2 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 1 - 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index a007fef081..2bbcdf97e4 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1260,6 +1260,9 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi const char *var; const char *dest_num = NULL, *callerid_num = NULL; const char *network_peer_uuid = NULL; + char sigbridge_peer[255]; + switch_channel_t *peer_chan = NULL; + switch_channel_t *our_chan = NULL; ftdm_hunting_scheme_t hunting; ftdm_usrmsg_t usrmsg; @@ -1613,17 +1616,22 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi goto fail; } + our_chan = switch_core_session_get_channel(*new_session); + if (network_peer_uuid) { switch_core_session_t *network_peer = switch_core_session_locate(network_peer_uuid); if (network_peer) { - const char *my_uuid = switch_core_session_get_uuid(*new_session); - private_t *peer_private = switch_core_session_get_private(network_peer); - switch_set_string(tech_pvt->network_peer_uuid, network_peer_uuid); - switch_set_string(peer_private->network_peer_uuid, my_uuid); + const char *my_uuid = switch_core_session_get_uuid(*new_session); + private_t *peer_private = switch_core_session_get_private(network_peer); + switch_set_string(tech_pvt->network_peer_uuid, network_peer_uuid); + switch_set_string(peer_private->network_peer_uuid, my_uuid); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Session %s is network-bridged with %s\n", my_uuid, network_peer_uuid); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Session %s is network-bridged with %s\n", + my_uuid, network_peer_uuid); - switch_core_session_rwunlock(network_peer); + snprintf(sigbridge_peer, sizeof(sigbridge_peer), "%u:%u", + ftdm_channel_get_span_id(peer_private->ftdmchan), ftdm_channel_get_id(peer_private->ftdmchan)); + switch_core_session_rwunlock(network_peer); } } @@ -1642,15 +1650,13 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi && (var = channel_get_variable(session, var_event, FREETDM_VAR_PREFIX "native_sigbridge")) && switch_true(var) && switch_core_session_compare(*new_session, session)) { - char sigbridge_peer[255]; private_t *peer_pvt = switch_core_session_get_private(session); - switch_channel_t *peer_chan = switch_core_session_get_channel(session); - switch_channel_t *our_chan = switch_core_session_get_channel(*new_session); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "Bridging native signaling of channel %s to channel %s\n", - switch_channel_get_name(peer_chan), switch_channel_get_name(our_chan)); snprintf(sigbridge_peer, sizeof(sigbridge_peer), "%u:%u", ftdm_channel_get_span_id(peer_pvt->ftdmchan), ftdm_channel_get_id(peer_pvt->ftdmchan)); + } + + if (!zstr(sigbridge_peer)) { + peer_chan = switch_core_session_get_channel(session); ftdm_usrmsg_add_var(&usrmsg, "sigbridge_peer", sigbridge_peer); } @@ -1669,7 +1675,13 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi } else { cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; } - goto fail; + goto fail; + } + + if (our_chan && peer_chan) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, + "Bridging native signaling of channel %s to channel %s\n", + switch_channel_get_name(peer_chan), switch_channel_get_name(our_chan)); } return SWITCH_CAUSE_SUCCESS; diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 6ebe5fc161..3b11611d49 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2520,7 +2520,6 @@ static ftdm_status_t _ftdm_channel_call_place_nl(const char *file, const char *f if (var) { ftdm_span_t *peer_span = NULL; ftdm_channel_t *peer_chan = NULL; - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "enabling native signaling bridge!\n"); ftdm_set_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE); ftdm_get_channel_from_string(var, &peer_span, &peer_chan); if (peer_chan) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 968e557acc..24f612545f 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -693,7 +693,7 @@ static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, ftdm_channel_advance_states(ftdmchan); } - SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]Relaying message %s from bridged peer\n", + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Relaying message %s from bridged peer\n", sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id)); switch (sngss7_event->event_id) { 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 59cb6a4f53..cc66365593 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 @@ -79,7 +79,6 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) sngss7_info->peer_data = peer_info; /* flush our own queue */ while ((event_clone = ftdm_queue_dequeue(sngss7_info->event_queue))) { - SS7_WARN("[CIC:%d]Discarding clone event from past call!\n", sngss7_info->circuit->cic); ftdm_safe_free(event_clone); } /* go up until release comes, note that state processing is done different and much simpler when there is a peer */ From a83f04ab6a7e2f8276f6e280c8b1eeb578897a5a Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 27 Jan 2012 00:13:59 -0500 Subject: [PATCH 21/34] freetdm: Relay the rest of SS7 messages supported by libsng_ss7 when in native bridge mode --- .../ftmod_sangoma_ss7_main.c | 55 ++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 24f612545f..06ddd7e8d1 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -561,7 +561,6 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev if (sngss7_event->event_id == SNGSS7_CON_IND_EVENT) { /* this is the first event in a call, flush the event queue */ while ((event_clone = ftdm_queue_dequeue(sngss7_info->event_queue))) { - SS7_WARN("[CIC:%d]Discarding clone event from past call!\n", sngss7_info->circuit->cic); ftdm_safe_free(event_clone); } /* clear the peer if any */ @@ -693,13 +692,13 @@ static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, ftdm_channel_advance_states(ftdmchan); } - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Relaying message %s from bridged peer\n", + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Receiving message %s from bridged peer\n", sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id)); switch (sngss7_event->event_id) { case (SNGSS7_CON_IND_EVENT): - SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]Rx IAM (bridged)??\n", sngss7_info->circuit->cic); + SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]Rx IAM while bridged??\n", sngss7_info->circuit->cic); break; case (SNGSS7_CON_CFM_EVENT): @@ -876,18 +875,48 @@ static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, /**************************************************************************/ case (SNGSS7_DAT_IND_EVENT): //handle_dat_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siInfoEvnt); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s\n", sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id)); + sng_cc_dat_request(1, + sngss7_info->suInstId, + sngss7_info->spInstId, + sngss7_info->circuit->id, + &sngss7_event->event.siInfoEvnt); break; /**************************************************************************/ case (SNGSS7_FAC_IND_EVENT): - //handle_fac_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType, &sngss7_event->event.siFacEvnt); + //handle_fac_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType, + //&sngss7_event->event.siFacEvnt); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s -> %d\n", sngss7_info->circuit->cic, + ftdm_sngss7_event2str(sngss7_event->event_id), sngss7_event->evntType); + sng_cc_fac_request(1, + sngss7_info->suInstId, + sngss7_info->spInstId, + sngss7_info->circuit->id, + sngss7_event->evntType, + &sngss7_event->event.siFacEvnt); + break; /**************************************************************************/ case (SNGSS7_FAC_CFM_EVENT): - //handle_fac_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType, &sngss7_event->event.siFacEvnt); + //handle_fac_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, + //sngss7_event->evntType, &sngss7_event->event.siFacEvnt); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s -> %d\n", sngss7_info->circuit->cic, + ftdm_sngss7_event2str(sngss7_event->event_id), sngss7_event->evntType); + sng_cc_fac_response(1, + sngss7_info->suInstId, + sngss7_info->spInstId, + sngss7_info->circuit->id, + sngss7_event->evntType, + &sngss7_event->event.siFacEvnt); break; /**************************************************************************/ case (SNGSS7_UMSG_IND_EVENT): //handle_umsg_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s\n", sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id)); + sng_cc_umsg_request (1, + sngss7_info->suInstId, + sngss7_info->spInstId, + sngss7_info->circuit->id); break; /**************************************************************************/ case (SNGSS7_STA_IND_EVENT): @@ -896,18 +925,30 @@ static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, /**************************************************************************/ case (SNGSS7_SUSP_IND_EVENT): //handle_susp_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siSuspEvnt); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s\n", sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id)); + sng_cc_susp_request (1, + sngss7_info->suInstId, + sngss7_info->spInstId, + sngss7_info->circuit->id, + &sngss7_event->event.siSuspEvnt); break; /**************************************************************************/ case (SNGSS7_RESM_IND_EVENT): //handle_resm_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siResmEvnt); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s\n", sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id)); + sng_cc_resm_request(1, + sngss7_info->suInstId, + sngss7_info->spInstId, + sngss7_info->circuit->id, + &sngss7_event->event.siResmEvnt); break; /**************************************************************************/ case (SNGSS7_SSP_STA_CFM_EVENT): - SS7_ERROR("dazed and confused ... hu?!\n"); + SS7_CRITICAL("dazed and confused ... hu?!\n"); break; /**************************************************************************/ default: - SS7_ERROR("Unknown Event Id!\n"); + SS7_ERROR("Failed to relay unknown event id %d!\n", sngss7_event->event_id); break; /**************************************************************************/ } From 2db41c5c793fd18acd25b0cd22499d7b1406b88e Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 27 Jan 2012 06:34:36 -0500 Subject: [PATCH 22/34] freetdm: Fix uninitialized var leading to segfault --- libs/freetdm/mod_freetdm/mod_freetdm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 2bbcdf97e4..a180f03fef 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1267,6 +1267,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi ftdm_usrmsg_t usrmsg; memset(&usrmsg, 0, sizeof(ftdm_usrmsg_t)); + memset(sigbridge_peer, 0, sizeof(sigbridge_peer)); if (!outbound_profile) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing caller profile\n"); @@ -1655,7 +1656,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi ftdm_channel_get_span_id(peer_pvt->ftdmchan), ftdm_channel_get_id(peer_pvt->ftdmchan)); } - if (!zstr(sigbridge_peer)) { + if (session && !zstr(sigbridge_peer)) { peer_chan = switch_core_session_get_channel(session); ftdm_usrmsg_add_var(&usrmsg, "sigbridge_peer", sigbridge_peer); } From 0ff8a087c616177f0162d4acab6bf7be2e60aa4a Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 27 Jan 2012 06:44:11 -0500 Subject: [PATCH 23/34] freetdm: Fix incorrect state transition from DOWN to UP when processing an SS7 clone event --- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 06ddd7e8d1..bcc21df7be 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -687,13 +687,13 @@ static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, { sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - if (ftdmchan->state < FTDM_CHANNEL_STATE_UP) { + if (ftdmchan->state < FTDM_CHANNEL_STATE_UP && ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); ftdm_channel_advance_states(ftdmchan); } - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Receiving message %s from bridged peer\n", - sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id)); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Receiving message %s from bridged peer (our state = %s)\n", + sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id), ftdm_channel_state2str(ftdmchan->state)); switch (sngss7_event->event_id) { From de56f3c465d98bddb916a106092db94a8459d853 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 27 Jan 2012 14:42:33 +0100 Subject: [PATCH 24/34] freetdm: spirou transparent IAM fix for called number --- .../ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) 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 cc66365593..b9914337a5 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 @@ -98,8 +98,18 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) /* first message in the queue should ALWAYS be an IAM */ SS7_ERROR_CHAN(ftdmchan, "Invalid initial peer message type '%d'\n", event_clone->event_id); } else { - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged)\n", sngss7_info->circuit->cic); + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; + + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged, dialing %s)\n", sngss7_info->circuit->cic, caller_data->dnis.digits); + + /* copy original incoming IAM */ memcpy(&iam, &event_clone->event.siConEvnt, sizeof(iam)); + + /* Change DNIS to whatever was specified, do not change NADI or anything else! */ + copy_tknStr_to_sngss7(caller_data->dnis.digits, &iam.cdPtyNum.addrSig, &iam.cdPtyNum.oddEven); + + /* SPIROU certification hack + If the IAM contains */ } /* since this is the first time we dequeue an event from the peer, make sure our main thread process any other events, this will trigger the interrupt in our span peer_chans queue which will wake up our main thread if it is sleeping */ From 572154693e3e972f50d4385ad3456f73e8235a69 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 27 Jan 2012 16:21:53 +0100 Subject: [PATCH 25/34] freetdm: spirou certification specific changes about RDNIS/RDINF usage --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) 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 b9914337a5..c1eef81d92 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 @@ -109,7 +109,31 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) copy_tknStr_to_sngss7(caller_data->dnis.digits, &iam.cdPtyNum.addrSig, &iam.cdPtyNum.oddEven); /* SPIROU certification hack - If the IAM contains */ + If the IAM already contain RDINF, just increment the count and set the RDNIS digits + otherwise, honor RDNIS and RDINF stuff coming from the user */ + if (iam.redirInfo.eh.pres == PRSNT_NODEF) { + const char *val = NULL; + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect info present\n", sngss7_info->circuit->cic); + if (iam.redirInfo.redirCnt.pres) { + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect count present = %d\n", sngss7_info->circuit->cic, iam.redirInfo.redirCnt.val); + iam.redirInfo.redirCnt.val++; + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect count incremented = %d\n", sngss7_info->circuit->cic, iam.redirInfo.redirCnt.val); + } + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_digits"); + if (!ftdm_strlen_zero(val)) { + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), found user supplied RDNIS digits = %s\n", sngss7_info->circuit->cic, val); + copy_tknStr_to_sngss7((char*)val, &iam.redirgNum.addrSig, &iam.redirgNum.oddEven); + } else { + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), not found user supplied RDNIS digits\n", sngss7_info->circuit->cic); + } + } else { + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect info not present, attempting to copy user supplied values\n", sngss7_info->circuit->cic); + /* Redirecting Number */ + copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum); + + /* Redirecting Information */ + copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo); + } } /* since this is the first time we dequeue an event from the peer, make sure our main thread process any other events, this will trigger the interrupt in our span peer_chans queue which will wake up our main thread if it is sleeping */ From 3199513c96b0fef5cca09b283361da449ffedcad Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 27 Jan 2012 16:22:45 +0100 Subject: [PATCH 26/34] freetdm: More spirou certification changes - Send RLC immediately even when in native bridge mode - Do not enqueue RLC coming from the network --- .../ftmod_sangoma_ss7_main.c | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index bcc21df7be..993ea68e5a 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -567,18 +567,20 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev sngss7_info->peer_data = NULL; } - /* clone the event and save it for later usage */ - event_clone = ftdm_calloc(1, sizeof(*sngss7_event)); - if (event_clone) { - memcpy(event_clone, sngss7_event, sizeof(*sngss7_event)); - ftdm_queue_enqueue(sngss7_info->event_queue, event_clone); - if (sngss7_info->peer_data) { - sngss7_span_data_t *sngss7_peer_span = (sngss7_span_data_t *)sngss7_info->peer_data->ftdmchan->span->signal_data; - /* we already have a peer attached, wake him up */ - ftdm_queue_enqueue(sngss7_peer_span->peer_chans, sngss7_info->ftdmchan); + /* clone the event and save it for later usage, we do not clone RLC messages */ + if (sngss7_event->event_id != SNGSS7_REL_CFM_EVENT) { + event_clone = ftdm_calloc(1, sizeof(*sngss7_event)); + if (event_clone) { + memcpy(event_clone, sngss7_event, sizeof(*sngss7_event)); + ftdm_queue_enqueue(sngss7_info->event_queue, event_clone); + if (sngss7_info->peer_data) { + sngss7_span_data_t *sngss7_peer_span = (sngss7_span_data_t *)sngss7_info->peer_data->ftdmchan->span->signal_data; + /* we already have a peer attached, wake him up */ + ftdm_queue_enqueue(sngss7_peer_span->peer_chans, sngss7_info->ftdmchan); + } } } - + /* we could test for sngss7_info->peer_data too, bit this flag is set earlier, the earlier we know the better */ if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { /* most messages are simply relayed in sig bridge mode, except for hangup which requires state changing */ @@ -981,6 +983,7 @@ static ftdm_status_t ftdm_sangoma_ss7_native_bridge_state_change(ftdm_channel_t case FTDM_CHANNEL_STATE_TERMINATING: { + ft_to_sngss7_rlc(ftdmchan); /* when receiving REL we move to TERMINATING and notify the user that the bridge is ending */ sngss7_send_signal(sngss7_info, FTDM_SIGEVENT_STOP); } From 8476d664656b9ffdb0cbb775d33d4ac4be53c039 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 27 Jan 2012 18:54:06 +0100 Subject: [PATCH 27/34] freetdm: Cancel ISUP T6 timer when using native bridge (Spirou certification fix) --- .../ftmod_sangoma_ss7_main.c | 59 +++++++++++++++++++ .../ftmod_sangoma_ss7_main.h | 2 + 2 files changed, 61 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 993ea68e5a..4c47ee0578 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -40,6 +40,13 @@ /* INCLUDE ********************************************************************/ #include "ftmod_sangoma_ss7_main.h" +#include +#include +#include +#include +#include +#include +#include /******************************************************************************/ /* DEFINES ********************************************************************/ @@ -567,6 +574,33 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev sngss7_info->peer_data = NULL; } + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { + + if (sngss7_event->event_id == SNGSS7_SUSP_IND_EVENT) { + sngss7_set_ckt_flag(sngss7_info, FLAG_SUS_RECVD); + sngss7_clear_ckt_flag(sngss7_info, FLAG_T6_CANCELED); + } + + if (sngss7_test_ckt_flag(sngss7_info, FLAG_SUS_RECVD) && + !sngss7_test_ckt_flag(sngss7_info, FLAG_T6_CANCELED)) { + /* SPIROU cert, disable ISUP T6 when bridged natively */ + int trc = 0; + SiCon *siCon = NULL; + if (siFindSuInstId(sngss7_info->suInstId, &siCon) != RFAILED) { + if (siCon) { + trc = siStopConTmr(siCon, TMR_T6I); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Stopped T6 timer (%d)\n", sngss7_info->circuit->cic, trc); + sngss7_set_ckt_flag(sngss7_info, FLAG_T6_CANCELED); + } else { + SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]siCon is null!\n", sngss7_info->circuit->cic); + } + } else { + SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]could not find siCon\n", sngss7_info->circuit->cic); + } + } + + } + /* clone the event and save it for later usage, we do not clone RLC messages */ if (sngss7_event->event_id != SNGSS7_REL_CFM_EVENT) { event_clone = ftdm_calloc(1, sizeof(*sngss7_event)); @@ -955,6 +989,29 @@ static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, /**************************************************************************/ } + if ((sngss7_event->event_id == SNGSS7_SUSP_IND_EVENT)) { + sngss7_set_ckt_flag(sngss7_info, FLAG_SUS_RECVD); + } + + if (sngss7_test_ckt_flag(sngss7_info, FLAG_SUS_RECVD) && + !sngss7_test_ckt_flag(sngss7_info, FLAG_T6_CANCELED)) { + /* SPIROU cert, disable ISUP T6 when bridged natively */ + int trc = 0; + SiCon *siCon = NULL; + if (siFindSuInstId(sngss7_info->suInstId, &siCon) != RFAILED) { + if (siCon) { + trc = siStopConTmr(siCon, TMR_T6I); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Stopped T6 timer (%d)\n", sngss7_info->circuit->cic, trc); + sngss7_set_ckt_flag(sngss7_info, FLAG_T6_CANCELED); + } else { + SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]siCon is null!\n", sngss7_info->circuit->cic); + } + } else { + SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]could not find siCon\n", sngss7_info->circuit->cic); + } + } + + } static ftdm_status_t ftdm_sangoma_ss7_native_bridge_state_change(ftdm_channel_t *ftdmchan); @@ -969,6 +1026,8 @@ static ftdm_status_t ftdm_sangoma_ss7_native_bridge_state_change(ftdm_channel_t case FTDM_CHANNEL_STATE_DOWN: { ftdm_channel_t *close_chan = ftdmchan; + sngss7_clear_ckt_flag(sngss7_info, FLAG_SUS_RECVD); + sngss7_clear_ckt_flag(sngss7_info, FLAG_T6_CANCELED); ftdm_channel_close (&close_chan); } break; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index 7404a8e55d..b5494bc174 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -550,6 +550,8 @@ typedef enum { FLAG_INFID_PAUSED = (1 << 15), FLAG_SENT_ACM = (1 << 16), FLAG_SENT_CPG = (1 << 17), + FLAG_SUS_RECVD = (1 << 18), + FLAG_T6_CANCELED = (1 << 19), FLAG_RELAY_DOWN = (1 << 30), FLAG_CKT_RECONFIG = (1 << 31) } sng_ckt_flag_t; From 777f946e2f0f02f058171c7c0e13a973d6bed837 Mon Sep 17 00:00:00 2001 From: James Zhang Date: Mon, 30 Jan 2012 10:28:08 -0500 Subject: [PATCH 28/34] freetdm: adding susp/resm/rels but not finished. disable t6 finished. --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 125 +++++++++++++++++- .../ftmod_sangoma_ss7_main.c | 27 ++-- 2 files changed, 142 insertions(+), 10 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c index 2c8f5172b9..d738edb959 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c @@ -71,6 +71,10 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int chan, int verbose); static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); +static ftdm_status_t handle_tx_susp(ftdm_stream_handle_t *stream, int span, int chan, int verbose); +static ftdm_status_t handle_tx_resm(ftdm_stream_handle_t *stream, int span, int chan, int verbose); +static ftdm_status_t handle_tx_rels(ftdm_stream_handle_t *stream, int span, int chan, int verbose); + static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int chan, int verbose); static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int chan, int verbose); @@ -458,9 +462,49 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha goto handle_cli_error; /**********************************************************************/ } + + /**************************************************************************/ + /* sending resume for a ckt's call */ + } else if (!strcasecmp(argv[c], "resm") == FTDM_FAIL) { + if (check_arg_count(argc, 5) == FTDM_FAIL) { + goto handle_cli_error_argc; + } + + if (extract_span_chan(argv, 2, &span, &chan) == FTDM_SUCCESS) { + handle_tx_resm(stream, span, chan, verbose); + } else { + stream->write_function(stream, "Bad command format. \n"); + goto handle_cli_error_argc; + } + /**************************************************************************/ + /* sending resume for a ckt's call */ + } else if (!strcasecmp(argv[c], "rels")) { + if (check_arg_count(argc, 5) == FTDM_FAIL) { + goto handle_cli_error_argc; + } + + if (extract_span_chan(argv, 2, &span, &chan) == FTDM_SUCCESS) { + handle_tx_rels(stream, span, chan, verbose); + } else { + stream->write_function(stream, "Bad command format.\n"); + goto handle_cli_error_argc; + } + + /**************************************************************************/ + /* sending suspend for a ckt's call */ + } else if (!strcasecmp(argv[c], "susp")) { + if (check_arg_count(argc, 5) == FTDM_FAIL) { + goto handle_cli_error_argc; + } + + if (extract_span_chan(argv, 2, &span, &chan) == FTDM_SUCCESS) { + handle_tx_susp(stream, span, chan, verbose); + } else { + stream->write_function(stream, "Bad command format. \n"); + goto handle_cli_error_argc; + } /**************************************************************************/ } else if (!strcasecmp(argv[c], "blo")) { - /**************************************************************************/ if (check_arg_count(argc, 2)) goto handle_cli_error_argc; c++; @@ -1330,6 +1374,85 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, return FTDM_SUCCESS; } +static ftdm_status_t handle_tx_resm(ftdm_stream_handle_t *stream, int span, int chan, int verbose) +{ + SS7_ERROR("JZ error alert. handle_tx_resm \n"); + return FTDM_FAIL; +} +static ftdm_status_t handle_tx_rels(ftdm_stream_handle_t *stream, int span, int chan, int verbose) +{ + SS7_ERROR("JZ error alert. handle_tx_rels \n"); + return FTDM_FAIL; +} + +/******************************************************************************/ +static ftdm_status_t handle_tx_susp(ftdm_stream_handle_t *stream, int span, int chan, int verbose) +{ + int x; + sngss7_chan_data_t *ss7_info; + ftdm_channel_t *ftdmchan; + int lspan; + int lchan; + + SS7_ERROR("JZ error alert. handle_tx_susp \n"); + return FTDM_FAIL; + + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { + ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; + ftdmchan = ss7_info->ftdmchan; + + /* if span == 0 then all spans should be printed */ + if (span == 0) { + lspan = ftdmchan->physical_span_id; + } else { + lspan = span; + } + + /* if chan == 0 then all chans should be printed */ + if (chan == 0) { + lchan = ftdmchan->physical_chan_id; + } else { + lchan = chan; + } + + if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change|give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic); + /* check if we need to die */ + ftdm_assert(0, "State change not completed\n"); + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + /* move to the next channel */ + continue; + } else { + /* throw the ckt block flag */ + sngss7_set_ckt_blk_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); + + /* set the channel to suspended state */ + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } /* if ( span and chan) */ + + } /* if ( cic != 0) */ + + /* go the next circuit */ + x++; + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ + + handle_show_blocks(stream, span, chan, verbose); + + return FTDM_SUCCESS; +} /******************************************************************************/ static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int chan, int verbose) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 4c47ee0578..3f87ccf713 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -40,13 +40,6 @@ /* INCLUDE ********************************************************************/ #include "ftmod_sangoma_ss7_main.h" -#include -#include -#include -#include -#include -#include -#include /******************************************************************************/ /* DEFINES ********************************************************************/ @@ -583,6 +576,14 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev if (sngss7_test_ckt_flag(sngss7_info, FLAG_SUS_RECVD) && !sngss7_test_ckt_flag(sngss7_info, FLAG_T6_CANCELED)) { + if (sng_cancel_isup_tmr(sngss7_info->suInstId, ISUP_T6i) == RFAILED ) { + SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]could not stop timer T6 \n", sngss7_info->circuit->cic); + } else { + sngss7_set_ckt_flag(sngss7_info, FLAG_T6_CANCELED); + SS7_ERROR_CHAN(ftdmchan,"[CIC:%d] isup timer T6 has been cancelled. \n", sngss7_info->circuit->cic); + } + +#if 0 /* SPIROU cert, disable ISUP T6 when bridged natively */ int trc = 0; SiCon *siCon = NULL; @@ -597,6 +598,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev } else { SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]could not find siCon\n", sngss7_info->circuit->cic); } +#endif } } @@ -995,6 +997,14 @@ static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, if (sngss7_test_ckt_flag(sngss7_info, FLAG_SUS_RECVD) && !sngss7_test_ckt_flag(sngss7_info, FLAG_T6_CANCELED)) { + if (sng_cancel_isup_tmr(sngss7_info->suInstId, ISUP_T6i) == RFAILED ) { + SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]could not stop timer T6 \n", sngss7_info->circuit->cic); + } else { + sngss7_set_ckt_flag(sngss7_info, FLAG_T6_CANCELED); + SS7_ERROR_CHAN(ftdmchan,"[CIC:%d] isup timer T6 has been cancelled. \n", sngss7_info->circuit->cic); + } + +#if 0 /* SPIROU cert, disable ISUP T6 when bridged natively */ int trc = 0; SiCon *siCon = NULL; @@ -1009,9 +1019,8 @@ static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, } else { SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]could not find siCon\n", sngss7_info->circuit->cic); } +#endif } - - } static ftdm_status_t ftdm_sangoma_ss7_native_bridge_state_change(ftdm_channel_t *ftdmchan); From 14d8b42e58355597cdfb49a30626313afa8e695a Mon Sep 17 00:00:00 2001 From: James Zhang Date: Mon, 30 Jan 2012 13:19:36 -0500 Subject: [PATCH 29/34] freetdm: testing code of sending suspend message --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 85 +++++++++---------- .../ftmod_sangoma_ss7_main.h | 2 +- 2 files changed, 42 insertions(+), 45 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c index d738edb959..6e97a3db4e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c @@ -1389,67 +1389,64 @@ static ftdm_status_t handle_tx_rels(ftdm_stream_handle_t *stream, int span, int static ftdm_status_t handle_tx_susp(ftdm_stream_handle_t *stream, int span, int chan, int verbose) { int x; + ftdm_channel_t *ftdmchan; + int lspan; + int lchan; + SiSuspEvnt suspEvnt; sngss7_chan_data_t *ss7_info; - ftdm_channel_t *ftdmchan; - int lspan; - int lchan; + /* SS7_ERROR("JZ error alert. handle_tx_susp \n"); return FTDM_FAIL; + */ + /* JZ implementation */ + + if (span <= 0 || chan <= 0 || chan >= 32 ) { + SS7_ERROR ("Wrong span number or chan number.\n"); + return FTDM_FAIL; + } + + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + for ( ; g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0; x++) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { + ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; ftdmchan = ss7_info->ftdmchan; - /* if span == 0 then all spans should be printed */ - if (span == 0) { - lspan = ftdmchan->physical_span_id; - } else { - lspan = span; + lspan = span; + lchan = chan; + + if ((ftdmchan->physical_span_id != lspan) && (ftdmchan->physical_chan_id != lchan)) { + continue; } - /* if chan == 0 then all chans should be printed */ - if (chan == 0) { - lchan = ftdmchan->physical_chan_id; - } else { - lchan = chan; - } + ftdm_mutex_lock(ftdmchan->mutex); - if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change|give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic); - /* check if we need to die */ - ftdm_assert(0, "State change not completed\n"); - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - /* move to the next channel */ - continue; - } else { - /* throw the ckt block flag */ - sngss7_set_ckt_blk_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); - - /* set the channel to suspended state */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - } - - /* unlock the channel again before we exit */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic); + ftdm_assert(0, "State change not completed\n"); ftdm_mutex_unlock(ftdmchan->mutex); + continue; + } - } /* if ( span and chan) */ - - } /* if ( cic != 0) */ - - /* go the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ + /* + sngss7_set_ckt_blk_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + */ + suspEvnt.susResInd.eh.pres = PRSNT_NODEF; + suspEvnt.susResInd.susResInd.pres = PRSNT_NODEF; + suspEvnt.susResInd.susResInd.val = EVTSITSUSPREQ; + + sng_cc_susp_request(lspan, ss7_info->suInstId, ss7_info->spInstId, ss7_info->circuit->id, &suspEvnt); + + ftdm_mutex_unlock(ftdmchan->mutex); + } + } handle_show_blocks(stream, span, chan, verbose); + /* end of JZ implementation */ return FTDM_SUCCESS; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index b5494bc174..f9aed03083 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -607,7 +607,7 @@ typedef enum { FLAG_GRP_HW_UNBLK_TX = (1 << 24), FLAG_GRP_HW_UNBLK_TX_DN = (1 << 25), FLAG_GRP_MN_UNBLK_TX = (1 << 26), - FLAG_GRP_MN_UNBLK_TX_DN = (1 << 27) + FLAG_GRP_MN_UNBLK_TX_DN = (1 << 27), } sng_ckt_block_flag_t; #define BLK_FLAGS_STRING \ From c1ad5677429d3c8be6ebfcc756e3328c0f82e073 Mon Sep 17 00:00:00 2001 From: James Zhang Date: Mon, 30 Jan 2012 17:37:57 -0500 Subject: [PATCH 30/34] freetdm: removing sus|res|rel commands --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 121 ------------------ .../ftmod_sangoma_ss7_main.c | 35 ----- 2 files changed, 156 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c index 6e97a3db4e..cb5584760f 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c @@ -71,10 +71,6 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int chan, int verbose); static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); -static ftdm_status_t handle_tx_susp(ftdm_stream_handle_t *stream, int span, int chan, int verbose); -static ftdm_status_t handle_tx_resm(ftdm_stream_handle_t *stream, int span, int chan, int verbose); -static ftdm_status_t handle_tx_rels(ftdm_stream_handle_t *stream, int span, int chan, int verbose); - static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int chan, int verbose); static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int chan, int verbose); @@ -462,47 +458,6 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha goto handle_cli_error; /**********************************************************************/ } - - /**************************************************************************/ - /* sending resume for a ckt's call */ - } else if (!strcasecmp(argv[c], "resm") == FTDM_FAIL) { - if (check_arg_count(argc, 5) == FTDM_FAIL) { - goto handle_cli_error_argc; - } - - if (extract_span_chan(argv, 2, &span, &chan) == FTDM_SUCCESS) { - handle_tx_resm(stream, span, chan, verbose); - } else { - stream->write_function(stream, "Bad command format. \n"); - goto handle_cli_error_argc; - } - /**************************************************************************/ - /* sending resume for a ckt's call */ - } else if (!strcasecmp(argv[c], "rels")) { - if (check_arg_count(argc, 5) == FTDM_FAIL) { - goto handle_cli_error_argc; - } - - if (extract_span_chan(argv, 2, &span, &chan) == FTDM_SUCCESS) { - handle_tx_rels(stream, span, chan, verbose); - } else { - stream->write_function(stream, "Bad command format.\n"); - goto handle_cli_error_argc; - } - - /**************************************************************************/ - /* sending suspend for a ckt's call */ - } else if (!strcasecmp(argv[c], "susp")) { - if (check_arg_count(argc, 5) == FTDM_FAIL) { - goto handle_cli_error_argc; - } - - if (extract_span_chan(argv, 2, &span, &chan) == FTDM_SUCCESS) { - handle_tx_susp(stream, span, chan, verbose); - } else { - stream->write_function(stream, "Bad command format. \n"); - goto handle_cli_error_argc; - } /**************************************************************************/ } else if (!strcasecmp(argv[c], "blo")) { if (check_arg_count(argc, 2)) goto handle_cli_error_argc; @@ -1374,82 +1329,6 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, return FTDM_SUCCESS; } -static ftdm_status_t handle_tx_resm(ftdm_stream_handle_t *stream, int span, int chan, int verbose) -{ - SS7_ERROR("JZ error alert. handle_tx_resm \n"); - return FTDM_FAIL; -} -static ftdm_status_t handle_tx_rels(ftdm_stream_handle_t *stream, int span, int chan, int verbose) -{ - SS7_ERROR("JZ error alert. handle_tx_rels \n"); - return FTDM_FAIL; -} - -/******************************************************************************/ -static ftdm_status_t handle_tx_susp(ftdm_stream_handle_t *stream, int span, int chan, int verbose) -{ - int x; - ftdm_channel_t *ftdmchan; - int lspan; - int lchan; - SiSuspEvnt suspEvnt; - sngss7_chan_data_t *ss7_info; - - /* - SS7_ERROR("JZ error alert. handle_tx_susp \n"); - return FTDM_FAIL; - */ - - /* JZ implementation */ - - if (span <= 0 || chan <= 0 || chan >= 32 ) { - SS7_ERROR ("Wrong span number or chan number.\n"); - return FTDM_FAIL; - } - - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - for ( ; g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0; x++) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = ss7_info->ftdmchan; - - lspan = span; - lchan = chan; - - if ((ftdmchan->physical_span_id != lspan) && (ftdmchan->physical_chan_id != lchan)) { - continue; - } - - ftdm_mutex_lock(ftdmchan->mutex); - - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic); - ftdm_assert(0, "State change not completed\n"); - ftdm_mutex_unlock(ftdmchan->mutex); - continue; - } - - /* - sngss7_set_ckt_blk_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - */ - suspEvnt.susResInd.eh.pres = PRSNT_NODEF; - suspEvnt.susResInd.susResInd.pres = PRSNT_NODEF; - suspEvnt.susResInd.susResInd.val = EVTSITSUSPREQ; - - sng_cc_susp_request(lspan, ss7_info->suInstId, ss7_info->spInstId, ss7_info->circuit->id, &suspEvnt); - - ftdm_mutex_unlock(ftdmchan->mutex); - } - } - - handle_show_blocks(stream, span, chan, verbose); - /* end of JZ implementation */ - - return FTDM_SUCCESS; -} /******************************************************************************/ static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int chan, int verbose) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 3f87ccf713..950a28500e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -582,25 +582,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev sngss7_set_ckt_flag(sngss7_info, FLAG_T6_CANCELED); SS7_ERROR_CHAN(ftdmchan,"[CIC:%d] isup timer T6 has been cancelled. \n", sngss7_info->circuit->cic); } - -#if 0 - /* SPIROU cert, disable ISUP T6 when bridged natively */ - int trc = 0; - SiCon *siCon = NULL; - if (siFindSuInstId(sngss7_info->suInstId, &siCon) != RFAILED) { - if (siCon) { - trc = siStopConTmr(siCon, TMR_T6I); - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Stopped T6 timer (%d)\n", sngss7_info->circuit->cic, trc); - sngss7_set_ckt_flag(sngss7_info, FLAG_T6_CANCELED); - } else { - SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]siCon is null!\n", sngss7_info->circuit->cic); - } - } else { - SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]could not find siCon\n", sngss7_info->circuit->cic); - } -#endif } - } /* clone the event and save it for later usage, we do not clone RLC messages */ @@ -1003,23 +985,6 @@ static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, sngss7_set_ckt_flag(sngss7_info, FLAG_T6_CANCELED); SS7_ERROR_CHAN(ftdmchan,"[CIC:%d] isup timer T6 has been cancelled. \n", sngss7_info->circuit->cic); } - -#if 0 - /* SPIROU cert, disable ISUP T6 when bridged natively */ - int trc = 0; - SiCon *siCon = NULL; - if (siFindSuInstId(sngss7_info->suInstId, &siCon) != RFAILED) { - if (siCon) { - trc = siStopConTmr(siCon, TMR_T6I); - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Stopped T6 timer (%d)\n", sngss7_info->circuit->cic, trc); - sngss7_set_ckt_flag(sngss7_info, FLAG_T6_CANCELED); - } else { - SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]siCon is null!\n", sngss7_info->circuit->cic); - } - } else { - SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]could not find siCon\n", sngss7_info->circuit->cic); - } -#endif } } From d1a772bfe9620f1305eeb7d97681a9c798d0108b Mon Sep 17 00:00:00 2001 From: James Zhang Date: Mon, 30 Jan 2012 18:02:26 -0500 Subject: [PATCH 31/34] freetdm: Only hangup with user message when release location information is set --- libs/freetdm/mod_freetdm/mod_freetdm.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index a180f03fef..b78cc078d4 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -506,10 +506,6 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session) int chan_id = 0; const char *name = NULL; - ftdm_usrmsg_t usrmsg; - memset(&usrmsg, 0, sizeof(ftdm_usrmsg_t)); - - channel = switch_core_session_get_channel(session); assert(channel != NULL); @@ -577,19 +573,20 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session) case FTDM_CHAN_TYPE_CAS: case FTDM_CHAN_TYPE_B: { - const char *sipvar; + const char *var = NULL; ftdm_call_cause_t hcause = switch_channel_get_cause_q850(channel); if (hcause < 1 || hcause > 127) { hcause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER; } - sipvar = switch_channel_get_variable(channel, "ss7_rel_loc"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_rel_loc", sipvar); + var = switch_channel_get_variable(channel, "ss7_rel_loc"); + if (var) { + ftdm_usrmsg_t usrmsg; + memset(&usrmsg, 0, sizeof(ftdm_usrmsg_t)); + ftdm_usrmsg_add_var(&usrmsg, "ss7_rel_loc", var); + ftdm_channel_call_hangup_with_cause_ex(tech_pvt->ftdmchan, hcause, &usrmsg); + } else { + ftdm_channel_call_hangup_with_cause(tech_pvt->ftdmchan, hcause); } - /* - ftdm_channel_call_hangup_with_cause(tech_pvt->ftdmchan, hcause); - */ - ftdm_channel_call_hangup_with_cause_ex(tech_pvt->ftdmchan, hcause, &usrmsg); } break; default: From b6c02364a790e81c2d67b33b1cd432ee9af9750d Mon Sep 17 00:00:00 2001 From: James Zhang Date: Mon, 30 Jan 2012 18:26:08 -0500 Subject: [PATCH 32/34] freetdm: Reduce the size of the span peer channels and ss7 info per channel clone event queues --- .../ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c | 2 +- .../ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h | 2 ++ .../ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 10 ++++------ .../ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 950a28500e..5f2beee65b 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -2367,7 +2367,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config) } /* create an peer channel queue for this span */ - if ((ftdm_queue_create(&(ss7_span_info)->peer_chans, SPAN_PENDING_CHANS_QUEUE_SIZE)) != FTDM_SUCCESS) { + if ((ftdm_queue_create(&(ss7_span_info)->peer_chans, SNGSS7_PEER_CHANS_QUEUE_SIZE)) != FTDM_SUCCESS) { SS7_CRITICAL("Unable to create peer chans queue!\n"); return FTDM_FAIL; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index f9aed03083..c77599d3d9 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -56,6 +56,8 @@ #define MAX_CIC_MAP_LENGTH 1000 #define SNGSS7_EVENT_QUEUE_SIZE 100 +#define SNGSS7_PEER_CHANS_QUEUE_SIZE 100 +#define SNGSS7_CHAN_EVENT_QUEUE_SIZE 5 #define MAX_SIZEOF_SUBADDR_IE 24 /* as per Q931 4.5.9 */ 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 c1eef81d92..20e661d73e 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 @@ -113,21 +113,19 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) otherwise, honor RDNIS and RDINF stuff coming from the user */ if (iam.redirInfo.eh.pres == PRSNT_NODEF) { const char *val = NULL; - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect info present\n", sngss7_info->circuit->cic); if (iam.redirInfo.redirCnt.pres) { - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect count present = %d\n", sngss7_info->circuit->cic, iam.redirInfo.redirCnt.val); iam.redirInfo.redirCnt.val++; - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect count incremented = %d\n", sngss7_info->circuit->cic, iam.redirInfo.redirCnt.val); + SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect count incremented = %d\n", sngss7_info->circuit->cic, iam.redirInfo.redirCnt.val); } val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_digits"); if (!ftdm_strlen_zero(val)) { - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), found user supplied RDNIS digits = %s\n", sngss7_info->circuit->cic, val); + SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), found user supplied RDNIS digits = %s\n", sngss7_info->circuit->cic, val); copy_tknStr_to_sngss7((char*)val, &iam.redirgNum.addrSig, &iam.redirgNum.oddEven); } else { - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), not found user supplied RDNIS digits\n", sngss7_info->circuit->cic); + SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), not found user supplied RDNIS digits\n", sngss7_info->circuit->cic); } } else { - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect info not present, attempting to copy user supplied values\n", sngss7_info->circuit->cic); + SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect info not present, attempting to copy user supplied values\n", sngss7_info->circuit->cic); /* Redirecting Number */ copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum); 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 d7732cce6c..e76397580e 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 @@ -2925,7 +2925,7 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan) /* prepare the global info sturcture */ ss7_info = ftdm_calloc(1, sizeof(sngss7_chan_data_t)); ss7_info->ftdmchan = NULL; - if (ftdm_queue_create(&ss7_info->event_queue, SNGSS7_EVENT_QUEUE_SIZE) != FTDM_SUCCESS) { + if (ftdm_queue_create(&ss7_info->event_queue, SNGSS7_CHAN_EVENT_QUEUE_SIZE) != FTDM_SUCCESS) { SS7_CRITICAL("Failed to create ss7 cic event queue\n"); } ss7_info->circuit = &g_ftdm_sngss7_data.cfg.isupCkt[x]; From c9c68a7759ab2ea60e9115d6046850311aa6b1b8 Mon Sep 17 00:00:00 2001 From: James Zhang Date: Mon, 30 Jan 2012 19:15:02 -0500 Subject: [PATCH 33/34] freetdm: Some more clean up for ss7 event cloning - The queue size has been bumped again, long calls could potentially require more elements (multiple resume/suspend) - The queue is only used when there is a call active --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c | 16 ++++++++++++---- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h | 12 ++++++++++-- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 8 ++++---- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 5f2beee65b..20b2199f21 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -545,6 +545,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev sngss7_chan_data_t *sngss7_info = NULL; ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *event_clone = NULL; + int clone_event = 0; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(sngss7_event->circuit, &sngss7_info, &ftdmchan)) { @@ -560,11 +561,16 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev if (sngss7_event->event_id == SNGSS7_CON_IND_EVENT) { /* this is the first event in a call, flush the event queue */ - while ((event_clone = ftdm_queue_dequeue(sngss7_info->event_queue))) { - ftdm_safe_free(event_clone); - } + sngss7_flush_queue(sngss7_info->event_queue); /* clear the peer if any */ sngss7_info->peer_data = NULL; + clone_event++; + } + + /* if the call has already started and the event is not a release confirmation, clone the event */ + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED) && + sngss7_event->event_id != SNGSS7_REL_CFM_EVENT) { + clone_event++; } if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { @@ -586,7 +592,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev } /* clone the event and save it for later usage, we do not clone RLC messages */ - if (sngss7_event->event_id != SNGSS7_REL_CFM_EVENT) { + if (clone_event) { event_clone = ftdm_calloc(1, sizeof(*sngss7_event)); if (event_clone) { memcpy(event_clone, sngss7_event, sizeof(*sngss7_event)); @@ -1002,6 +1008,7 @@ static ftdm_status_t ftdm_sangoma_ss7_native_bridge_state_change(ftdm_channel_t ftdm_channel_t *close_chan = ftdmchan; sngss7_clear_ckt_flag(sngss7_info, FLAG_SUS_RECVD); sngss7_clear_ckt_flag(sngss7_info, FLAG_T6_CANCELED); + sngss7_flush_queue(sngss7_info->event_queue); ftdm_channel_close (&close_chan); } break; @@ -1517,6 +1524,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan) /* close the channel */ SS7_DEBUG_CHAN(ftdmchan,"FTDM Channel Close %s\n", ""); + sngss7_flush_queue(sngss7_info->event_queue); ftdm_channel_close (&close_chan); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index c77599d3d9..fb60183bf8 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -57,7 +57,7 @@ #define SNGSS7_EVENT_QUEUE_SIZE 100 #define SNGSS7_PEER_CHANS_QUEUE_SIZE 100 -#define SNGSS7_CHAN_EVENT_QUEUE_SIZE 5 +#define SNGSS7_CHAN_EVENT_QUEUE_SIZE 100 #define MAX_SIZEOF_SUBADDR_IE 24 /* as per Q931 4.5.9 */ @@ -65,6 +65,14 @@ (switchtype == LSI_SW_ANS92) || \ (switchtype == LSI_SW_ANS95) +#define sngss7_flush_queue(queue) \ + do { \ + void *__queue_data = NULL; \ + while ((__queue_data = ftdm_queue_dequeue(queue))) { \ + ftdm_safe_free(__queue_data); \ + } \ + } while (0) + typedef struct ftdm2trillium { uint8_t ftdm_val; uint8_t trillium_val; @@ -552,7 +560,7 @@ typedef enum { FLAG_INFID_PAUSED = (1 << 15), FLAG_SENT_ACM = (1 << 16), FLAG_SENT_CPG = (1 << 17), - FLAG_SUS_RECVD = (1 << 18), + FLAG_SUS_RECVD = (1 << 18), FLAG_T6_CANCELED = (1 << 19), FLAG_RELAY_DOWN = (1 << 30), FLAG_CKT_RECONFIG = (1 << 31) 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 20e661d73e..00d06905dd 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 @@ -70,17 +70,17 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) SS7_ERROR_CHAN(ftdmchan, "Peer channel '%s' has different signaling type %d'\n", var, peer_span->signal_type); } else { - sngss7_event_data_t *event_clone = NULL; peer_info = peer_chan->call_data; SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Starting native bridge with peer CIC %d\n", sngss7_info->circuit->cic, peer_info->circuit->cic); + /* make each one of us aware of the native bridge */ peer_info->peer_data = sngss7_info; sngss7_info->peer_data = peer_info; + /* flush our own queue */ - while ((event_clone = ftdm_queue_dequeue(sngss7_info->event_queue))) { - ftdm_safe_free(event_clone); - } + sngss7_flush_queue(sngss7_info->event_queue); + /* go up until release comes, note that state processing is done different and much simpler when there is a peer */ ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); ftdm_channel_advance_states(ftdmchan); From cca407d09a1dbddfa876497ac9f3c172e2eac92b Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 31 Jan 2012 15:18:53 -0500 Subject: [PATCH 34/34] freetdm: Fix bug in SS7 state processing introduced during the changes for native bridging that caused infinite SUSPEND state executions due to peer member not being cleared at the end of the call --- .../ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 20b2199f21..fa36c7280a 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -1049,14 +1049,14 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan) sngss7_info->ckt_flags, sngss7_info->blk_flags); - if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) { + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { + /* DIALING is the only state we process normally when doing an outgoing call that is natively bridged */ + if (ftdmchan->state != FTDM_CHANNEL_STATE_DIALING) { + return ftdm_sangoma_ss7_native_bridge_state_change(ftdmchan); + } sngss7_info->peer_data = NULL; } - if (sngss7_info->peer_data) { - return ftdm_sangoma_ss7_native_bridge_state_change(ftdmchan); - } - /*check what state we are supposed to be in */ switch (ftdmchan->state) { /**************************************************************************/