[asterisk-commits] file: trunk r393831 - in /trunk: build_tools/ include/asterisk/ main/ res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jul 8 14:20:02 CDT 2013


Author: file
Date: Mon Jul  8 14:19:55 2013
New Revision: 393831

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=393831
Log:
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/

Modified:
    trunk/build_tools/cflags-devmode.xml
    trunk/include/asterisk/channel.h
    trunk/include/asterisk/stasis_channels.h
    trunk/main/bridging.c
    trunk/main/channel.c
    trunk/main/channel_internal_api.c
    trunk/main/cli.c
    trunk/main/manager.c
    trunk/main/manager_bridging.c
    trunk/main/manager_channels.c
    trunk/main/pbx.c
    trunk/main/stasis_channels.c
    trunk/res/res_agi.c

Modified: trunk/build_tools/cflags-devmode.xml
URL: http://svnview.digium.com/svn/asterisk/trunk/build_tools/cflags-devmode.xml?view=diff&rev=393831&r1=393830&r2=393831
==============================================================================
--- trunk/build_tools/cflags-devmode.xml (original)
+++ trunk/build_tools/cflags-devmode.xml Mon Jul  8 14:19:55 2013
@@ -24,9 +24,6 @@
 		<member name="THREAD_CRASH" displayname="Crash on mutex errors">
 			<support_level>extended</support_level>
 		</member>
-		<member name="CHANNEL_TRACE" displayname="Enable CHANNEL(trace) function">
-			<support_level>extended</support_level>
-		</member>
 		<member name="TEST_FRAMEWORK" displayname="Enable Test Framework API">
 			<support_level>extended</support_level>
 		</member>

Modified: trunk/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/channel.h?view=diff&rev=393831&r1=393830&r2=393831
==============================================================================
--- trunk/include/asterisk/channel.h (original)
+++ trunk/include/asterisk/channel.h Mon Jul  8 14:19:55 2013
@@ -1419,39 +1419,6 @@
  * \return a pointer to the structure, or NULL if no matching technology found
  */
 const struct ast_channel_tech *ast_get_channel_tech(const char *name);
-
-#ifdef CHANNEL_TRACE
-/*!
- * \brief Update the context backtrace if tracing is enabled
- * \return Returns 0 on success, -1 on failure
- */
-int ast_channel_trace_update(struct ast_channel *chan);
-
-/*!
- * \brief Enable context tracing in the channel
- * \return Returns 0 on success, -1 on failure
- */
-int ast_channel_trace_enable(struct ast_channel *chan);
-
-/*!
- * \brief Disable context tracing in the channel.
- * \note Does not remove current trace entries
- * \return Returns 0 on success, -1 on failure
- */
-int ast_channel_trace_disable(struct ast_channel *chan);
-
-/*!
- * \brief Whether or not context tracing is enabled
- * \return Returns -1 when the trace is enabled. 0 if not.
- */
-int ast_channel_trace_is_enabled(struct ast_channel *chan);
-
-/*!
- * \brief Put the channel backtrace in a string
- * \return Returns the amount of lines in the backtrace. -1 on error.
- */
-int ast_channel_trace_serialize(struct ast_channel *chan, struct ast_str **out);
-#endif
 
 /*!
  * \brief Hang up a channel
@@ -4230,6 +4197,18 @@
 
 /*!
  * \since 12
+ * \brief Gets the variables for a given channel, as set using pbx_builtin_setvar_helper().
+ *
+ * The returned variable list is an AO2 object, so ao2_cleanup() to free it.
+ *
+ * \param chan Channel to get variables for
+ * \return List of channel variables.
+ * \return \c NULL on error
+ */
+struct varshead *ast_channel_get_vars(struct ast_channel *chan);
+
+/*!
+ * \since 12
  * \brief A topic which publishes the events for a particular channel.
  *
  * If the given \a chan is \c NULL, ast_channel_topic_all() is returned.

Modified: trunk/include/asterisk/stasis_channels.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/stasis_channels.h?view=diff&rev=393831&r1=393830&r2=393831
==============================================================================
--- trunk/include/asterisk/stasis_channels.h (original)
+++ trunk/include/asterisk/stasis_channels.h Mon Jul  8 14:19:55 2013
@@ -39,6 +39,7 @@
 struct ast_channel_snapshot {
 	AST_DECLARE_STRING_FIELDS(
 		AST_STRING_FIELD(name);             /*!< ASCII unique channel name */
+		AST_STRING_FIELD(type);             /*!< Type of channel technology */
 		AST_STRING_FIELD(accountcode);      /*!< Account code for billing */
 		AST_STRING_FIELD(peeraccount);      /*!< Peer account code for billing */
 		AST_STRING_FIELD(userfield);        /*!< Userfield for CEL billing */
@@ -58,18 +59,31 @@
 		AST_STRING_FIELD(dialed_subaddr);   /*!< Dialed subaddress */
 		AST_STRING_FIELD(connected_name);   /*!< Connected Line Name */
 		AST_STRING_FIELD(connected_number); /*!< Connected Line Number */
+		AST_STRING_FIELD(effective_name);   /*!< Effective Connected Line Name */
+		AST_STRING_FIELD(effective_number); /*!< Effective Connected Line Number */
 		AST_STRING_FIELD(language);         /*!< The default spoken language for the channel */
+		AST_STRING_FIELD(bridgeid);         /*!< Unique Bridge Identifier */
+		AST_STRING_FIELD(nativeformats);    /*!< Native formats on the channel */
+		AST_STRING_FIELD(readformat);       /*!< The current read format */
+		AST_STRING_FIELD(writeformat);      /*!< The current write format */
+		AST_STRING_FIELD(writetrans);       /*!< The current write translation path */
+		AST_STRING_FIELD(readtrans);        /*!< The current read translation path */
 	);
 
+	char callid[AST_CALLID_BUFFER_LENGTH];  /*!< Callid for the channel */
 	struct timeval creationtime;            /*!< The time of channel creation */
+	struct timeval hanguptime;              /*!< When the channel should hang up */
 	enum ast_channel_state state;           /*!< State of line */
 	int priority;                           /*!< Dialplan: Current extension priority */
 	int amaflags;                           /*!< AMA flags for billing */
 	int hangupcause;                        /*!< Why is the channel hanged up. See causes.h */
 	int caller_pres;                        /*!< Caller ID presentation. */
 	struct ast_flags flags;                 /*!< channel flags of AST_FLAG_ type */
+	ast_group_t callgroup;                  /*!< Call group */
+	ast_group_t pickupgroup;                /*!< Pickup group */
 	struct ast_flags softhangup_flags;      /*!< softhangup channel flags */
 	struct varshead *manager_vars;          /*!< Variables to be appended to manager events */
+	struct varshead *channel_vars;          /*!< Variables set on the channel */
 };
 
 /*!

Modified: trunk/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/bridging.c?view=diff&rev=393831&r1=393830&r2=393831
==============================================================================
--- trunk/main/bridging.c (original)
+++ trunk/main/bridging.c Mon Jul  8 14:19:55 2013
@@ -6885,38 +6885,29 @@
 	return cmp;
 }
 
-struct bridge_complete {
-	/*! Nth match to return. */
-	int state;
-	/*! Which match currently on. */
-	int which;
-};
-
-static int complete_bridge_search(void *obj, void *arg, void *data, int flags)
-{
-	struct bridge_complete *search = data;
-
-	if (++search->which > search->state) {
-		return CMP_MATCH;
-	}
-	return 0;
-}
-
 static char *complete_bridge(const char *word, int state)
 {
-	char *ret;
-	struct ast_bridge *bridge;
-	struct bridge_complete search = {
-		.state = state,
-		};
-
-	bridge = ao2_callback_data(bridges, ast_strlen_zero(word) ? 0 : OBJ_PARTIAL_KEY,
-		complete_bridge_search, (char *) word, &search);
-	if (!bridge) {
+	char *ret = NULL;
+	int wordlen = strlen(word), which = 0;
+	RAII_VAR(struct ao2_container *, cached_bridges, NULL, ao2_cleanup);
+	struct ao2_iterator iter;
+	struct stasis_message *msg;
+
+	if (!(cached_bridges = stasis_cache_dump(ast_bridge_topic_all_cached(), ast_bridge_snapshot_type()))) {
 		return NULL;
 	}
-	ret = ast_strdup(bridge->uniqueid);
-	ao2_ref(bridge, -1);
+
+	iter = ao2_iterator_init(cached_bridges, 0);
+	for (; (msg = ao2_iterator_next(&iter)); ao2_ref(msg, -1)) {
+		struct ast_bridge_snapshot *snapshot = stasis_message_data(msg);
+
+		if (!strncasecmp(word, snapshot->uniqueid, wordlen) && (++which > state)) {
+			ret = ast_strdup(snapshot->uniqueid);
+			break;
+		}
+	}
+	ao2_iterator_destroy(&iter);
+
 	return ret;
 }
 
@@ -6925,8 +6916,9 @@
 #define FORMAT_HDR "%-36s %5s %-15s %s\n"
 #define FORMAT_ROW "%-36s %5u %-15s %s\n"
 
+	RAII_VAR(struct ao2_container *, cached_bridges, NULL, ao2_cleanup);
 	struct ao2_iterator iter;
-	struct ast_bridge *bridge;
+	struct stasis_message *msg;
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -6939,17 +6931,22 @@
 		return NULL;
 	}
 
-/* BUGBUG this command may need to be changed to look at the stasis cache. */
+	if (!(cached_bridges = stasis_cache_dump(ast_bridge_topic_all_cached(), ast_bridge_snapshot_type()))) {
+		ast_cli(a->fd, "Failed to retrieve cached bridges\n");
+		return CLI_SUCCESS;
+	}
+
 	ast_cli(a->fd, FORMAT_HDR, "Bridge-ID", "Chans", "Type", "Technology");
-	iter = ao2_iterator_init(bridges, 0);
-	for (; (bridge = ao2_iterator_next(&iter)); ao2_ref(bridge, -1)) {
-		ast_bridge_lock(bridge);
+
+	iter = ao2_iterator_init(cached_bridges, 0);
+	for (; (msg = ao2_iterator_next(&iter)); ao2_ref(msg, -1)) {
+		struct ast_bridge_snapshot *snapshot = stasis_message_data(msg);
+
 		ast_cli(a->fd, FORMAT_ROW,
-			bridge->uniqueid,
-			bridge->num_channels,
-			bridge->v_table ? bridge->v_table->name : "<unknown>",
-			bridge->technology ? bridge->technology->name : "<unknown>");
-		ast_bridge_unlock(bridge);
+			snapshot->uniqueid,
+			snapshot->num_channels,
+			S_OR(snapshot->subclass, "<unknown>"),
+			S_OR(snapshot->technology, "<unknown>"));
 	}
 	ao2_iterator_destroy(&iter);
 	return CLI_SUCCESS;
@@ -6958,10 +6955,28 @@
 #undef FORMAT_ROW
 }
 
+/*! \brief Internal callback function for sending channels in a bridge to the CLI */
+static int bridge_show_specific_print_channel(void *obj, void *arg, int flags)
+{
+	const char *uniqueid = obj;
+	struct ast_cli_args *a = arg;
+	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+	struct ast_channel_snapshot *snapshot;
+
+	if (!(msg = stasis_cache_get(ast_channel_topic_all_cached(), ast_channel_snapshot_type(), uniqueid))) {
+		return 0;
+	}
+	snapshot = stasis_message_data(msg);
+
+	ast_cli(a->fd, "Channel: %s\n", snapshot->name);
+
+	return 0;
+}
+
 static char *handle_bridge_show_specific(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	struct ast_bridge *bridge;
-	struct ast_bridge_channel *bridge_channel;
+	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+	struct ast_bridge_snapshot *snapshot;
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -6977,28 +6992,22 @@
 		return NULL;
 	}
 
-/* BUGBUG this command may need to be changed to look at the stasis cache. */
 	if (a->argc != 3) {
 		return CLI_SHOWUSAGE;
 	}
 
-	bridge = ao2_find(bridges, a->argv[2], OBJ_KEY);
-	if (!bridge) {
+	msg = stasis_cache_get(ast_bridge_topic_all_cached(), ast_bridge_snapshot_type(), a->argv[2]);
+	if (!msg) {
 		ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
 		return CLI_SUCCESS;
 	}
 
-	ast_bridge_lock(bridge);
-	ast_cli(a->fd, "Id: %s\n", bridge->uniqueid);
-	ast_cli(a->fd, "Type: %s\n", bridge->v_table ? bridge->v_table->name : "<unknown>");
-	ast_cli(a->fd, "Technology: %s\n",
-		bridge->technology ? bridge->technology->name : "<unknown>");
-	ast_cli(a->fd, "Num-Channels: %u\n", bridge->num_channels);
-	AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
-		ast_cli(a->fd, "Channel: %s\n", ast_channel_name(bridge_channel->chan));
-	}
-	ast_bridge_unlock(bridge);
-	ao2_ref(bridge, -1);
+	snapshot = stasis_message_data(msg);
+	ast_cli(a->fd, "Id: %s\n", snapshot->uniqueid);
+	ast_cli(a->fd, "Type: %s\n", S_OR(snapshot->subclass, "<unknown>"));
+	ast_cli(a->fd, "Technology: %s\n", S_OR(snapshot->technology, "<unknown>"));
+	ast_cli(a->fd, "Num-Channels: %u\n", snapshot->num_channels);
+	ao2_callback(snapshot->channels, OBJ_NODATA, bridge_show_specific_print_channel, a);
 
 	return CLI_SUCCESS;
 }

Modified: trunk/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/channel.c?view=diff&rev=393831&r1=393830&r2=393831
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Mon Jul  8 14:19:55 2013
@@ -126,22 +126,6 @@
 	const struct ast_channel_tech *tech;
 	AST_LIST_ENTRY(chanlist) list;
 };
-
-#ifdef CHANNEL_TRACE
-/*! \brief Structure to hold channel context backtrace data */
-struct ast_chan_trace_data {
-	int enabled;
-	AST_LIST_HEAD_NOLOCK(, ast_chan_trace) trace;
-};
-
-/*! \brief Structure to save contexts where an ast_chan has been into */
-struct ast_chan_trace {
-	char context[AST_MAX_CONTEXT];
-	char exten[AST_MAX_EXTENSION];
-	int priority;
-	AST_LIST_ENTRY(ast_chan_trace) entry;
-};
-#endif
 
 /*! \brief the list of registered channel types */
 static AST_RWLIST_HEAD_STATIC(backends, chanlist);
@@ -471,132 +455,6 @@
 	.fixup = kill_fixup,
 	.hangup = kill_hangup,
 };
-
-#ifdef CHANNEL_TRACE
-/*! \brief Destructor for the channel trace datastore */
-static void ast_chan_trace_destroy_cb(void *data)
-{
-	struct ast_chan_trace *trace;
-	struct ast_chan_trace_data *traced = data;
-	while ((trace = AST_LIST_REMOVE_HEAD(&traced->trace, entry))) {
-		ast_free(trace);
-	}
-	ast_free(traced);
-}
-
-/*! \brief Datastore to put the linked list of ast_chan_trace and trace status */
-static const struct ast_datastore_info ast_chan_trace_datastore_info = {
-	.type = "ChanTrace",
-	.destroy = ast_chan_trace_destroy_cb
-};
-
-/*! \brief Put the channel backtrace in a string */
-int ast_channel_trace_serialize(struct ast_channel *chan, struct ast_str **buf)
-{
-	int total = 0;
-	struct ast_chan_trace *trace;
-	struct ast_chan_trace_data *traced;
-	struct ast_datastore *store;
-
-	ast_channel_lock(chan);
-	store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
-	if (!store) {
-		ast_channel_unlock(chan);
-		return total;
-	}
-	traced = store->data;
-	ast_str_reset(*buf);
-	AST_LIST_TRAVERSE(&traced->trace, trace, entry) {
-		if (ast_str_append(buf, 0, "[%d] => %s, %s, %d\n", total, trace->context, trace->exten, trace->priority) < 0) {
-			ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
-			total = -1;
-			break;
-		}
-		total++;
-	}
-	ast_channel_unlock(chan);
-	return total;
-}
-
-/* !\brief Whether or not context tracing is enabled */
-int ast_channel_trace_is_enabled(struct ast_channel *chan)
-{
-	struct ast_datastore *store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
-	if (!store)
-		return 0;
-	return ((struct ast_chan_trace_data *)store->data)->enabled;
-}
-
-/*! \brief Update the context backtrace data if tracing is enabled */
-static int ast_channel_trace_data_update(struct ast_channel *chan, struct ast_chan_trace_data *traced)
-{
-	struct ast_chan_trace *trace;
-	if (!traced->enabled)
-		return 0;
-	/* If the last saved context does not match the current one
-	   OR we have not saved any context so far, then save the current context */
-	if ((!AST_LIST_EMPTY(&traced->trace) && strcasecmp(AST_LIST_FIRST(&traced->trace)->context, ast_channel_context(chan))) ||
-	    (AST_LIST_EMPTY(&traced->trace))) {
-		/* Just do some debug logging */
-		if (AST_LIST_EMPTY(&traced->trace))
-			ast_debug(1, "Setting initial trace context to %s\n", ast_channel_context(chan));
-		else
-			ast_debug(1, "Changing trace context from %s to %s\n", AST_LIST_FIRST(&traced->trace)->context, ast_channel_context(chan));
-		/* alloc or bail out */
-		trace = ast_malloc(sizeof(*trace));
-		if (!trace)
-			return -1;
-		/* save the current location and store it in the trace list */
-		ast_copy_string(trace->context, ast_channel_context(chan), sizeof(trace->context));
-		ast_copy_string(trace->exten, ast_channel_exten(chan), sizeof(trace->exten));
-		trace->priority = ast_channel_priority(chan);
-		AST_LIST_INSERT_HEAD(&traced->trace, trace, entry);
-	}
-	return 0;
-}
-
-/*! \brief Update the context backtrace if tracing is enabled */
-int ast_channel_trace_update(struct ast_channel *chan)
-{
-	struct ast_datastore *store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
-	if (!store)
-		return 0;
-	return ast_channel_trace_data_update(chan, store->data);
-}
-
-/*! \brief Enable context tracing in the channel */
-int ast_channel_trace_enable(struct ast_channel *chan)
-{
-	struct ast_datastore *store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
-	struct ast_chan_trace_data *traced;
-	if (!store) {
-		store = ast_datastore_alloc(&ast_chan_trace_datastore_info, "ChanTrace");
-		if (!store)
-			return -1;
-		traced = ast_calloc(1, sizeof(*traced));
-		if (!traced) {
-			ast_datastore_free(store);
-			return -1;
-		}
-		store->data = traced;
-		AST_LIST_HEAD_INIT_NOLOCK(&traced->trace);
-		ast_channel_datastore_add(chan, store);
-	}
-	((struct ast_chan_trace_data *)store->data)->enabled = 1;
-	ast_channel_trace_data_update(chan, store->data);
-	return 0;
-}
-
-/*! \brief Disable context tracing in the channel */
-int ast_channel_trace_disable(struct ast_channel *chan)
-{
-	struct ast_datastore *store = ast_channel_datastore_find(chan, &ast_chan_trace_datastore_info, NULL);
-	if (!store)
-		return 0;
-	((struct ast_chan_trace_data *)store->data)->enabled = 0;
-	return 0;
-}
-#endif /* CHANNEL_TRACE */
 
 /*! \brief Checks to see if a channel is needing hang up */
 int ast_check_hangup(struct ast_channel *chan)
@@ -5357,6 +5215,9 @@
 		if (direction && ast_channel_generatordata(chan)) {
 			generator_write_format_change(chan);
 		}
+
+		ast_channel_publish_snapshot(chan);
+
 		return 0;
 	}
 
@@ -5429,6 +5290,9 @@
 	if (direction && ast_channel_generatordata(chan)) {
 		generator_write_format_change(chan);
 	}
+
+	ast_channel_publish_snapshot(chan);
+
 	return res;
 }
 
@@ -7782,7 +7646,7 @@
 }
 
 /*!
- * \brief Destructor for the return value from ast_channel_get_manager_vars().
+ * \brief Destructor for lists of variables.
  * \param obj AO2 object.
  */
 static void varshead_dtor(void *obj)
@@ -7793,6 +7657,31 @@
 	while ((var = AST_RWLIST_REMOVE_HEAD(head, entries))) {
 		ast_var_delete(var);
 	}
+}
+
+struct varshead *ast_channel_get_vars(struct ast_channel *chan)
+{
+	RAII_VAR(struct varshead *, ret, NULL, ao2_cleanup);
+	struct ast_var_t *cv;
+
+	ret = ao2_alloc(sizeof(*ret), varshead_dtor);
+
+	if (!ret) {
+		return NULL;
+	}
+
+	AST_LIST_TRAVERSE(ast_channel_varshead(chan), cv, entries) {
+		struct ast_var_t *var = ast_var_assign(ast_var_name(cv), ast_var_value(cv));
+
+		if (!var) {
+			return NULL;
+		}
+
+		AST_LIST_INSERT_TAIL(ret, var, entries);
+	}
+
+	ao2_ref(ret, +1);
+	return ret;
 }
 
 struct varshead *ast_channel_get_manager_vars(struct ast_channel *chan)

Modified: trunk/main/channel_internal_api.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/channel_internal_api.c?view=diff&rev=393831&r1=393830&r2=393831
==============================================================================
--- trunk/main/channel_internal_api.c (original)
+++ trunk/main/channel_internal_api.c Mon Jul  8 14:19:55 2013
@@ -868,6 +868,7 @@
 void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
 {
 	chan->tech = value;
+	ast_channel_publish_snapshot(chan);
 }
 enum ast_channel_adsicpe ast_channel_adsicpe(const struct ast_channel *chan)
 {
@@ -913,6 +914,7 @@
 		call_identifier_to,
 		call_identifier_from);
 
+	ast_channel_publish_snapshot(chan);
 }
 void ast_channel_state_set(struct ast_channel *chan, enum ast_channel_state value)
 {
@@ -1037,6 +1039,7 @@
 void ast_channel_whentohangup_set(struct ast_channel *chan, struct timeval *value)
 {
 	chan->whentohangup = *value;
+	ast_channel_publish_snapshot(chan);
 }
 void ast_channel_varshead_set(struct ast_channel *chan, struct varshead *value)
 {
@@ -1094,6 +1097,7 @@
 void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
 {
 	chan->callgroup = value;
+	ast_channel_publish_snapshot(chan);
 }
 ast_group_t ast_channel_pickupgroup(const struct ast_channel *chan)
 {
@@ -1102,6 +1106,7 @@
 void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
 {
 	chan->pickupgroup = value;
+	ast_channel_publish_snapshot(chan);
 }
 struct ast_namedgroups *ast_channel_named_callgroups(const struct ast_channel *chan)
 {
@@ -1277,6 +1282,7 @@
 void ast_channel_internal_bridge_set(struct ast_channel *chan, struct ast_bridge *value)
 {
 	chan->bridge = value;
+	ast_channel_publish_snapshot(chan);
 }
 
 struct ast_bridge_channel *ast_channel_internal_bridge_channel(const struct ast_channel *chan)

Modified: trunk/main/cli.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/cli.c?view=diff&rev=393831&r1=393830&r2=393831
==============================================================================
--- trunk/main/cli.c (original)
+++ trunk/main/cli.c Mon Jul  8 14:19:55 2013
@@ -61,6 +61,8 @@
 #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 @@
 #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 @@
 	} 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 @@
 				"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 @@
 				}
 			}
 			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);
-			}
-		}
-		ast_channel_unlock(c);
-		ao2_cleanup(bridge);
-	}
-
-	if (iter) {
-		ast_channel_iterator_destroy(iter);
-	}
+				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);
+			}
+		}
+	}
+	ao2_iterator_destroy(&it_chans);
 
 	if (!concise) {
 		numchans = ast_active_channels();
@@ -1414,23 +1411,15 @@
 
 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 @@
 
 	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 @@
 		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;
@@ -1474,15 +1462,6 @@
 	} else {
 		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"
@@ -1499,15 +1478,11 @@
 		"    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 @@
 		"   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')) {
+		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");
+
+	AST_LIST_TRAVERSE(snapshot->channel_vars, var, entries) {
+		ast_str_append(&output, 0, "%s=%s\n", ast_var_name(var), ast_var_value(var));
+	}
+
+	if (ast_cdr_serialize_variables(snapshot->name, &obuf, '=', '\n')) {
 		ast_str_append(&output, 0, "  CDR Variables:\n%s\n", ast_str_buffer(obuf));
 	}
-
-#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));
-	}
-#endif
-
-	ast_channel_unlock(c);
-	c = ast_channel_unref(c);
-	ao2_cleanup(bridge);
 
 	ast_cli(a->fd, "%s", ast_str_buffer(output));
 	ast_free(output);
@@ -1605,38 +1561,32 @@
 
 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 = &notfound; /* 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) {
-		return NULL;
-	}
-
-	while (ret == &notfound && (c = ast_channel_iterator_next(iter))) {
-		if (++which > state) {
-			ast_channel_lock(c);
-			ret = ast_strdup(ast_channel_name(c));
-			ast_channel_unlock(c);
-		}
-		ast_channel_unref(c);
-	}
-
-	ast_channel_iterator_destroy(iter);
-
-	return ret == &notfound ? NULL : ret;
+	if (!(cached_channels = stasis_cache_dump(ast_channel_topic_all_cached(), ast_channel_snapshot_type()))) {
+		return NULL;
+	}
+
+	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;
+		}
+	}
+	ao2_iterator_destroy(&iter);
+
+	return ret;
 }
 
 static char *group_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
@@ -2037,7 +1987,7 @@
  * \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.
  *

Modified: trunk/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/manager.c?view=diff&rev=393831&r1=393830&r2=393831
==============================================================================
--- trunk/main/manager.c (original)
+++ trunk/main/manager.c Mon Jul  8 14:19:55 2013
@@ -92,8 +92,9 @@
 #include "asterisk/strings.h"
 #include "asterisk/stringfields.h"
 #include "asterisk/presencestate.h"
-#include "asterisk/stasis.h"
 #include "asterisk/stasis_message_router.h"
+#include "asterisk/stasis_channels.h"
+#include "asterisk/stasis_bridging.h"
 #include "asterisk/test.h"
 #include "asterisk/json.h"
 #include "asterisk/bridging.h"
@@ -221,6 +222,106 @@
 			value for the specified channel variables.</para>
 		</description>
 	</manager>
+	<managerEvent language="en_US" name="Status">
+		<managerEventInstance class="EVENT_FLAG_CALL">
+			<synopsis>Raised in response to a Status command.</synopsis>
+			<syntax>
+				<parameter name="ActionID" required="false"/>
+				<parameter name="Channel">
+					<para>Name of the channel</para>
+				</parameter>
+				<parameter name="Type">
+					<para>Type of channel</para>
+				</parameter>
+				<parameter name="DNID">
+					<para>Dialed number identifier</para>
+				</parameter>
+				<parameter name="ChannelState">
+					<para>A numeric code for the channel's current state, related to ChannelStateDesc</para>
+				</parameter>
+				<parameter name="ChannelStateDesc">
+					<para>Name for the channel's current state</para>
+					<enumlist>
+						<enum name="Down"/>
+						<enum name="Rsrvd"/>
+						<enum name="OffHook"/>
+						<enum name="Dialing"/>
+						<enum name="Ring"/>
+						<enum name="Ringing"/>
+						<enum name="Up"/>
+						<enum name="Busy"/>
+						<enum name="Dialing Offhook"/>
+						<enum name="Pre-ring"/>
+						<enum name="Unknown"/>
+					</enumlist>
+				</parameter>
+				<parameter name="CallerIDNum">
+				</parameter>
+				<parameter name="CallerIDName">
+				</parameter>
+				<parameter name="ConnectedLineNum">
+				</parameter>
+				<parameter name="ConnectedLineName">
+				</parameter>
+				<parameter name="EffectiveConnectedLineNum">
+				</parameter>
+				<parameter name="EffectiveConnectedLineName">
+				</parameter>
+				<parameter name="AccountCode">
+				</parameter>
+				<parameter name="Context">
+				</parameter>
+				<parameter name="Exten">
+				</parameter>
+				<parameter name="Priority">
+				</parameter>
+				<parameter name="Uniqueid">
+					<para>Unique identifier for the channel</para>
+				</parameter>
+				<parameter name="TimeToHangup">
+					<para>Absolute lifetime of the channel</para>
+				</parameter>
+				<parameter name="BridgeID">
+					<para>Identifier of the bridge the channel is in, may be empty if not in one</para>
+				</parameter>
+				<parameter name="Linkedid">
+				</parameter>
+				<parameter name="Application">
+					<para>Application currently executing on the channel</para>
+				</parameter>
+				<parameter name="Data">
+					<para>Data given to the currently executing channel</para>
+				</parameter>
+				<parameter name="Nativeformats">
+					<para>Media formats the connected party is willing to send or receive</para>
+				</parameter>
+				<parameter name="Readformat">
+					<para>Media formats that frames from the channel are received in</para>
+				</parameter>
+				<parameter name="Readtrans">
+					<para>Translation path for media received in native formats</para>
+				</parameter>
+				<parameter name="Writeformat">
+					<para>Media formats that frames to the channel are accepted in</para>
+				</parameter>
+				<parameter name="Writetrans">
+					<para>Translation path for media sent to the connected party</para>
+				</parameter>
+				<parameter name="Callgroup">
+					<para>Configured call group on the channel</para>
+				</parameter>
+				<parameter name="Pickupgroup">
+					<para>Configured pickup group on the channel</para>
+				</parameter>
+				<parameter name="Seconds">
+					<para>Number of seconds the channel has been active</para>
+				</parameter>
+			</syntax>
+			<see-also>
+				<ref type="manager">Status</ref>
+			</see-also>
+		</managerEventInstance>
+	</managerEvent>
 	<manager name="Setvar" language="en_US">
 		<synopsis>
 			Set a channel variable.
@@ -3745,11 +3846,8 @@
 	const char *name = astman_get_header(m, "Channel");
 	const char *cvariables = astman_get_header(m, "Variables");
 	char *variables = ast_strdupa(S_OR(cvariables, ""));
-	struct ast_channel *c;
-	struct ast_bridge *bridge;
-	char bridge_text[256];
-	struct timeval now = ast_tvnow();
-	long elapsed_seconds = 0;
+	RAII_VAR(struct ao2_container *, cached_channels, NULL, ao2_cleanup);
+	struct stasis_message *msg;
 	int channels = 0;
 	int all = ast_strlen_zero(name); /* set if we want all channels */
 	const char *id = astman_get_header(m, "ActionID");

[... 564 lines stripped ...]



More information about the asterisk-commits mailing list