]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Merge root@192.168.1.163:/freeswitch
authorDavid Yat Sin <dyatsin@sangoma.com>
Thu, 15 Apr 2010 15:54:32 +0000 (11:54 -0400)
committerDavid Yat Sin <dyatsin@sangoma.com>
Thu, 15 Apr 2010 15:54:32 +0000 (11:54 -0400)
Conflicts:

libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c

1  2 
libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c

index 0870985aa461a9294b5006be13ccb8a0c281888d,f7f1aac7ad882c6f0512e392a6d7a34b9844fae9..c950798b09a8ccc6ff8ea9c726eef1478c9b9c9f
@@@ -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);
  
 -      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;
 -      }
+       /* 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;
+       }
        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;
        }
  
                        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;