From e9e0edb33f3df2028137b11e808d8016852ee88f Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 13 Jan 2010 17:53:22 +0000 Subject: [PATCH] merged revision 938:956 from openzap/trunk git-svn-id: http://svn.openzap.org/svn/openzap/branches/sangoma_boost@959 a93c3328-9c30-0410-af19-c9cd2b2d52af --- libs/freetdm/mod_openzap/mod_openzap.c | 30 ++++--- libs/freetdm/src/include/openzap.h | 27 ++++--- .../freetdm/src/ozmod/ozmod_isdn/ozmod_isdn.c | 7 ++ libs/freetdm/src/ozmod/ozmod_r2/ozmod_r2.c | 4 +- .../ozmod_sangoma_boost/ozmod_sangoma_boost.c | 81 +++++++++++-------- libs/freetdm/src/ozmod/ozmod_zt/ozmod_zt.h | 2 +- 6 files changed, 96 insertions(+), 55 deletions(-) diff --git a/libs/freetdm/mod_openzap/mod_openzap.c b/libs/freetdm/mod_openzap/mod_openzap.c index 9d8120d0fb..6d283eaf3f 100644 --- a/libs/freetdm/mod_openzap/mod_openzap.c +++ b/libs/freetdm/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/freetdm/src/include/openzap.h b/libs/freetdm/src/include/openzap.h index 15996fd64c..7281684afc 100644 --- a/libs/freetdm/src/include/openzap.h +++ b/libs/freetdm/src/include/openzap.h @@ -280,6 +280,7 @@ extern "C" { /* The while(0) below throws a conditional expression is constant warning */ #pragma warning(disable:4127) #endif + #define zap_set_state_locked_wait(obj, s) \ do { \ int __safety = 100; \ @@ -292,17 +293,31 @@ extern "C" { } \ } while(0); -#define zap_locked_wait_for_flag_cleared(obj, flag, time) \ +#define zap_wait_for_flag_cleared(obj, flag, time) \ do { \ int __safety = time; \ - while(__safety-- && zap_test_flag(obj, flag)) { \ + 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); \ + 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); + + +typedef enum { + ZAP_STATE_CHANGE_FAIL, + ZAP_STATE_CHANGE_SUCCESS, + ZAP_STATE_CHANGE_SAME, +} zap_state_change_result_t; #define zap_set_state_r(obj, s, l, r) if ( obj->state == s ) { \ zap_log(ZAP_LOG_WARNING, "Why bother changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, zap_channel_state2str(obj->state), zap_channel_state2str(s)); r = ZAP_STATE_CHANGE_SAME; \ @@ -324,12 +339,6 @@ extern "C" { */ #define zap_copy_flags(dest, src, flags) (dest)->flags &= ~(flags); (dest)->flags |= ((src)->flags & (flags)) -typedef enum { - ZAP_STATE_CHANGE_FAIL, - ZAP_STATE_CHANGE_SUCCESS, - ZAP_STATE_CHANGE_SAME, -} zap_state_change_result_t; - struct zap_stream_handle { zap_stream_handle_write_function_t write_function; zap_stream_handle_raw_write_function_t raw_write_function; diff --git a/libs/freetdm/src/ozmod/ozmod_isdn/ozmod_isdn.c b/libs/freetdm/src/ozmod/ozmod_isdn/ozmod_isdn.c index f703c86f93..d927610668 100644 --- a/libs/freetdm/src/ozmod/ozmod_isdn/ozmod_isdn.c +++ b/libs/freetdm/src/ozmod/ozmod_isdn/ozmod_isdn.c @@ -31,6 +31,13 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + * Workaround for missing u_int / u_short types on solaris + */ +#if defined(HAVE_LIBPCAP) && defined(__SunOS) +#define __EXTENSIONS__ +#endif + #include "openzap.h" #include "Q931.h" #include "Q921.h" diff --git a/libs/freetdm/src/ozmod/ozmod_r2/ozmod_r2.c b/libs/freetdm/src/ozmod/ozmod_r2/ozmod_r2.c index 8000aa2a64..acc2de62a1 100644 --- a/libs/freetdm/src/ozmod/ozmod_r2/ozmod_r2.c +++ b/libs/freetdm/src/ozmod/ozmod_r2/ozmod_r2.c @@ -165,7 +165,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", @@ -216,7 +216,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/freetdm/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c b/libs/freetdm/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c index 59f6f8ecdc..4d8581f806 100644 --- a/libs/freetdm/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c +++ b/libs/freetdm/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c @@ -222,7 +222,7 @@ static zap_channel_t *find_zchan(zap_span_t *span, sangomabc_short_event_t *even break; } else { zchan = NULL; - zap_log(ZAP_LOG_ERROR, "Channel %d:%d ~ %d:%d is already in use.\n", + zap_log(ZAP_LOG_DEBUG, "Channel %d:%d ~ %d:%d is already in use.\n", span->channels[i]->span_id, span->channels[i]->chan_id, span->channels[i]->physical_span_id, @@ -699,9 +699,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*)(intptr_t)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; } @@ -753,6 +755,7 @@ static void handle_call_stop(zap_span_t *span, sangomabc_connection_t *mcon, san 0, SIGBOOST_EVENT_CALL_STOPPED_ACK, 0); + zap_mutex_unlock(zchan->mutex); return; } else { zap_set_state_r(zchan, ZAP_CHANNEL_STATE_TERMINATING, 0, r); @@ -809,6 +812,8 @@ static void handle_call_answer(zap_span_t *span, sangomabc_connection_t *mcon, s } } +static __inline__ void advance_chan_states(zap_channel_t *zchan); + /** * \brief Handler for call start event * \param span Span where event was fired @@ -820,10 +825,19 @@ static void handle_call_start(zap_span_t *span, sangomabc_connection_t *mcon, sa zap_channel_t *zchan; if (!(zchan = find_zchan(span, (sangomabc_short_event_t*)event, 0))) { - goto error; + if (!(zchan = find_zchan(span, (sangomabc_short_event_t*)event, 1))) { + zap_log(ZAP_LOG_CRIT, "START CANT FIND CHAN %d:%d AT ALL\n", event->span+1,event->chan+1); + goto error; + } + advance_chan_states(zchan); + if (!(zchan = find_zchan(span, (sangomabc_short_event_t*)event, 0))) { + zap_log(ZAP_LOG_CRIT, "START CANT FIND CHAN %d:%d EVEN AFTER STATE ADVANCE\n", event->span+1,event->chan+1); + goto error; + } } if (zap_channel_open_chan(zchan) != ZAP_SUCCESS) { + zap_log(ZAP_LOG_CRIT, "START CANT OPEN CHAN %d:%d\n", event->span+1,event->chan+1); goto error; } @@ -866,9 +880,6 @@ static void handle_call_start(zap_span_t *span, sangomabc_connection_t *mcon, sa return; error: - - zap_log(ZAP_LOG_CRIT, "START CANT FIND A CHAN %d:%d\n", event->span,event->chan); - sangomabc_exec_command(mcon, event->span, event->chan, @@ -978,9 +989,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; @@ -990,7 +999,7 @@ static int parse_sangoma_event(zap_span_t *span, sangomabc_connection_t *mcon, s case SIGBOOST_EVENT_CALL_START_ACK: handle_call_start_ack(mcon, event); break; - case SIGBOOST_EVENT_CALL_PROGRESS: + case SIGBOOST_EVENT_CALL_PROGRESS: handle_call_progress(mcon, event); break; case SIGBOOST_EVENT_CALL_START_NACK: @@ -1072,14 +1081,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, - BOOST_SPAN(zchan), - BOOST_CHAN(zchan), - 0, - SIGBOOST_EVENT_CALL_STOPPED_ACK, - 0); + if (zchan->call_data && ((uint32_t)(intptr_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; @@ -1183,20 +1203,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, - BOOST_SPAN(zchan), - BOOST_CHAN(zchan), - 0, - SIGBOOST_EVENT_CALL_START_NACK_ACK, - 0); - } - break; case ZAP_CHANNEL_STATE_TERMINATING: { sig.event_id = ZAP_SIGEVENT_STOP; @@ -1208,6 +1214,17 @@ static __inline__ void state_advance(zap_channel_t *zchan) } } +static __inline__ void advance_chan_states(zap_channel_t *zchan) +{ + zap_mutex_lock(zchan->mutex); + while (zap_test_flag(zchan, ZAP_CHANNEL_STATE_CHANGE)) { + zap_clear_flag(zchan, ZAP_CHANNEL_STATE_CHANGE); + state_advance(zchan); + zap_channel_complete_state(zchan); + } + zap_mutex_unlock(zchan->mutex); +} + /** * \brief Initialises outgoing requests array */ @@ -1710,7 +1727,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, @@ -1721,14 +1738,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, diff --git a/libs/freetdm/src/ozmod/ozmod_zt/ozmod_zt.h b/libs/freetdm/src/ozmod/ozmod_zt/ozmod_zt.h index f82cf0ff10..687269a983 100644 --- a/libs/freetdm/src/ozmod/ozmod_zt/ozmod_zt.h +++ b/libs/freetdm/src/ozmod/ozmod_zt/ozmod_zt.h @@ -242,7 +242,7 @@ ZT_SIG_CLEAR = (1 << 7), ZT_SIG_HDLCRAW = ((1 << 8) | ZT_SIG_CLEAR), ZT_SIG_HDLCFCS = ((1 << 9) | ZT_SIG_HDLCRAW), ZT_SIG_CAS = (1 << 15), -ZT_SIG_HARDHDLC = (1 << 19), +ZT_SIG_HARDHDLC = ((1 << 19) | ZT_SIG_CLEAR), } zt_sigtype_t; typedef enum {