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;
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;
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"));
}
}
}
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++;
}
}
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;
"--------------------------------------------------------------------------------\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);
}
}
}
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);
}
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;