]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add reset state (make sure you do full rebuild)
authorAnthony Minessale <anthony.minessale@gmail.com>
Tue, 3 Jul 2007 02:10:35 +0000 (02:10 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Tue, 3 Jul 2007 02:10:35 +0000 (02:10 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5493 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_loadable_module.h
src/include/switch_module_interfaces.h
src/include/switch_types.h
src/switch_channel.c
src/switch_core_state_machine.c
src/switch_ivr_bridge.c
src/switch_ivr_play_say.c

index 3eb9dc309128e7aa2adac8560d6a8b0ffbaa51f8..2d2b1fde0b9372250162af69576e57a599f98831 100644 (file)
@@ -256,7 +256,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_unload_module(char *dir,
   \param filename the path to the module's dll or so file
   \return SWITCH_STATUS_SUCCESS on a successful load
 */
-SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename);
+SWITCH_MOD_DECLARE(switch_status_t) switch_module_load( switch_loadable_module_interface_t **module_interface, char *filename);
 SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void);
 
 /*!
index 10b91dff3c5ccf5f423057776d5d2a1f23cbd719..dcb314076fe1ee1fc58742a2bb76f65935d79389 100644 (file)
@@ -53,7 +53,8 @@ typedef enum {
        SWITCH_SHN_ON_LOOPBACK,
        SWITCH_SHN_ON_TRANSMIT,
        SWITCH_SHN_ON_HOLD,
-       SWITCH_SHN_ON_HIBERNATE
+       SWITCH_SHN_ON_HIBERNATE,
+       SWITCH_SHN_ON_RESET,
 } switch_state_handler_name_t;
 
 struct switch_state_handler_table {
@@ -73,6 +74,8 @@ struct switch_state_handler_table {
        switch_state_handler_t on_hold;
        /*! executed when the state changes to hibernate */
        switch_state_handler_t on_hibernate;
+       /*! executed when the state changes to reset */
+       switch_state_handler_t on_reset;
        void *padding[10];
 };
 
index 07c810927272a58049ba2d8cced43cc4efd6505d..bab55250b7903b6e0954790cfde1321ee339fe95 100644 (file)
@@ -527,6 +527,7 @@ CS_EXECUTE   - Channel is executing it's dialplan
 CS_LOOPBACK  - Channel is in loopback
 CS_HOLD                 - Channel is on hold
 CS_HIBERNATE - Channel is in a sleep state
+CS_RESET        - Channel is in a reset state
 CS_HANGUP    - Channel is flagged for hangup and ready to end
 CS_DONE      - Channel is ready to be destroyed and out of the state machine
 </pre>
@@ -540,6 +541,7 @@ typedef enum {
        CS_LOOPBACK,
        CS_HOLD,
        CS_HIBERNATE,
+       CS_RESET,
        CS_HANGUP,
        CS_DONE
 } switch_channel_state_t;
index b758430a53328461eafa3e012aa1b9508d87800b..b87bee64eaf752ad95d4b63814df05639c267fe2 100644 (file)
@@ -509,7 +509,8 @@ SWITCH_DECLARE(uint8_t) switch_channel_ready(switch_channel_t *channel)
 
        assert(channel != NULL);
        
-       if (!channel->hangup_cause && channel->state > CS_RING && channel->state < CS_HANGUP && !switch_test_flag(channel, CF_TRANSFER)) {
+       if (!channel->hangup_cause && channel->state > CS_RING && channel->state < CS_HANGUP && channel->state != CS_RESET && 
+               !switch_test_flag(channel, CF_TRANSFER)) {
                ret++;
        }
 
@@ -525,6 +526,7 @@ static const char *state_names[] = {
        "CS_LOOPBACK",
        "CS_HOLD",
        "CS_HIBERNATE",
+       "CS_RESET",
        "CS_HANGUP",
        "CS_DONE",
        NULL
@@ -589,6 +591,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c
 
        switch (last_state) {
        case CS_NEW:
+       case CS_RESET:
                switch (state) {
                default:
                        ok++;
@@ -604,6 +607,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c
                case CS_EXECUTE:
                case CS_HOLD:
                case CS_HIBERNATE:
+               case CS_RESET:
                        ok++;
                default:
                        break;
@@ -617,6 +621,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c
                case CS_EXECUTE:
                case CS_HOLD:
                case CS_HIBERNATE:
+               case CS_RESET:
                        ok++;
                default:
                        break;
@@ -630,6 +635,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c
                case CS_EXECUTE:
                case CS_HOLD:
                case CS_HIBERNATE:
+               case CS_RESET:
                        ok++;
                default:
                        break;
@@ -643,6 +649,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c
                case CS_EXECUTE:
                case CS_TRANSMIT:
                case CS_HIBERNATE:
+               case CS_RESET:
                        ok++;
                default:
                        break;
@@ -655,6 +662,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c
                case CS_EXECUTE:
                case CS_TRANSMIT:
                case CS_HOLD:
+               case CS_RESET:
                        ok++;
                default:
                        break;
@@ -669,6 +677,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c
                case CS_TRANSMIT:
                case CS_HOLD:
                case CS_HIBERNATE:
+               case CS_RESET:
                        ok++;
                default:
                        break;
@@ -682,6 +691,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c
                case CS_RING:
                case CS_HOLD:
                case CS_HIBERNATE:
+               case CS_RESET:
                        ok++;
                default:
                        break;
@@ -752,6 +762,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c
        if (channel->state_flags) {
                channel->flags |= channel->state_flags;
                channel->state_flags = 0;
+
        }
 
        switch_mutex_unlock(channel->flag_mutex);
index 2490f0ea2aaedbe9b705b6e9641b72097b1bb8ca..1608ea103fc692f7b2408338964443eae38a953f 100644 (file)
@@ -47,6 +47,14 @@ static void switch_core_standard_on_hangup(switch_core_session_t *session)
 
 }
 
+static void switch_core_standard_on_reset(switch_core_session_t *session)
+{
+
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Standard RESET %s\n",
+                                         switch_channel_get_name(session->channel));
+       
+}
+
 static void switch_core_standard_on_ring(switch_core_session_t *session)
 {
        switch_dialplan_interface_t *dialplan_interface = NULL;
@@ -433,6 +441,41 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
                                        }
                                }
                                break;
+                       case CS_RESET:          /* Look for a dialplan and find something to do */
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) State RESET\n", switch_channel_get_name(session->channel));
+                               if (!driver_state_handler->on_reset
+                                       || (driver_state_handler->on_reset && driver_state_handler->on_reset(session) == SWITCH_STATUS_SUCCESS
+                                               && midstate == switch_channel_get_state(session->channel))) {
+                                       while ((application_state_handler = switch_channel_get_state_handler(session->channel, index++)) != 0) {
+                                               if (!application_state_handler || !application_state_handler->on_reset
+                                                       || (application_state_handler->on_reset
+                                                               && application_state_handler->on_reset(session) == SWITCH_STATUS_SUCCESS
+                                                               && midstate == switch_channel_get_state(session->channel))) {
+                                                       proceed++;
+                                                       continue;
+                                               } else {
+                                                       proceed = 0;
+                                                       break;
+                                               }
+                                       }
+                                       index = 0;
+                                       while (proceed && (application_state_handler = switch_core_get_state_handler(index++)) != 0) {
+                                               if (!application_state_handler || !application_state_handler->on_reset ||
+                                                       (application_state_handler->on_reset &&
+                                                        application_state_handler->on_reset(session) == SWITCH_STATUS_SUCCESS
+                                                        && midstate == switch_channel_get_state(session->channel))) {
+                                                       proceed++;
+                                                       continue;
+                                               } else {
+                                                       proceed = 0;
+                                                       break;
+                                               }
+                                       }
+                                       if (proceed) {
+                                               switch_core_standard_on_reset(session);
+                                       }
+                               }
+                               break;
                        case CS_EXECUTE:        /* Execute an Operation */
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) State EXECUTE\n", switch_channel_get_name(session->channel));
                                if (!driver_state_handler->on_execute
index 710d0483dea1478580c880ba7ba0725741dcde7f..4b988c99653efb44d319f281351a04632e17cdc2 100644 (file)
@@ -262,11 +262,27 @@ static const switch_state_handler_table_t audio_bridge_peer_state_handlers = {
 };
 
 
+static switch_status_t uuid_bridge_on_reset(switch_core_session_t *session)
+{
+       switch_channel_t *channel = NULL;
+
+       channel = switch_core_session_get_channel(session);
+    assert(channel != NULL);
+
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CUSTOM RESET\n");
+
+       if (switch_channel_test_flag(channel, CF_ORIGINATOR)) {
+               switch_channel_set_state(channel, CS_TRANSMIT);
+       }
+
+       return SWITCH_STATUS_SUCCESS;
+}
 
 static switch_status_t uuid_bridge_on_transmit(switch_core_session_t *session)
 {
        switch_channel_t *channel = NULL;
        switch_core_session_t *other_session;
+       char *other_uuid = NULL;
 
        channel = switch_core_session_get_channel(session);
        assert(channel != NULL);
@@ -274,13 +290,13 @@ static switch_status_t uuid_bridge_on_transmit(switch_core_session_t *session)
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CUSTOM TRANSMIT\n");
        switch_channel_clear_state_handler(channel, NULL);
 
-       switch_channel_set_flag(channel, CF_BREAK);
-
        if (!switch_channel_test_flag(channel, CF_ORIGINATOR)) {
+               switch_channel_set_flag(channel, CF_TAGGED);
                return SWITCH_STATUS_FALSE;
        }
-
-       if ((other_session = switch_channel_get_private(channel, SWITCH_UUID_BRIDGE))) {
+       
+       if ((other_uuid = switch_channel_get_variable(channel, SWITCH_UUID_BRIDGE)) && 
+               (other_session = switch_core_session_locate(other_uuid))) {
                switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
                switch_channel_state_t state = switch_channel_get_state(other_channel);
                switch_channel_state_t mystate = switch_channel_get_state(channel);
@@ -288,20 +304,19 @@ static switch_status_t uuid_bridge_on_transmit(switch_core_session_t *session)
                uint8_t ready_a, ready_b;
                switch_caller_profile_t *profile, *new_profile;
 
-
-               switch_channel_clear_flag(channel, CF_TRANSFER);
-               switch_channel_set_private(channel, SWITCH_UUID_BRIDGE, NULL);
-
-               while (mystate <= CS_HANGUP && state <= CS_HANGUP && !switch_channel_test_flag(other_channel, CF_TAGGED)) {
+               switch_channel_set_variable(channel, SWITCH_UUID_BRIDGE, NULL);
+               switch_channel_set_state(other_channel, CS_TRANSMIT);
+               for(;;) {
+                       if (mystate >= CS_HANGUP || state >= CS_HANGUP || switch_channel_test_flag(other_channel, CF_TAGGED)) {
+                               break;
+                       }
                        switch_yield(1000);
                        state = switch_channel_get_state(other_channel);
                        mystate = switch_channel_get_state(channel);
                }
-
+               switch_channel_clear_flag(channel, CF_TRANSFER);
                switch_channel_clear_flag(other_channel, CF_TRANSFER);
                switch_channel_clear_flag(other_channel, CF_TAGGED);
-
-
                switch_core_session_reset(session);
                switch_core_session_reset(other_session);
 
@@ -316,6 +331,7 @@ static switch_status_t uuid_bridge_on_transmit(switch_core_session_t *session)
                        if (!ready_b) {
                                switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
                        }
+                       switch_core_session_rwunlock(other_session);
                        return SWITCH_STATUS_FALSE;
                }
 
@@ -348,6 +364,7 @@ static switch_status_t uuid_bridge_on_transmit(switch_core_session_t *session)
                }
 
                switch_ivr_multi_threaded_bridge(session, other_session, NULL, NULL, NULL);
+               switch_core_session_rwunlock(other_session);
        } else {
                switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
        }
@@ -364,7 +381,9 @@ static const switch_state_handler_table_t uuid_bridge_state_handlers = {
        /*.on_hangup */ NULL,
        /*.on_loopback */ NULL,
        /*.on_transmit */ uuid_bridge_on_transmit,
-       /*.on_hold */ NULL
+       /*.on_hold */ NULL,
+       /*.on_hibernate*/ NULL,
+       /*.on_reset*/ uuid_bridge_on_reset
 };
 
 static switch_status_t signal_bridge_on_hibernate(switch_core_session_t *session)
@@ -654,29 +673,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(char *originator_uuid, ch
                        switch_channel_set_flag(originator_channel, CF_ORIGINATOR);
                        switch_channel_add_state_handler(originator_channel, &uuid_bridge_state_handlers);
                        switch_channel_add_state_handler(originatee_channel, &uuid_bridge_state_handlers);
-                       switch_channel_set_flag(originatee_channel, CF_TAGGED);
-                       switch_channel_set_private(originator_channel, SWITCH_UUID_BRIDGE, originatee_session);
-
+                       switch_channel_set_variable(originator_channel, SWITCH_UUID_BRIDGE, switch_core_session_get_uuid(originatee_session));
+                       
                        switch_channel_set_flag(originator_channel, CF_BREAK);
                        switch_channel_set_flag(originatee_channel, CF_BREAK);
                        
-                       /* switch_channel_set_state_flag sets flags you want to be set when the next state change happens */
-                       switch_channel_set_state_flag(originator_channel, CF_TRANSFER);
-                       switch_channel_set_state_flag(originatee_channel, CF_TRANSFER);
-
                        /* change the states and let the chips fall where they may */
-                       switch_channel_set_state(originator_channel, CS_TRANSMIT);
-                       switch_channel_set_state(originatee_channel, CS_TRANSMIT);
+                       switch_channel_set_state(originator_channel, CS_RESET);
+                       switch_channel_set_state(originatee_channel, CS_RESET);
+
+                       status = SWITCH_STATUS_SUCCESS;
 
                        /* release the read locks we have on the channels */
                        switch_core_session_rwunlock(originator_session);
                        switch_core_session_rwunlock(originatee_session);
 
-                       status = SWITCH_STATUS_SUCCESS;
-
-                       while (switch_channel_get_state(originatee_channel) < CS_HANGUP && switch_channel_test_flag(originatee_channel, CF_TAGGED)) {
-                               switch_yield(20000);
-                       }
                } else {
                        switch_core_session_rwunlock(originator_session);
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "no channel for originatee uuid %s\n", originatee_uuid);
index 963e31eed4e47c60425ecb2536c9fda6f214ebd3..5ee4b61ee9cb6c16266e526151b6c0fbf2c0e1aa 100644 (file)
@@ -394,7 +394,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
 
        for(;;) {
                switch_size_t len;
-
+               
                if (!switch_channel_ready(channel)) {
                        status = SWITCH_STATUS_FALSE;
                        break;
@@ -547,7 +547,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi
 
        for(;;) {
                switch_status_t status = switch_core_session_read_frame(session, &read_frame, 1000, 0);
-               
+
                if (!switch_channel_ready(channel)) {
             status = SWITCH_STATUS_FALSE;
             break;
@@ -556,6 +556,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi
 
                if (switch_channel_test_flag(channel, CF_BREAK)) {
                        switch_channel_clear_flag(channel, CF_BREAK);
+                       status = SWITCH_STATUS_BREAK;
                        break;
                }
 
@@ -799,13 +800,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
 
        ilen = samples;
 
-       while (switch_channel_ready(channel)) {
+       for(;;) {
                int done = 0;
                int do_speed = 1;
                int last_speed = -1;
 
+               //printf("xxxxxxxxxxxWTF %d %d %d\n", switch_channel_get_state(channel), switch_channel_ready(channel), switch_channel_test_flag(channel, CF_TRANSFER));
+               
+               if (!switch_channel_ready(channel)) {
+            status = SWITCH_STATUS_FALSE;
+            break;
+        }
+
                if (switch_channel_test_flag(channel, CF_BREAK)) {
                        switch_channel_clear_flag(channel, CF_BREAK);
+                       status = SWITCH_STATUS_BREAK;
                        break;
                }
 
@@ -1176,11 +1185,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
        }
 
        ilen = len;
-       while (switch_channel_ready(channel)) {
+       for(;;) {
                switch_event_t *event;
 
+               if (!switch_channel_ready(channel)) {
+            status = SWITCH_STATUS_FALSE;
+            break;
+        }
+
                if (switch_channel_test_flag(channel, CF_BREAK)) {
                        switch_channel_clear_flag(channel, CF_BREAK);
+                       status = SWITCH_STATUS_BREAK;
                        break;
                }