summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/app_agent_pool.c4
-rw-r--r--apps/app_meetme.c4
-rw-r--r--apps/app_queue.c12
-rw-r--r--include/asterisk/channel.h9
-rw-r--r--include/asterisk/stasis_channels.h39
-rw-r--r--main/aoc.c2
-rw-r--r--main/bridge_channel.c10
-rw-r--r--main/cel.c4
-rw-r--r--main/channel.c41
-rw-r--r--main/channel_internal_api.c6
-rw-r--r--main/cli.c121
-rw-r--r--main/core_local.c10
-rw-r--r--main/dial.c2
-rw-r--r--main/endpoints.c3
-rw-r--r--main/manager.c157
-rw-r--r--main/pbx.c24
-rw-r--r--main/pickup.c4
-rw-r--r--main/stasis_bridges.c12
-rw-r--r--main/stasis_cache.c21
-rw-r--r--main/stasis_channels.c71
-rw-r--r--res/ari/resource_channels.c4
-rw-r--r--res/res_agi.c24
-rw-r--r--res/res_pjsip/pjsip_configuration.c9
23 files changed, 322 insertions, 271 deletions
diff --git a/apps/app_agent_pool.c b/apps/app_agent_pool.c
index a6a68f1a3..5095001cf 100644
--- a/apps/app_agent_pool.c
+++ b/apps/app_agent_pool.c
@@ -1442,7 +1442,7 @@ static void send_agent_login(struct ast_channel *chan, const char *agent)
return;
}
- ast_channel_publish_blob(chan, ast_channel_agent_login_type(), blob);
+ ast_channel_publish_cached_blob(chan, ast_channel_agent_login_type(), blob);
}
static void send_agent_logoff(struct ast_channel *chan, const char *agent, long logintime)
@@ -1458,7 +1458,7 @@ static void send_agent_logoff(struct ast_channel *chan, const char *agent, long
return;
}
- ast_channel_publish_blob(chan, ast_channel_agent_logoff_type(), blob);
+ ast_channel_publish_cached_blob(chan, ast_channel_agent_logoff_type(), blob);
}
/*!
diff --git a/apps/app_meetme.c b/apps/app_meetme.c
index b6f5fffb9..1a780e6ff 100644
--- a/apps/app_meetme.c
+++ b/apps/app_meetme.c
@@ -1379,9 +1379,7 @@ static void meetme_stasis_generate_msg(struct ast_conference *meetme_conference,
}
}
- ast_channel_lock(chan);
- msg = ast_channel_blob_create(chan, message_type, json_object);
- ast_channel_unlock(chan);
+ msg = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), message_type, json_object);
if (!msg) {
return;
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 8e26135cd..fe6b00ab0 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -3510,9 +3510,7 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *
"Queue", q->name,
"Position", qe->pos,
"Count", q->count);
- ast_channel_lock(qe->chan);
- ast_channel_publish_blob(qe->chan, queue_caller_join_type(), blob);
- ast_channel_unlock(qe->chan);
+ ast_channel_publish_cached_blob(qe->chan, queue_caller_join_type(), blob);
ast_debug(1, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, ast_channel_name(qe->chan), qe->pos );
}
ao2_unlock(q);
@@ -3791,9 +3789,7 @@ static void leave_queue(struct queue_ent *qe)
"Queue", q->name,
"Position", qe->pos,
"Count", q->count);
- ast_channel_lock(qe->chan);
- ast_channel_publish_blob(qe->chan, queue_caller_leave_type(), blob);
- ast_channel_unlock(qe->chan);
+ ast_channel_publish_cached_blob(qe->chan, queue_caller_leave_type(), blob);
ast_debug(1, "Queue '%s' Leave, Channel '%s'\n", q->name, ast_channel_name(qe->chan));
/* Take us out of the queue */
if (prev) {
@@ -4395,9 +4391,7 @@ static void record_abandoned(struct queue_ent *qe)
qe->parent->callsabandoned++;
ao2_unlock(qe->parent);
- ast_channel_lock(qe->chan);
- ast_channel_publish_blob(qe->chan, queue_caller_abandon_type(), blob);
- ast_channel_unlock(qe->chan);
+ ast_channel_publish_cached_blob(qe->chan, queue_caller_abandon_type(), blob);
}
/*! \brief RNA == Ring No Answer. Common code that is executed when we try a queue member and they don't answer. */
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 3575bae8f..505e4bac9 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -4179,6 +4179,15 @@ void ast_channel_dialed_causes_clear(const struct ast_channel *chan);
struct ast_flags *ast_channel_flags(struct ast_channel *chan);
/*!
+ * \since 12.4.0
+ * \brief Return whether or not any manager variables have been set
+ *
+ * \retval 0 if no manager variables are expected
+ * \retval 1 if manager variables are expected
+ */
+int ast_channel_has_manager_vars(void);
+
+/*!
* \since 12
* \brief Sets the variables to be stored in the \a manager_vars field of all
* snapshots.
diff --git a/include/asterisk/stasis_channels.h b/include/asterisk/stasis_channels.h
index b4097b31b..a252a2a90 100644
--- a/include/asterisk/stasis_channels.h
+++ b/include/asterisk/stasis_channels.h
@@ -39,17 +39,16 @@
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 */
AST_STRING_FIELD(uniqueid); /*!< Unique Channel Identifier */
AST_STRING_FIELD(linkedid); /*!< Linked Channel Identifier -- gets propagated by linkage */
- AST_STRING_FIELD(hangupsource); /*!< Who is responsible for hanging up this channel */
AST_STRING_FIELD(appl); /*!< Current application */
AST_STRING_FIELD(data); /*!< Data passed to current application */
AST_STRING_FIELD(context); /*!< Dialplan: Current extension context */
AST_STRING_FIELD(exten); /*!< Dialplan: Current extension number */
+ 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 */
+ AST_STRING_FIELD(hangupsource); /*!< Who is responsible for hanging up this channel */
AST_STRING_FIELD(caller_name); /*!< Caller ID Name */
AST_STRING_FIELD(caller_number); /*!< Caller ID Number */
AST_STRING_FIELD(caller_dnid); /*!< Dialed ID Number */
@@ -59,31 +58,20 @@ struct ast_channel_snapshot {
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 */
+ AST_STRING_FIELD(type); /*!< Type of channel technology */
);
- 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 */
int tech_properties; /*!< Properties of the channel's technology */
};
@@ -321,6 +309,23 @@ void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_ty
struct ast_json *blob);
/*!
+ * \brief Publish a channel blob message using the latest snapshot from the cache
+ * \since 12.4.0
+ *
+ * \param chan Channel publishing the blob.
+ * \param type Type of stasis message.
+ * \param blob The blob being published. (NULL if no blob)
+ *
+ * \note As this only accesses the uniqueid and topic of the channel - neither of
+ * which should ever be changed on a channel anyhow - a channel does not have to
+ * be locked when calling this function.
+ *
+ * \return Nothing
+ */
+void ast_channel_publish_cached_blob(struct ast_channel *chan, struct stasis_message_type *type,
+ struct ast_json *blob);
+
+/*!
* \since 12
* \brief Set flag to indicate channel snapshot is being staged.
*
diff --git a/main/aoc.c b/main/aoc.c
index 7dd888ec2..de43efcb5 100644
--- a/main/aoc.c
+++ b/main/aoc.c
@@ -1871,7 +1871,7 @@ int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_chan
return 0;
}
- ast_channel_publish_blob(chan, msg_type, blob);
+ ast_channel_publish_cached_blob(chan, msg_type, blob);
return 0;
}
diff --git a/main/bridge_channel.c b/main/bridge_channel.c
index 9a1e40bba..9b1b5737e 100644
--- a/main/bridge_channel.c
+++ b/main/bridge_channel.c
@@ -838,18 +838,16 @@ int ast_bridge_channel_write_hold(struct ast_bridge_channel *bridge_channel, con
datalen = 0;
}
- ast_channel_lock(bridge_channel->chan);
- ast_channel_publish_blob(bridge_channel->chan, ast_channel_hold_type(), blob);
- ast_channel_unlock(bridge_channel->chan);
+ ast_channel_publish_cached_blob(bridge_channel->chan, ast_channel_hold_type(), blob);
+
return ast_bridge_channel_write_control_data(bridge_channel, AST_CONTROL_HOLD,
moh_class, datalen);
}
int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel)
{
- ast_channel_lock(bridge_channel->chan);
- ast_channel_publish_blob(bridge_channel->chan, ast_channel_unhold_type(), NULL);
- ast_channel_unlock(bridge_channel->chan);
+ ast_channel_publish_cached_blob(bridge_channel->chan, ast_channel_unhold_type(), NULL);
+
return ast_bridge_channel_write_control_data(bridge_channel, AST_CONTROL_UNHOLD, NULL, 0);
}
diff --git a/main/cel.c b/main/cel.c
index e61adfcec..c7f4fc366 100644
--- a/main/cel.c
+++ b/main/cel.c
@@ -1798,9 +1798,7 @@ void ast_cel_publish_event(struct ast_channel *chan,
"event_type", event_type,
"event_details", blob);
- ast_channel_lock(chan);
- message = ast_channel_blob_create(chan, cel_generic_type(), cel_blob);
- ast_channel_unlock(chan);
+ message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), cel_generic_type(), cel_blob);
if (message) {
stasis_publish(ast_cel_topic(), message);
}
diff --git a/main/channel.c b/main/channel.c
index dd3539479..04c396a71 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -1270,7 +1270,6 @@ int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HOLD };
int res;
- ast_channel_lock(chan);
if (!ast_strlen_zero(musicclass)) {
f.data.ptr = (void *) musicclass;
f.datalen = strlen(musicclass) + 1;
@@ -1279,10 +1278,10 @@ int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
"musicclass", musicclass);
}
- ast_channel_publish_blob(chan, ast_channel_hold_type(), blob);
+ ast_channel_publish_cached_blob(chan, ast_channel_hold_type(), blob);
res = ast_queue_frame(chan, &f);
- ast_channel_unlock(chan);
+
return res;
}
@@ -1291,11 +1290,10 @@ int ast_queue_unhold(struct ast_channel *chan)
struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_UNHOLD };
int res;
- ast_channel_lock(chan);
- ast_channel_publish_blob(chan, ast_channel_unhold_type(), NULL);
+ ast_channel_publish_cached_blob(chan, ast_channel_unhold_type(), NULL);
res = ast_queue_frame(chan, &f);
- ast_channel_unlock(chan);
+
return res;
}
@@ -3639,7 +3637,7 @@ static void send_dtmf_begin_event(struct ast_channel *chan,
return;
}
- ast_channel_publish_blob(chan, ast_channel_dtmf_begin_type(), blob);
+ ast_channel_publish_cached_blob(chan, ast_channel_dtmf_begin_type(), blob);
}
static void send_dtmf_end_event(struct ast_channel *chan,
@@ -3656,7 +3654,7 @@ static void send_dtmf_end_event(struct ast_channel *chan,
return;
}
- ast_channel_publish_blob(chan, ast_channel_dtmf_end_type(), blob);
+ ast_channel_publish_cached_blob(chan, ast_channel_dtmf_end_type(), blob);
}
static void ast_read_generator_actions(struct ast_channel *chan, struct ast_frame *f)
@@ -3988,7 +3986,6 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
ast_frfree(f);
f = &ast_null_frame;
} else {
- /* Answer the CDR */
ast_setstate(chan, AST_STATE_UP);
}
} else if (f->subclass.integer == AST_CONTROL_READ_ACTION) {
@@ -5332,10 +5329,6 @@ static int set_format(struct ast_channel *chan,
generator_write_format_change(chan);
}
- ast_channel_lock(chan);
- ast_channel_publish_snapshot(chan);
- ast_channel_unlock(chan);
-
return 0;
}
@@ -5415,10 +5408,6 @@ static int set_format(struct ast_channel *chan,
generator_write_format_change(chan);
}
- ast_channel_lock(chan);
- ast_channel_publish_snapshot(chan);
- ast_channel_unlock(chan);
-
return res;
}
@@ -7414,6 +7403,17 @@ static void free_channelvars(void)
AST_RWLIST_UNLOCK(&channelvars);
}
+int ast_channel_has_manager_vars(void)
+{
+ int vars_present;
+
+ AST_RWLIST_RDLOCK(&channelvars);
+ vars_present = !AST_LIST_EMPTY(&channelvars);
+ AST_RWLIST_UNLOCK(&channelvars);
+
+ return vars_present;
+}
+
void ast_channel_set_manager_vars(size_t varc, char **vars)
{
size_t i;
@@ -7644,12 +7644,9 @@ void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
{
struct ast_variable *cur;
- ast_channel_stage_snapshot(chan);
-
- for (cur = vars; cur; cur = cur->next)
+ for (cur = vars; cur; cur = cur->next) {
pbx_builtin_setvar_helper(chan, cur->name, cur->value);
-
- ast_channel_stage_snapshot_done(chan);
+ }
}
static void *silence_generator_alloc(struct ast_channel *chan, void *data)
diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c
index 9cc99f3d5..0c5117e6d 100644
--- a/main/channel_internal_api.c
+++ b/main/channel_internal_api.c
@@ -943,9 +943,8 @@ void ast_channel_callid_set(struct ast_channel *chan, struct ast_callid *callid)
ast_channel_name(chan),
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)
{
chan->state = value;
@@ -1073,7 +1072,6 @@ void ast_channel_dtmf_tv_set(struct ast_channel *chan, struct timeval *value)
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)
{
@@ -1131,7 +1129,6 @@ ast_group_t ast_channel_callgroup(const struct ast_channel *chan)
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)
{
@@ -1140,7 +1137,6 @@ ast_group_t ast_channel_pickupgroup(const struct ast_channel *chan)
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)
{
diff --git a/main/cli.c b/main/cli.c
index 0fbdb69f6..bff58695d 100644
--- a/main/cli.c
+++ b/main/cli.c
@@ -1513,8 +1513,7 @@ 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)
{
- RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
- struct ast_channel_snapshot *snapshot;
+ struct ast_channel *chan;
struct timeval now;
char cdrtime[256];
struct ast_str *obuf;/*!< Buffer for CDR variables. */
@@ -1522,6 +1521,12 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
long elapsed_seconds=0;
int hour=0, min=0, sec=0;
struct ast_var_t *var;
+ char nativeformats[256];
+ struct ast_str *write_transpath = ast_str_alloca(256);
+ struct ast_str *read_transpath = ast_str_alloca(256);
+ struct ast_bridge *bridge;
+ struct ast_callid *callid;
+ char callid_buf[32];
switch (cmd) {
case CLI_INIT:
@@ -1538,25 +1543,27 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
return CLI_SHOWUSAGE;
}
- now = ast_tvnow();
-
- if (!(msg = stasis_cache_get(ast_channel_cache_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) {
return CLI_FAILURE;
}
+
output = ast_str_create(8192);
if (!output) {
return CLI_FAILURE;
}
- if (!ast_tvzero(snapshot->creationtime)) {
- elapsed_seconds = now.tv_sec - snapshot->creationtime.tv_sec;
+ chan = ast_channel_get_by_name(a->argv[3]);
+ if (!chan) {
+ ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]);
+ return CLI_SUCCESS;
+ }
+
+ now = ast_tvnow();
+ ast_channel_lock(chan);
+
+ if (!ast_tvzero(ast_channel_creationtime(chan))) {
+ elapsed_seconds = now.tv_sec - ast_channel_creationtime(chan).tv_sec;
hour = elapsed_seconds / 3600;
min = (elapsed_seconds % 3600) / 60;
sec = elapsed_seconds % 60;
@@ -1565,6 +1572,16 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
strcpy(cdrtime, "N/A");
}
+ ast_translate_path_to_str(ast_channel_writetrans(chan), &write_transpath);
+ ast_translate_path_to_str(ast_channel_readtrans(chan), &read_transpath);
+
+ bridge = ast_channel_get_bridge(chan);
+ callid = ast_channel_callid(chan);
+ if (callid) {
+ ast_callid_strnprint(callid_buf, sizeof(callid_buf), callid);
+ ast_callid_unref(callid);
+ }
+
ast_str_append(&output, 0,
" -- General --\n"
" Name: %s\n"
@@ -1597,51 +1614,63 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
" Application: %s\n"
" Data: %s\n"
" Call Identifer: %s\n",
- 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,
+ ast_channel_name(chan),
+ ast_channel_tech(chan)->type,
+ ast_channel_uniqueid(chan),
+ ast_channel_linkedid(chan),
+ S_COR(ast_channel_caller(chan)->id.number.valid,
+ ast_channel_caller(chan)->id.number.str, "(N/A)"),
+ S_COR(ast_channel_caller(chan)->id.name.valid,
+ ast_channel_caller(chan)->id.name.str, "(N/A)"),
+ S_COR(ast_channel_connected(chan)->id.number.valid,
+ ast_channel_connected(chan)->id.number.str, "(N/A)"),
+ S_COR(ast_channel_connected(chan)->id.name.valid,
+ ast_channel_connected(chan)->id.name.str, "(N/A)"),
+ S_COR(ast_channel_connected_effective_id(chan).number.valid,
+ ast_channel_connected_effective_id(chan).number.str, "(N/A)"),
+ S_COR(ast_channel_connected_effective_id(chan).name.valid,
+ ast_channel_connected_effective_id(chan).name.str, "(N/A)"),
+ S_OR(ast_channel_dialed(chan)->number.str, "(N/A)"),
+ ast_channel_language(chan),
+ ast_state2str(ast_channel_state(chan)),
+ ast_channel_state(chan),
+ ast_getformatname_multiple(nativeformats, sizeof(nativeformats), ast_channel_nativeformats(chan)),
+ ast_getformatname(ast_channel_writeformat(chan)),
+ ast_getformatname(ast_channel_readformat(chan)),
+ ast_str_strlen(write_transpath) ? "Yes" : "No",
+ ast_str_buffer(write_transpath),
+ ast_str_strlen(read_transpath) ? "Yes" : "No",
+ ast_str_buffer(read_transpath),
+ ast_channel_whentohangup(chan)->tv_sec,
cdrtime,
- 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)"));
-
+ bridge ? bridge->uniqueid : "(Not bridged)",
+ ast_channel_context(chan),
+ ast_channel_exten(chan),
+ ast_channel_priority(chan),
+ ast_channel_callgroup(chan),
+ ast_channel_pickupgroup(chan),
+ S_OR(ast_channel_appl(chan), "(N/A)"),
+ S_OR(ast_channel_data(chan), "(Empty)"),
+ S_OR(callid_buf, "(None)")
+ );
ast_str_append(&output, 0, " Variables:\n");
- AST_LIST_TRAVERSE(snapshot->channel_vars, var, entries) {
+ AST_LIST_TRAVERSE(ast_channel_varshead(chan), 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')) {
+ if (ast_cdr_serialize_variables(ast_channel_name(chan), &obuf, '=', '\n')) {
ast_str_append(&output, 0, " CDR Variables:\n%s\n", ast_str_buffer(obuf));
}
+ ast_channel_unlock(chan);
+
ast_cli(a->fd, "%s", ast_str_buffer(output));
ast_free(output);
+
+ ao2_cleanup(bridge);
+ ast_channel_unref(chan);
+
return CLI_SUCCESS;
}
diff --git a/main/core_local.c b/main/core_local.c
index 98db5e575..e803f29ec 100644
--- a/main/core_local.c
+++ b/main/core_local.c
@@ -328,12 +328,12 @@ static struct ast_multi_channel_blob *local_channel_optimization_blob(struct loc
RAII_VAR(struct ast_channel_snapshot *, local_one_snapshot, NULL, ao2_cleanup);
RAII_VAR(struct ast_channel_snapshot *, local_two_snapshot, NULL, ao2_cleanup);
- local_one_snapshot = ast_channel_snapshot_create(p->base.owner);
+ local_one_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(p->base.owner));
if (!local_one_snapshot) {
return NULL;
}
- local_two_snapshot = ast_channel_snapshot_create(p->base.chan);
+ local_two_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(p->base.chan));
if (!local_two_snapshot) {
return NULL;
}
@@ -371,7 +371,7 @@ static void local_optimization_started_cb(struct ast_unreal_pvt *base, struct as
if (source) {
RAII_VAR(struct ast_channel_snapshot *, source_snapshot, NULL, ao2_cleanup);
- source_snapshot = ast_channel_snapshot_create(source);
+ source_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(source));
if (!source_snapshot) {
return;
}
@@ -516,12 +516,12 @@ static void publish_local_bridge_message(struct local_pvt *p)
goto end;
}
- one_snapshot = ast_channel_snapshot_create(owner);
+ one_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(owner));
if (!one_snapshot) {
goto end;
}
- two_snapshot = ast_channel_snapshot_create(chan);
+ two_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
if (!two_snapshot) {
goto end;
}
diff --git a/main/dial.c b/main/dial.c
index 2563c707b..f03d43d25 100644
--- a/main/dial.c
+++ b/main/dial.c
@@ -323,7 +323,7 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe
ast_channel_appl_set(channel->owner, "AppDial2");
ast_channel_data_set(channel->owner, "(Outgoing Line)");
- ast_publish_channel_state(channel->owner);
+
memset(ast_channel_whentohangup(channel->owner), 0, sizeof(*ast_channel_whentohangup(channel->owner)));
/* Inherit everything from he who spawned this dial */
diff --git a/main/endpoints.c b/main/endpoints.c
index 9cc0178e0..10b32e268 100644
--- a/main/endpoints.c
+++ b/main/endpoints.c
@@ -203,9 +203,6 @@ int ast_endpoint_add_channel(struct ast_endpoint *endpoint,
ast_str_container_add(endpoint->channel_ids, ast_channel_uniqueid(chan));
ao2_unlock(endpoint);
- ast_channel_lock(chan);
- ast_publish_channel_state(chan);
- ast_channel_unlock(chan);
endpoint_publish_snapshot(endpoint);
return 0;
diff --git a/main/manager.c b/main/manager.c
index 7a7e8903a..6e056a163 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -99,6 +99,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/bridge.h"
#include "asterisk/features_config.h"
#include "asterisk/rtp_engine.h"
+#include "asterisk/translate.h"
/*** DOCUMENTATION
<manager name="Ping" language="en_US">
@@ -3846,95 +3847,110 @@ static int action_getvar(struct mansession *s, const struct message *m)
static int action_status(struct mansession *s, const struct message *m)
{
const char *name = astman_get_header(m, "Channel");
- const char *cvariables = astman_get_header(m, "Variables");
- char *variables = ast_strdupa(S_OR(cvariables, ""));
- RAII_VAR(struct ao2_container *, cached_channels, NULL, ao2_cleanup);
- struct stasis_message *msg;
+ const char *chan_variables = astman_get_header(m, "Variables");
+ const char *id = astman_get_header(m, "ActionID");
+ char *variables = ast_strdupa(S_OR(chan_variables, ""));
+ struct ast_str *variable_str = ast_str_create(1024);
+ struct ast_str *write_transpath = ast_str_alloca(256);
+ struct ast_str *read_transpath = ast_str_alloca(256);
+ struct ast_channel *chan;
+ char nativeformats[256];
int channels = 0;
int all = ast_strlen_zero(name); /* set if we want all channels */
- const char *id = astman_get_header(m, "ActionID");
- char idText[256];
+ char id_text[256];
+ struct ast_channel_iterator *it_chans = NULL;
AST_DECLARE_APP_ARGS(vars,
AST_APP_ARG(name)[100];
);
- struct ast_str *str = ast_str_create(1000);
- struct ao2_iterator it_chans;
- struct timeval now = ast_tvnow();
- if (!ast_strlen_zero(id)) {
- snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
- } else {
- idText[0] = '\0';
+ if (!variable_str) {
+ astman_send_error(s, m, "Memory Allocation Failure");
+ return 1;
}
if (!(function_capable_string_allowed_with_auths(variables, s->session->writeperm))) {
+ ast_free(variable_str);
astman_send_error(s, m, "Status Access Forbidden: Variables");
return 0;
}
if (all) {
- if (!(cached_channels = stasis_cache_dump(ast_channel_cache_by_name(), ast_channel_snapshot_type()))) {
- ast_free(str);
+ if (!(it_chans = ast_channel_iterator_all_new())) {
+ ast_free(variable_str);
astman_send_error(s, m, "Memory Allocation Failure");
return 1;
}
- it_chans = ao2_iterator_init(cached_channels, 0);
- msg = ao2_iterator_next(&it_chans);
+ chan = ast_channel_iterator_next(it_chans);
} else {
- if (!(msg = stasis_cache_get(ast_channel_cache_by_name(), ast_channel_snapshot_type(), name))) {
+ chan = ast_channel_get_by_name(name);
+ if (!chan) {
astman_send_error(s, m, "No such channel");
- ast_free(str);
+ ast_free(variable_str);
return 0;
}
}
astman_send_ack(s, m, "Channel status will follow");
- if (!ast_strlen_zero(cvariables)) {
+ if (!ast_strlen_zero(id)) {
+ snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
+ } else {
+ id_text[0] = '\0';
+ }
+
+ if (!ast_strlen_zero(chan_variables)) {
AST_STANDARD_APP_ARGS(vars, variables);
}
/* if we look by name, we break after the first iteration */
- for (; msg; ao2_ref(msg, -1), msg = all ? ao2_iterator_next(&it_chans) : NULL) {
- struct ast_channel_snapshot *snapshot = stasis_message_data(msg);
- struct ast_channel *c;
- struct ast_str *built = ast_manager_build_channel_state_string_prefix(snapshot, "");
- long elapsed_seconds = 0;
+ for (; chan; all ? chan = ast_channel_iterator_next(it_chans) : 0) {
+ struct timeval now;
+ long elapsed_seconds;
+ struct ast_bridge *bridge;
- if (!built) {
- continue;
- }
+ ast_channel_lock(chan);
+
+ now = ast_tvnow();
+ elapsed_seconds = ast_tvdiff_sec(now, ast_channel_creationtime(chan));
- if (!ast_strlen_zero(cvariables) && (c = ast_channel_get_by_name(snapshot->name))) {
+ if (!ast_strlen_zero(chan_variables)) {
int i;
- ast_str_reset(str);
+ ast_str_reset(variable_str);
for (i = 0; i < vars.argc; i++) {
char valbuf[512], *ret = NULL;
if (vars.name[i][strlen(vars.name[i]) - 1] == ')') {
- if (ast_func_read(c, vars.name[i], valbuf, sizeof(valbuf)) < 0) {
+ if (ast_func_read(chan, vars.name[i], valbuf, sizeof(valbuf)) < 0) {
valbuf[0] = '\0';
}
ret = valbuf;
} else {
- pbx_retrieve_variable(c, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL);
+ pbx_retrieve_variable(chan, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL);
}
- ast_str_append(&str, 0, "Variable: %s=%s\r\n", vars.name[i], ret);
+ ast_str_append(&variable_str, 0, "Variable: %s=%s\r\n", vars.name[i], ret);
}
- ast_channel_unref(c);
}
channels++;
-
- if (!ast_tvzero(snapshot->creationtime)) {
- elapsed_seconds = now.tv_sec - snapshot->creationtime.tv_sec;
- }
+ bridge = ast_channel_get_bridge(chan);
astman_append(s,
"Event: Status\r\n"
"Privilege: Call\r\n"
+ "Channel: %s\r\n"
+ "ChannelState: %u\r\n"
+ "ChannelStateDesc: %s\r\n"
+ "CallerIDNum: %s\r\n"
+ "CallerIDName: %s\r\n"
+ "ConnectedLineNum: %s\r\n"
+ "ConnectedLineName: %s\r\n"
+ "Accountcode: %s\r\n"
+ "Context: %s\r\n"
+ "Exten: %s\r\n"
+ "Priority: %d\r\n"
+ "Uniqueid: %s\r\n"
"Type: %s\r\n"
"DNID: %s\r\n"
"EffectiveConnectedLineNum: %s\r\n"
@@ -3954,43 +3970,56 @@ static int action_status(struct mansession *s, const struct message *m)
"Seconds: %ld\r\n"
"%s"
"%s"
- "%s"
"\r\n",
- snapshot->type,
- snapshot->caller_dnid,
- S_OR(snapshot->effective_number, "<unknown>"),
- S_OR(snapshot->effective_name, "<unknown>"),
- snapshot->hanguptime.tv_sec,
- snapshot->bridgeid,
- snapshot->linkedid,
- snapshot->appl,
- snapshot->data,
- snapshot->nativeformats,
- snapshot->readformat,
- snapshot->readtrans,
- snapshot->writeformat,
- snapshot->writetrans,
- snapshot->callgroup,
- snapshot->pickupgroup,
- (long) elapsed_seconds,
- ast_str_buffer(built),
- ast_str_buffer(str),
- idText);
+ ast_channel_name(chan),
+ ast_channel_state(chan),
+ ast_state2str(ast_channel_state(chan)),
+ S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "<unknown>"),
+ S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, "<unknown>"),
+ S_COR(ast_channel_connected(chan)->id.number.valid, ast_channel_connected(chan)->id.number.str, "<unknown>"),
+ S_COR(ast_channel_connected(chan)->id.name.valid, ast_channel_connected(chan)->id.name.str, "<unknown>"),
+ ast_channel_accountcode(chan),
+ ast_channel_context(chan),
+ ast_channel_exten(chan),
+ ast_channel_priority(chan),
+ ast_channel_uniqueid(chan),
+ ast_channel_tech(chan)->type,
+ S_OR(ast_channel_dialed(chan)->number.str, ""),
+ S_COR(ast_channel_connected_effective_id(chan).number.valid, ast_channel_connected_effective_id(chan).number.str, "<unknown>"),
+ S_COR(ast_channel_connected_effective_id(chan).name.valid, ast_channel_connected_effective_id(chan).name.str, "<unknown>"),
+ ast_channel_whentohangup(chan)->tv_sec,
+ bridge ? bridge->uniqueid : "",
+ ast_channel_linkedid(chan),
+ ast_channel_appl(chan),
+ ast_channel_data(chan),
+ ast_getformatname_multiple(nativeformats, sizeof(nativeformats), ast_channel_nativeformats(chan)),
+ ast_getformatname(ast_channel_readformat(chan)),
+ ast_translate_path_to_str(ast_channel_readtrans(chan), &read_transpath),
+ ast_getformatname(ast_channel_writeformat(chan)),
+ ast_translate_path_to_str(ast_channel_writetrans(chan), &write_transpath),
+ ast_channel_callgroup(chan),
+ ast_channel_pickupgroup(chan),
+ (long)elapsed_seconds,
+ ast_str_buffer(variable_str),
+ id_text);
+
+ ao2_cleanup(bridge);
- ast_free(built);
+ ast_channel_unlock(chan);
+ chan = ast_channel_unref(chan);
}
- if (all) {
- ao2_iterator_destroy(&it_chans);
+ if (it_chans) {
+ ast_channel_iterator_destroy(it_chans);
}
astman_append(s,
"Event: StatusComplete\r\n"
"%s"
"Items: %d\r\n"
- "\r\n", idText, channels);
+ "\r\n", id_text, channels);
- ast_free(str);
+ ast_free(variable_str);
return 0;
}
diff --git a/main/pbx.c b/main/pbx.c
index b1c50e5ab..3c7b127e6 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -8369,8 +8369,7 @@ static char *handle_show_device2extenstate(struct ast_cli_entry *e, int cmd, str
/*! \brief CLI support for listing chanvar's variables in a parseable way */
static char *handle_show_chanvar(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
- struct ast_channel_snapshot *snapshot;
+ struct ast_channel *chan;
struct ast_var_t *var;
switch (cmd) {
@@ -8384,19 +8383,23 @@ static char *handle_show_chanvar(struct ast_cli_entry *e, int cmd, struct ast_cl
return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
}
- if (a->argc != e->args + 1)
+ if (a->argc != e->args + 1) {
return CLI_SHOWUSAGE;
+ }
- if (!(msg = stasis_cache_get(ast_channel_cache_by_name(), ast_channel_snapshot_type(), a->argv[3]))) {
+ chan = ast_channel_get_by_name(a->argv[e->args]);
+ if (!chan) {
ast_cli(a->fd, "Channel '%s' not found\n", a->argv[e->args]);
return CLI_FAILURE;
}
- snapshot = stasis_message_data(msg);
- AST_LIST_TRAVERSE(snapshot->channel_vars, var, entries) {
+ ast_channel_lock(chan);
+ AST_LIST_TRAVERSE(ast_channel_varshead(chan), var, entries) {
ast_cli(a->fd, "%s=%s\n", ast_var_name(var), ast_var_value(var));
}
+ ast_channel_unlock(chan);
+ ast_channel_unref(chan);
return CLI_SUCCESS;
}
@@ -10187,7 +10190,7 @@ static void *pbx_outgoing_exec(void *data)
struct ast_app *app = pbx_findapp(outgoing->app);
if (app) {
- ast_verb(4, "Launching %s(%s) on %s\n", outgoing->app, outgoing->appdata,
+ ast_verb(4, "Launching %s(%s) on %s\n", outgoing->app, S_OR(outgoing->appdata, ""),
ast_channel_name(ast_dial_answered(outgoing->dial)));
pbx_exec(ast_dial_answered(outgoing->dial), app, outgoing->appdata);
} else {
@@ -11444,14 +11447,11 @@ int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const
AST_LIST_TRAVERSE_SAFE_END;
if (value && (newvariable = ast_var_assign(name, value))) {
- if (headp == &globals)
+ if (headp == &globals) {
ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
+ }
AST_LIST_INSERT_HEAD(headp, newvariable, entries);
ast_channel_publish_varset(chan, name, value);
-
- if (headp != &globals) {
- ast_channel_publish_snapshot(chan);
- }
}
if (chan)
diff --git a/main/pickup.c b/main/pickup.c
index a415f1672..5be0c03ab 100644
--- a/main/pickup.c
+++ b/main/pickup.c
@@ -361,9 +361,7 @@ int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
goto pickup_failed;
}
- ast_channel_lock(target);
- target_snapshot = ast_channel_snapshot_create(target);
- ast_channel_unlock(target);
+ target_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(target));
if (!target_snapshot) {
goto pickup_failed;
}
diff --git a/main/stasis_bridges.c b/main/stasis_bridges.c
index 1e0b36edf..c5df5f4f9 100644
--- a/main/stasis_bridges.c
+++ b/main/stasis_bridges.c
@@ -407,9 +407,7 @@ struct stasis_message *ast_bridge_blob_create(
}
if (chan) {
- ast_channel_lock(chan);
- obj->channel = ast_channel_snapshot_create(chan);
- ast_channel_unlock(chan);
+ obj->channel = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
if (obj->channel == NULL) {
return NULL;
}
@@ -593,9 +591,7 @@ static int bridge_channel_snapshot_pair_init(struct ast_bridge_channel_pair *pai
}
}
- ast_channel_lock(pair->channel);
- snapshot_pair->channel_snapshot = ast_channel_snapshot_create(pair->channel);
- ast_channel_unlock(pair->channel);
+ snapshot_pair->channel_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(pair->channel));
if (!snapshot_pair->channel_snapshot) {
return -1;
}
@@ -1072,9 +1068,7 @@ void ast_bridge_publish_attended_transfer_link(int is_external, enum ast_transfe
transfer_msg->dest_type = AST_ATTENDED_TRANSFER_DEST_LINK;
for (i = 0; i < 2; ++i) {
- ast_channel_lock(locals[i]);
- transfer_msg->dest.links[i] = ast_channel_snapshot_create(locals[i]);
- ast_channel_unlock(locals[i]);
+ transfer_msg->dest.links[i] = ast_channel_snapshot_get_latest(ast_channel_uniqueid(locals[i]));
if (!transfer_msg->dest.links[i]) {
return;
}
diff --git a/main/stasis_cache.c b/main/stasis_cache.c
index c1dab8539..8b4304e5f 100644
--- a/main/stasis_cache.c
+++ b/main/stasis_cache.c
@@ -127,9 +127,17 @@ struct stasis_caching_topic *stasis_caching_unsubscribe_and_join(struct stasis_c
return NULL;
}
+/*!
+ * \brief The key for an entry in the cache
+ * \note The items in this struct must be immutable for the item in the cache
+ */
struct cache_entry_key {
+ /*! The message type of the item stored in the cache */
struct stasis_message_type *type;
+ /*! The unique ID of the item stored in the cache */
const char *id;
+ /*! The hash, computed from \c type and \c id */
+ unsigned int hash;
};
struct stasis_cache_entry {
@@ -166,6 +174,12 @@ static void cache_entry_dtor(void *obj)
AST_VECTOR_FREE(&entry->remote);
}
+static void cache_entry_compute_hash(struct cache_entry_key *key)
+{
+ key->hash = ast_hashtab_hash_string(stasis_message_type_name(key->type));
+ key->hash += ast_hashtab_hash_string(key->id);
+}
+
static struct stasis_cache_entry *cache_entry_create(struct stasis_message_type *type, const char *id, struct stasis_message *snapshot)
{
struct stasis_cache_entry *entry;
@@ -187,6 +201,7 @@ static struct stasis_cache_entry *cache_entry_create(struct stasis_message_type
return NULL;
}
entry->key.type = ao2_bump(type);
+ cache_entry_compute_hash(&entry->key);
is_remote = ast_eid_cmp(&ast_eid_default, stasis_message_eid(snapshot)) ? 1 : 0;
if (AST_VECTOR_INIT(&entry->remote, is_remote)) {
@@ -211,7 +226,6 @@ static int cache_entry_hash(const void *obj, int flags)
{
const struct stasis_cache_entry *object;
const struct cache_entry_key *key;
- int hash = 0;
switch (flags & OBJ_SEARCH_MASK) {
case OBJ_SEARCH_KEY:
@@ -227,9 +241,7 @@ static int cache_entry_hash(const void *obj, int flags)
return 0;
}
- hash += ast_hashtab_hash_string(stasis_message_type_name(key->type));
- hash += ast_hashtab_hash_string(key->id);
- return hash;
+ return (int)key->hash;
}
static int cache_entry_cmp(void *obj, void *arg, int flags)
@@ -347,6 +359,7 @@ static struct stasis_cache_entry *cache_find(struct ao2_container *entries, stru
search_key.type = type;
search_key.id = id;
+ cache_entry_compute_hash(&search_key);
entry = ao2_find(entries, &search_key, OBJ_SEARCH_KEY | OBJ_NOLOCK);
/* Ensure that what we looked for is what we found. */
diff --git a/main/stasis_channels.c b/main/stasis_channels.c
index f38edb0e1..ad9da50cf 100644
--- a/main/stasis_channels.c
+++ b/main/stasis_channels.c
@@ -195,18 +195,12 @@ static void channel_snapshot_dtor(void *obj)
ast_string_field_free_memory(snapshot);
ao2_cleanup(snapshot->manager_vars);
- ao2_cleanup(snapshot->channel_vars);
}
struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *chan)
{
struct ast_channel_snapshot *snapshot;
struct ast_bridge *bridge;
- char nativeformats[256];
- struct ast_str *write_transpath = ast_str_alloca(256);
- struct ast_str *read_transpath = ast_str_alloca(256);
- struct ast_party_id effective_connected_id;
- struct ast_callid *callid;
/* no snapshots for dummy channels */
if (!ast_channel_tech(chan)) {
@@ -263,38 +257,16 @@ struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *cha
ao2_cleanup(bridge);
}
- ast_string_field_set(snapshot, nativeformats, ast_getformatname_multiple(nativeformats, sizeof(nativeformats),
- ast_channel_nativeformats(chan)));
- ast_string_field_set(snapshot, readformat, ast_getformatname(ast_channel_readformat(chan)));
- ast_string_field_set(snapshot, writeformat, ast_getformatname(ast_channel_writeformat(chan)));
- ast_string_field_set(snapshot, writetrans, ast_translate_path_to_str(ast_channel_writetrans(chan), &write_transpath));
- ast_string_field_set(snapshot, readtrans, ast_translate_path_to_str(ast_channel_readtrans(chan), &read_transpath));
-
- effective_connected_id = ast_channel_connected_effective_id(chan);
- ast_string_field_set(snapshot, effective_name,
- S_COR(effective_connected_id.name.valid, effective_connected_id.name.str, ""));
- ast_string_field_set(snapshot, effective_number,
- S_COR(effective_connected_id.number.valid, effective_connected_id.number.str, ""));
-
- if ((callid = ast_channel_callid(chan))) {
- ast_callid_strnprint(snapshot->callid, sizeof(snapshot->callid), callid);
- ast_callid_unref(callid);
- }
-
snapshot->creationtime = ast_channel_creationtime(chan);
- snapshot->hanguptime = *(ast_channel_whentohangup(chan));
snapshot->state = ast_channel_state(chan);
snapshot->priority = ast_channel_priority(chan);
snapshot->amaflags = ast_channel_amaflags(chan);
snapshot->hangupcause = ast_channel_hangupcause(chan);
ast_copy_flags(&snapshot->flags, ast_channel_flags(chan), 0xFFFFFFFF);
snapshot->caller_pres = ast_party_id_presentation(&ast_channel_caller(chan)->id);
- snapshot->callgroup = ast_channel_callgroup(chan);
- snapshot->pickupgroup = ast_channel_pickupgroup(chan);
ast_set_flag(&snapshot->softhangup_flags, ast_channel_softhangup_internal_flag(chan));
snapshot->manager_vars = ast_channel_get_manager_vars(chan);
- snapshot->channel_vars = ast_channel_get_vars(chan);
snapshot->tech_properties = ast_channel_tech(chan)->properties;
return snapshot;
@@ -347,7 +319,11 @@ void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_cha
if (caller) {
ast_channel_lock(caller);
- caller_snapshot = ast_channel_snapshot_create(caller);
+ if (ast_strlen_zero(dialstatus)) {
+ caller_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(caller));
+ } else {
+ caller_snapshot = ast_channel_snapshot_create(caller);
+ }
ast_channel_unlock(caller);
if (!caller_snapshot) {
return;
@@ -356,7 +332,11 @@ void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_cha
}
ast_channel_lock(peer);
- peer_snapshot = ast_channel_snapshot_create(peer);
+ if (ast_strlen_zero(dialstatus)) {
+ peer_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(peer));
+ } else {
+ peer_snapshot = ast_channel_snapshot_create(peer);
+ }
ast_channel_unlock(peer);
if (!peer_snapshot) {
return;
@@ -682,9 +662,24 @@ void ast_channel_publish_snapshot(struct ast_channel *chan)
stasis_publish(ast_channel_topic(chan), message);
}
+void ast_channel_publish_cached_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
+{
+ struct stasis_message *message;
+
+ if (!blob) {
+ blob = ast_json_null();
+ }
+
+ message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), type, blob);
+ if (message) {
+ stasis_publish(ast_channel_topic(chan), message);
+ }
+ ao2_cleanup(message);
+}
+
void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
{
- RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+ struct stasis_message *message;
if (!blob) {
blob = ast_json_null();
@@ -694,11 +689,12 @@ void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_ty
if (message) {
stasis_publish(ast_channel_topic(chan), message);
}
+ ao2_cleanup(message);
}
void ast_channel_publish_varset(struct ast_channel *chan, const char *name, const char *value)
{
- RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+ struct ast_json *blob;
ast_assert(name != NULL);
ast_assert(value != NULL);
@@ -711,7 +707,15 @@ void ast_channel_publish_varset(struct ast_channel *chan, const char *name, cons
return;
}
- ast_channel_publish_blob(chan, ast_channel_varset_type(), blob);
+ if (chan && !ast_channel_has_manager_vars()) {
+ ast_channel_publish_cached_blob(chan, ast_channel_varset_type(), blob);
+ } else {
+ /* This function is NULL safe. If there are manager variables,
+ * we have to produce the full snapshot.
+ */
+ ast_channel_publish_blob(chan, ast_channel_varset_type(), blob);
+ }
+ ast_json_unref(blob);
}
static struct ast_manager_event_blob *varset_to_ami(struct stasis_message *msg)
@@ -1179,3 +1183,4 @@ int ast_stasis_channels_init(void)
return res;
}
+
diff --git a/res/ari/resource_channels.c b/res/ari/resource_channels.c
index 30ced1b2f..647344303 100644
--- a/res/ari/resource_channels.c
+++ b/res/ari/resource_channels.c
@@ -859,7 +859,7 @@ static void ari_channels_handle_originate_with_id(const char *args_endpoint,
return;
}
- snapshot = ast_channel_snapshot_create(chan);
+ snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
ast_channel_unlock(chan);
if (!ast_strlen_zero(args_app)) {
@@ -1086,7 +1086,7 @@ static void ari_channels_handle_snoop_channel(
return;
}
- snapshot = ast_channel_snapshot_create(snoop);
+ snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(snoop));
ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
}
diff --git a/res/res_agi.c b/res/res_agi.c
index e223603a6..3adf36bac 100644
--- a/res/res_agi.c
+++ b/res/res_agi.c
@@ -1481,11 +1481,11 @@ static enum agi_result launch_asyncagi(struct ast_channel *chan, int argc, char
to execute based on the setup info */
ast_uri_encode(agi_buffer, ami_buffer, AMI_BUF_SIZE, ast_uri_http);
startblob = ast_json_pack("{s: s}", "Env", ami_buffer);
- ast_channel_lock(chan);
- ast_channel_publish_blob(chan, agi_async_start_type(), startblob);
- hungup = ast_check_hangup(chan);
- ast_channel_unlock(chan);
+ ast_channel_publish_cached_blob(chan, agi_async_start_type(), startblob);
+
+ hungup = ast_check_hangup_locked(chan);
+
for (;;) {
/*
* Process as many commands as we can. Commands are added via
@@ -1529,9 +1529,7 @@ static enum agi_result launch_asyncagi(struct ast_channel *chan, int argc, char
if (execblob && !ast_strlen_zero(cmd->cmd_id)) {
ast_json_object_set(execblob, "CommandId", ast_json_string_create(cmd->cmd_id));
}
- ast_channel_lock(chan);
- ast_channel_publish_blob(chan, agi_async_exec_type(), execblob);
- ast_channel_unlock(chan);
+ ast_channel_publish_cached_blob(chan, agi_async_exec_type(), execblob);
free_agi_cmd(cmd);
@@ -1591,9 +1589,7 @@ async_agi_done:
ast_speech_destroy(async_agi.speech);
}
/* notify manager users this channel cannot be controlled anymore by Async AGI */
- ast_channel_lock(chan);
- ast_channel_publish_blob(chan, agi_async_end_type(), NULL);
- ast_channel_unlock(chan);
+ ast_channel_publish_cached_blob(chan, agi_async_end_type(), NULL);
async_agi_abort:
/* close the pipe */
@@ -3665,9 +3661,7 @@ static void publish_async_exec_end(struct ast_channel *chan, int command_id, con
"Command", command,
"ResultCode", result_code,
"Result", result);
- ast_channel_lock(chan);
- ast_channel_publish_blob(chan, agi_exec_end_type(), blob);
- ast_channel_unlock(chan);
+ ast_channel_publish_cached_blob(chan, agi_exec_end_type(), blob);
}
static enum agi_result agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf, int dead)
@@ -3685,9 +3679,7 @@ static enum agi_result agi_handle_command(struct ast_channel *chan, AGI *agi, ch
startblob = ast_json_pack("{s: i, s: s}",
"CommandId", command_id,
"Command", ami_cmd);
- ast_channel_lock(chan);
- ast_channel_publish_blob(chan, agi_exec_start_type(), startblob);
- ast_channel_unlock(chan);
+ ast_channel_publish_cached_blob(chan, agi_exec_start_type(), startblob);
parse_args(buf, &argc, argv);
c = find_command(argv, 0);
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index 511b61393..ea3326969 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1393,8 +1393,8 @@ static int cli_channel_print_header(void *obj, void *arg, int flags)
indent = CLI_INDENT_TO_SPACES(context->indent_level);
filler = CLI_LAST_TABSTOP - indent - 38;
ast_str_append(&context->output_buffer, 0,
- "%*s: <Codec> Exten: <DialedExten%*.*s> CLCID: <ConnectedLineCID.......>\n",
- indent, "Codec", filler, filler, CLI_HEADER_FILLER);
+ "%*s: <DialedExten%*.*s> CLCID: <ConnectedLineCID.......>\n",
+ indent, "Exten", filler, filler, CLI_HEADER_FILLER);
context->indent_level--;
}
@@ -1438,9 +1438,8 @@ static int cli_channel_print_body(void *obj, void *arg, int flags)
flexwidth = CLI_LAST_TABSTOP - indent - 25;
ast_str_append(&context->output_buffer, 0,
- "%*s: %-7s Exten: %-*.*s CLCID: \"%s\" <%s>\n",
- indent, "Codec",
- snapshot->nativeformats,
+ "%*s: %-*.*s CLCID: \"%s\" <%s>\n",
+ indent, "Exten",
flexwidth, flexwidth,
snapshot->exten,
snapshot->connected_name,