diff --git a/libs/openzap/mod_openzap/mod_openzap.c b/libs/openzap/mod_openzap/mod_openzap.c index 88c75c2d9d..ff5a564d51 100644 --- a/libs/openzap/mod_openzap/mod_openzap.c +++ b/libs/openzap/mod_openzap/mod_openzap.c @@ -817,50 +817,57 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session, tech_pvt = (private_t *) switch_core_session_get_private(session); assert(tech_pvt != NULL); - + assert(tech_pvt->zchan != NULL); + + zap_mutex_lock(tech_pvt->zchan->mutex); + if (tech_pvt->zchan->state == ZAP_CHANNEL_STATE_TERMINATING) { + zap_mutex_unlock(tech_pvt->zchan->mutex); + return SWITCH_STATUS_SUCCESS; + } + switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_RINGING: { if (switch_channel_test_flag(channel, CF_OUTBOUND)) { - zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS); + zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS); } else { - zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS); + zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS); } } break; case SWITCH_MESSAGE_INDICATE_PROGRESS: { if (switch_channel_test_flag(channel, CF_OUTBOUND)) { - zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS); - zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_MEDIA); + zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS); + zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_MEDIA); } else { /* Don't skip messages in the ISDN call setup * TODO: make the isdn stack smart enough to handle that itself * until then, this is here for safety... */ if (tech_pvt->zchan->state < ZAP_CHANNEL_STATE_PROGRESS) { - zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS); + zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS); } - zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS_MEDIA); + zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS_MEDIA); } } break; case SWITCH_MESSAGE_INDICATE_ANSWER: { if (switch_channel_test_flag(channel, CF_OUTBOUND)) { - zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED); + zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED); } else { /* Don't skip messages in the ISDN call setup * TODO: make the isdn stack smart enough to handle that itself * until then, this is here for safety... */ if (tech_pvt->zchan->state < ZAP_CHANNEL_STATE_PROGRESS) { - zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS); + zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS); } if (tech_pvt->zchan->state < ZAP_CHANNEL_STATE_PROGRESS_MEDIA) { - zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS_MEDIA); + zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS_MEDIA); } - zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_UP); + zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_UP); } } break; @@ -868,6 +875,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session, break; } + zap_mutex_unlock(tech_pvt->zchan->mutex); return SWITCH_STATUS_SUCCESS; } diff --git a/libs/openzap/src/include/openzap.h b/libs/openzap/src/include/openzap.h index 2c7d132b3b..cfbf065b06 100644 --- a/libs/openzap/src/include/openzap.h +++ b/libs/openzap/src/include/openzap.h @@ -268,6 +268,26 @@ /* The while(0) below throws a conditional expression is constant warning */ #pragma warning(disable:4127) #endif + +#define zap_wait_for_flag_cleared(obj, flag, time) \ + do { \ + int __safety = time; \ + while(__safety-- && zap_test_flag(obj, flag)) { \ + zap_mutex_unlock(obj->mutex); \ + zap_sleep(10); \ + zap_mutex_lock(obj->mutex); \ + } \ + if(!__safety) { \ + zap_log(ZAP_LOG_CRIT, "flag %d was never cleared\n", flag); \ + } \ + } while(0); + +#define zap_set_state_wait(obj, s) \ + do { \ + zap_channel_set_state(obj, s, 0); \ + zap_wait_for_flag_cleared(obj, ZAP_CHANNEL_STATE_CHANGE, 100); \ + } while(0); + #define zap_set_state_locked_wait(obj, s) \ do { \ int __safety = 100; \ @@ -280,16 +300,6 @@ } \ } while(0); -#define zap_locked_wait_for_flag_cleared(obj, flag, time) \ - do { \ - int __safety = time; \ - while(__safety-- && zap_test_flag(obj, flag)) { \ - zap_sleep(10); \ - } \ - if(!__safety) { \ - zap_log(ZAP_LOG_CRIT, "flag %d was never cleared\n", flag); \ - } \ - } while(0); typedef enum { diff --git a/libs/openzap/src/ozmod/ozmod_r2/ozmod_r2.c b/libs/openzap/src/ozmod/ozmod_r2/ozmod_r2.c index 9683aa57b2..f911e67d95 100644 --- a/libs/openzap/src/ozmod/ozmod_r2/ozmod_r2.c +++ b/libs/openzap/src/ozmod/ozmod_r2/ozmod_r2.c @@ -166,7 +166,7 @@ static ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) zap_mutex_lock(zchan->mutex); /* the channel may be down but the thread not quite done */ - zap_locked_wait_for_flag_cleared(zchan, ZAP_CHANNEL_INTHREAD, 200); + zap_wait_for_flag_cleared(zchan, ZAP_CHANNEL_INTHREAD, 200); if (zap_test_flag(zchan, ZAP_CHANNEL_INTHREAD)) { zap_log(ZAP_LOG_ERROR, "%d:%d Yay! R2 outgoing call in channel that is already in thread.\n", @@ -217,7 +217,7 @@ static void zap_r2_on_call_init(openr2_chan_t *r2chan) } /* the channel may be down but the thread not quite done */ - zap_locked_wait_for_flag_cleared(zchan, ZAP_CHANNEL_INTHREAD, 200); + zap_wait_for_flag_cleared(zchan, ZAP_CHANNEL_INTHREAD, 200); if (zap_test_flag(zchan, ZAP_CHANNEL_INTHREAD)) { zap_log(ZAP_LOG_ERROR, "Cannot handle request to start call in channel %d, already in thread!\n", diff --git a/libs/openzap/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c b/libs/openzap/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c index 892094126e..4c4caffb9b 100644 --- a/libs/openzap/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c +++ b/libs/openzap/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c @@ -372,9 +372,9 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request) while(zap_running() && OUTBOUND_REQUESTS[r].status == BST_ACK) { zap_sleep(1); if (--sanity <= 0) { - status = ZAP_FAIL; - *zchan = NULL; - goto done; + status = ZAP_FAIL; + *zchan = NULL; + goto done; } //printf("WTF %d\n", sanity); } @@ -625,9 +625,11 @@ static void handle_call_start_nack(zap_span_t *span, sangomabc_connection_t *mco if ((zchan = find_zchan(span, event, 1))) { int r = 0; assert(!zap_test_flag(zchan, ZAP_CHANNEL_OUTBOUND)); + + zchan->call_data = (void*)event->event_id; zap_mutex_lock(zchan->mutex); - zap_set_state_r(zchan, ZAP_CHANNEL_STATE_CANCEL, 0, r); + zap_set_state_r(zchan, ZAP_CHANNEL_STATE_TERMINATING, 0, r); if (r == ZAP_STATE_CHANGE_SUCCESS) { zchan->caller_data.hangup_cause = event->release_cause; } @@ -898,9 +900,7 @@ static int parse_sangoma_event(zap_span_t *span, sangomabc_connection_t *mcon, s } assert(event->call_setup_id <= MAX_REQ_ID); - switch(event->event_id) { - case SIGBOOST_EVENT_CALL_START: handle_call_start(span, mcon, (sangomabc_event_t*)event); break; @@ -992,14 +992,25 @@ static __inline__ void state_advance(zap_channel_t *zchan) if (!zap_test_sflag(zchan, SFLAG_SENT_FINAL_MSG)) { zap_set_sflag_locked(zchan, SFLAG_SENT_FINAL_MSG); - sangomabc_exec_command(mcon, - zchan->physical_span_id-1, - zchan->physical_chan_id-1, - 0, - SIGBOOST_EVENT_CALL_STOPPED_ACK, - 0); + if (zchan->call_data && ((uint32_t)zchan->call_data == SIGBOOST_EVENT_CALL_START_NACK)) { + sangomabc_exec_command(mcon, + zchan->physical_span_id-1, + zchan->physical_chan_id-1, + 0, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + 0); + + } else { + sangomabc_exec_command(mcon, + zchan->physical_span_id-1, + zchan->physical_chan_id-1, + 0, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + 0); + } } zchan->sflags = 0; + zchan->call_data = NULL; zap_channel_done(zchan); } break; @@ -1103,20 +1114,6 @@ static __inline__ void state_advance(zap_channel_t *zchan) } } break; - case ZAP_CHANNEL_STATE_CANCEL: - { - sig.event_id = ZAP_SIGEVENT_STOP; - status = sangoma_boost_data->signal_cb(&sig); - zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN); - zap_set_sflag_locked(zchan, SFLAG_SENT_FINAL_MSG); - sangomabc_exec_command(mcon, - zchan->physical_span_id-1, - zchan->physical_chan_id-1, - 0, - SIGBOOST_EVENT_CALL_START_NACK_ACK, - 0); - } - break; case ZAP_CHANNEL_STATE_TERMINATING: { sig.event_id = ZAP_SIGEVENT_STOP; @@ -1476,7 +1473,7 @@ static zap_state_map_t boost_state_map = { ZSD_INBOUND, ZSM_UNACCEPTABLE, {ZAP_CHANNEL_STATE_RING, ZAP_END}, - {ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_CANCEL, ZAP_CHANNEL_STATE_PROGRESS, ZAP_CHANNEL_STATE_PROGRESS_MEDIA, ZAP_END} + {ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_TERMINATING, ZAP_CHANNEL_STATE_PROGRESS, ZAP_CHANNEL_STATE_PROGRESS_MEDIA,ZAP_END} }, { ZSD_INBOUND, @@ -1487,14 +1484,14 @@ static zap_state_map_t boost_state_map = { { ZSD_INBOUND, ZSM_UNACCEPTABLE, - {ZAP_CHANNEL_STATE_CANCEL, ZAP_CHANNEL_STATE_HANGUP_COMPLETE, ZAP_CHANNEL_STATE_TERMINATING, ZAP_END}, + {ZAP_CHANNEL_STATE_HANGUP_COMPLETE, ZAP_CHANNEL_STATE_TERMINATING, ZAP_END}, {ZAP_CHANNEL_STATE_DOWN, ZAP_END}, }, { ZSD_INBOUND, ZSM_UNACCEPTABLE, {ZAP_CHANNEL_STATE_PROGRESS, ZAP_CHANNEL_STATE_PROGRESS_MEDIA, ZAP_END}, - {ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_CANCEL, ZAP_CHANNEL_STATE_TERMINATING, ZAP_CHANNEL_STATE_UP, ZAP_CHANNEL_STATE_PROGRESS_MEDIA, ZAP_END}, + {ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_TERMINATING, ZAP_CHANNEL_STATE_UP, ZAP_CHANNEL_STATE_PROGRESS_MEDIA, ZAP_END}, }, { ZSD_INBOUND,