From 5f876497bcbe066e97d93a562a834231c093a29f Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 8 Mar 2013 15:15:07 -0500 Subject: [PATCH] freetdm: - Added ftdm_usage command to check if a channel has calls (ie, is busy) - Refactored ftdm CLI management to allow standalone APIs to be registered - Minor logging changes here and there --- libs/freetdm/mod_freetdm/mod_freetdm.c | 114 ++++++++++++++++++++----- libs/freetdm/src/ftdm_config.c | 2 +- libs/freetdm/src/ftdm_io.c | 1 + 3 files changed, 94 insertions(+), 23 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 2b0517dd79..a7346fdb2e 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -5187,36 +5187,96 @@ end: return SWITCH_STATUS_SUCCESS; } +SWITCH_STANDARD_API(ftdm_api_exec_usage) +{ + char *mycmd = NULL, *argv[10] = { 0 }; + int argc = 0; + uint32_t chan_id = 0; + ftdm_channel_t *chan = NULL; + ftdm_span_t *span = NULL; + uint32_t tokencnt = 0; + /*ftdm_cli_entry_t *entry = NULL;*/ + + if (!zstr(cmd) && (mycmd = strdup(cmd))) { + argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (!argc) { + stream->write_function(stream, "-ERR invalid args\n"); + goto end; + } + + if (argc < 2) { + stream->write_function(stream, "-ERR invalid args\n"); + goto end; + } + + ftdm_span_find_by_name(argv[0], &span); + chan_id = atoi(argv[1]); + if (!span) { + stream->write_function(stream, "-ERR invalid span\n"); + goto end; + } + + if (chan_id <= 0) { + stream->write_function(stream, "-ERR invalid channel\n"); + goto end; + } + + if (chan_id > ftdm_span_get_chan_count(span)) { + stream->write_function(stream, "-ERR invalid channel\n"); + goto end; + } + + chan = ftdm_span_get_channel(span, chan_id); + if (!chan) { + stream->write_function(stream, "-ERR channel not configured\n"); + goto end; + } + + tokencnt = ftdm_channel_get_token_count(chan); + stream->write_function(stream, "%d", tokencnt); + +end: + switch_safe_free(mycmd); + return SWITCH_STATUS_SUCCESS; +} + struct ftdm_cli_entry { const char *name; const char *args; const char *complete; + const char *desc; ftdm_cli_function_t execute; + switch_api_function_t execute_api; }; static ftdm_cli_entry_t ftdm_cli_options[] = { - { "list", "", "", ftdm_cmd_list }, - { "start", "", "", ftdm_cmd_start_stop }, - { "stop", "", "", ftdm_cmd_start_stop }, - { "reset", " []", "", ftdm_cmd_reset }, - { "alarms", " ", "", ftdm_cmd_alarms }, - { "dump", " []", "", ftdm_cmd_dump }, - { "sigstatus", "get|set [] []", "::[set:get", ftdm_cmd_sigstatus }, - { "trace", " []", "", ftdm_cmd_trace }, - { "notrace", " []", "", ftdm_cmd_notrace }, - { "gains", " []", "", ftdm_cmd_gains }, - { "dtmf", "on|off []", "::[on:off", ftdm_cmd_dtmf }, - { "queuesize", " []", "", ftdm_cmd_queuesize }, - { "iostats", "enable|disable|flush|print ", "::[enable:disable:flush:print", ftdm_cmd_iostats }, - { "ioread", " [num_times] [interval]", "", ftdm_cmd_ioread }, + { "list", "", "", NULL, ftdm_cmd_list, NULL }, + { "start", "", "", NULL, ftdm_cmd_start_stop, NULL }, + { "stop", "", "", NULL, ftdm_cmd_start_stop, NULL }, + { "reset", " []", "", NULL, ftdm_cmd_reset, NULL }, + { "alarms", " ", "", NULL, ftdm_cmd_alarms, NULL }, + { "dump", " []", "", NULL, ftdm_cmd_dump, NULL }, + { "sigstatus", "get|set [] []", "::[set:get", NULL, ftdm_cmd_sigstatus, NULL }, + { "trace", " []", "", NULL, ftdm_cmd_trace, NULL }, + { "notrace", " []", "", NULL, ftdm_cmd_notrace, NULL }, + { "gains", " []", "", NULL, ftdm_cmd_gains, NULL }, + { "dtmf", "on|off []", "::[on:off", NULL, ftdm_cmd_dtmf, NULL }, + { "queuesize", " []", "", NULL, ftdm_cmd_queuesize, NULL }, + { "iostats", "enable|disable|flush|print ", "::[enable:disable:flush:print", NULL, ftdm_cmd_iostats, NULL }, + { "ioread", " [num_times] [interval]", "", NULL, ftdm_cmd_ioread, NULL }, + + /* Stand-alone commands (not part of the generic ftdm API */ + { "ftdm_usage", " ", "", "Return channel call count", NULL, ftdm_api_exec_usage }, /* 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", "[!]", "", NULL }, - { "core flag", "[!] [] []", "", NULL }, - { "core spanflag", "[!] []", "", NULL }, - { "core calls", "", "", NULL }, + { "core state", "[!]", "", NULL, NULL, NULL }, + { "core flag", "[!] [] []", "", NULL, NULL, NULL }, + { "core spanflag", "[!] []", "", NULL, NULL, NULL }, + { "core calls", "", "", NULL, NULL, NULL }, }; static void print_usage(switch_stream_handle_t *stream, ftdm_cli_entry_t *cli) @@ -5233,12 +5293,15 @@ static void print_full_usage(switch_stream_handle_t *stream) stream->write_function(stream, "--------------------------------------------------------------------------------\n"); for (i = 0 ; i < ftdm_array_len(ftdm_cli_options); i++) { entry = &ftdm_cli_options[i]; + if (entry->execute_api) { + continue; + } stream->write_function(stream, "ftdm %s %s\n", entry->name, entry->args); } stream->write_function(stream, "--------------------------------------------------------------------------------\n"); } -SWITCH_STANDARD_API(ft_function) +SWITCH_STANDARD_API(ftdm_api_exec) { char *mycmd = NULL, *argv[10] = { 0 }; int argc = 0; @@ -5379,12 +5442,19 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load) freetdm_endpoint_interface->io_routines = &freetdm_io_routines; freetdm_endpoint_interface->state_handler = &freetdm_state_handlers; - SWITCH_ADD_API(commands_api_interface, "ftdm", "FreeTDM commands", ft_function, " "); + SWITCH_ADD_API(commands_api_interface, "ftdm", "FreeTDM commands", ftdm_api_exec, " "); for (i = 0 ; i < ftdm_array_len(ftdm_cli_options); i++) { char complete_cli[512]; entry = &ftdm_cli_options[i]; - snprintf(complete_cli, sizeof(complete_cli), "add ftdm %s %s", entry->name, entry->complete); - switch_console_set_complete(complete_cli); + if (entry->execute_api) { + /* This is a stand-alone API */ + SWITCH_ADD_API(commands_api_interface, entry->name, entry->desc, ftdm_api_exec_usage, entry->args); + snprintf(complete_cli, sizeof(complete_cli), "add %s %s", entry->name, entry->complete); + switch_console_set_complete(complete_cli); + } else { + snprintf(complete_cli, sizeof(complete_cli), "add ftdm %s %s", entry->name, entry->complete); + switch_console_set_complete(complete_cli); + } } SWITCH_ADD_APP(app_interface, "disable_ec", "Disable Echo Canceller", "Disable Echo Canceller", disable_ec_function, "", SAF_NONE); diff --git a/libs/freetdm/src/ftdm_config.c b/libs/freetdm/src/ftdm_config.c index 42b93cd78e..1564a0424b 100644 --- a/libs/freetdm/src/ftdm_config.c +++ b/libs/freetdm/src/ftdm_config.c @@ -77,7 +77,7 @@ int ftdm_config_open_file(ftdm_config_t *cfg, const char *file_path) memset(cfg, 0, sizeof(*cfg)); cfg->lockto = -1; - ftdm_log(FTDM_LOG_DEBUG, "Configuration file is %s.\n", path); + ftdm_log(FTDM_LOG_DEBUG, "Configuration file is %s\n", path); f = fopen(path, "r"); if (!f) { diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 1c1b4b9045..26ca79adea 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -5116,6 +5116,7 @@ static ftdm_status_t load_config(void) sprintf(chan_config.group_name, "__default"); if (!ftdm_config_open_file(&cfg, cfg_name)) { + ftdm_log(FTDM_LOG_ERROR, "Failed to open configuration file %s\n", cfg_name); return FTDM_FAIL; }