]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Added core spanflag CLI command
authorDavid Yat Sin <dyatsin@sangoma.com>
Wed, 20 Jun 2012 20:28:00 +0000 (16:28 -0400)
committerDavid Yat Sin <dyatsin@sangoma.com>
Wed, 20 Jun 2012 20:28:00 +0000 (16:28 -0400)
libs/freetdm/mod_freetdm/mod_freetdm.c
libs/freetdm/src/ftdm_io.c
libs/freetdm/src/include/private/ftdm_types.h

index 63abc9f28427cb3e11f61d78722935ec99187e8a..12cb7e5ef7b64cd4019e9a125ecfa11c4fe669a4 100755 (executable)
@@ -5069,7 +5069,8 @@ static ftdm_cli_entry_t ftdm_cli_options[] =
        /* Fake handlers as they are handled within freetdm library,
         * we should provide a way inside freetdm to query for completions from signaling modules */
        { "core state", "[!]<state_name>", "", NULL },
-       { "core flag", "[!]<flag_value>", "", NULL },
+       { "core flag", "[!]<flag-int-value|flag-name> [<span_id|span_name>] [<chan_id>]", "", NULL },
+       { "core spanflag", "[!]<flag-int-value|flag-name> [<span_id|span_name>]", "", NULL },
        { "core calls", "", "", NULL },
 };
 
index a9cb0b4f2abdd4746797ea19eedf4367450ab314..6052971274bfe07e8a633629e178d82f64e40cc9 100644 (file)
@@ -63,12 +63,78 @@ struct tm *localtime_r(const time_t *clock, struct tm *result);
 ftdm_time_t time_last_throttle_log = 0;
 ftdm_time_t time_current_throttle_log = 0;
 
+typedef struct val_str {
+       const char *str;
+       unsigned long long val;
+} val_str_t;
+
+static val_str_t channel_flag_strs[] =  {
+       { "configured" ,  FTDM_CHANNEL_CONFIGURED},
+       { "ready",  FTDM_CHANNEL_READY},
+       { "open",  FTDM_CHANNEL_OPEN},
+       { "dtmf-detect",  FTDM_CHANNEL_DTMF_DETECT},
+       { "suppress-dtmf",  FTDM_CHANNEL_SUPRESS_DTMF},
+       { "transcode",  FTDM_CHANNEL_TRANSCODE},
+       { "buffer",  FTDM_CHANNEL_BUFFER},
+       { "in-thread",  FTDM_CHANNEL_INTHREAD},
+       { "wink",  FTDM_CHANNEL_WINK},
+       { "flash",  FTDM_CHANNEL_FLASH},
+       { "state-change",  FTDM_CHANNEL_STATE_CHANGE},
+       { "hold",  FTDM_CHANNEL_HOLD},
+       { "in-use",  FTDM_CHANNEL_INUSE},
+       { "off-hook",  FTDM_CHANNEL_OFFHOOK},
+       { "ringing",  FTDM_CHANNEL_RINGING},
+       { "progress-detect",  FTDM_CHANNEL_PROGRESS_DETECT},
+       { "callerid-detect",  FTDM_CHANNEL_CALLERID_DETECT},
+       { "outbound",  FTDM_CHANNEL_OUTBOUND},
+       { "suspended",  FTDM_CHANNEL_SUSPENDED},
+       { "3-way",  FTDM_CHANNEL_3WAY},
+       { "progress",  FTDM_CHANNEL_PROGRESS},
+       { "media",  FTDM_CHANNEL_MEDIA},
+       { "answered",  FTDM_CHANNEL_ANSWERED},
+       { "mute",  FTDM_CHANNEL_MUTE},
+       { "use-rx-gain",  FTDM_CHANNEL_USE_RX_GAIN},
+       { "use-tx-gain",  FTDM_CHANNEL_USE_TX_GAIN},
+       { "in-alarm",  FTDM_CHANNEL_IN_ALARM},
+       { "sig-up",  FTDM_CHANNEL_SIG_UP},
+       { "user-hangup",  FTDM_CHANNEL_USER_HANGUP},
+       { "rx-disabled",  FTDM_CHANNEL_RX_DISABLED},
+       { "tx-disabled",  FTDM_CHANNEL_TX_DISABLED},
+       { "call-started",  FTDM_CHANNEL_CALL_STARTED},
+       { "non-block",  FTDM_CHANNEL_NONBLOCK},
+       { "ind-ack-pending",  FTDM_CHANNEL_IND_ACK_PENDING},
+       { "blocking",  FTDM_CHANNEL_BLOCKING},
+       { "media",  FTDM_CHANNEL_DIGITAL_MEDIA},
+       { "native-sigbridge",  FTDM_CHANNEL_NATIVE_SIGBRIDGE},
+       { "invalid",  FTDM_CHANNEL_MAX_FLAG},
+};
+
+static val_str_t span_flag_strs[] =  {
+       { "configured", FTDM_SPAN_CONFIGURED},
+       { "started", FTDM_SPAN_STARTED},
+       { "state-change", FTDM_SPAN_STATE_CHANGE},
+       { "suspended", FTDM_SPAN_SUSPENDED},
+       { "in-thread", FTDM_SPAN_IN_THREAD},
+       { "stop-thread", FTDM_SPAN_STOP_THREAD},
+       { "use-chan-queue", FTDM_SPAN_USE_CHAN_QUEUE},
+       { "suggest-chan-id", FTDM_SPAN_SUGGEST_CHAN_ID},
+       { "use-av-rate", FTDM_SPAN_USE_AV_RATE},
+       { "power-saving", FTDM_SPAN_PWR_SAVING},
+       { "signals-queue", FTDM_SPAN_USE_SIGNALS_QUEUE},
+       { "proceed-state", FTDM_SPAN_USE_PROCEED_STATE},
+       { "skip-state", FTDM_SPAN_USE_SKIP_STATES},
+       { "non-stoppable", FTDM_SPAN_NON_STOPPABLE},
+       { "use-transfer", FTDM_SPAN_USE_TRANSFER},
+};
+
 static ftdm_status_t ftdm_call_set_call_id(ftdm_channel_t *fchan, ftdm_caller_data_t *caller_data);
 static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data);
 static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan);
 static ftdm_status_t ftdm_channel_sig_indicate(ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication, ftdm_usrmsg_t *usrmsg);
-static const char *channel_val2str(unsigned long long flag);
-static unsigned long long channel_str2val(const char *flag_name);
+
+static const char *ftdm_val2str(unsigned long long val, val_str_t *val_str_table, ftdm_size_t array_size, const char *default_str);
+static unsigned long long ftdm_str2val(const char *str, val_str_t *val_str_table, ftdm_size_t array_size, unsigned long long default_val);
+
 
 static int time_is_init = 0;
 
@@ -1051,7 +1117,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_add_channel(ftdm_span_t *span, ftdm_socket_t
                        i++;
                }
 
-               ftdm_set_flag(new_chan, FTDM_CHANNEL_CONFIGURED | FTDM_CHANNEL_READY);          
+               ftdm_set_flag(new_chan, FTDM_CHANNEL_CONFIGURED | FTDM_CHANNEL_READY);
                new_chan->state = FTDM_CHANNEL_STATE_DOWN;
                new_chan->state_status = FTDM_STATE_STATUS_COMPLETED;
                *chan = new_chan;
@@ -4370,28 +4436,28 @@ static void print_channels_by_flag(ftdm_stream_handle_t *stream, ftdm_span_t *in
                                                stream->write_function(stream, "[s%dc%d][%d:%d] flag !%d(!%s) ON \n",
                                                                                                fchan->span_id, fchan->chan_id,
                                                                                                fchan->physical_span_id, fchan->physical_chan_id,
-                                                                                               flagval, channel_val2str(flagval));
+                                                                                               flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
 
                                                mycount++;
                                        } else {
                                                stream->write_function(stream, "[s%dc%d][%d:%d] flag !%d(!%s) OFF \n",
                                                                                                fchan->span_id, fchan->chan_id,
                                                                                                fchan->physical_span_id, fchan->physical_chan_id,
-                                                                                               flagval, channel_val2str(flagval));
+                                                                                               flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
                                        }
-                               } else if (!not) {
+                               } else {
                                        if (ftdm_test_flag(fchan, flag)) {
-                                                                                               stream->write_function(stream, "[s%dc%d][%d:%d] flag %d(%s) ON\n",
+                                               stream->write_function(stream, "[s%dc%d][%d:%d] flag %d(%s) ON\n",
                                                                                                fchan->span_id, fchan->chan_id,
                                                                                                fchan->physical_span_id, fchan->physical_chan_id,
-                                                                                               flagval, channel_val2str(flagval));
+                                                                                               flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
 
                                                mycount++;
                                        } else {
                                                stream->write_function(stream, "[s%dc%d][%d:%d] flag %d(%s) OFF \n",
                                                                                                fchan->span_id, fchan->chan_id,
                                                                                                fchan->physical_span_id, fchan->physical_chan_id,
-                                                                                               flagval, channel_val2str(flagval));
+                                                                                               flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
                                        }
                                }
                        }
@@ -4412,16 +4478,16 @@ static void print_channels_by_flag(ftdm_stream_handle_t *stream, ftdm_span_t *in
                        for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) {
                                fchan = ftdm_iterator_current(curr);
                                if (not && !ftdm_test_flag(fchan, flag)) {
-                                       stream->write_function(stream, "[s%dc%d][%d:%d] has not flag %d\n", 
+                                       stream->write_function(stream, "[s%dc%d][%d:%d] flag !%d(!%s)\n",
                                                        fchan->span_id, fchan->chan_id, 
                                                        fchan->physical_span_id, fchan->physical_chan_id, 
-                                                       flagval);
+                                                       flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
                                        mycount++;
                                } else if (!not && ftdm_test_flag(fchan, flag)) {
-                                       stream->write_function(stream, "[s%dc%d][%d:%d] has flag %d\n", 
+                                       stream->write_function(stream, "[s%dc%d][%d:%d] flag %d(%s)\n",
                                                        fchan->span_id, fchan->chan_id, 
                                                        fchan->physical_span_id, fchan->physical_chan_id, 
-                                                       flagval);
+                                                       flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
                                        mycount++;
                                }
                        }
@@ -4433,6 +4499,68 @@ end:
        ftdm_mutex_unlock(globals.mutex);
 }
 
+static void print_spans_by_flag(ftdm_stream_handle_t *stream, ftdm_span_t *inspan, int32_t flagval, int not, int *count)
+{
+       ftdm_hash_iterator_t *i = NULL;
+       ftdm_span_t *span;
+       const void *key = NULL;
+       void *val = NULL;
+       uint32_t flag = (1 << flagval);
+       int mycount = 0;
+
+       *count = 0;
+
+       ftdm_mutex_lock(globals.mutex);
+
+       if (inspan) {
+               if (not) {
+                       if (!ftdm_test_flag(inspan, flag)) {
+                               stream->write_function(stream, "[s%d] flag !%d(!%s) ON \n",
+                                                                               inspan->span_id,
+                                                                               flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
+
+                               mycount++;
+                       } else {
+                               stream->write_function(stream, "[s%d] flag !%d(!%s) OFF \n",
+                                                                               inspan->span_id,
+                                                                               flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
+                       }
+               } else {
+                       if (ftdm_test_flag(inspan, flag)) {
+                               stream->write_function(stream, "[s%d] flag %d(%s) ON \n",
+                                                                               inspan->span_id,
+                                                                               flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
+                               mycount++;
+                       } else {
+                               stream->write_function(stream, "[s%d] flag %d(%s) OFF \n",
+                                                                               inspan->span_id,
+                                                                               flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
+                       }
+               }
+       } else {
+               for (i = hashtable_first(globals.span_hash); i; i = hashtable_next(i)) {
+                       hashtable_this(i, &key, NULL, &val);
+                       if (!key || !val) {
+                               break;
+                       }
+                       span = val;
+                       if (not && !ftdm_test_flag(span, flag)) {
+                               stream->write_function(stream, "[s%d] flag !%d(!%s)\n",
+                                                                               span->span_id,
+                                                                               flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
+                               mycount++;
+                       } else if (!not && ftdm_test_flag(span, flag)) {
+                               stream->write_function(stream, "[s%d] flag %d(%s)\n",
+                                                                           span->span_id,
+                                                                               flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
+                               mycount++;
+                       }
+               }
+       }
+       *count = mycount;
+       ftdm_mutex_unlock(globals.mutex);
+}
+
 static void print_channels_by_state(ftdm_stream_handle_t *stream, ftdm_channel_state_t state, int not, int *count)
 {
        ftdm_hash_iterator_t *i = NULL;
@@ -4483,83 +4611,47 @@ static void print_core_usage(ftdm_stream_handle_t *stream)
        "--------------------------------------------------------------------------------\n"
        "ftdm core state [!]<state-name> - List all channels in or not in the given state\n"
        "ftdm core flag [!]<flag-int-value|flag-name> [<span_id|span_name>] [<chan_id>] - List all channels with the given flag value set\n"
+       "ftdm core spanflag [!]<flag-int-value|flag-name> [<span_id|span_name>] - List all spans with the given span flag value set\n"
        "ftdm core calls - List all known calls to the FreeTDM core\n"
        "--------------------------------------------------------------------------------\n");
 }
 
-typedef struct channel_flags_str {
-       const char *name;
-       unsigned long long channel_flag;
-} channel_flag_str_t;
-
-static channel_flag_str_t channel_flag_strs[] =  {
- { "configured" ,  FTDM_CHANNEL_CONFIGURED},
- { "ready",  FTDM_CHANNEL_READY},
- { "open",  FTDM_CHANNEL_OPEN},
- { "dtmf-detect",  FTDM_CHANNEL_DTMF_DETECT},
- { "suppress-dtmf",  FTDM_CHANNEL_SUPRESS_DTMF},
- { "transcode",  FTDM_CHANNEL_TRANSCODE},
- { "buffer",  FTDM_CHANNEL_BUFFER},
- { "in-thread",  FTDM_CHANNEL_INTHREAD},
- { "wink",  FTDM_CHANNEL_WINK},
- { "flash",  FTDM_CHANNEL_FLASH},
- { "state-change",  FTDM_CHANNEL_STATE_CHANGE},
- { "hold",  FTDM_CHANNEL_HOLD},
- { "in-use",  FTDM_CHANNEL_INUSE},
- { "off-hook",  FTDM_CHANNEL_OFFHOOK},
- { "ringing",  FTDM_CHANNEL_RINGING},
- { "progress-detect",  FTDM_CHANNEL_PROGRESS_DETECT},
- { "callerid-detect",  FTDM_CHANNEL_CALLERID_DETECT},
- { "outbound",  FTDM_CHANNEL_OUTBOUND},
- { "suspended",  FTDM_CHANNEL_SUSPENDED},
- { "3-way",  FTDM_CHANNEL_3WAY},
- { "progress",  FTDM_CHANNEL_PROGRESS},
- { "media",  FTDM_CHANNEL_MEDIA},
- { "answered",  FTDM_CHANNEL_ANSWERED},
- { "mute",  FTDM_CHANNEL_MUTE},
- { "use-rx-gain",  FTDM_CHANNEL_USE_RX_GAIN},
- { "use-tx-gain",  FTDM_CHANNEL_USE_TX_GAIN},
- { "in-alarm",  FTDM_CHANNEL_IN_ALARM},
- { "sig-up",  FTDM_CHANNEL_SIG_UP},
- { "user-hangup",  FTDM_CHANNEL_USER_HANGUP},
- { "rx-disabled",  FTDM_CHANNEL_RX_DISABLED},
- { "tx-disabled",  FTDM_CHANNEL_TX_DISABLED},
- { "call-started",  FTDM_CHANNEL_CALL_STARTED},
- { "non-block",  FTDM_CHANNEL_NONBLOCK},
- { "ind-ack-pending",  FTDM_CHANNEL_IND_ACK_PENDING},
- { "blocking",  FTDM_CHANNEL_BLOCKING},
- { "media",  FTDM_CHANNEL_DIGITAL_MEDIA},
- { "native-sigbridge",  FTDM_CHANNEL_NATIVE_SIGBRIDGE},
- { "invalid",  FTDM_CHANNEL_MAX_FLAG},
-};
 
-static unsigned long long channel_str2val(const char *flag_name)
+static unsigned long long ftdm_str2val(const char *str, val_str_t *val_str_table, ftdm_size_t array_size, unsigned long long default_val)
 {
        int i;
-       for (i = 0; i < ftdm_array_len(channel_flag_strs); i++) {
-               if (!strcasecmp(channel_flag_strs[i].name, flag_name)) {
-                       return channel_flag_strs[i].channel_flag;
+       for (i = 0; i < array_size; i++) {
+               if (!strcasecmp(val_str_table[i].str, str)) {
+                       return val_str_table[i].val;
                }
        }
-       return FTDM_CHANNEL_MAX_FLAG;
+       return default_val;
 }
 
-static const char *channel_val2str(unsigned long long flag)
+static const char *ftdm_val2str(unsigned long long val, val_str_t *val_str_table, ftdm_size_t array_size, const char *default_str)
 {
        int i;
-       for (i = 0; i < ftdm_array_len(channel_flag_strs); i++) {
-               if (channel_flag_strs[i].channel_flag == flag) {
-                       return channel_flag_strs[i].name;
+       for (i = 0; i < array_size; i++) {
+               if (val_str_table[i].val == val) {
+                       return val_str_table[i].str;
                }
        }
-       return "invalid";
+       return default_str;
 }
 
 static void print_channel_flag_values(ftdm_stream_handle_t *stream)
 {
        int i;
        for (i = 0; i < ftdm_array_len(channel_flag_strs); i++) {
-               stream->write_function(stream, "%s\n", channel_flag_strs[i].name);
+               stream->write_function(stream, "%s\n", channel_flag_strs[i].str);
+       }
+}
+
+static void print_span_flag_values(ftdm_stream_handle_t *stream)
+{
+       int i;
+       for (i = 0; i < ftdm_array_len(span_flag_strs); i++) {
+               stream->write_function(stream, "%s\n", span_flag_strs[i].str);
        }
 }
 
@@ -4631,12 +4723,13 @@ static char *handle_core_command(const char *cmd)
                }
                
                if (isalpha(flag[0])) {
-                       flagval = channel_str2val(flag);
+                       flagval = ftdm_str2val(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), FTDM_CHANNEL_MAX_FLAG);
                        if (flagval == FTDM_CHANNEL_MAX_FLAG) {
                                stream.write_function(&stream, "\nInvalid channel flag value. Possible channel flags\n");
                                print_channel_flag_values(&stream);
                                goto done;
                        }
+                       flagval = flagval >> 1;
                } else {
                        flagval = atoi(flag);
                }
@@ -4661,6 +4754,44 @@ static char *handle_core_command(const char *cmd)
 
                print_channels_by_flag(&stream, fspan, chan_id, flagval, not, &count);
                stream.write_function(&stream, "\nTotal channels %s %d: %d\n", not ? "without flag" : "with flag", flagval, count);
+       } else if (!strcasecmp(argv[0], "spanflag")) {
+               if (argc < 2) {
+                       stream.write_function(&stream, "core spanflag command requires an argument\n");
+                       print_core_usage(&stream);
+                       goto done;
+               }
+
+               flag = argv[1];
+               if (argv[1][0] == '!') {
+                       not = 1;
+                       flag++;
+               }
+
+               if (isalpha(flag[0])) {
+                       flagval = ftdm_str2val(flag, span_flag_strs, ftdm_array_len(span_flag_strs), FTDM_SPAN_MAX_FLAG);
+                       if (flagval == FTDM_SPAN_MAX_FLAG) {
+                               stream.write_function(&stream, "\nInvalid span flag value. Possible span flags\n");
+                               print_span_flag_values(&stream);
+                               goto done;
+                       }
+                       flagval = flagval >> 1;
+               } else {
+                       flagval = atoi(flag);
+               }
+
+               /* Specific span specified */
+               if (argv[2]) {
+                       ftdm_span_find_by_name(argv[2], &fspan);
+                       if (!fspan) {
+                               stream.write_function(&stream, "-ERR span:%s not found\n", argv[2]);
+                               goto done;
+                       }
+               }
+
+               print_spans_by_flag(&stream, fspan, flagval, not, &count);
+               if (!fspan) {
+                       stream.write_function(&stream, "\nTotal spans %s %d: %d\n", not ? "without flag" : "with flag", flagval, count);
+               }
        } else if (!strcasecmp(argv[0], "calls")) {
                ftdm_mutex_lock(globals.call_id_mutex);
                current_call_id = globals.last_call_id;
index 7df764e52f245ad845b792a02fc59beb1d8c16fb..19d496bea462193fd6d5fec9ddbf7f1b0590acd0 100755 (executable)
@@ -197,6 +197,8 @@ typedef enum {
        FTDM_SPAN_NON_STOPPABLE = (1 << 13),
        /* If this flag is set, then this span supports TRANSFER state */
        FTDM_SPAN_USE_TRANSFER = (1 << 14),
+       /* This is the last flag, no more flags bigger than this */
+       FTDM_SPAN_MAX_FLAG = (1 << 15),
 } ftdm_span_flag_t;
 
 /*! \brief Channel supported features */