]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
merged revision 938:956 from openzap/trunk
authorMoises Silva <moy@sangoma.com>
Wed, 13 Jan 2010 17:53:22 +0000 (17:53 +0000)
committerMoises Silva <moy@sangoma.com>
Wed, 13 Jan 2010 17:53:22 +0000 (17:53 +0000)
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
libs/freetdm/src/include/openzap.h
libs/freetdm/src/ozmod/ozmod_isdn/ozmod_isdn.c
libs/freetdm/src/ozmod/ozmod_r2/ozmod_r2.c
libs/freetdm/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c
libs/freetdm/src/ozmod/ozmod_zt/ozmod_zt.h

index 9d8120d0fbcf019595eb642fd6ecbaa5deac844e..6d283eaf3f7351f06e2bb815da1e589f51713f57 100644 (file)
@@ -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;
 }
 
index 15996fd64cea9461709112c9a823b8a5d1240715..7281684afc70f41910f5f232b13a09a6ab51d3c6 100644 (file)
@@ -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;
index f703c86f93837c1a334187b97cba2744360170d0..d927610668143f2ea5c3b85e8f2a315c4d5679dd 100644 (file)
  * 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"
index 8000aa2a6431800d97debf0c25122148c0dc08b5..acc2de62a1a2a4b659099e308d927c94637d04c9 100644 (file)
@@ -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", 
index 59f6f8ecdc0de8dbe04e3de1d352821cb04c3ed8..4d8581f8069585735c04a6cd37083025d3c76571 100644 (file)
@@ -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,
index f82cf0ff1080e0bd716cb2a6d31734206ca8e093..687269a98329d7277a2cf84b3ba3a4e4b9e2e50a 100644 (file)
@@ -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 {