]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add new callstate field to channels table
authorAnthony Minessale <anthm@freeswitch.org>
Sat, 5 Jun 2010 00:03:36 +0000 (19:03 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Sat, 5 Jun 2010 00:03:36 +0000 (19:03 -0500)
src/include/switch_channel.h
src/include/switch_types.h
src/mod/endpoints/mod_sofia/sofia_glue.c
src/switch_channel.c
src/switch_core_sqldb.c

index 775bf91e92c9e568c8308fa242f694b0e051829d..58b38312f203b1baf4510a9753eb99b4aef1ed22 100644 (file)
@@ -560,6 +560,12 @@ SWITCH_DECLARE(char *) switch_channel_get_flag_string(switch_channel_t *channel)
 SWITCH_DECLARE(char *) switch_channel_get_cap_string(switch_channel_t *channel);
 SWITCH_DECLARE(int) switch_channel_state_change_pending(switch_channel_t *channel);
 
+SWITCH_DECLARE(void) switch_channel_set_callstate(switch_channel_t *channel, switch_channel_callstate_t callstate);
+SWITCH_DECLARE(switch_channel_callstate_t) switch_channel_get_callstate(switch_channel_t *channel);
+SWITCH_DECLARE(const char *) switch_channel_callstate2str(switch_channel_callstate_t callstate);
+SWITCH_DECLARE(switch_call_cause_t) switch_channel_str2callstate(const char *str);
+SWITCH_DECLARE(void) switch_channel_mark_hold(switch_channel_t *channel, switch_bool_t on);
+
 /** @} */
 
 SWITCH_END_EXTERN_C
index 55cd26c148db83e8a8549bd810758363e2f04a63..02f21a04d370b24c3986ec2c2641b52de7d7e2d8 100644 (file)
@@ -875,6 +875,16 @@ typedef uint32_t switch_core_session_message_flag_t;
 #define SWITCH_CHANNEL_CHANNEL_LOG(x) SWITCH_CHANNEL_ID_SESSION, __FILE__, __SWITCH_FUNC__, __LINE__, (const char*)switch_channel_get_session(x)
 #define SWITCH_CHANNEL_UUID_LOG(x) SWITCH_CHANNEL_ID_LOG, __FILE__, __SWITCH_FUNC__, __LINE__, (x)
 
+typedef enum {
+       CCS_DOWN,
+       CCS_DIALING,
+       CCS_RINGING,
+       CCS_EARLY,
+       CCS_ACTIVE,
+       CCS_HELD,
+       CCS_HANGUP
+} switch_channel_callstate_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)
@@ -1337,6 +1347,8 @@ typedef enum {
        SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE,
        SWITCH_EVENT_CHANNEL_EXECUTE,
        SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE,
+       SWITCH_EVENT_CHANNEL_HOLD,
+       SWITCH_EVENT_CHANNEL_UNHOLD,
        SWITCH_EVENT_CHANNEL_BRIDGE,
        SWITCH_EVENT_CHANNEL_UNBRIDGE,
        SWITCH_EVENT_CHANNEL_PROGRESS,
index 0a65752bba778ba66f275d10ab4689d31f1d71c4..002687884bc660c732214f8fea6dda73c7ae37b2 100644 (file)
@@ -3323,6 +3323,7 @@ void sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly)
 
                        sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
                        switch_channel_set_flag(tech_pvt->channel, CF_LEG_HOLDING);
+                       switch_channel_mark_hold(tech_pvt->channel, SWITCH_TRUE);
                        switch_channel_presence(tech_pvt->channel, "unknown", msg, NULL);
 
                        if (tech_pvt->max_missed_hold_packets) {
@@ -3349,6 +3350,7 @@ void sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly)
                if (sofia_test_flag(tech_pvt, TFLAG_HOLD_LOCK)) {
                        sofia_set_flag(tech_pvt, TFLAG_SIP_HOLD);
                        switch_channel_set_flag(tech_pvt->channel, CF_LEG_HOLDING);
+                       switch_channel_mark_hold(tech_pvt->channel, SWITCH_TRUE);
                }
 
                sofia_clear_flag_locked(tech_pvt, TFLAG_HOLD_LOCK);
@@ -3380,6 +3382,7 @@ void sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly)
 
                        sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
                        switch_channel_clear_flag(tech_pvt->channel, CF_LEG_HOLDING);
+                       switch_channel_mark_hold(tech_pvt->channel, SWITCH_FALSE);
                        switch_channel_presence(tech_pvt->channel, "unknown", "unhold", NULL);
                }
        }
index 2b34c6bd72afd8993a79e36d95ba7a45e25bee4a..49dd06d054c491906e18728ea8501694700f361a 100644 (file)
@@ -122,6 +122,7 @@ struct switch_channel {
        switch_core_session_t *session;
        switch_channel_state_t state;
        switch_channel_state_t running_state;
+       switch_channel_callstate_t callstate;
        uint32_t flags[CF_FLAG_MAX];
        uint32_t caps[CC_FLAG_MAX];
        uint8_t state_flags[CF_FLAG_MAX];
@@ -139,6 +140,7 @@ struct switch_channel {
        opaque_channel_flag_t opaque_flags;
 };
 
+
 SWITCH_DECLARE(const char *) switch_channel_cause2str(switch_call_cause_t cause)
 {
        uint8_t x;
@@ -178,6 +180,68 @@ SWITCH_DECLARE(switch_call_cause_t) switch_channel_get_cause(switch_channel_t *c
 }
 
 
+struct switch_callstate_table {
+       const char *name;
+       switch_channel_callstate_t callstate;
+};
+static struct switch_callstate_table STATE_CHART[] = {
+    {"DOWN", CCS_DOWN},
+    {"DIALING", CCS_DIALING},
+    {"RINGING", CCS_RINGING},
+    {"EARLY", CCS_EARLY},
+    {"ACTIVE", CCS_ACTIVE},
+    {"HELD", CCS_HELD},
+    {"HANGUP", CCS_HANGUP},
+    {NULL, 0}
+};
+
+
+SWITCH_DECLARE(void) switch_channel_set_callstate(switch_channel_t *channel, switch_channel_callstate_t callstate)
+{
+       channel->callstate = callstate;
+}
+
+SWITCH_DECLARE(switch_channel_callstate_t) switch_channel_get_callstate(switch_channel_t *channel)
+{
+       return channel->callstate;
+}
+
+
+SWITCH_DECLARE(const char *) switch_channel_callstate2str(switch_channel_callstate_t callstate)
+{
+       uint8_t x;
+       const char *str = "UNKNOWN";
+
+       for (x = 0; x < (sizeof(STATE_CHART) / sizeof(struct switch_cause_table)) - 1; x++) {
+               if (STATE_CHART[x].callstate == callstate) {
+                       str = STATE_CHART[x].name;
+                       break;
+               }
+       }
+
+       return str;
+}
+
+SWITCH_DECLARE(switch_call_cause_t) switch_channel_str2callstate(const char *str)
+{
+       uint8_t x;
+       switch_channel_callstate_t callstate = SWITCH_CAUSE_NONE;
+
+       if (*str > 47 && *str < 58) {
+               callstate = atoi(str);
+       } else {
+               for (x = 0; x < (sizeof(STATE_CHART) / sizeof(struct switch_callstate_table)) - 1 && STATE_CHART[x].name; x++) {
+                       if (!strcasecmp(STATE_CHART[x].name, str)) {
+                               callstate = STATE_CHART[x].callstate;
+                               break;
+                       }
+               }
+       }
+       return callstate;
+}
+
+
+
 SWITCH_DECLARE(void) switch_channel_perform_audio_sync(switch_channel_t *channel, const char *file, const char *func, int line)
 {
        if (switch_channel_media_ready(channel)) {
@@ -537,6 +601,23 @@ SWITCH_DECLARE(void) switch_channel_presence(switch_channel_t *channel, const ch
        }
 }
 
+SWITCH_DECLARE(void) switch_channel_mark_hold(switch_channel_t *channel, switch_bool_t on)
+{
+       switch_event_t *event;
+
+       if (on) {
+               switch_channel_set_flag(channel, CF_LEG_HOLDING);
+       } else {
+               switch_channel_clear_flag(channel, CF_LEG_HOLDING);
+       }
+
+       if (switch_event_create(&event, on ? SWITCH_EVENT_CHANNEL_HOLD : SWITCH_EVENT_CHANNEL_UNHOLD) == SWITCH_STATUS_SUCCESS) {
+               switch_channel_event_set_data(channel, event);
+               switch_event_fire(&event);
+       }
+
+}
+
 SWITCH_DECLARE(const char *) switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup)
 {
        const char *v = NULL, *r = NULL;
@@ -1134,6 +1215,12 @@ SWITCH_DECLARE(void) switch_channel_set_flag_value(switch_channel_t *channel, sw
        if (flag == CF_OUTBOUND) {
                switch_channel_set_variable(channel, "is_outbound", "true");
        }
+
+       if (flag == CF_LEG_HOLDING) {
+               switch_channel_set_callstate(channel, CCS_HELD);
+       }
+
+
 }
 
 SWITCH_DECLARE(void) switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
@@ -1221,6 +1308,10 @@ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch
        if (flag == CF_OUTBOUND) {
                switch_channel_set_variable(channel, "is_outbound", NULL);
        }
+
+       if (flag == CF_LEG_HOLDING) {
+               switch_channel_set_callstate(channel, CCS_ACTIVE);
+       }
 }
 
 
@@ -1357,11 +1448,21 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(
 
        if (state <= CS_DESTROY) {
                switch_event_t *event;
+
+               if (state == CS_ROUTING) {
+                       switch_channel_set_callstate(channel, CCS_RINGING);
+               } else if (switch_channel_test_flag(channel, CF_ANSWERED)) {
+                       switch_channel_set_callstate(channel, CCS_ACTIVE);
+               } else if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
+                       switch_channel_set_callstate(channel, CCS_EARLY);
+               }
+
                if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_STATE) == SWITCH_STATUS_SUCCESS) {
                        if (state == CS_ROUTING) {
                                switch_channel_event_set_data(channel, event);
                        } else {
                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", switch_channel_state_name(state));
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-State", switch_channel_callstate2str(channel->callstate));
                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-State-Number", "%d", state);
                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Name", channel->name);
                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(channel->session));
@@ -1622,6 +1723,7 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann
        }
 
        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", switch_channel_state_name(channel->state));
+       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-State", switch_channel_callstate2str(channel->callstate));
        switch_snprintf(state_num, sizeof(state_num), "%d", channel->state);
        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State-Number", state_num);
        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Name", switch_channel_get_name(channel));
@@ -2134,6 +2236,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_hangup(switch_chan
                        switch_channel_set_variable(channel, "presence_call_info", NULL);
                }
 
+               switch_channel_set_callstate(channel, CCS_HANGUP);
                channel->hangup_cause = hangup_cause;
                switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_NOTICE, "Hangup %s [%s] [%s]\n",
                                                  channel->name, state_names[last_state], switch_channel_cause2str(channel->hangup_cause));
@@ -2219,6 +2322,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_
 
                switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_NOTICE, "Pre-Answer %s!\n", channel->name);
                switch_channel_set_flag(channel, CF_EARLY_MEDIA);
+               switch_channel_set_callstate(channel, CCS_EARLY);
                switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "EARLY MEDIA");
                if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA) == SWITCH_STATUS_SUCCESS) {
                        switch_channel_event_set_data(channel, event);
@@ -2360,6 +2464,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_chan
        }
 
        switch_channel_set_flag(channel, CF_ANSWERED);
+       switch_channel_set_callstate(channel, CCS_ACTIVE);
 
        if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_ANSWER) == SWITCH_STATUS_SUCCESS) {
                switch_channel_event_set_data(channel, event);
index e7a2d2822e69e38be88aa22cbd923158bdb42acf..061c77fccc187e953fd9471c99963c35e1251e06 100644 (file)
@@ -977,14 +977,15 @@ static void core_event_handler(switch_event_t *event)
                        break;
                }
        case SWITCH_EVENT_CHANNEL_CREATE:
-               sql = switch_mprintf("insert into channels (uuid,direction,created,created_epoch, name,state,dialplan,context,hostname) "
-                                                        "values('%q','%q','%q','%ld','%q','%q','%q','%q','%q')",
+               sql = switch_mprintf("insert into channels (uuid,direction,created,created_epoch, name,state,callstate,dialplan,context,hostname) "
+                                                        "values('%q','%q','%q','%ld','%q','%q','%q','%q','%q','%q')",
                                                         switch_event_get_header_nil(event, "unique-id"),
                                                         switch_event_get_header_nil(event, "call-direction"),
                                                         switch_event_get_header_nil(event, "event-date-local"),
                                                         (long) switch_epoch_time_now(NULL),
                                                         switch_event_get_header_nil(event, "channel-name"),
                                                         switch_event_get_header_nil(event, "channel-state"),
+                                                        switch_event_get_header_nil(event, "channel-call-state"),
                                                         switch_event_get_header_nil(event, "caller-dialplan"),
                                                         switch_event_get_header_nil(event, "caller-context"), switch_core_get_variable("hostname")
                        );
@@ -999,9 +1000,12 @@ static void core_event_handler(switch_event_t *event)
                         switch_event_get_header_nil(event, "channel-write-codec-rate"),
                         switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
                break;
+       case SWITCH_EVENT_CHANNEL_HOLD:
+       case SWITCH_EVENT_CHANNEL_UNHOLD:
        case SWITCH_EVENT_CHANNEL_EXECUTE:
-               sql = switch_mprintf("update channels set application='%q',application_data='%q',"
+               sql = switch_mprintf("update channels set callstate='%q',application='%q',application_data='%q',"
                                                         "presence_id='%q',presence_data='%q' where uuid='%q' and hostname='%q'",
+                                                        switch_event_get_header_nil(event, "channel-call-state"),
                                                         switch_event_get_header_nil(event, "application"),
                                                         switch_event_get_header_nil(event, "application-data"),
                                                         switch_event_get_header_nil(event, "channel-presence-id"),
@@ -1009,7 +1013,6 @@ static void core_event_handler(switch_event_t *event)
                                                         switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")
 
                        );
-
                break;
        case SWITCH_EVENT_CHANNEL_STATE:
                {
@@ -1025,10 +1028,11 @@ static void core_event_handler(switch_event_t *event)
                        case CS_DESTROY:
                                break;
                        case CS_ROUTING:
-                               sql = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',"
+                               sql = switch_mprintf("update channels set state='%s',callstate='%q',cid_name='%q',cid_num='%q',"
                                                                         "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q' "
                                                                         "where uuid='%s' and hostname='%q'",
                                                                         switch_event_get_header_nil(event, "channel-state"),
+                                                                        switch_event_get_header_nil(event, "channel-call-state"),
                                                                         switch_event_get_header_nil(event, "caller-caller-id-name"),
                                                                         switch_event_get_header_nil(event, "caller-caller-id-number"),
                                                                         switch_event_get_header_nil(event, "caller-network-addr"),
@@ -1040,8 +1044,9 @@ static void core_event_handler(switch_event_t *event)
                                                                         switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
                                break;
                        default:
-                               sql = switch_mprintf("update channels set state='%s' where uuid='%s' and hostname='%q'",
+                               sql = switch_mprintf("update channels set state='%s',callstate='%s' where uuid='%s' and hostname='%q'",
                                                                         switch_event_get_header_nil(event, "channel-state"),
+                                                                        switch_event_get_header_nil(event, "channel-call-state"),
                                                                         switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
                                break;
                        }
@@ -1186,6 +1191,7 @@ static char create_channels_sql[] =
        "   created_epoch  INTEGER,\n"
        "   name  VARCHAR(1024),\n"
        "   state  VARCHAR(64),\n"
+       "   callstate  VARCHAR(64),\n"
        "   cid_name  VARCHAR(1024),\n"
        "   cid_num  VARCHAR(256),\n"
        "   ip_addr  VARCHAR(256),\n"
@@ -1323,7 +1329,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
        case SCDB_TYPE_ODBC:
                {
                        char *err;
-                       switch_cache_db_test_reactive(dbh, "select hostname from channels", "DROP TABLE channels", create_channels_sql);
+                       switch_cache_db_test_reactive(dbh, "select callstate from channels", "DROP TABLE channels", create_channels_sql);
                        switch_cache_db_test_reactive(dbh, "select hostname from calls", "DROP TABLE calls", create_calls_sql);
                        switch_cache_db_test_reactive(dbh, "select ikey from interfaces", "DROP TABLE interfaces", create_interfaces_sql);
                        switch_cache_db_test_reactive(dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql);