make device state code more accurate

This commit is contained in:
Anthony Minessale 2014-05-31 00:30:59 +05:00
parent 79a888de2c
commit 495db48f5a
5 changed files with 56 additions and 28 deletions

View File

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

View File

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

View File

@ -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,

View File

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

View File

@ -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) { \