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
This commit is contained in:
Anthony Minessale 2009-03-04 04:19:33 +00:00
parent 1908898362
commit d7a12df53f
8 changed files with 104 additions and 34 deletions

View 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];
};

View 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;

View 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
};

View 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)

View 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)

View 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;
}

View 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;

View 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);