diff options
Diffstat (limited to 'main/cli.c')
-rw-r--r-- | main/cli.c | 151 |
1 files changed, 107 insertions, 44 deletions
diff --git a/main/cli.c b/main/cli.c index 1d3843183..8217e52d1 100644 --- a/main/cli.c +++ b/main/cli.c @@ -789,6 +789,7 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar int numchans = 0, concise = 0, verbose = 0, count = 0; int fd, argc; char **argv; + struct ast_channel_iterator *iter = NULL; switch (cmd) { case CLI_INIT: @@ -831,10 +832,18 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar "CallerID", "Duration", "Accountcode", "BridgedTo"); } - while ((c = ast_channel_walk_locked(c)) != NULL) { - struct ast_channel *bc = ast_bridged_channel(c); + if (!count && !(iter = ast_channel_iterator_all_new(0))) { + return CLI_FAILURE; + } + + for (; iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) { + struct ast_channel *bc; char durbuf[10] = "-"; + ast_channel_lock(c); + + bc = ast_bridged_channel(c); + if (!count) { if ((concise || verbose) && c->cdr && !ast_tvzero(c->cdr->start)) { int duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); @@ -876,10 +885,15 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar ast_cli(fd, FORMAT_STRING, c->name, locbuf, ast_state2str(c->_state), appdata); } } - numchans++; ast_channel_unlock(c); } + + if (iter) { + ast_channel_iterator_destroy(iter); + } + if (!concise) { + numchans = ast_active_channels(); ast_cli(fd, "%d active channel%s\n", numchans, ESS(numchans)); if (option_maxcalls) ast_cli(fd, "%d of %d max active call%s (%5.2f%% of capacity)\n", @@ -890,6 +904,7 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar ast_cli(fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls())); } + return CLI_SUCCESS; #undef FORMAT_STRING @@ -914,15 +929,21 @@ static char *handle_softhangup(struct ast_cli_entry *e, int cmd, struct ast_cli_ case CLI_GENERATE: return ast_complete_channels(a->line, a->word, a->pos, a->n, e->args); } - if (a->argc != 4) + + if (a->argc != 4) { return CLI_SHOWUSAGE; - c = ast_get_channel_by_name_locked(a->argv[3]); - if (c) { + } + + if ((c = ast_channel_get_by_name(a->argv[3]))) { + ast_channel_lock(c); ast_cli(a->fd, "Requested Hangup on channel '%s'\n", c->name); ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); ast_channel_unlock(c); - } else + c = ast_channel_unref(c); + } else { ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]); + } + return CLI_SUCCESS; } @@ -1174,10 +1195,41 @@ static char *handle_commandcomplete(struct ast_cli_entry *e, int cmd, struct ast return CLI_SUCCESS; } +struct channel_set_debug_args { + int fd; + int is_off; +}; + +static int channel_set_debug(void *obj, void *arg, void *data, int flags) +{ + struct ast_channel *chan = obj; + struct channel_set_debug_args *args = data; + + ast_channel_lock(chan); + + if (!(chan->fin & DEBUGCHAN_FLAG) || !(chan->fout & DEBUGCHAN_FLAG)) { + if (args->is_off) { + chan->fin &= ~DEBUGCHAN_FLAG; + chan->fout &= ~DEBUGCHAN_FLAG; + } else { + chan->fin |= DEBUGCHAN_FLAG; + chan->fout |= DEBUGCHAN_FLAG; + } + ast_cli(args->fd, "Debugging %s on channel %s\n", args->is_off ? "disabled" : "enabled", + chan->name); + } + + ast_channel_unlock(chan); + + return 0; +} + static char *handle_core_set_debug_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_channel *c = NULL; - int is_all, is_off = 0; + struct channel_set_debug_args args = { + .fd = a->fd, + }; switch (cmd) { case CLI_INIT: @@ -1193,47 +1245,37 @@ static char *handle_core_set_debug_channel(struct ast_cli_entry *e, int cmd, str return NULL; return a->n == 0 ? ast_strdup("all") : ast_complete_channels(a->line, a->word, a->pos, a->n - 1, e->args); } + /* 'core set debug channel {all|chan_id}' */ if (a->argc == e->args + 2) { if (!strcasecmp(a->argv[e->args + 1], "off")) - is_off = 1; + args.is_off = 1; else return CLI_SHOWUSAGE; - } else if (a->argc != e->args + 1) + } else if (a->argc != e->args + 1) { return CLI_SHOWUSAGE; + } - is_all = !strcasecmp("all", a->argv[e->args]); - if (is_all) { - if (is_off) { + if (!strcasecmp("all", a->argv[e->args])) { + if (args.is_off) { global_fin &= ~DEBUGCHAN_FLAG; global_fout &= ~DEBUGCHAN_FLAG; } else { global_fin |= DEBUGCHAN_FLAG; global_fout |= DEBUGCHAN_FLAG; } - c = ast_channel_walk_locked(NULL); + ast_channel_callback(channel_set_debug, NULL, &args, OBJ_NODATA | OBJ_MULTIPLE); } else { - c = ast_get_channel_by_name_locked(a->argv[e->args]); - if (c == NULL) + if ((c = ast_channel_get_by_name(a->argv[e->args]))) { + channel_set_debug(c, NULL, &args, 0); + ast_channel_unref(c); + } else { ast_cli(a->fd, "No such channel %s\n", a->argv[e->args]); - } - while (c) { - if (!(c->fin & DEBUGCHAN_FLAG) || !(c->fout & DEBUGCHAN_FLAG)) { - if (is_off) { - c->fin &= ~DEBUGCHAN_FLAG; - c->fout &= ~DEBUGCHAN_FLAG; - } else { - c->fin |= DEBUGCHAN_FLAG; - c->fout |= DEBUGCHAN_FLAG; - } - ast_cli(a->fd, "Debugging %s on channel %s\n", is_off ? "disabled" : "enabled", c->name); } - ast_channel_unlock(c); - if (!is_all) - break; - c = ast_channel_walk_locked(c); } - ast_cli(a->fd, "Debugging on new channels is %s\n", is_off ? "disabled" : "enabled"); + + ast_cli(a->fd, "Debugging on new channels is %s\n", args.is_off ? "disabled" : "enabled"); + return CLI_SUCCESS; } @@ -1279,22 +1321,29 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar return ast_complete_channels(a->line, a->word, a->pos, a->n, 3); } - if (a->argc != 4) + if (a->argc != 4) { return CLI_SHOWUSAGE; + } + now = ast_tvnow(); - c = ast_get_channel_by_name_locked(a->argv[3]); - if (!c) { + + if (!(c = ast_channel_get_by_name(a->argv[3]))) { ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]); return CLI_SUCCESS; } + + ast_channel_lock(c); + if (c->cdr) { elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; hour = elapsed_seconds / 3600; min = (elapsed_seconds % 3600) / 60; sec = elapsed_seconds % 60; snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec); - } else + } else { strcpy(cdrtime, "N/A"); + } + ast_cli(a->fd, " -- General --\n" " Name: %s\n" @@ -1347,17 +1396,24 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar ( c-> data ? S_OR(c->data, "(Empty)") : "(None)"), (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)")); - if (pbx_builtin_serialize_variables(c, &out)) + if (pbx_builtin_serialize_variables(c, &out)) { ast_cli(a->fd," Variables:\n%s\n", ast_str_buffer(out)); - if (c->cdr && ast_cdr_serialize_variables(c->cdr, &out, '=', '\n', 1)) + } + + if (c->cdr && ast_cdr_serialize_variables(c->cdr, &out, '=', '\n', 1)) { ast_cli(a->fd," CDR Variables:\n%s\n", ast_str_buffer(out)); + } + #ifdef CHANNEL_TRACE trace_enabled = ast_channel_trace_is_enabled(c); ast_cli(a->fd, " Context Trace: %s\n", trace_enabled ? "Enabled" : "Disabled"); if (trace_enabled && ast_channel_trace_serialize(c, &out)) ast_cli(a->fd, " Trace:\n%s\n", ast_str_buffer(out)); #endif + ast_channel_unlock(c); + c = ast_channel_unref(c); + return CLI_SUCCESS; } @@ -1381,20 +1437,27 @@ char *ast_complete_channels(const char *line, const char *word, int pos, int sta { struct ast_channel *c = NULL; int which = 0; - int wordlen; char notfound = '\0'; char *ret = ¬found; /* so NULL can break the loop */ + struct ast_channel_iterator *iter; - if (pos != rpos) + if (pos != rpos) { return NULL; + } - wordlen = strlen(word); + if (!(iter = ast_channel_iterator_by_name_new(0, word, strlen(word)))) { + return NULL; + } - while (ret == ¬found && (c = ast_channel_walk_locked(c))) { - if (!strncasecmp(word, c->name, wordlen) && ++which > state) + while (ret == ¬found && (c = ast_channel_iterator_next(iter))) { + if (++which > state) { + ast_channel_lock(c); ret = ast_strdup(c->name); - ast_channel_unlock(c); + ast_channel_unlock(c); + } + ast_channel_unref(c); } + return ret == ¬found ? NULL : ret; } |