]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add new state for CDR and leg_delay_start originate var and fix FSCORE-315
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 4 Mar 2009 04:19:33 +0000 (04:19 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 4 Mar 2009 04:19:33 +0000 (04:19 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@12403 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_module_interfaces.h
src/include/switch_types.h
src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c
src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c
src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c
src/switch_channel.c
src/switch_core_state_machine.c
src/switch_ivr_originate.c

index 3e8c72fb8482af013d9e0591546eae12d5569435..17536c4966f46ca237e117d6c582a6f6d738e5a2 100644 (file)
@@ -55,7 +55,8 @@ typedef enum {
        SWITCH_SHN_ON_CONSUME_MEDIA,
        SWITCH_SHN_ON_HIBERNATE,
        SWITCH_SHN_ON_RESET,
-       SWITCH_SHN_ON_PARK
+       SWITCH_SHN_ON_PARK,
+       SWITCH_SHN_ON_REPORTING
 } switch_state_handler_name_t;
 
 struct switch_state_handler_table {
@@ -79,6 +80,8 @@ struct switch_state_handler_table {
        switch_state_handler_t on_reset;
        /*! executed when the state changes to park */
        switch_state_handler_t on_park;
+       /*! executed when the state changes to reporting */
+       switch_state_handler_t on_reporting;
        void *padding[10];
 };
 
index 87a193913f71a72ea8450907261f02938b97a1c0..79055d309e7a37078bd1d5a8d06778183a7fccf2 100644 (file)
@@ -753,17 +753,18 @@ typedef uint32_t switch_core_session_message_flag_t;
   \enum switch_channel_state_t
   \brief Channel States (these are the defaults, CS_SOFT_EXECUTE, CS_EXCHANGE_MEDIA, and CS_CONSUME_MEDIA are often overridden by specific apps)
 <pre>
-CS_NEW       - Channel is newly created 
-CS_INIT      - Channel has been initilized
-CS_ROUTING   - Channel is looking for an extension to execute
-CS_SOFT_EXECUTE  - Channel is ready to execute from 3rd party control
-CS_EXECUTE   - Channel is executing it's dialplan 
+CS_NEW       - Channel is newly created.
+CS_INIT      - Channel has been initilized.
+CS_ROUTING   - Channel is looking for an extension to execute.
+CS_SOFT_EXECUTE  - Channel is ready to execute from 3rd party control.
+CS_EXECUTE   - Channel is executing it's dialplan.
 CS_EXCHANGE_MEDIA  - Channel is exchanging media with another channel.
 CS_PARK      - Channel is accepting media awaiting commands.
 CS_CONSUME_MEDIA                - Channel is consuming all media and dropping it.
-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_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_HANGUP    - Channel is ready to collect call detail.
 CS_DONE      - Channel is ready to be destroyed and out of the state machine
 </pre>
  */
@@ -779,6 +780,7 @@ typedef enum {
        CS_HIBERNATE,
        CS_RESET,
        CS_HANGUP,
+       CS_REPORTING,
        CS_DONE,
        CS_NONE
 } switch_channel_state_t;
@@ -851,6 +853,7 @@ typedef enum {
        CF_VERBOSE_EVENTS,
        CF_PAUSE_BUGS,
        CF_DIVERT_EVENTS,
+       CF_BLOCK_STATE,
        /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
        CF_FLAG_MAX
 } switch_channel_flag_t;
index 0c549fb2b8fece07bbabc44986fe96dc696142dc..237800186faf9e1913bb4aee086af388a0bfaf11 100644 (file)
@@ -165,7 +165,7 @@ static void write_cdr(const char *path, const char *log_line)
        switch_mutex_unlock(fd->mutex);
 }
 
-static switch_status_t my_on_hangup(switch_core_session_t *session)
+static switch_status_t my_on_reporting(switch_core_session_t *session)
 {
        switch_channel_t *channel = switch_core_session_get_channel(session);
        switch_status_t status = SWITCH_STATUS_SUCCESS;
@@ -286,9 +286,14 @@ static switch_state_handler_table_t state_handlers = {
        /*.on_init */ NULL,
        /*.on_routing */ NULL,
        /*.on_execute */ NULL,
-       /*.on_hangup */ my_on_hangup,
+       /*.on_hangup */ NULL,
        /*.on_exchange_media */ NULL,
-       /*.on_soft_execute */ NULL
+       /*.on_soft_execute */ NULL,
+       /*.on_consume_media*/ NULL,
+       /*.on_hibernate*/ NULL,
+       /*.on_reset*/ NULL,
+       /*.on_park*/ NULL,
+       /*.on_reporting*/ my_on_reporting
 };
 
 
index 3b7f1769cbb40fc91b4805e08845af068130587f..985a0ff09bcb4811ed9e5d3698a3e1d4cf926ea0 100644 (file)
@@ -371,7 +371,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session)
        return (retval);
 }
 
-static switch_status_t my_on_hangup(switch_core_session_t *session)
+static switch_status_t my_on_reporting(switch_core_session_t *session)
 {
        switch_xml_t cdr;
        switch_channel_t *channel = switch_core_session_get_channel(session);
@@ -406,7 +406,7 @@ static switch_status_t my_on_hangup(switch_core_session_t *session)
 
        switch_thread_rwlock_rdlock(globals.rwlock);
 
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[mod_radius_cdr] Entering my_on_hangup\n");
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[mod_radius_cdr] Entering my_on_reporting\n");
 
        rad_config = my_radius_init();
 
@@ -705,9 +705,14 @@ static const switch_state_handler_table_t state_handlers = {
        /*.on_init */ NULL,
        /*.on_routing */ my_on_routing,
        /*.on_execute */ NULL,
-       /*.on_hangup */ my_on_hangup,
+       /*.on_hangup */ NULL,
        /*.on_exchange_media */ NULL,
-       /*.on_soft_execute */ NULL
+       /*.on_soft_execute */ NULL,
+       /*.on_consume_media*/ NULL,
+       /*.on_hibernate*/ NULL,
+       /*.on_reset*/ NULL,
+       /*.on_park*/ NULL,
+       /*.on_reporting*/ my_on_reporting
 };
 
 SWITCH_MODULE_LOAD_FUNCTION(mod_radius_cdr_load)
index 3e87bdcbc082aa46ab0b69b489d298e57f7748ee..529d8523ac394291f083430a183dbcd6b9bf3c07 100644 (file)
@@ -66,7 +66,7 @@ static size_t httpCallBack(char *buffer, size_t size, size_t nitems, void *outst
        return size * nitems;
 }
 
-static switch_status_t my_on_hangup(switch_core_session_t *session)
+static switch_status_t my_on_reporting(switch_core_session_t *session)
 {
        switch_xml_t cdr;
        char *xml_text = NULL;
@@ -264,9 +264,14 @@ static switch_state_handler_table_t state_handlers = {
        /*.on_init */ NULL,
        /*.on_routing */ NULL,
        /*.on_execute */ NULL,
-       /*.on_hangup */ my_on_hangup,
+       /*.on_hangup */ NULL,
        /*.on_exchange_media */ NULL,
-       /*.on_soft_execute */ NULL
+       /*.on_soft_execute */ NULL,
+       /*.on_consume_media*/ NULL,
+       /*.on_hibernate*/ NULL,
+       /*.on_reset*/ NULL,
+       /*.on_park*/ NULL,
+       /*.on_reporting*/ my_on_reporting
 };
 
 SWITCH_MODULE_LOAD_FUNCTION(mod_xml_cdr_load)
index b671d0ecb6337d9157418ce1124c82630df1ebb7..010f42d73998a9e14459a7929abf7003b116702f 100644 (file)
@@ -767,7 +767,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_wait_for_flag(switch_channel_t *c
                        return SWITCH_STATUS_FALSE;
                }
 
-               if (!switch_channel_ready(channel)) {
+               if (switch_channel_down(channel)) {
                        return SWITCH_STATUS_FALSE;
                }
 
@@ -925,6 +925,7 @@ static const char *state_names[] = {
        "CS_HIBERNATE",
        "CS_RESET",
        "CS_HANGUP",
+       "CS_REPORTING",
        "CS_DONE",
        NULL
 };
@@ -1176,6 +1177,16 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c
                break;
 
        case CS_HANGUP:
+               switch (state) {
+               case CS_REPORTING:
+               case CS_DONE:
+                       ok++;
+               default:
+                       break;
+               }
+               break;
+
+       case CS_REPORTING:
                switch (state) {
                case CS_DONE:
                        ok++;
@@ -1573,6 +1584,9 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_hangup(switch_chan
                                                                                                                                         const char *file, const char *func, int line, switch_call_cause_t hangup_cause)
 {
        switch_assert(channel != NULL);
+
+       switch_channel_clear_flag(channel, CF_BLOCK_STATE);
+
        switch_mutex_lock(channel->state_mutex);
 
        if (channel->caller_profile && channel->caller_profile->times && !channel->caller_profile->times->hungup) {
@@ -1609,6 +1623,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_hangup(switch_chan
        }
 
        switch_mutex_unlock(channel->state_mutex);
+
        return channel->state;
 }
 
index f675c8313a7106b134d16f51060047843c278b76..56f7c3b225396ba5d17fc1c4467562321a5dc707 100644 (file)
@@ -47,6 +47,13 @@ static void switch_core_standard_on_hangup(switch_core_session_t *session)
                                          switch_channel_get_name(session->channel), switch_channel_cause2str(switch_channel_get_cause(session->channel)));
 }
 
+static void switch_core_standard_on_reporting(switch_core_session_t *session)
+{
+
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Standard REPORTING, cause: %s\n",
+                                         switch_channel_get_name(session->channel), switch_channel_cause2str(switch_channel_get_cause(session->channel)));
+}
+
 static void switch_core_standard_on_reset(switch_core_session_t *session)
 {
 
@@ -373,28 +380,29 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
        switch_mutex_lock(session->mutex);
 
        while ((state = switch_channel_get_state(session->channel)) != CS_DONE) {
+
+               switch_channel_wait_for_flag(session->channel, CF_BLOCK_STATE, SWITCH_FALSE, 0, NULL);
+               
                midstate = state;
-               if (state != switch_channel_get_running_state(session->channel) || state == CS_HANGUP) {
+               if (state != switch_channel_get_running_state(session->channel) || state >= CS_HANGUP) {
                        int index = 0;
                        int proceed = 1;
                        int global_proceed = 1;
                        int do_extra_handlers = 1;
-
+                       
                        switch_channel_set_running_state(session->channel, state);
                        switch_channel_clear_flag(session->channel, CF_TRANSFER);
                        switch_channel_clear_flag(session->channel, CF_REDIRECT);
 
                        switch (state) {
-                       case CS_NEW:            /* Just created, Waiting for first instructions */
+                       case CS_NEW: /* Just created, Waiting for first instructions */
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) State NEW\n", switch_channel_get_name(session->channel));
                                break;
                        case CS_DONE:
                                goto done;
-                       case CS_HANGUP: /* Deactivate and end the thread */
+                       case CS_REPORTING: /* Call Detail */
                                {
                                        const char *var = switch_channel_get_variable(session->channel, SWITCH_PROCESS_CDR_VARIABLE);
-                                       const char *hook_var;
-                                       switch_core_session_t *use_session = NULL;
                                        
                                        if (!switch_strlen_zero(var)) {
                                                if (!strcasecmp(var, "a_only")) {
@@ -410,6 +418,16 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
                                                }
                                        }
 
+                                       STATE_MACRO(reporting, "REPORTING");
+                                       
+                                       switch_channel_set_state(session->channel, CS_DONE);
+                               }
+                               goto done;
+                       case CS_HANGUP: /* Deactivate and end the thread */
+                               {
+                                       const char *hook_var;
+                                       switch_core_session_t *use_session = NULL;
+                                       
                                        switch_core_media_bug_remove_all(session);
                                        
                                        STATE_MACRO(hangup, "HANGUP");
@@ -448,7 +466,8 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
                                                switch_safe_free(stream.data);
                                        }
                                }
-                               goto done;
+                               switch_channel_set_state(session->channel, CS_REPORTING);
+                               break;
                        case CS_INIT:           /* Basic setup tasks */
                                STATE_MACRO(init, "INIT");
                                break;
index 806fd6d37e70e26fc6890be8e5b2d3a4ed398b8f..f09b385861b64477f0a1fb59500b108b853f0478 100644 (file)
@@ -86,6 +86,7 @@ typedef struct {
        uint8_t answered;
        uint32_t per_channel_timelimit_sec;
        uint32_t per_channel_progress_timelimit_sec;
+       uint32_t per_channel_delay_start;
 } originate_status_t;
 
 
@@ -177,7 +178,7 @@ static void *SWITCH_THREAD_FUNC collect_thread_run(switch_thread_t *thread, void
                goto wbreak;
        }
 
-       if (!switch_channel_ready(channel)) {
+       if (switch_channel_up(channel)) {
                switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
                goto wbreak;
        }
@@ -228,6 +229,11 @@ static int check_per_channel_timeouts(originate_global_t *oglobals,
        time_t elapsed = switch_epoch_time_now(NULL) - start;
 
        for (i = 0; i < max; i++) {
+               if (originate_status[i].peer_channel && originate_status[i].per_channel_delay_start && elapsed > originate_status[i].per_channel_delay_start) {
+                       switch_channel_clear_flag(originate_status[i].peer_channel, CF_BLOCK_STATE);
+                       originate_status[i].per_channel_delay_start = 0;
+               }
+
                if (originate_status[i].peer_channel && switch_channel_up(originate_status[i].peer_channel)) {
                        if (originate_status[i].per_channel_progress_timelimit_sec && elapsed > originate_status[i].per_channel_progress_timelimit_sec &&
                                !(
@@ -1493,6 +1499,15 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                                                        originate_status[i].per_channel_progress_timelimit_sec = (uint32_t) val;
                                                }
                                        }
+
+                                       if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "leg_delay_start"))) {
+                                               int val = atoi(vvar);
+                                               if (val > 0) {
+                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Setting leg delay start to %d\n", 
+                                                                                         switch_channel_get_name(originate_status[0].peer_channel), val);
+                                                       originate_status[i].per_channel_delay_start = (uint32_t) val;
+                                               }
+                                       }
                                }
 
                                if (!table) {
@@ -1511,11 +1526,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                                }
 
                                if (!switch_core_session_running(originate_status[i].peer_session)) {
-                                       /*if (!(flags & SOF_NOBLOCK)) {
-                                         switch_channel_set_state(originate_status[i].peer_channel, CS_ROUTING);
-                                         }
-                                         } else {
-                                       */
+                                       if (originate_status[i].per_channel_delay_start) {
+                                               switch_channel_set_flag(originate_status[i].peer_channel, CF_BLOCK_STATE);
+                                       }
                                        switch_core_session_thread_launch(originate_status[i].peer_session);
                                }
                        }
@@ -1842,6 +1855,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                                        continue;
                                }
 
+                               switch_channel_clear_flag(originate_status[i].peer_channel, CF_BLOCK_STATE);
+
                                if (switch_channel_test_flag(originate_status[i].peer_channel, CF_TRANSFER) 
                                        || switch_channel_test_flag(originate_status[i].peer_channel, CF_REDIRECT) 
                                        || switch_channel_test_flag(originate_status[i].peer_channel, CF_BRIDGED) ||
@@ -1867,7 +1882,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                                                        }
                                                }
                                        }
-                                       if (switch_channel_ready(originate_status[i].peer_channel)) {
+                                       if (switch_channel_up(originate_status[i].peer_channel)) {
                                                if (caller_channel && i == 0) {
                                                        holding = switch_channel_get_variable(caller_channel, SWITCH_HOLDING_UUID_VARIABLE);
                                                        holding = switch_core_session_strdup(oglobals.session, holding);