]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
fix races in bypass media regarding channel signalling that may cause answer to be...
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 19 Aug 2011 21:25:26 +0000 (16:25 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 19 Aug 2011 21:25:32 +0000 (16:25 -0500)
src/include/switch_core.h
src/include/switch_ivr.h
src/mod/endpoints/mod_sofia/sofia.c
src/switch_channel.c
src/switch_core_session.c
src/switch_core_state_machine.c
src/switch_ivr.c
src/switch_ivr_originate.c

index 61d89bfcd093b907ca78f3cd5cde6e13ee72f0c2..8d4a0cd1221dbc9d28964d3c036c7ef23145863f 100644 (file)
@@ -687,7 +687,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_thread_launch(_In_ switch_co
 /*! 
   \brief Signal a session's state machine thread that a state change has occured
 */
-SWITCH_DECLARE(void) switch_core_session_wake_session_thread(_In_ switch_core_session_t *session);
+SWITCH_DECLARE(switch_status_t) switch_core_session_wake_session_thread(_In_ switch_core_session_t *session);
 SWITCH_DECLARE(void) switch_core_session_signal_state_change(_In_ switch_core_session_t *session);
 
 /*! 
index 76ce54242960679ce0732bdb562c4f19fa256c2d..5ce8c882d2d08ef18031cacf7a16bbef4cd3e365 100644 (file)
@@ -111,6 +111,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_events(switch_core_session_
 SWITCH_DECLARE(switch_status_t) switch_ivr_parse_next_event(switch_core_session_t *session);
 SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_messages(switch_core_session_t *session);
 SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_signal_data(switch_core_session_t *session);
+SWITCH_DECLARE(switch_status_t) switch_ivr_process_indications(switch_core_session_t *session, switch_core_session_message_t *message);
+
 /*!
   \brief Wait for time to pass for a specified number of milliseconds
   \param session the session to wait for.
index 6b119b62d13b47e51649000771683a7428d5a1fc..2475a5cc0bad270acce5af787b670e0b7e0707c5 100644 (file)
@@ -1257,9 +1257,7 @@ void sofia_event_callback(nua_event_t event,
 
                if (!zstr(sofia_private->uuid)) {
                        if ((session = switch_core_session_locate(sofia_private->uuid))) {
-                               switch_channel_t *channel = switch_core_session_get_channel(session);
-
-                               if (switch_core_session_running(session) && !switch_channel_test_flag(channel, CF_PROXY_MODE)) {
+                               if (switch_core_session_running(session)) {
                                        switch_core_session_queue_signal_data(session, de);
                                } else {
                                        switch_core_session_message_t msg = { 0 };
index 0a6071105fef78090273369ea234903cdc568df9..755f140513e870fb318e242e72f45ba4208513c0 100644 (file)
@@ -2885,6 +2885,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_
                        switch_channel_set_flag(channel, CF_PASSTHRU_PTIME_MISMATCH);
                }
 
+
                /* if we're the child of another channel and the other channel is in a blocking read they will never realize we have answered so send 
                   a SWITCH_SIG_BREAK to interrupt any blocking reads on that channel
                 */
index 28ef9fd96a79c058f76b0cf5435db6e8831bc3a1..70f7e55f6161ce1e279d782356fa8006788ba839 100644 (file)
@@ -832,9 +832,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_flush_message(switch_core_se
 
        switch_assert(session != NULL);
 
+
        if (session->message_queue) {
                while ((status = (switch_status_t) switch_queue_trypop(session->message_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
                        message = (switch_core_session_message_t *) pop;
+                       switch_ivr_process_indications(session, message);
                        switch_core_session_free_message(&message);
                }
        }
@@ -1124,14 +1126,20 @@ SWITCH_DECLARE(switch_channel_t *) switch_core_session_get_channel(switch_core_s
        return session->channel;
 }
 
-SWITCH_DECLARE(void) switch_core_session_wake_session_thread(switch_core_session_t *session)
+SWITCH_DECLARE(switch_status_t) switch_core_session_wake_session_thread(switch_core_session_t *session)
 {
+       switch_status_t status;
+
        /* If trylock fails the signal is already awake so we needn't bother */
 
-       if (switch_mutex_trylock(session->mutex) == SWITCH_STATUS_SUCCESS) {
+       status = switch_mutex_trylock(session->mutex);
+
+       if (status == SWITCH_STATUS_SUCCESS) {
                switch_thread_cond_signal(session->cond);
                switch_mutex_unlock(session->mutex);
        }
+
+       return status;
 }
 
 SWITCH_DECLARE(void) switch_core_session_signal_state_change(switch_core_session_t *session)
index 1ab9af91a9297d182c0467a5bc7497625dff66be..1bb97aa03daf6c3f2d0d1b388377a948ea3d527b 100644 (file)
@@ -422,13 +422,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
                                        switch_channel_hangup(session->channel, SWITCH_CAUSE_INVALID_CALL_REFERENCE);
                                }
                        } else {
-                               switch_core_session_message_t *message;
-
-                               while (switch_core_session_dequeue_message(session, &message) == SWITCH_STATUS_SUCCESS) {
-                                       switch_core_session_receive_message(session, message);
-                                       message = NULL;
-                               }
-
+                               switch_ivr_parse_all_events(session);
                                switch_ivr_parse_all_events(session);
 
                                if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) {
@@ -440,11 +434,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
                                }
 
                                switch_ivr_parse_all_events(session);
-
-                               while (switch_core_session_dequeue_message(session, &message) == SWITCH_STATUS_SUCCESS) {
-                                       switch_core_session_receive_message(session, message);
-                                       message = NULL;
-                               }
+                               switch_ivr_parse_all_events(session);
                        }
                }
        }
index 0989cbc4d4e6e4a4d0284bc37b3a1e5611ca23bb..575dc477010dc08b86b0180dca1508fd8fd4d476 100644 (file)
@@ -668,43 +668,51 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_next_event(switch_core_session_
 
 }
 
-SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_messages(switch_core_session_t *session)
+SWITCH_DECLARE(switch_status_t) switch_ivr_process_indications(switch_core_session_t *session, switch_core_session_message_t *message)
 {
-       switch_core_session_message_t *message;
+       switch_status_t status = SWITCH_STATUS_SUCCESS;
        switch_channel_t *channel = switch_core_session_get_channel(session);
-       int i = 0;
-
-       switch_ivr_parse_all_signal_data(session);
-
-       while (switch_core_session_dequeue_message(session, &message) == SWITCH_STATUS_SUCCESS) {
-               i++;
                
                switch(message->message_id) {
                case SWITCH_MESSAGE_INDICATE_ANSWER:
                        if (switch_channel_answer(channel) != SWITCH_STATUS_SUCCESS) {
                                switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
                        }
-                       switch_core_session_free_message(&message);
                        break;
                case SWITCH_MESSAGE_INDICATE_PROGRESS:
                        if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
                                switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
                        }
-                       switch_core_session_free_message(&message);
                        break;
                case SWITCH_MESSAGE_INDICATE_RINGING:
                        if (switch_channel_ring_ready(channel) != SWITCH_STATUS_SUCCESS) {
                                switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
                        }
-                       switch_core_session_free_message(&message);
                        break;
                default:
-                       switch_core_session_receive_message(session, message);
+               status = SWITCH_STATUS_FALSE;
                        break;
                }
 
-               message = NULL;
+       return status;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_messages(switch_core_session_t *session)
+{
+       switch_core_session_message_t *message;
+       int i = 0;
+
+       switch_ivr_parse_all_signal_data(session);
 
+       while (switch_core_session_dequeue_message(session, &message) == SWITCH_STATUS_SUCCESS) {
+               i++;
+
+               if (switch_ivr_process_indications(session, message) == SWITCH_STATUS_SUCCESS) {
+                       switch_core_session_free_message(&message);
+               } else {
+                       switch_core_session_receive_message(session, message);
+                       message = NULL;
+               }
        }
 
        return i ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
index 9ab1c1b1daa5f0edbda6114cbdbc945f3d122b29..91bd1420f0b800036acc36ff7cbeedf1b90453e3 100644 (file)
@@ -1030,6 +1030,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_answer(switch_core_session_t
                switch_buffer_destroy(&ringback.audio_buffer);
        }
 
+       
+       switch_ivr_parse_all_events(session);
+       
        switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
 
        if (switch_core_codec_ready(&write_codec)) {
@@ -3162,9 +3165,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                        if (caller_channel) {
                                if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
                                        switch_channel_pass_callee_id(peer_channel, caller_channel);
+                                       if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
+                                               status = SWITCH_STATUS_SUCCESS;
+                                       } else {
                                        status = switch_channel_answer(caller_channel);
+                                       }
                                } else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
+                                       if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
+                                               status = SWITCH_STATUS_SUCCESS;
+                                       } else {
                                        status = switch_channel_pre_answer(caller_channel);
+                                       }
                                } else {
                                        status = SWITCH_STATUS_SUCCESS;
                                }
@@ -3462,6 +3473,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                switch_ivr_sleep(*bleg, 0, SWITCH_TRUE, NULL);
        }
 
+       if (oglobals.session) {
+               switch_ivr_parse_all_events(oglobals.session);
+       }
+
        if (oglobals.session && status == SWITCH_STATUS_SUCCESS) {
                switch_ivr_sleep(oglobals.session, 0, SWITCH_TRUE, NULL);
        }