{
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];
{
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);
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;