]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
make device state code more accurate
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 30 May 2014 19:30:59 +0000 (00:30 +0500)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 30 May 2014 19:34:28 +0000 (00:34 +0500)
Conflicts:
src/switch_core_state_machine.c

src/include/switch_core.h
src/include/switch_types.h
src/switch_channel.c
src/switch_core_io.c
src/switch_core_state_machine.c

index 6ebfc82ed44e2d98a654f28822e2ec20aa7611f8..afd91897706bb0fc144c7d3d279609707ad57d71 100644 (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;
index e213800dd73d173a5b10188e13352d75838009a8..125a35607143c0d9ae0efe996bcfd32ad068daf8 100644 (file)
@@ -1120,7 +1120,7 @@ typedef enum {
        CCS_HELD,
        CCS_RING_WAIT,
        CCS_HANGUP,
-       CCS_UNHOLD
+       CCS_UNHELD
 } switch_channel_callstate_t;
 
 typedef enum {
@@ -1129,6 +1129,7 @@ typedef enum {
        SDS_ACTIVE,
        SDS_ACTIVE_MULTI,
        SDS_HELD,
+       SDS_UNHELD,
        SDS_HANGUP
 } switch_device_state_t;
 
index 7dbb1843cbe3753db215f3ead3b8a3109e47d5f5..5ad2ae08e61165c0522dd3b954f1c5f182e0bc7c 100644 (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));
@@ -1949,7 +1948,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);
@@ -1959,8 +1958,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)) {
@@ -4697,6 +4699,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++;
@@ -4881,23 +4890,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;
+       if (drec->state != SDS_HANGUP) {
+               if (drec->stats.offhook == 0 || drec->stats.hup == drec->stats.total) {
+                       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 {
-                                       drec->state = SDS_DOWN;
+                                       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;
                        }
-               } else if (drec->stats.active == 1) {
-                       drec->state = SDS_ACTIVE;
-               } else {
-                       drec->state = SDS_ACTIVE_MULTI;
                }
        }
 
@@ -4935,7 +4948,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();
        }
 
@@ -4959,6 +4972,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) {
@@ -4969,7 +4983,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),
@@ -4981,6 +4995,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,
index 9fd70a8c16910e8d33996b10e149cecccfb2cc24..b34163c3eb04b633bde40daf0cd4a739df4d06b1 100644 (file)
@@ -918,6 +918,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;
 }
 
index 16fc3a3d8ccd0c26f1670ed612bb1eed23846eae..143abf26029246d527f8fee744e09f039e1e7a87 100644 (file)
@@ -304,7 +304,10 @@ 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_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);     \
+               }                                                                                                                               \
                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) { \