From 63a2c847ebe320f4c4d16e1d34cfc4e84365e357 Mon Sep 17 00:00:00 2001 From: James Zhang Date: Fri, 16 Mar 2012 12:24:10 -0400 Subject: [PATCH] freetdm: merge native bridge fix from releases.3.4 which solves the crash on outgoing calls after native bridge --- libs/freetdm/src/ftdm_io.c | 6 ++++ .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 4 +++ .../ftmod_sangoma_ss7_main.c | 30 +++++++++++-------- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 26 ++++++++-------- 4 files changed, 39 insertions(+), 27 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 63029e74e0..a2d80a40eb 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2453,6 +2453,12 @@ FT_DECLARE(ftdm_status_t) ftdm_get_channel_from_string(const char *string_id, ft *out_span = NULL; *out_channel = NULL; + if (!string_id) { + ftdm_log(FTDM_LOG_ERROR, "Cannot parse NULL channel id string\n"); + status = FTDM_EINVAL; + goto done; + } + 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); 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 ece88caac2..3f1a03f4d8 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 @@ -1325,6 +1325,10 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, }else { stream->write_function(stream, "relay=N"); } + +#ifdef SMG_RELAY_DBG + stream->write_function(stream, "| flag=0x%llx", ftdmchan->flags); +#endif } #ifdef SMG_RELAY_DBG 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 9b6c561742..fe129c0f73 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 @@ -615,20 +615,22 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev 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); + if (sngss7_info->peer_data) { + 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(peer_chan, FTDM_CHANNEL_STATE_DOWN); + ftdm_channel_lock(peer_chan); + if (peer_chan->state != FTDM_CHANNEL_STATE_DOWN) { + ftdm_set_state(peer_chan, FTDM_CHANNEL_STATE_DOWN); + } + ftdm_channel_unlock(peer_chan); + + ftdm_channel_lock(ftdmchan); } - ftdm_channel_unlock(peer_chan); - - ftdm_channel_lock(ftdmchan); } } break; @@ -1087,12 +1089,14 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan) /*now go to the RING state */ state_flag = 0; ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); + } else if (i >= sngss7_info->circuit->min_digits) { SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, sngss7_info->circuit->min_digits); /*now go to the RING state */ state_flag = 0; ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); + } else { /* if we are coming from idle state then we have already been here once before */ if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) { @@ -1100,7 +1104,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan) i, sngss7_info->circuit->min_digits, ftdmchan->caller_data.dnis.digits); - + /* start ISUP t35 */ if (ftdm_sched_timer (sngss7_info->t35.sched, "t35", 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 fb91b834ec..5f0a0f0960 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 @@ -57,12 +57,12 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) memset (&iam, 0x0, sizeof (iam)); - var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "sigbridge_peer"); - if (!ftdm_strlen_zero(var)) { + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { ftdm_span_t *peer_span = NULL; ftdm_channel_t *peer_chan = NULL; sngss7_chan_data_t *peer_info = NULL; + var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "sigbridge_peer"); 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); @@ -82,16 +82,16 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) /* flush our own queue */ sngss7_flush_queue(sngss7_info->event_queue); - /* Go to up until release comes, note that state processing is done different and much simpler when there is a peer, - We can't go to UP state right away yet though, so do not set the state to UP here, wait until the end of this function - because moving from one state to another causes the ftdmchan->usrmsg structure to be wiped - and we still need those variables for further IAM processing */ + /* Go to up until release comes, note that state processing is done different and much simpler when there is a peer, + We can't go to UP state right away yet though, so do not set the state to UP here, wait until the end of this function + because moving from one state to another causes the ftdmchan->usrmsg structure to be wiped + and we still need those variables for further IAM processing */ native_going_up = FTDM_TRUE; } } } - if (sngss7_info->peer_data) { + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE) && 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 */ @@ -224,18 +224,17 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) &iam, 0); - if (native_going_up) { /* - Note that this function (ft_to_sngss7_iam) is run within the main SS7 processing loop in - response to the DIALING state handler, we can set the state to UP here and that will + Note that this function (ft_to_sngss7_iam) is run within the main SS7 processing loop in + response to the DIALING state handler, we can set the state to UP here and that will implicitly complete the DIALING state, but we *MUST* also advance the state handler right away for a native bridge, otherwise, the processing state function (ftdm_sangoma_ss7_process_state_change) will complete the state without having executed the handler for FTDM_CHANNEL_STATE_UP, and we won't notify the user sending FTDM_SIGEVENT_UP which can cause the application to misbehave (ie, no audio) */ ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); ftdm_channel_advance_states(ftdmchan); - } + } SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -267,15 +266,14 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) acm.bckCallInd.end2EndInfoInd.val = E2EINF_NOINFO; acm.bckCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF; - acm.bckCallInd.isdnUsrPrtInd.val = ISUP_NOTUSED; + acm.bckCallInd.isdnUsrPrtInd.val = ISUP_NOTUSED; backwardInd = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "acm_bi_iup"); if (!ftdm_strlen_zero(backwardInd)) { ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied backward indicator ISDN user part indicator ACM, value \"%s\"\n", backwardInd); if (atoi(backwardInd) != 0 ) { - acm.bckCallInd.isdnUsrPrtInd.val = ISUP_USED; + acm.bckCallInd.isdnUsrPrtInd.val = ISUP_USED; } } - acm.bckCallInd.holdInd.pres = PRSNT_NODEF; acm.bckCallInd.holdInd.val = HOLD_NOTREQD; acm.bckCallInd.isdnAccInd.pres = PRSNT_NODEF;