From: David Yat Sin Date: Thu, 15 Apr 2010 15:54:32 +0000 (-0400) Subject: Merge root@192.168.1.163:/freeswitch X-Git-Tag: git2svn-syncpoint-master~209^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c4f821f822a3e815889f17c90b6dbc7b50cdd24d;p=thirdparty%2Ffreeswitch.git Merge root@192.168.1.163:/freeswitch Conflicts: libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c --- c4f821f822a3e815889f17c90b6dbc7b50cdd24d diff --cc libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c index 0870985aa4,f7f1aac7ad..c950798b09 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c @@@ -215,10 -237,32 +240,26 @@@ static ftdm_channel_t *find_ftdmchan(ft { uint32_t i; ftdm_channel_t *ftdmchan = NULL; - ftdm_sangoma_boost_data_t *sangoma_boost_data; - uint32_t targetspan = event->span+1; - uint32_t targetchan = event->chan+1; ++ + ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; + uint32_t targetspan = BOOST_EVENT_SPAN(sangoma_boost_data->sigmod, event); + uint32_t targetchan = BOOST_EVENT_CHAN(sangoma_boost_data->sigmod, event); + /* NC: Sanity check in case the call setup id does not relate + to span. This can happen if RESTART is received on a + full load. Where stray ACK messages can arrive after + a RESTART has taken place. + */ + if (!span) { + ftdm_log(FTDM_LOG_CRIT, "No Span for Event=%s s%dc%d cid=%d\n", + BOOST_DECODE_EVENT_ID(event->event_id), + event->span, + event->chan, + event->call_setup_id); + return NULL; + } + - sangoma_boost_data = span->signal_data; - - if (sangoma_boost_data->sigmod) { - /* span is not strictly needed here since we're supposed to get only events for our span */ - targetspan = event->span; - targetchan = event->chan; - } + for(i = 1; i <= span->chan_count; i++) { if (span->channels[i]->physical_span_id == targetspan && span->channels[i]->physical_chan_id == targetchan) { ftdmchan = span->channels[i]; @@@ -547,10 -606,15 +603,15 @@@ static void handle_call_start_ack(sango { ftdm_channel_t *ftdmchan = NULL; - uint32_t event_span = event->span+1; - uint32_t event_chan = event->chan+1; + uint32_t event_span = BOOST_EVENT_SPAN(mcon->sigmod, event); + uint32_t event_chan = BOOST_EVENT_CHAN(mcon->sigmod, event); + if (nack_map[event->call_setup_id]) { + /* In this scenario outgoing call was alrady stopped + via NACK and now we are expecting an NACK_ACK. + If we receive an ACK its a race condition thus + ignor it */ return; } @@@ -607,10 -676,37 +668,37 @@@ OUTBOUND_REQUESTS[event->call_setup_id].status = BST_READY; return; } - } + } else { + + ftdm_assert(!mcon->sigmod, "CALL STOP ACK: Invalid Sigmod Path"); + + if ((ftdmchan = find_ftdmchan(OUTBOUND_REQUESTS[event->call_setup_id].span, (sangomabc_short_event_t*)event, 1))) { + int r; + /* NC: If we get CALL START ACK and channel is in active state + then we are completely out of sync with the other end. + Treat CALL START ACK as CALL STOP and hangup the current call. + */ + + if (ftdmchan->state == FTDM_CHANNEL_STATE_UP || + ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA || + ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS) { + ftdm_log(FTDM_LOG_CRIT, "FTDM_CHAN STATE UP/PROG/PROG_MEDIA -> Changed to HANGUP %d:%d\n", event->span+1,event->chan+1); + ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP, 0, r); + + } else if (ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) { + /* Do nothing because outgoing STOP will generaate a stop ack */ + + } else { + ftdm_log(FTDM_LOG_CRIT, "FTDM_CHAN STATE INVALID %s on IN CALL ACK %d:%d\n", ftdm_channel_state2str(ftdmchan->state),event->span+1,event->chan+1); + + } + ftdmchan=NULL; + } + } + if (!ftdmchan) { - ftdm_log(FTDM_LOG_CRIT, "START ACK CANT FIND A CHAN %d:%d\n", event->span+1,event->chan+1); + ftdm_log(FTDM_LOG_CRIT, "START ACK CANT FIND A CHAN %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); } else { /* only reason to be here is failed to open channel when we we're in sigmod */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); @@@ -881,13 -998,21 +990,19 @@@ static void handle_call_start(ftdm_span if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 0))) { if ((ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 1))) { int r; + + /* NC: If we get CALL START and channel is in active state + then we are completely out of sync with the other end. + Treat CALL START as CALL STOP and hangup the current call. + */ + if (ftdmchan->state == FTDM_CHANNEL_STATE_UP) { - ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE UP -> Changed to TERMINATING %d:%d\n", event->span+1,event->chan+1); + ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE UP -> Changed to TERMINATING %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, 0, r); } else if (ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) { - ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE HANGUP -> Changed to HANGUP COMPLETE %d:%d\n", event->span+1,event->chan+1); - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, 0, r); + ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE HANGUP -> Changed to HANGUP COMPLETE %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, 0, r); } else { - ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE INVALID %s on IN CALL %d:%d\n", ftdm_channel_state2str(ftdmchan->state),event->span+1,event->chan+1); - + ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE INVALID %s on IN CALL %d:%d\n", ftdm_channel_state2str(ftdmchan->state),BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); } ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG); ftdmchan = NULL;