From 7c044acbd90640321db8b78ed5a3b0ab8bc7844b Mon Sep 17 00:00:00 2001 From: Joshua Colp Date: Mon, 8 Jul 2013 19:19:55 +0000 Subject: Refactor operations to access the stasis cache instead of objects directly when retrieving information. (closes issue ASTERISK-21883) Review: https://reviewboard.asterisk.org/r/2645/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@393831 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- main/cli.c | 250 +++++++++++++++++++++++++------------------------------------ 1 file changed, 100 insertions(+), 150 deletions(-) (limited to 'main/cli.c') diff --git a/main/cli.c b/main/cli.c index 3431d1de8..34951711f 100644 --- a/main/cli.c +++ b/main/cli.c @@ -61,6 +61,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/threadstorage.h" #include "asterisk/translate.h" #include "asterisk/bridging.h" +#include "asterisk/stasis_channels.h" +#include "asterisk/stasis_bridging.h" /*! * \brief List of restrictions per user. @@ -877,9 +879,10 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar #define VERBOSE_FORMAT_STRING "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n" #define VERBOSE_FORMAT_STRING2 "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n" - struct ast_channel *c = NULL; + RAII_VAR(struct ao2_container *, channels, NULL, ao2_cleanup); + struct ao2_iterator it_chans; + struct stasis_message *msg; int numchans = 0, concise = 0, verbose = 0, count = 0; - struct ast_channel_iterator *iter = NULL; switch (cmd) { case CLI_INIT: @@ -911,6 +914,12 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar } else if (a->argc != e->args - 1) return CLI_SHOWUSAGE; + + if (!(channels = stasis_cache_dump(ast_channel_topic_all_cached_by_name(), ast_channel_snapshot_type()))) { + ast_cli(a->fd, "Failed to retrieve cached channels\n"); + return CLI_SUCCESS; + } + if (!count) { if (!concise && !verbose) ast_cli(a->fd, FORMAT_STRING2, "Channel", "Location", "State", "Application(Data)"); @@ -919,21 +928,14 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar "CallerID", "Duration", "Accountcode", "PeerAccount", "BridgeID"); } - if (!count && !(iter = ast_channel_iterator_all_new())) { - return CLI_FAILURE; - } - - for (; iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) { - struct ast_bridge *bridge; + it_chans = ao2_iterator_init(channels, 0); + for (; (msg = ao2_iterator_next(&it_chans)); ao2_ref(msg, -1)) { + struct ast_channel_snapshot *cs = stasis_message_data(msg); char durbuf[10] = "-"; - ast_channel_lock(c); - - bridge = ast_channel_get_bridge(c); - if (!count) { - if ((concise || verbose) && !ast_tvzero(ast_channel_creationtime(c))) { - int duration = (int)(ast_tvdiff_ms(ast_tvnow(), ast_channel_creationtime(c)) / 1000); + if ((concise || verbose) && !ast_tvzero(cs->creationtime)) { + int duration = (int)(ast_tvdiff_ms(ast_tvnow(), cs->creationtime) / 1000); if (verbose) { int durh = duration / 3600; int durm = (duration % 3600) / 60; @@ -944,43 +946,38 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar } } if (concise) { - ast_cli(a->fd, CONCISE_FORMAT_STRING, ast_channel_name(c), ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c), ast_state2str(ast_channel_state(c)), - ast_channel_appl(c) ? ast_channel_appl(c) : "(None)", - S_OR(ast_channel_data(c), ""), /* XXX different from verbose ? */ - S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, ""), - S_OR(ast_channel_accountcode(c), ""), - S_OR(ast_channel_peeraccount(c), ""), - ast_channel_amaflags(c), + ast_cli(a->fd, CONCISE_FORMAT_STRING, cs->name, cs->context, cs->exten, cs->priority, ast_state2str(cs->state), + S_OR(cs->appl, "(None)"), + cs->data, + cs->caller_number, + cs->accountcode, + cs->peeraccount, + cs->amaflags, durbuf, - bridge ? bridge->uniqueid : "(Not bridged)", - ast_channel_uniqueid(c)); + cs->bridgeid, + cs->uniqueid); } else if (verbose) { - ast_cli(a->fd, VERBOSE_FORMAT_STRING, ast_channel_name(c), ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c), ast_state2str(ast_channel_state(c)), - ast_channel_appl(c) ? ast_channel_appl(c) : "(None)", - ast_channel_data(c) ? S_OR(ast_channel_data(c), "(Empty)" ): "(None)", - S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, ""), + ast_cli(a->fd, VERBOSE_FORMAT_STRING, cs->name, cs->context, cs->exten, cs->priority, ast_state2str(cs->state), + S_OR(cs->appl, "(None)"), + S_OR(cs->data, "(Empty)"), + cs->caller_number, durbuf, - S_OR(ast_channel_accountcode(c), ""), - S_OR(ast_channel_peeraccount(c), ""), - bridge ? bridge->uniqueid : "(Not bridged)"); + cs->accountcode, + cs->peeraccount, + cs->bridgeid); } else { char locbuf[40] = "(None)"; char appdata[40] = "(None)"; - if (!ast_strlen_zero(ast_channel_context(c)) && !ast_strlen_zero(ast_channel_exten(c))) - snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", ast_channel_exten(c), ast_channel_context(c), ast_channel_priority(c)); - if (ast_channel_appl(c)) - snprintf(appdata, sizeof(appdata), "%s(%s)", ast_channel_appl(c), S_OR(ast_channel_data(c), "")); - ast_cli(a->fd, FORMAT_STRING, ast_channel_name(c), locbuf, ast_state2str(ast_channel_state(c)), appdata); + if (!cs->context && !cs->exten) + snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", cs->exten, cs->context, cs->priority); + if (cs->appl) + snprintf(appdata, sizeof(appdata), "%s(%s)", cs->appl, S_OR(cs->data, "")); + ast_cli(a->fd, FORMAT_STRING, cs->name, locbuf, ast_state2str(cs->state), appdata); } } - ast_channel_unlock(c); - ao2_cleanup(bridge); - } - - if (iter) { - ast_channel_iterator_destroy(iter); } + ao2_iterator_destroy(&it_chans); if (!concise) { numchans = ast_active_channels(); @@ -1414,23 +1411,15 @@ static char *handle_nodebugchan_deprecated(struct ast_cli_entry *e, int cmd, str static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - struct ast_channel *c=NULL; + RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); + struct ast_channel_snapshot *snapshot; struct timeval now; char cdrtime[256]; - char nf[256]; - struct ast_str *write_transpath = ast_str_alloca(256); - struct ast_str *read_transpath = ast_str_alloca(256); - struct ast_str *obuf;/*!< Buffer for variable, CDR variable, and trace output. */ + struct ast_str *obuf;/*!< Buffer for CDR variables. */ struct ast_str *output;/*!< Accumulation buffer for all output. */ long elapsed_seconds=0; int hour=0, min=0, sec=0; - struct ast_callid *callid; - char call_identifier_str[AST_CALLID_BUFFER_LENGTH] = ""; - struct ast_party_id effective_connected_id; -#ifdef CHANNEL_TRACE - int trace_enabled; -#endif - struct ast_bridge *bridge; + struct ast_var_t *var; switch (cmd) { case CLI_INIT: @@ -1449,10 +1438,11 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar now = ast_tvnow(); - if (!(c = ast_channel_get_by_name(a->argv[3]))) { + if (!(msg = stasis_cache_get(ast_channel_topic_all_cached_by_name(), ast_channel_snapshot_type(), a->argv[3]))) { ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]); return CLI_SUCCESS; } + snapshot = stasis_message_data(msg); obuf = ast_str_thread_get(&ast_str_thread_global_buf, 16); if (!obuf) { @@ -1463,10 +1453,8 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar return CLI_FAILURE; } - ast_channel_lock(c); - - if (!ast_tvzero(ast_channel_creationtime(c))) { - elapsed_seconds = now.tv_sec - ast_channel_creationtime(c).tv_sec; + if (!ast_tvzero(snapshot->creationtime)) { + elapsed_seconds = now.tv_sec - snapshot->creationtime.tv_sec; hour = elapsed_seconds / 3600; min = (elapsed_seconds % 3600) / 60; sec = elapsed_seconds % 60; @@ -1475,15 +1463,6 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar strcpy(cdrtime, "N/A"); } - /* Construct the call identifier string based on the status of the channel's call identifier */ - if ((callid = ast_channel_callid(c))) { - ast_callid_strnprint(call_identifier_str, sizeof(call_identifier_str), callid); - ast_callid_unref(callid); - } - - effective_connected_id = ast_channel_connected_effective_id(c); - bridge = ast_channel_get_bridge(c); - ast_str_append(&output, 0, " -- General --\n" " Name: %s\n" @@ -1499,15 +1478,11 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar " DNID Digits: %s\n" " Language: %s\n" " State: %s (%d)\n" - " Rings: %d\n" " NativeFormats: %s\n" " WriteFormat: %s\n" " ReadFormat: %s\n" " WriteTranscode: %s %s\n" " ReadTranscode: %s %s\n" - "1st File Descriptor: %d\n" - " Frames in: %d%s\n" - " Frames out: %d%s\n" " Time to Hangup: %ld\n" " Elapsed Time: %s\n" " Bridge ID: %s\n" @@ -1519,68 +1494,49 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar " Pickup Group: %llu\n" " Application: %s\n" " Data: %s\n" - " Blocking in: %s\n" " Call Identifer: %s\n", - ast_channel_name(c), - ast_channel_tech(c)->type, - ast_channel_uniqueid(c), - ast_channel_linkedid(c), - S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, "(N/A)"), - S_COR(ast_channel_caller(c)->id.name.valid, ast_channel_caller(c)->id.name.str, "(N/A)"), - S_COR(ast_channel_connected(c)->id.number.valid, ast_channel_connected(c)->id.number.str, "(N/A)"), - S_COR(ast_channel_connected(c)->id.name.valid, ast_channel_connected(c)->id.name.str, "(N/A)"), - S_COR(effective_connected_id.number.valid, effective_connected_id.number.str, "(N/A)"), - S_COR(effective_connected_id.name.valid, effective_connected_id.name.str, "(N/A)"), - S_OR(ast_channel_dialed(c)->number.str, "(N/A)"), - ast_channel_language(c), - ast_state2str(ast_channel_state(c)), - ast_channel_state(c), - ast_channel_rings(c), - ast_getformatname_multiple(nf, sizeof(nf), ast_channel_nativeformats(c)), - ast_getformatname(ast_channel_writeformat(c)), - ast_getformatname(ast_channel_readformat(c)), - ast_channel_writetrans(c) ? "Yes" : "No", - ast_translate_path_to_str(ast_channel_writetrans(c), &write_transpath), - ast_channel_readtrans(c) ? "Yes" : "No", - ast_translate_path_to_str(ast_channel_readtrans(c), &read_transpath), - ast_channel_fd(c, 0), - ast_channel_fin(c) & ~DEBUGCHAN_FLAG, - (ast_channel_fin(c) & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", - ast_channel_fout(c) & ~DEBUGCHAN_FLAG, - (ast_channel_fout(c) & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", - (long) ast_channel_whentohangup(c)->tv_sec, + snapshot->name, + snapshot->type, + snapshot->uniqueid, + snapshot->linkedid, + S_OR(snapshot->caller_number, "(N/A)"), + S_OR(snapshot->caller_name, "(N/A)"), + S_OR(snapshot->connected_number, "(N/A)"), + S_OR(snapshot->connected_name, "(N/A)"), + S_OR(snapshot->effective_number, "(N/A)"), + S_OR(snapshot->effective_name, "(N/A)"), + S_OR(snapshot->caller_dnid, "(N/A)"), + snapshot->language, + ast_state2str(snapshot->state), + snapshot->state, + snapshot->nativeformats, + snapshot->writeformat, + snapshot->readformat, + !ast_strlen_zero(snapshot->writetrans) ? "Yes" : "No", + snapshot->writetrans, + !ast_strlen_zero(snapshot->readtrans) ? "Yes" : "No", + snapshot->readtrans, + (long) snapshot->hanguptime.tv_sec, cdrtime, - bridge ? bridge->uniqueid : "(Not bridged)", - ast_channel_context(c), - ast_channel_exten(c), - ast_channel_priority(c), - ast_channel_callgroup(c), - ast_channel_pickupgroup(c), - (ast_channel_appl(c) ? ast_channel_appl(c) : "(N/A)" ), - (ast_channel_data(c) ? S_OR(ast_channel_data(c), "(Empty)") : "(None)"), - (ast_test_flag(ast_channel_flags(c), AST_FLAG_BLOCKING) ? ast_channel_blockproc(c) : "(Not Blocking)"), - S_OR(call_identifier_str, "(None)")); - - if (pbx_builtin_serialize_variables(c, &obuf)) { - ast_str_append(&output, 0, " Variables:\n%s\n", ast_str_buffer(obuf)); - } - - if (ast_cdr_serialize_variables(ast_channel_name(c), &obuf, '=', '\n')) { - ast_str_append(&output, 0, " CDR Variables:\n%s\n", ast_str_buffer(obuf)); - } + S_OR(snapshot->bridgeid, "(Not bridged)"), + snapshot->context, + snapshot->exten, + snapshot->priority, + snapshot->callgroup, + snapshot->pickupgroup, + S_OR(snapshot->appl, "(N/A)"), + S_OR(snapshot->data, "(Empty)"), + S_OR(snapshot->callid, "(None)")); + + ast_str_append(&output, 0, " Variables:\n"); -#ifdef CHANNEL_TRACE - trace_enabled = ast_channel_trace_is_enabled(c); - ast_str_append(&output, 0, " Context Trace: %s\n", - trace_enabled ? "Enabled" : "Disabled"); - if (trace_enabled && ast_channel_trace_serialize(c, &obuf)) { - ast_str_append(&output, 0, " Trace:\n%s\n", ast_str_buffer(obuf)); + AST_LIST_TRAVERSE(snapshot->channel_vars, var, entries) { + ast_str_append(&output, 0, "%s=%s\n", ast_var_name(var), ast_var_value(var)); } -#endif - ast_channel_unlock(c); - c = ast_channel_unref(c); - ao2_cleanup(bridge); + if (ast_cdr_serialize_variables(snapshot->name, &obuf, '=', '\n')) { + ast_str_append(&output, 0, " CDR Variables:\n%s\n", ast_str_buffer(obuf)); + } ast_cli(a->fd, "%s", ast_str_buffer(output)); ast_free(output); @@ -1605,38 +1561,32 @@ char *ast_cli_complete(const char *word, const char * const choices[], int state char *ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos) { - struct ast_channel *c = NULL; - int which = 0; - char notfound = '\0'; - char *ret = ¬found; /* so NULL can break the loop */ - struct ast_channel_iterator *iter; + int wordlen = strlen(word), which = 0; + RAII_VAR(struct ao2_container *, cached_channels, NULL, ao2_cleanup); + char *ret = NULL; + struct ao2_iterator iter; + struct stasis_message *msg; if (pos != rpos) { return NULL; } - if (ast_strlen_zero(word)) { - iter = ast_channel_iterator_all_new(); - } else { - iter = ast_channel_iterator_by_name_new(word, strlen(word)); - } - - if (!iter) { + if (!(cached_channels = stasis_cache_dump(ast_channel_topic_all_cached(), ast_channel_snapshot_type()))) { return NULL; } - while (ret == ¬found && (c = ast_channel_iterator_next(iter))) { - if (++which > state) { - ast_channel_lock(c); - ret = ast_strdup(ast_channel_name(c)); - ast_channel_unlock(c); + iter = ao2_iterator_init(cached_channels, 0); + for (; (msg = ao2_iterator_next(&iter)); ao2_ref(msg, -1)) { + struct ast_channel_snapshot *snapshot = stasis_message_data(msg); + + if (!strncasecmp(word, snapshot->name, wordlen) && (++which > state)) { + ret = ast_strdup(snapshot->name); + break; } - ast_channel_unref(c); } + ao2_iterator_destroy(&iter); - ast_channel_iterator_destroy(iter); - - return ret == ¬found ? NULL : ret; + return ret; } static char *group_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) @@ -2037,7 +1987,7 @@ static char *is_prefix(const char *word, const char *token, * \param cmds * \param match_type has 3 possible values: * 0 returns if the search key is equal or longer than the entry. - * note that trailing optional arguments are skipped. + * note that trailing optional arguments are skipped. * -1 true if the mismatch is on the last word XXX not true! * 1 true only on complete, exact match. * -- cgit v1.2.3