From d7a12df53faa188ba586b448e41e6ae84bbc40bf Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 4 Mar 2009 04:19:33 +0000 Subject: [PATCH] add new state for CDR and leg_delay_start originate var and fix FSCORE-315 git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@12403 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_module_interfaces.h | 5 ++- src/include/switch_types.h | 19 ++++++----- .../event_handlers/mod_cdr_csv/mod_cdr_csv.c | 11 +++++-- .../mod_radius_cdr/mod_radius_cdr.c | 13 +++++--- src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c | 11 +++++-- src/switch_channel.c | 17 +++++++++- src/switch_core_state_machine.c | 33 +++++++++++++++---- src/switch_ivr_originate.c | 29 ++++++++++++---- 8 files changed, 104 insertions(+), 34 deletions(-) diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 3e8c72fb84..17536c4966 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -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]; }; diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 87a193913f..79055d309e 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -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)
-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
 
*/ @@ -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; diff --git a/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c b/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c index 0c549fb2b8..237800186f 100644 --- a/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c +++ b/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c @@ -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 }; diff --git a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c b/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c index 3b7f1769cb..985a0ff09b 100644 --- a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c +++ b/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c @@ -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) diff --git a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c index 3e87bdcbc0..529d8523ac 100644 --- a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c +++ b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c @@ -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) diff --git a/src/switch_channel.c b/src/switch_channel.c index b671d0ecb6..010f42d739 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -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; } diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index f675c8313a..56f7c3b225 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -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; diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 806fd6d37e..f09b385861 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -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);