From 495db48f5a15e5499c3527d8fb2b48c6eb295e15 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 31 May 2014 00:30:59 +0500 Subject: [PATCH] make device state code more accurate --- src/include/switch_core.h | 3 ++ src/include/switch_types.h | 3 +- src/switch_channel.c | 65 ++++++++++++++++++++------------- src/switch_core_io.c | 6 +++ src/switch_core_state_machine.c | 7 +++- 5 files changed, 56 insertions(+), 28 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 22780dd4ac..e38a8ae003 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -100,6 +100,9 @@ typedef struct switch_device_stats_s { uint32_t held; uint32_t held_in; uint32_t held_out; + uint32_t unheld; + uint32_t unheld_in; + uint32_t unheld_out; uint32_t hup; uint32_t hup_in; uint32_t hup_out; diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 18a829055b..d7f5bc747e 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1184,7 +1184,7 @@ typedef enum { CCS_HELD, CCS_RING_WAIT, CCS_HANGUP, - CCS_UNHOLD + CCS_UNHELD } switch_channel_callstate_t; typedef enum { @@ -1193,6 +1193,7 @@ typedef enum { SDS_ACTIVE, SDS_ACTIVE_MULTI, SDS_HELD, + SDS_UNHELD, SDS_HANGUP } switch_device_state_t; diff --git a/src/switch_channel.c b/src/switch_channel.c index 7220cb8ac6..df391b9336 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -243,7 +243,7 @@ static struct switch_callstate_table CALLSTATE_CHART[] = { {"HELD", CCS_HELD}, {"RING_WAIT", CCS_RING_WAIT}, {"HANGUP", CCS_HANGUP}, - {"UNHOLD", CCS_UNHOLD}, + {"UNHELD", CCS_UNHELD}, {NULL, 0} }; @@ -257,6 +257,7 @@ static struct switch_device_state_table DEVICE_STATE_CHART[] = { {"ACTIVE", SDS_ACTIVE}, {"ACTIVE_MULTI", SDS_ACTIVE_MULTI}, {"HELD", SDS_HELD}, + {"UNHELD", SDS_UNHELD}, {"HANGUP", SDS_HANGUP}, {NULL, 0} }; @@ -268,7 +269,7 @@ SWITCH_DECLARE(void) switch_channel_perform_set_callstate(switch_channel_t *chan switch_event_t *event; switch_channel_callstate_t o_callstate = channel->callstate; - if (o_callstate == callstate) return; + if (o_callstate == callstate || o_callstate == CCS_HANGUP) return; channel->callstate = callstate; if (channel->device_node) { @@ -278,9 +279,7 @@ SWITCH_DECLARE(void) switch_channel_perform_set_callstate(switch_channel_t *chan "(%s) Callstate Change %s -> %s\n", channel->name, switch_channel_callstate2str(o_callstate), switch_channel_callstate2str(callstate)); - if (callstate != CCS_HANGUP) { - switch_channel_check_device_state(channel, channel->callstate); - } + switch_channel_check_device_state(channel, channel->callstate); if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_CALLSTATE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Original-Channel-Call-State", switch_channel_callstate2str(o_callstate)); @@ -1959,7 +1958,7 @@ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch } if (ACTIVE) { - switch_channel_set_callstate(channel, CCS_UNHOLD); + switch_channel_set_callstate(channel, CCS_UNHELD); switch_mutex_lock(channel->profile_mutex); if (channel->caller_profile->times->last_hold) { channel->caller_profile->times->hold_accum += (switch_time_now() - channel->caller_profile->times->last_hold); @@ -1969,8 +1968,11 @@ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch channel->hold_record->off = switch_time_now(); } + if (switch_channel_test_flag(channel, CF_PROXY_MODE) && switch_channel_test_flag(channel, CF_BRIDGED)) { + switch_channel_set_callstate(channel, CCS_ACTIVE); + } + switch_mutex_unlock(channel->profile_mutex); - switch_channel_set_callstate(channel, CCS_ACTIVE); } if (flag == CF_ORIGINATOR && switch_channel_test_flag(channel, CF_ANSWERED) && switch_channel_up_nosig(channel)) { @@ -4722,6 +4724,13 @@ static void fetch_device_stats(switch_device_record_t *drec) } else { drec->stats.held_out++; } + } else if (np->callstate == CCS_UNHELD) { + drec->stats.unheld++; + if (np->direction == SWITCH_CALL_DIRECTION_INBOUND) { + drec->stats.unheld_in++; + } else { + drec->stats.unheld_out++; + } } else { if (np->callstate == CCS_EARLY) { drec->stats.early++; @@ -4906,23 +4915,27 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ fetch_device_stats(drec); - if (drec->stats.offhook == 0) { - drec->state = SDS_HANGUP; - } else { - if (drec->stats.active == 0) { - if ((drec->stats.ringing_out + drec->stats.early_out) > 0 || drec->stats.ring_wait > 0) { - drec->state = SDS_RINGING; - } else { - if (drec->stats.held > 0) { - drec->state = SDS_HELD; - } else { - drec->state = SDS_DOWN; - } - } - } else if (drec->stats.active == 1) { - drec->state = SDS_ACTIVE; + if (drec->state != SDS_HANGUP) { + if (drec->stats.offhook == 0 || drec->stats.hup == drec->stats.total) { + drec->state = SDS_HANGUP; } else { - drec->state = SDS_ACTIVE_MULTI; + if (drec->stats.active == 0) { + if ((drec->stats.ringing_out + drec->stats.early_out) > 0 || drec->stats.ring_wait > 0) { + drec->state = SDS_RINGING; + } else { + if (drec->stats.held > 0) { + drec->state = SDS_HELD; + } else if (drec->stats.unheld > 0) { + drec->state = SDS_UNHELD; + } else { + drec->state = SDS_DOWN; + } + } + } else if (drec->stats.active == 1) { + drec->state = SDS_ACTIVE; + } else { + drec->state = SDS_ACTIVE_MULTI; + } } } @@ -4960,7 +4973,7 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ break; } - if (drec->active_start && drec->state != SDS_ACTIVE && drec->state != SDS_ACTIVE_MULTI) { + if (callstate != CCS_UNHELD && drec->active_start && drec->state != SDS_ACTIVE && drec->state != SDS_ACTIVE_MULTI) { drec->active_stop = switch_micro_time_now(); } @@ -4984,6 +4997,7 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-Early", "%u", drec->stats.early); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-Active", "%u", drec->stats.active); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-Held", "%u", drec->stats.held); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-UnHeld", "%u", drec->stats.unheld); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-Hup", "%u", drec->stats.hup); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Talk-Time-Start-Uepoch", "%"SWITCH_TIME_T_FMT, drec->active_start); if (drec->active_stop) { @@ -4994,7 +5008,7 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "%s device: %s\nState: %s Dev State: %s/%s Total:%u Offhook:%u " - "Ringing:%u Early:%u Active:%u Held:%u Hungup:%u Dur: %u Ringtime: %u Holdtime: %u %s\n", + "Ringing:%u Early:%u Active:%u Held:%u Unheld:%u Hungup:%u Dur: %u Ringtime: %u Holdtime: %u %s\n", switch_channel_get_name(channel), drec->device_id, switch_channel_callstate2str(callstate), @@ -5006,6 +5020,7 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ drec->stats.early, drec->stats.active, drec->stats.held, + drec->stats.unheld, drec->stats.hup, drec->active_stop ? (uint32_t)(drec->active_stop - drec->active_start) / 1000 : 0, drec->ring_stop ? (uint32_t)(drec->ring_stop - drec->ring_start) / 1000 : 0, diff --git a/src/switch_core_io.c b/src/switch_core_io.c index fcd51d5b04..eb294a6773 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -973,6 +973,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_mutex_unlock(session->read_codec->mutex); switch_mutex_unlock(session->codec_read_mutex); + + if (status == SWITCH_STATUS_SUCCESS && switch_channel_get_callstate(session->channel) == CCS_UNHELD) { + switch_channel_set_callstate(session->channel, CCS_ACTIVE); + } + + return status; } diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index c37d66b35d..91fe8f7a3d 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -355,8 +355,11 @@ void switch_core_state_machine_init(switch_memory_pool_t *pool) #define STATE_MACRO(__STATE, __STATE_STR) do { \ midstate = state; \ - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) State %s\n", switch_channel_get_name(session->channel), __STATE_STR); \ - switch_core_session_refresh_video(session);\ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) State %s\n", switch_channel_get_name(session->channel), __STATE_STR); \ + if (state < CS_HANGUP && switch_channel_get_callstate(session->channel) == CCS_UNHELD) { \ + switch_channel_set_callstate(session->channel, CCS_ACTIVE); \ + } \ + switch_core_session_refresh_video(session); \ if (!driver_state_handler->on_##__STATE || (driver_state_handler->on_##__STATE(session) == SWITCH_STATUS_SUCCESS \ )) { \ while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler(session->channel, index++)) != 0) { \