agent_blob = stasis_message_data(msg);
if (ast_channel_agent_login_type() == stasis_message_type(msg)) {
- ast_queue_log("NONE", agent_blob->snapshot->uniqueid,
+ ast_queue_log("NONE", agent_blob->snapshot->base->uniqueid,
ast_json_string_get(ast_json_object_get(agent_blob->blob, "agent")),
- "AGENTLOGIN", "%s", agent_blob->snapshot->name);
+ "AGENTLOGIN", "%s", agent_blob->snapshot->base->name);
} else if (ast_channel_agent_logoff_type() == stasis_message_type(msg)) {
- ast_queue_log("NONE", agent_blob->snapshot->uniqueid,
+ ast_queue_log("NONE", agent_blob->snapshot->base->uniqueid,
ast_json_string_get(ast_json_object_get(agent_blob->blob, "agent")),
- "AGENTLOGOFF", "%s|%ld", agent_blob->snapshot->name,
+ "AGENTLOGOFF", "%s|%ld", agent_blob->snapshot->base->name,
(long) ast_json_integer_get(ast_json_object_get(agent_blob->blob, "logintime")));
}
}
ast_str_set(&transfer_str, 0, "APP|%s", atxfer_msg->dest.app);
break;
case AST_ATTENDED_TRANSFER_DEST_LINK:
- ast_str_set(&transfer_str, 0, "LINK|%s|%s", atxfer_msg->dest.links[0]->name,
- atxfer_msg->dest.links[1]->name);
+ ast_str_set(&transfer_str, 0, "LINK|%s|%s", atxfer_msg->dest.links[0]->base->name,
+ atxfer_msg->dest.links[1]->base->name);
break;
case AST_ATTENDED_TRANSFER_DEST_THREEWAY:
case AST_ATTENDED_TRANSFER_DEST_FAIL:
return;
}
- ast_queue_log(queue_data->queue->name, caller->uniqueid, queue_data->member->membername, "ATTENDEDTRANSFER", "%s|%ld|%ld|%d",
+ ast_queue_log(queue_data->queue->name, caller->base->uniqueid, queue_data->member->membername, "ATTENDEDTRANSFER", "%s|%ld|%ld|%d",
ast_str_buffer(transfer_str),
(long) (queue_data->starttime - queue_data->holdstart),
(long) (time(NULL) - queue_data->starttime), queue_data->caller_pos);
return;
}
- if (!strcmp(enter_blob->channel->uniqueid, queue_data->caller_uniqueid)) {
+ if (!strcmp(enter_blob->channel->base->uniqueid, queue_data->caller_uniqueid)) {
ast_string_field_set(queue_data, bridge_uniqueid,
enter_blob->bridge->uniqueid);
ast_debug(3, "Detected entry of caller channel %s into bridge %s\n",
- enter_blob->channel->name, queue_data->bridge_uniqueid);
+ enter_blob->channel->base->name, queue_data->bridge_uniqueid);
}
}
context = transfer_msg->context;
ast_debug(3, "Detected blind transfer in queue %s\n", queue_data->queue->name);
- ast_queue_log(queue_data->queue->name, caller_snapshot->uniqueid, queue_data->member->membername,
+ ast_queue_log(queue_data->queue->name, caller_snapshot->base->uniqueid, queue_data->member->membername,
"BLINDTRANSFER", "%s|%s|%ld|%ld|%d",
exten, context,
(long) (queue_data->starttime - queue_data->holdstart),
return;
}
- if (!strcmp(local_one->uniqueid, queue_data->member_uniqueid)) {
+ if (!strcmp(local_one->base->uniqueid, queue_data->member_uniqueid)) {
optimization = &queue_data->member_optimize;
- } else if (!strcmp(local_two->uniqueid, queue_data->caller_uniqueid)) {
+ } else if (!strcmp(local_two->base->uniqueid, queue_data->caller_uniqueid)) {
optimization = &queue_data->caller_optimize;
} else {
return;
/* We only allow move-swap optimizations, so there had BETTER be a source */
ast_assert(source != NULL);
- optimization->source_chan_uniqueid = ast_strdup(source->uniqueid);
+ optimization->source_chan_uniqueid = ast_strdup(source->base->uniqueid);
if (!optimization->source_chan_uniqueid) {
- ast_log(LOG_ERROR, "Unable to track local channel optimization for channel %s. Expect further errors\n", local_one->name);
+ ast_log(LOG_ERROR, "Unable to track local channel optimization for channel %s. Expect further errors\n", local_one->base->name);
return;
}
id = ast_json_integer_get(ast_json_object_get(ast_multi_channel_blob_get_json(optimization_blob), "id"));
return;
}
- if (!strcmp(local_one->uniqueid, queue_data->member_uniqueid)) {
+ if (!strcmp(local_one->base->uniqueid, queue_data->member_uniqueid)) {
optimization = &queue_data->member_optimize;
is_caller = 0;
- } else if (!strcmp(local_two->uniqueid, queue_data->caller_uniqueid)) {
+ } else if (!strcmp(local_two->base->uniqueid, queue_data->caller_uniqueid)) {
optimization = &queue_data->caller_optimize;
is_caller = 1;
} else {
return;
}
- if (!strcmp(channel_blob->snapshot->uniqueid, queue_data->caller_uniqueid)) {
+ if (!strcmp(channel_blob->snapshot->base->uniqueid, queue_data->caller_uniqueid)) {
reason = CALLER;
- } else if (!strcmp(channel_blob->snapshot->uniqueid, queue_data->member_uniqueid)) {
+ } else if (!strcmp(channel_blob->snapshot->base->uniqueid, queue_data->member_uniqueid)) {
reason = AGENT;
} else {
ao2_unlock(queue_data);
return;
}
- chan = ast_channel_get_by_name(channel_blob->snapshot->name);
+ chan = ast_channel_get_by_name(channel_blob->snapshot->base->name);
if (chan && (ast_channel_has_role(chan, AST_TRANSFERER_ROLE_NAME) ||
!ast_strlen_zero(pbx_builtin_getvar_helper(chan, "ATTENDEDTRANSFER")) ||
!ast_strlen_zero(pbx_builtin_getvar_helper(chan, "BLINDTRANSFER")))) {
ao2_unlock(queue_data);
ast_debug(3, "Detected hangup of queue %s channel %s\n", reason == CALLER ? "caller" : "member",
- channel_blob->snapshot->name);
+ channel_blob->snapshot->base->name);
- ast_queue_log(queue_data->queue->name, caller_snapshot->uniqueid, queue_data->member->membername,
+ ast_queue_log(queue_data->queue->name, caller_snapshot->base->uniqueid, queue_data->member->membername,
reason == CALLER ? "COMPLETECALLER" : "COMPLETEAGENT", "%ld|%ld|%d",
(long) (queue_data->starttime - queue_data->holdstart),
(long) (time(NULL) - queue_data->starttime), queue_data->caller_pos);
continue;
}
- if (chan_pjsip_get_hold(snapshot->uniqueid)) {
+ if (chan_pjsip_get_hold(snapshot->base->uniqueid)) {
ast_devstate_aggregate_add(&aggregate, AST_DEVICE_ONHOLD);
} else {
ast_devstate_aggregate_add(&aggregate, ast_state_chan2dev(snapshot->state));
switch (flags & OBJ_SEARCH_MASK) {
case OBJ_SEARCH_OBJECT:
- right_key = right_obj->name;
+ right_key = right_obj->base->name;
/* Fall through */
case OBJ_SEARCH_KEY:
- cmp = strcmp(left_obj->name, right_key);
+ cmp = strcmp(left_obj->base->name, right_key);
break;
case OBJ_SEARCH_PARTIAL_KEY:
- cmp = strncmp(left_obj->name, right_key, strlen(right_key));
+ cmp = strncmp(left_obj->base->name, right_key, strlen(right_key));
break;
default:
cmp = 0;
switch (flags & OBJ_SEARCH_MASK) {
case OBJ_SEARCH_OBJECT:
- cmp = strcmp(left_obj->bridgeid, right_obj->bridgeid);
+ cmp = strcmp(left_obj->bridge->id, right_obj->bridge->id);
if (cmp) {
return cmp;
}
- right_key = right_obj->name;
+ right_key = right_obj->base->name;
/* Fall through */
case OBJ_SEARCH_KEY:
- cmp = strcmp(left_obj->name, right_key);
+ cmp = strcmp(left_obj->base->name, right_key);
break;
case OBJ_SEARCH_PARTIAL_KEY:
- cmp = strncmp(left_obj->name, right_key, strlen(right_key));
+ cmp = strncmp(left_obj->base->name, right_key, strlen(right_key));
break;
default:
cmp = 0;
switch (flags & OBJ_SEARCH_MASK) {
case OBJ_SEARCH_OBJECT:
- right_key = right_obj->name;
+ right_key = right_obj->base->name;
/* Fall through */
case OBJ_SEARCH_KEY:
- if (strcmp(left_obj->name, right_key) == 0) {
+ if (strcmp(left_obj->base->name, right_key) == 0) {
cmp = CMP_MATCH | CMP_STOP;
}
break;
case OBJ_SEARCH_PARTIAL_KEY:
- if (strncmp(left_obj->name, right_key, strlen(right_key)) == 0) {
+ if (strncmp(left_obj->base->name, right_key, strlen(right_key)) == 0) {
cmp = CMP_MATCH;
}
break;
switch (flags & OBJ_SEARCH_MASK) {
case OBJ_SEARCH_OBJECT:
- if (strcmp(left_obj->bridgeid, right_obj->bridgeid) == 0
- && strcmp(left_obj->name, right_obj->name) == 0) {
+ if (strcmp(left_obj->bridge->id, right_obj->bridge->id) == 0
+ && strcmp(left_obj->base->name, right_obj->base->name) == 0) {
return CMP_MATCH | CMP_STOP;
}
break;
case OBJ_SEARCH_KEY:
- if (strcmp(left_obj->name, right_key) == 0) {
+ if (strcmp(left_obj->base->name, right_key) == 0) {
cmp = CMP_MATCH | CMP_STOP;
}
break;
case OBJ_SEARCH_PARTIAL_KEY:
- if (strncmp(left_obj->name, right_key, strlen(right_key)) == 0) {
+ if (strncmp(left_obj->base->name, right_key, strlen(right_key)) == 0) {
cmp = CMP_MATCH;
}
break;
struct ast_channel_snapshot *snapshot = obj;
struct ao2_container *snapshots = arg;
- if (!strcmp(snapshot->type, "PJSIP")) {
+ if (!strcmp(snapshot->base->type, "PJSIP")) {
ao2_link(snapshots, snapshot);
return CMP_MATCH;
}
struct ast_channel_snapshot *channel = obj;
regex_t *regexbuf = arg;
- if (!regexec(regexbuf, channel->name, 0, NULL, 0)
- || !regexec(regexbuf, channel->appl, 0, NULL, 0)) {
+ if (!regexec(regexbuf, channel->base->name, 0, NULL, 0)
+ || !regexec(regexbuf, channel->dialplan->appl, 0, NULL, 0)) {
return 0;
}
{
const struct ast_channel_snapshot *snapshot = obj;
- return snapshot->name;
+ return snapshot->base->name;
}
static void *cli_channel_retrieve_by_id(const char *id)
ast_assert(context->output_buffer != NULL);
- print_name_len = strlen(snapshot->name) + strlen(snapshot->appl) + 2;
+ print_name_len = strlen(snapshot->base->name) + strlen(snapshot->dialplan->appl) + 2;
print_name = alloca(print_name_len);
/* Append the application */
- snprintf(print_name, print_name_len, "%s/%s", snapshot->name, snapshot->appl);
+ snprintf(print_name, print_name_len, "%s/%s", snapshot->base->name, snapshot->dialplan->appl);
indent = CLI_INDENT_TO_SPACES(context->indent_level);
flexwidth = CLI_LAST_TABSTOP - indent;
- ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, 32);
+ ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->base->creationtime.tv_sec, print_time, 32);
ast_str_append(&context->output_buffer, 0, "%*s: %-*.*s %-12.12s %-11.11s\n",
CLI_INDENT_TO_SPACES(context->indent_level), "Channel",
"%*s: %-*.*s CLCID: \"%s\" <%s>\n",
indent, "Exten",
flexwidth, flexwidth,
- snapshot->exten,
- snapshot->connected_name,
- snapshot->connected_number
+ snapshot->dialplan->exten,
+ snapshot->connected->name,
+ snapshot->connected->number
);
context->indent_level--;
if (context->indent_level == 0) {
{
struct ast_sip_cli_context *context = arg;
const struct ast_channel_snapshot *snapshot = obj;
- struct ast_channel *channel = ast_channel_get_by_name(snapshot->name);
+ struct ast_channel *channel = ast_channel_get_by_name(snapshot->base->name);
struct ast_sip_channel_pvt *cpvt = channel ? ast_channel_tech_pvt(channel) : NULL;
struct ast_sip_session *session;
struct ast_sip_session_media *media;
ast_assert(context->output_buffer != NULL);
if (!channel) {
- ast_str_append(&context->output_buffer, 0, " %s not valid\n", snapshot->name);
+ ast_str_append(&context->output_buffer, 0, " %s not valid\n", snapshot->base->name);
return -1;
}
session = cpvt->session;
if (!session) {
- ast_str_append(&context->output_buffer, 0, " %s not valid\n", snapshot->name);
+ ast_str_append(&context->output_buffer, 0, " %s not valid\n", snapshot->base->name);
ast_channel_unlock(channel);
ao2_cleanup(channel);
return -1;
media = session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO];
if (!media || !media->rtp) {
- ast_str_append(&context->output_buffer, 0, " %s not valid\n", snapshot->name);
+ ast_str_append(&context->output_buffer, 0, " %s not valid\n", snapshot->base->name);
ast_channel_unlock(channel);
ao2_cleanup(channel);
return -1;
ast_channel_unlock(channel);
- print_name = ast_strdupa(snapshot->name);
+ print_name = ast_strdupa(snapshot->base->name);
/* Skip the PJSIP/. We know what channel type it is and we need the space. */
print_name += 6;
- ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, 32);
+ ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->base->creationtime.tv_sec, print_time, 32);
if (ast_rtp_instance_get_stats(rtp, &stats, AST_RTP_INSTANCE_STAT_ALL)) {
- ast_str_append(&context->output_buffer, 0, "%s direct media\n", snapshot->name);
+ ast_str_append(&context->output_buffer, 0, "%s direct media\n", snapshot->base->name);
} else {
ast_str_append(&context->output_buffer, 0,
" %8.8s %-18.18s %-8.8s %-6.6s %6u%s %6u%s %3u %7.3f %6u%s %6u%s %3u %7.3f %7.3f\n",
- snapshot->bridgeid,
+ snapshot->bridge->id,
print_name,
print_time,
codec_in_use,
; Display certain channel variables every time a channel-oriented
; event is emitted:
;
+; Note that this does incur a performance penalty and should be avoided if possible.
+;
;channelvars = var1,var2,var3
;[username]
; Display certain channel variables every time a channel-oriented
; event is emitted:
;
+; Note that this does incur a performance penalty and should be avoided if possible.
+;
;channelvars = var1,var2,var3
; debug = on ; enable some debugging info in AMI messages (default off).
ast_callid ast_channel_callid(const struct ast_channel *chan);
struct ast_channel_snapshot *ast_channel_snapshot(const struct ast_channel *chan);
void ast_channel_snapshot_set(struct ast_channel *chan, struct ast_channel_snapshot *snapshot);
+struct ast_flags *ast_channel_snapshot_segment_flags(struct ast_channel *chan);
/*!
* \pre chan is locked
* @{
*/
+/*!
+ * \since 17
+ * \brief Channel snapshot invalidation flags, used to force generation of segments
+ */
+enum ast_channel_snapshot_segment_invalidation {
+ /*! Invalidate the bridge segment */
+ AST_CHANNEL_SNAPSHOT_INVALIDATE_BRIDGE = (1 << 1),
+ /*! Invalidate the dialplan segment */
+ AST_CHANNEL_SNAPSHOT_INVALIDATE_DIALPLAN = (1 << 2),
+ /*! Invalidate the connected segment */
+ AST_CHANNEL_SNAPSHOT_INVALIDATE_CONNECTED = (1 << 3),
+ /*! Invalidate the caller segment */
+ AST_CHANNEL_SNAPSHOT_INVALIDATE_CALLER = (1 << 4),
+ /*! Invalidate the hangup segment */
+ AST_CHANNEL_SNAPSHOT_INVALIDATE_HANGUP = (1 << 5),
+ /*! Invalidate the peer segment */
+ AST_CHANNEL_SNAPSHOT_INVALIDATE_PEER = (1 << 6),
+ /*! Invalidate the base segment */
+ AST_CHANNEL_SNAPSHOT_INVALIDATE_BASE = (1 << 7),
+};
+
+/*!
+ * \since 17
+ * \brief Structure containing bridge information for a channel snapshot.
+ */
+struct ast_channel_snapshot_bridge {
+ char id[0]; /*!< Unique Bridge Identifier */
+};
+
+/*!
+ * \since 17
+ * \brief Structure containing dialplan information for a channel snapshot.
+ */
+struct ast_channel_snapshot_dialplan {
+ AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(appl); /*!< Current application */
+ AST_STRING_FIELD(data); /*!< Data passed to current application */
+ AST_STRING_FIELD(context); /*!< Current extension context */
+ AST_STRING_FIELD(exten); /*!< Current extension number */
+ );
+ int priority; /*!< Current extension priority */
+};
+
+/*!
+ * \since 17
+ * \brief Structure containing caller information for a channel snapshot.
+ */
+struct ast_channel_snapshot_caller {
+ AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(name); /*!< Caller ID Name */
+ AST_STRING_FIELD(number); /*!< Caller ID Number */
+ AST_STRING_FIELD(dnid); /*!< Dialed ID Number */
+ AST_STRING_FIELD(dialed_subaddr); /*!< Dialed subaddress */
+ AST_STRING_FIELD(ani); /*!< Caller ID ANI Number */
+ AST_STRING_FIELD(rdnis); /*!< Caller ID RDNIS Number */
+ AST_STRING_FIELD(subaddr); /*!< Caller subaddress */
+ );
+ int pres; /*!< Caller ID presentation. */
+};
+
+/*!
+ * \since 17
+ * \brief Structure containing connected information for a channel snapshot.
+ */
+struct ast_channel_snapshot_connected {
+ char *number; /*!< Connected Line Number */
+ char name[0]; /*!< Connected Line Name */
+};
+
+/*!
+ * \since 17
+ * \brief Structure containing base information for a channel snapshot.
+ */
+struct ast_channel_snapshot_base {
+ AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(name); /*!< ASCII unique channel name */
+ AST_STRING_FIELD(uniqueid); /*!< Unique Channel Identifier */
+ AST_STRING_FIELD(accountcode); /*!< Account code for billing */
+ AST_STRING_FIELD(userfield); /*!< Userfield for CEL billing */
+ AST_STRING_FIELD(language); /*!< The default spoken language for the channel */
+ AST_STRING_FIELD(type); /*!< Type of channel technology */
+ );
+ struct timeval creationtime; /*!< The time of channel creation */
+ int tech_properties; /*!< Properties of the channel's technology */
+};
+
+/*!
+ * \since 17
+ * \brief Structure containing peer information for a channel snapshot.
+ */
+struct ast_channel_snapshot_peer {
+ char *linkedid; /*!< Linked Channel Identifier -- gets propagated by linkage */
+ char account[0]; /*!< Peer account code for billing */
+};
+
+/*!
+ * \since 17
+ * \brief Structure containing hangup information for a channel snapshot.
+ */
+struct ast_channel_snapshot_hangup {
+ int cause; /*!< Why is the channel hanged up. See causes.h */
+ char source[0]; /*!< Who is responsible for hanging up this channel */
+};
+
/*!
* \since 12
* \brief Structure representing a snapshot of channel state.
*
* While not enforced programmatically, this object is shared across multiple
* threads, and should be treated as an immutable object.
+ *
+ * It is guaranteed that the segments of this snapshot will always exist
+ * when accessing the snapshot.
*/
struct ast_channel_snapshot {
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(name); /*!< ASCII unique channel name */
- AST_STRING_FIELD(uniqueid); /*!< Unique Channel Identifier */
- AST_STRING_FIELD(linkedid); /*!< Linked Channel Identifier -- gets propagated by linkage */
- 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 */
- AST_STRING_FIELD(caller_ani); /*!< Caller ID ANI Number */
- AST_STRING_FIELD(caller_rdnis); /*!< Caller ID RDNIS Number */
- AST_STRING_FIELD(caller_subaddr); /*!< Caller subaddress */
- 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(language); /*!< The default spoken language for the channel */
- AST_STRING_FIELD(bridgeid); /*!< Unique Bridge Identifier */
- AST_STRING_FIELD(type); /*!< Type of channel technology */
- );
-
- struct timeval creationtime; /*!< The time of channel creation */
- 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 */
- struct ast_flags softhangup_flags; /*!< softhangup channel flags */
- struct varshead *manager_vars; /*!< Variables to be appended to manager events */
- int tech_properties; /*!< Properties of the channel's technology */
- struct varshead *ari_vars; /*!< Variables to be appended to ARI events */
+ struct ast_channel_snapshot_base *base; /*!< Base information about the channel */
+ struct ast_channel_snapshot_peer *peer; /*!< Peer information */
+ struct ast_channel_snapshot_caller *caller; /*!< Information about the caller */
+ struct ast_channel_snapshot_connected *connected; /*!< Information about who this channel is connected to */
+ struct ast_channel_snapshot_bridge *bridge; /*!< Information about the bridge */
+ struct ast_channel_snapshot_dialplan *dialplan; /*!< Information about the dialplan */
+ struct ast_channel_snapshot_hangup *hangup; /*!< Hangup information */
+ enum ast_channel_state state; /*!< State of line */
+ int amaflags; /*!< AMA flags for billing */
+ struct ast_flags flags; /*!< channel flags of AST_FLAG_ type */
+ struct ast_flags softhangup_flags; /*!< softhangup channel flags */
+ struct varshead *manager_vars; /*!< Variables to be appended to manager events */
+ struct varshead *ari_vars; /*!< Variables to be appended to ARI events */
};
/*!
*/
void ast_channel_stage_snapshot_done(struct ast_channel *chan);
+/*!
+ * \since 17
+ * \brief Invalidate a channel snapshot segment from being reused
+ *
+ * \pre chan is locked
+ *
+ * \param chan Channel to invalidate the segment on.
+ * \param segment The segment to invalidate.
+ */
+void ast_channel_snapshot_invalidate_segment(struct ast_channel *chan,
+ enum ast_channel_snapshot_segment_invalidation segment);
+
/*!
* \since 12
* \brief Publish a \ref ast_channel_snapshot for a channel.
return 0;
}
- ast_cli(a->fd, "Channel: %s\n", snapshot->name);
+ ast_cli(a->fd, "Channel: %s\n", snapshot->base->name);
ao2_ref(snapshot, -1);
return 0;
static void cdr_object_transition_state(struct cdr_object *cdr, struct cdr_object_fn_table *fn_table)
{
CDR_DEBUG("%p - Transitioning CDR for %s from state %s to %s\n",
- cdr, cdr->party_a.snapshot->name,
+ cdr, cdr->party_a.snapshot->base->name,
cdr->fn_table ? cdr->fn_table->name : "NONE", fn_table->name);
cdr->fn_table = fn_table;
if (cdr->fn_table->init_function) {
{
ao2_lock(active_cdrs_all);
if (cdr->party_b.snapshot) {
- if (strcasecmp(cdr->party_b_name, cdr->party_b.snapshot->name)) {
+ if (strcasecmp(cdr->party_b_name, cdr->party_b.snapshot->base->name)) {
ao2_unlink_flags(active_cdrs_all, cdr, OBJ_NOLOCK);
- ast_string_field_set(cdr, party_b_name, cdr->party_b.snapshot->name);
+ ast_string_field_set(cdr, party_b_name, cdr->party_b.snapshot->base->name);
ao2_link_flags(active_cdrs_all, cdr, OBJ_NOLOCK);
}
} else {
ao2_cleanup(cdr);
return NULL;
}
- ast_string_field_set(cdr, uniqueid, chan->uniqueid);
- ast_string_field_set(cdr, name, chan->name);
- ast_string_field_set(cdr, linkedid, chan->linkedid);
+ ast_string_field_set(cdr, uniqueid, chan->base->uniqueid);
+ ast_string_field_set(cdr, name, chan->base->name);
+ ast_string_field_set(cdr, linkedid, chan->peer->linkedid);
cdr->disposition = AST_CDR_NULL;
cdr->sequence = ast_atomic_fetchadd_int(&global_cdr_sequence, +1);
cdr->party_a.snapshot = chan;
ao2_t_ref(cdr->party_a.snapshot, +1, "bump snapshot during CDR creation");
- CDR_DEBUG("%p - Created CDR for channel %s\n", cdr, chan->name);
+ CDR_DEBUG("%p - Created CDR for channel %s\n", cdr, chan->base->name);
cdr_object_transition_state(cdr, &single_state_fn_table);
* will attempt to clear the application and restore the dummy originate application
* of "AppDialX". Ignore application changes to AppDialX as a result.
*/
- if (strcmp(new_snapshot->appl, old_snapshot->appl)
- && strncasecmp(new_snapshot->appl, "appdial", 7)
- && (strcmp(new_snapshot->context, old_snapshot->context)
- || strcmp(new_snapshot->exten, old_snapshot->exten)
- || new_snapshot->priority != old_snapshot->priority)) {
+ if (strcmp(new_snapshot->dialplan->appl, old_snapshot->dialplan->appl)
+ && strncasecmp(new_snapshot->dialplan->appl, "appdial", 7)
+ && (strcmp(new_snapshot->dialplan->context, old_snapshot->dialplan->context)
+ || strcmp(new_snapshot->dialplan->exten, old_snapshot->dialplan->exten)
+ || new_snapshot->dialplan->priority != old_snapshot->dialplan->priority)) {
return 1;
}
/* Neither party is dialed and neither has the Party A flag - defer to
* creation time */
- if (left->snapshot->creationtime.tv_sec < right->snapshot->creationtime.tv_sec) {
+ if (left->snapshot->base->creationtime.tv_sec < right->snapshot->base->creationtime.tv_sec) {
return left;
- } else if (left->snapshot->creationtime.tv_sec > right->snapshot->creationtime.tv_sec) {
+ } else if (left->snapshot->base->creationtime.tv_sec > right->snapshot->base->creationtime.tv_sec) {
return right;
- } else if (left->snapshot->creationtime.tv_usec > right->snapshot->creationtime.tv_usec) {
+ } else if (left->snapshot->base->creationtime.tv_usec > right->snapshot->base->creationtime.tv_usec) {
return right;
} else {
/* Okay, fine, take the left one */
/* Don't create records for CDRs where the party A was a dialed channel */
if (snapshot_is_dialed(it_cdr->party_a.snapshot) && !it_cdr->party_b.snapshot) {
ast_debug(1, "CDR for %s is dialed and has no Party B; discarding\n",
- it_cdr->party_a.snapshot->name);
+ it_cdr->party_a.snapshot->base->name);
continue;
}
/* Party A */
ast_assert(party_a != NULL);
- ast_copy_string(cdr_copy->accountcode, party_a->accountcode, sizeof(cdr_copy->accountcode));
+ ast_copy_string(cdr_copy->accountcode, party_a->base->accountcode, sizeof(cdr_copy->accountcode));
cdr_copy->amaflags = party_a->amaflags;
- ast_copy_string(cdr_copy->channel, party_a->name, sizeof(cdr_copy->channel));
- ast_callerid_merge(cdr_copy->clid, sizeof(cdr_copy->clid), party_a->caller_name, party_a->caller_number, "");
- ast_copy_string(cdr_copy->src, party_a->caller_number, sizeof(cdr_copy->src));
- ast_copy_string(cdr_copy->uniqueid, party_a->uniqueid, sizeof(cdr_copy->uniqueid));
+ ast_copy_string(cdr_copy->channel, party_a->base->name, sizeof(cdr_copy->channel));
+ ast_callerid_merge(cdr_copy->clid, sizeof(cdr_copy->clid), party_a->caller->name, party_a->caller->number, "");
+ ast_copy_string(cdr_copy->src, party_a->caller->number, sizeof(cdr_copy->src));
+ ast_copy_string(cdr_copy->uniqueid, party_a->base->uniqueid, sizeof(cdr_copy->uniqueid));
ast_copy_string(cdr_copy->lastapp, it_cdr->appl, sizeof(cdr_copy->lastapp));
ast_copy_string(cdr_copy->lastdata, it_cdr->data, sizeof(cdr_copy->lastdata));
ast_copy_string(cdr_copy->dst, it_cdr->exten, sizeof(cdr_copy->dst));
/* Party B */
if (party_b) {
- ast_copy_string(cdr_copy->dstchannel, party_b->name, sizeof(cdr_copy->dstchannel));
- ast_copy_string(cdr_copy->peeraccount, party_b->accountcode, sizeof(cdr_copy->peeraccount));
+ ast_copy_string(cdr_copy->dstchannel, party_b->base->name, sizeof(cdr_copy->dstchannel));
+ ast_copy_string(cdr_copy->peeraccount, party_b->base->accountcode, sizeof(cdr_copy->peeraccount));
if (!ast_strlen_zero(it_cdr->party_b.userfield)) {
snprintf(cdr_copy->userfield, sizeof(cdr_copy->userfield), "%s;%s", it_cdr->party_a.userfield, it_cdr->party_b.userfield);
}
struct ast_cdr *pub_cdr;
CDR_DEBUG("%p - Dispatching CDR for Party A %s, Party B %s\n", cdr,
- cdr->party_a.snapshot->name,
- cdr->party_b.snapshot ? cdr->party_b.snapshot->name : "<none>");
+ cdr->party_a.snapshot->base->name,
+ cdr->party_b.snapshot ? cdr->party_b.snapshot->base->name : "<none>");
pub_cdr = cdr_object_create_public_records(cdr);
cdr_detach(pub_cdr);
}
if (cdr->disposition == AST_CDR_NULL) {
if (!ast_tvzero(cdr->answer)) {
cdr->disposition = AST_CDR_ANSWERED;
- } else if (cdr->party_a.snapshot->hangupcause) {
- cdr_object_set_disposition(cdr, cdr->party_a.snapshot->hangupcause);
- } else if (cdr->party_b.snapshot && cdr->party_b.snapshot->hangupcause) {
- cdr_object_set_disposition(cdr, cdr->party_b.snapshot->hangupcause);
+ } else if (cdr->party_a.snapshot->hangup->cause) {
+ cdr_object_set_disposition(cdr, cdr->party_a.snapshot->hangup->cause);
+ } else if (cdr->party_b.snapshot && cdr->party_b.snapshot->hangup->cause) {
+ cdr_object_set_disposition(cdr, cdr->party_b.snapshot->hangup->cause);
} else {
cdr->disposition = AST_CDR_FAILED;
}
/* tv_usec is suseconds_t, which could be int or long */
ast_debug(1, "Finalized CDR for %s - start %ld.%06ld answer %ld.%06ld end %ld.%06ld dispo %s\n",
- cdr->party_a.snapshot->name,
+ cdr->party_a.snapshot->base->name,
(long)cdr->start.tv_sec,
(long)cdr->start.tv_usec,
(long)cdr->answer.tv_sec,
static void cdr_object_update_cid(struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
{
if (!old_snapshot->snapshot) {
- set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller_dnid);
- set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller_subaddr);
- set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->dialed_subaddr);
+ set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller->dnid);
+ set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller->subaddr);
+ set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->caller->dialed_subaddr);
return;
}
- if (strcmp(old_snapshot->snapshot->caller_dnid, new_snapshot->caller_dnid)) {
- set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller_dnid);
+ if (strcmp(old_snapshot->snapshot->caller->dnid, new_snapshot->caller->dnid)) {
+ set_variable(&old_snapshot->variables, "dnid", new_snapshot->caller->dnid);
}
- if (strcmp(old_snapshot->snapshot->caller_subaddr, new_snapshot->caller_subaddr)) {
- set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller_subaddr);
+ if (strcmp(old_snapshot->snapshot->caller->subaddr, new_snapshot->caller->subaddr)) {
+ set_variable(&old_snapshot->variables, "callingsubaddr", new_snapshot->caller->subaddr);
}
- if (strcmp(old_snapshot->snapshot->dialed_subaddr, new_snapshot->dialed_subaddr)) {
- set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->dialed_subaddr);
+ if (strcmp(old_snapshot->snapshot->caller->dialed_subaddr, new_snapshot->caller->dialed_subaddr)) {
+ set_variable(&old_snapshot->variables, "calledsubaddr", new_snapshot->caller->dialed_subaddr);
}
}
static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
{
- ast_assert(strcasecmp(snapshot->name, cdr->party_a.snapshot->name) == 0);
+ ast_assert(strcasecmp(snapshot->base->name, cdr->party_a.snapshot->base->name) == 0);
/* Finalize the CDR if we're in hangup logic and we're set to do so */
if (ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)
*/
if (!ast_test_flag(&snapshot->flags, AST_FLAG_SUBROUTINE_EXEC)
|| ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
- if (strcmp(cdr->context, snapshot->context)) {
- ast_string_field_set(cdr, context, snapshot->context);
+ if (strcmp(cdr->context, snapshot->dialplan->context)) {
+ ast_string_field_set(cdr, context, snapshot->dialplan->context);
}
- if (strcmp(cdr->exten, snapshot->exten)) {
- ast_string_field_set(cdr, exten, snapshot->exten);
+ if (strcmp(cdr->exten, snapshot->dialplan->exten)) {
+ ast_string_field_set(cdr, exten, snapshot->dialplan->exten);
}
}
* here.
*/
if (!ast_test_flag(&cdr->flags, AST_CDR_LOCK_APP)
- && !ast_strlen_zero(snapshot->appl)
- && (strncasecmp(snapshot->appl, "appdial", 7) || ast_strlen_zero(cdr->appl))) {
- if (strcmp(cdr->appl, snapshot->appl)) {
- ast_string_field_set(cdr, appl, snapshot->appl);
+ && !ast_strlen_zero(snapshot->dialplan->appl)
+ && (strncasecmp(snapshot->dialplan->appl, "appdial", 7) || ast_strlen_zero(cdr->appl))) {
+ if (strcmp(cdr->appl, snapshot->dialplan->appl)) {
+ ast_string_field_set(cdr, appl, snapshot->dialplan->appl);
}
- if (strcmp(cdr->data, snapshot->data)) {
- ast_string_field_set(cdr, data, snapshot->data);
+ if (strcmp(cdr->data, snapshot->dialplan->data)) {
+ ast_string_field_set(cdr, data, snapshot->dialplan->data);
}
/* Dial (app_dial) is a special case. Because pre-dial handlers, which
* something people typically don't want to see, if we see a channel enter
* into Dial here, we set the appl/data accordingly and lock it.
*/
- if (!strcmp(snapshot->appl, "Dial")) {
+ if (!strcmp(snapshot->dialplan->appl, "Dial")) {
ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
}
}
- if (strcmp(cdr->linkedid, snapshot->linkedid)) {
- ast_string_field_set(cdr, linkedid, snapshot->linkedid);
+ if (strcmp(cdr->linkedid, snapshot->peer->linkedid)) {
+ ast_string_field_set(cdr, linkedid, snapshot->peer->linkedid);
}
cdr_object_check_party_a_answer(cdr);
cdr_object_check_party_a_hangup(cdr);
{
char park_info[128];
- ast_assert(!strcasecmp(parking_info->parkee->name, cdr->party_a.snapshot->name));
+ ast_assert(!strcasecmp(parking_info->parkee->base->name, cdr->party_a.snapshot->base->name));
/* Update Party A information regardless */
cdr->fn_table->process_party_a(cdr, parking_info->parkee);
static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_channel_snapshot *caller, struct ast_channel_snapshot *peer)
{
- if (caller && !strcasecmp(cdr->party_a.snapshot->name, caller->name)) {
+ if (caller && !strcasecmp(cdr->party_a.snapshot->base->name, caller->base->name)) {
base_process_party_a(cdr, caller);
CDR_DEBUG("%p - Updated Party A %s snapshot\n", cdr,
- cdr->party_a.snapshot->name);
+ cdr->party_a.snapshot->base->name);
cdr_object_swap_snapshot(&cdr->party_b, peer);
cdr_all_relink(cdr);
CDR_DEBUG("%p - Updated Party B %s snapshot\n", cdr,
- cdr->party_b.snapshot->name);
+ cdr->party_b.snapshot->base->name);
/* If we have two parties, lock the application that caused the
* two parties to be associated. This prevents mid-call event
* macros/gosubs from perturbing the CDR application/data
*/
ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
- } else if (!strcasecmp(cdr->party_a.snapshot->name, peer->name)) {
+ } else if (!strcasecmp(cdr->party_a.snapshot->base->name, peer->base->name)) {
/* We're the entity being dialed, i.e., outbound origination */
base_process_party_a(cdr, peer);
CDR_DEBUG("%p - Updated Party A %s snapshot\n", cdr,
- cdr->party_a.snapshot->name);
+ cdr->party_a.snapshot->base->name);
}
cdr_object_transition_state(cdr, &dial_state_fn_table);
struct cdr_object_snapshot *party_a;
/* Don't match on ourselves */
- if (!strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name)) {
+ if (!strcasecmp(cdr->party_a.snapshot->base->name, cand_cdr->party_a.snapshot->base->name)) {
return 1;
}
/* Try the candidate CDR's Party A first */
party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a);
- if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
+ if (!strcasecmp(party_a->snapshot->base->name, cdr->party_a.snapshot->base->name)) {
CDR_DEBUG("%p - Party A %s has new Party B %s\n",
- cdr, cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name);
+ cdr, cdr->party_a.snapshot->base->name, cand_cdr->party_a.snapshot->base->name);
cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
cdr_all_relink(cdr);
if (!cand_cdr->party_b.snapshot) {
/* Try their Party B, unless it's us */
if (!cand_cdr->party_b.snapshot
- || !strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_b.snapshot->name)) {
+ || !strcasecmp(cdr->party_a.snapshot->base->name, cand_cdr->party_b.snapshot->base->name)) {
return 1;
}
party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_b);
- if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
+ if (!strcasecmp(party_a->snapshot->base->name, cdr->party_a.snapshot->base->name)) {
CDR_DEBUG("%p - Party A %s has new Party B %s\n",
- cdr, cdr->party_a.snapshot->name, cand_cdr->party_b.snapshot->name);
+ cdr, cdr->party_a.snapshot->base->name, cand_cdr->party_b.snapshot->base->name);
cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_b);
cdr_all_relink(cdr);
return 0;
{
ast_assert(snapshot != NULL);
ast_assert(cdr->party_b.snapshot
- && !strcasecmp(cdr->party_b.snapshot->name, snapshot->name));
+ && !strcasecmp(cdr->party_b.snapshot->base->name, snapshot->base->name));
cdr_object_swap_snapshot(&cdr->party_b, snapshot);
} else {
party_a = peer;
}
- ast_assert(!strcasecmp(cdr->party_a.snapshot->name, party_a->name));
+ ast_assert(!strcasecmp(cdr->party_a.snapshot->base->name, party_a->base->name));
cdr_object_swap_snapshot(&cdr->party_a, party_a);
if (cdr->party_b.snapshot) {
- if (strcasecmp(cdr->party_b.snapshot->name, peer->name)) {
+ if (strcasecmp(cdr->party_b.snapshot->base->name, peer->base->name)) {
/* Not the status for this CDR - defer back to the message router */
return 1;
}
}
/* Skip any records that aren't our Party B */
- if (strcasecmp(cdr->party_b.snapshot->name, cand_cdr->party_a.snapshot->name)) {
+ if (strcasecmp(cdr->party_b.snapshot->base->name, cand_cdr->party_a.snapshot->base->name)) {
continue;
}
cdr_object_snapshot_copy(&cdr->party_b, &cand_cdr->party_a);
static void bridge_state_process_party_b(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)
{
ast_assert(cdr->party_b.snapshot
- && !strcasecmp(cdr->party_b.snapshot->name, snapshot->name));
+ && !strcasecmp(cdr->party_b.snapshot->base->name, snapshot->base->name));
cdr_object_swap_snapshot(&cdr->party_b, snapshot);
if (strcmp(cdr->bridge, bridge->uniqueid)) {
return 1;
}
- if (strcasecmp(cdr->party_a.snapshot->name, channel->name)
+ if (strcasecmp(cdr->party_a.snapshot->base->name, channel->base->name)
&& cdr->party_b.snapshot
- && strcasecmp(cdr->party_b.snapshot->name, channel->name)) {
+ && strcasecmp(cdr->party_b.snapshot->base->name, channel->base->name)) {
return 1;
}
cdr_object_transition_state(cdr, &finalized_state_fn_table);
static int parked_state_process_bridge_leave(struct cdr_object *cdr, struct ast_bridge_snapshot *bridge, struct ast_channel_snapshot *channel)
{
- if (strcasecmp(cdr->party_a.snapshot->name, channel->name)) {
+ if (strcasecmp(cdr->party_a.snapshot->base->name, channel->base->name)) {
return 1;
}
cdr_object_transition_state(cdr, &finalized_state_fn_table);
*/
static int filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
{
- return snapshot->tech_properties & AST_CHAN_TP_INTERNAL;
+ return snapshot->base->tech_properties & AST_CHAN_TP_INTERNAL;
}
/*!
CDR_DEBUG("Dial %s message for %s, %s: %u.%08u\n",
ast_strlen_zero(dial_status) ? "Begin" : "End",
- caller ? caller->name : "(none)",
- peer ? peer->name : "(none)",
+ caller ? caller->base->name : "(none)",
+ peer ? peer->base->name : "(none)",
(unsigned int)stasis_message_timestamp(message)->tv_sec,
(unsigned int)stasis_message_timestamp(message)->tv_usec);
/* Figure out who is running this show */
if (caller) {
- cdr = ao2_find(active_cdrs_master, caller->uniqueid, OBJ_SEARCH_KEY);
+ cdr = ao2_find(active_cdrs_master, caller->base->uniqueid, OBJ_SEARCH_KEY);
} else {
- cdr = ao2_find(active_cdrs_master, peer->uniqueid, OBJ_SEARCH_KEY);
+ cdr = ao2_find(active_cdrs_master, peer->base->uniqueid, OBJ_SEARCH_KEY);
}
if (!cdr) {
- ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", caller ? caller->name : peer->name);
+ ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", caller ? caller->base->name : peer->base->name);
ast_assert(0);
return;
}
}
CDR_DEBUG("%p - Processing Dial Begin message for channel %s, peer %s\n",
it_cdr,
- caller ? caller->name : "(none)",
- peer ? peer->name : "(none)");
+ caller ? caller->base->name : "(none)",
+ peer ? peer->base->name : "(none)");
res &= it_cdr->fn_table->process_dial_begin(it_cdr,
caller,
peer);
}
CDR_DEBUG("%p - Processing Dial End message for channel %s, peer %s\n",
it_cdr,
- caller ? caller->name : "(none)",
- peer ? peer->name : "(none)");
+ caller ? caller->base->name : "(none)",
+ peer ? peer->base->name : "(none)");
it_cdr->fn_table->process_dial_end(it_cdr,
caller,
peer,
* is consistent with the key.
*/
ast_assert(cdr->party_b.snapshot
- && !strcasecmp(cdr->party_b.snapshot->name, party_b->name));
+ && !strcasecmp(cdr->party_b.snapshot->base->name, party_b->base->name));
#endif
/* Don't transition to the finalized state - let the Party A do
* asserts the snapshot to be this way.
*/
if (!cdr->party_b.snapshot
- || strcasecmp(cdr->party_b.snapshot->name, party_b->name)) {
+ || strcasecmp(cdr->party_b.snapshot->base->name, party_b->base->name)) {
ast_log(LOG_NOTICE,
"CDR for Party A %s(%s) has inconsistent Party B %s name. Message can be ignored but this shouldn't happen.\n",
cdr->linkedid,
- cdr->party_a.snapshot->name,
+ cdr->party_a.snapshot->base->name,
cdr->party_b_name);
return 0;
}
}
/* Auto-fall through will increment the priority but have no application */
- if (ast_strlen_zero(new_snapshot->appl)) {
+ if (ast_strlen_zero(new_snapshot->dialplan->appl)) {
return 0;
}
cdr->is_root = 1;
ao2_link(active_cdrs_master, cdr);
} else {
- cdr = ao2_find(active_cdrs_master, update->new_snapshot->uniqueid, OBJ_SEARCH_KEY);
+ cdr = ao2_find(active_cdrs_master, update->new_snapshot->base->uniqueid, OBJ_SEARCH_KEY);
}
/* Handle Party A */
if (!cdr) {
- ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", update->new_snapshot->name);
+ ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", update->new_snapshot->base->name);
ast_assert(0);
} else {
int all_reject = 1;
if (ast_test_flag(&update->new_snapshot->flags, AST_FLAG_DEAD)) {
ao2_lock(cdr);
- CDR_DEBUG("%p - Beginning finalize/dispatch for %s\n", cdr, update->old_snapshot->name);
+ CDR_DEBUG("%p - Beginning finalize/dispatch for %s\n", cdr, update->old_snapshot->base->name);
for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
cdr_object_finalize(it_cdr);
}
/* Handle Party B */
if (update->new_snapshot) {
ao2_callback_data(active_cdrs_all, OBJ_NODATA | OBJ_MULTIPLE | OBJ_SEARCH_KEY,
- cdr_object_update_party_b, (char *) update->new_snapshot->name, update->new_snapshot);
+ cdr_object_update_party_b, (char *) update->new_snapshot->base->name, update->new_snapshot);
}
if (ast_test_flag(&update->new_snapshot->flags, AST_FLAG_DEAD)) {
ao2_callback_data(active_cdrs_all, OBJ_NODATA | OBJ_MULTIPLE | OBJ_SEARCH_KEY,
- cdr_object_finalize_party_b, (char *) update->new_snapshot->name, update->new_snapshot);
+ cdr_object_finalize_party_b, (char *) update->new_snapshot->base->name, update->new_snapshot);
}
ao2_cleanup(cdr);
* is consistent with the key.
*/
ast_assert(cdr->party_b.snapshot
- && !strcasecmp(cdr->party_b.snapshot->name, leave_data->channel->name));
+ && !strcasecmp(cdr->party_b.snapshot->base->name, leave_data->channel->base->name));
/* It is our Party B, in our bridge. Set the end time and let the handler
* transition our CDR appropriately when we leave the bridge.
}
CDR_DEBUG("Bridge Leave message for %s: %u.%08u\n",
- channel->name,
+ channel->base->name,
(unsigned int)stasis_message_timestamp(message)->tv_sec,
(unsigned int)stasis_message_timestamp(message)->tv_usec);
- cdr = ao2_find(active_cdrs_master, channel->uniqueid, OBJ_SEARCH_KEY);
+ cdr = ao2_find(active_cdrs_master, channel->base->uniqueid, OBJ_SEARCH_KEY);
if (!cdr) {
- ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
+ ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->base->name);
ast_assert(0);
return;
}
continue;
}
CDR_DEBUG("%p - Processing Bridge Leave for %s\n",
- it_cdr, channel->name);
+ it_cdr, channel->base->name);
if (!it_cdr->fn_table->process_bridge_leave(it_cdr, bridge, channel)) {
ast_string_field_set(it_cdr, bridge, "");
left_bridge = 1;
if (left_bridge
&& strcmp(bridge->subclass, "parking")) {
ao2_callback_data(active_cdrs_all, OBJ_NODATA | OBJ_MULTIPLE | OBJ_SEARCH_KEY,
- cdr_object_party_b_left_bridge_cb, (char *) leave_data.channel->name,
+ cdr_object_party_b_left_bridge_cb, (char *) leave_data.channel->base->name,
&leave_data);
}
ast_string_field_set(new_cdr, bridge, cdr->bridge);
cdr_object_transition_state(new_cdr, &bridge_state_fn_table);
CDR_DEBUG("%p - Party A %s has new Party B %s\n",
- new_cdr, new_cdr->party_a.snapshot->name,
- party_b->snapshot->name);
+ new_cdr, new_cdr->party_a.snapshot->base->name,
+ party_b->snapshot->base->name);
}
/*!
}
/* If the candidate is us or someone we've taken on, pass on by */
- if (!strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name)
+ if (!strcasecmp(cdr->party_a.snapshot->base->name, cand_cdr->party_a.snapshot->base->name)
|| (cdr->party_b.snapshot
- && !strcasecmp(cdr->party_b.snapshot->name, cand_cdr->party_a.snapshot->name))) {
+ && !strcasecmp(cdr->party_b.snapshot->base->name, cand_cdr->party_a.snapshot->base->name))) {
break;
}
party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a);
/* We're party A - make a new CDR, append it to us, and set the candidate as
* Party B */
- if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) {
+ if (!strcasecmp(party_a->snapshot->base->name, cdr->party_a.snapshot->base->name)) {
bridge_candidate_add_to_cdr(cdr, &cand_cdr->party_a);
break;
}
/* We're Party B. Check if we can add ourselves immediately or if we need
* a new CDR for them (they already have a Party B) */
if (cand_cdr->party_b.snapshot
- && strcasecmp(cand_cdr->party_b.snapshot->name, cdr->party_a.snapshot->name)) {
+ && strcasecmp(cand_cdr->party_b.snapshot->base->name, cdr->party_a.snapshot->base->name)) {
bridge_candidate_add_to_cdr(cand_cdr, &cdr->party_a);
} else {
CDR_DEBUG("%p - Party A %s has new Party B %s\n",
- cand_cdr, cand_cdr->party_a.snapshot->name,
- cdr->party_a.snapshot->name);
+ cand_cdr, cand_cdr->party_a.snapshot->base->name,
+ cdr->party_a.snapshot->base->name);
cdr_object_snapshot_copy(&cand_cdr->party_b, &cdr->party_a);
cdr_all_relink(cand_cdr);
/* It's possible that this joined at one point and was never chosen
}
if (it_cdr->fn_table->process_party_a) {
CDR_DEBUG("%p - Updating Party A %s snapshot\n", it_cdr,
- channel->name);
+ channel->base->name);
it_cdr->fn_table->process_party_a(it_cdr, channel);
}
}
for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
if (it_cdr->fn_table->process_party_a) {
CDR_DEBUG("%p - Updating Party A %s snapshot\n", it_cdr,
- channel->name);
+ channel->base->name);
it_cdr->fn_table->process_party_a(it_cdr, channel);
}
/* Notify all states that they have entered a bridge */
if (it_cdr->fn_table->process_bridge_enter) {
CDR_DEBUG("%p - Processing bridge enter for %s\n", it_cdr,
- channel->name);
+ channel->base->name);
result = it_cdr->fn_table->process_bridge_enter(it_cdr, bridge, channel);
switch (result) {
case BRIDGE_ENTER_ONLY_PARTY:
}
CDR_DEBUG("Bridge Enter message for channel %s: %u.%08u\n",
- channel->name,
+ channel->base->name,
(unsigned int)stasis_message_timestamp(message)->tv_sec,
(unsigned int)stasis_message_timestamp(message)->tv_usec);
- cdr = ao2_find(active_cdrs_master, channel->uniqueid, OBJ_SEARCH_KEY);
+ cdr = ao2_find(active_cdrs_master, channel->base->uniqueid, OBJ_SEARCH_KEY);
if (!cdr) {
- ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
+ ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->base->name);
ast_assert(0);
return;
}
}
CDR_DEBUG("Parked Call message for channel %s: %u.%08u\n",
- channel->name,
+ channel->base->name,
(unsigned int)stasis_message_timestamp(message)->tv_sec,
(unsigned int)stasis_message_timestamp(message)->tv_usec);
- cdr = ao2_find(active_cdrs_master, channel->uniqueid, OBJ_SEARCH_KEY);
+ cdr = ao2_find(active_cdrs_master, channel->base->uniqueid, OBJ_SEARCH_KEY);
if (!cdr) {
- ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name);
+ ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->base->name);
ast_assert(0);
return;
}
struct cdr_object *cdr = obj;
const char *name = arg;
- if (!strcasecmp(cdr->party_a.snapshot->name, name) ||
- (cdr->party_b.snapshot && !strcasecmp(cdr->party_b.snapshot->name, name))) {
+ if (!strcasecmp(cdr->party_a.snapshot->base->name, name) ||
+ (cdr->party_b.snapshot && !strcasecmp(cdr->party_b.snapshot->base->name, name))) {
return CMP_MATCH;
}
return 0;
struct cdr_object *cdr = obj;
const char *name = arg;
- if (!strcasecmp(cdr->party_a.snapshot->name, name)) {
+ if (!strcasecmp(cdr->party_a.snapshot->base->name, name)) {
return CMP_MATCH;
}
return 0;
if (it_cdr->fn_table == &finalized_state_fn_table && it_cdr->next != NULL) {
continue;
}
- if (!strcasecmp(channel_name, it_cdr->party_a.snapshot->name)) {
+ if (!strcasecmp(channel_name, it_cdr->party_a.snapshot->base->name)) {
headp = &it_cdr->party_a.variables;
} else if (it_cdr->party_b.snapshot
- && !strcasecmp(channel_name, it_cdr->party_b.snapshot->name)) {
+ && !strcasecmp(channel_name, it_cdr->party_b.snapshot->base->name)) {
headp = &it_cdr->party_b.variables;
}
if (headp) {
struct ast_channel_snapshot *party_b = cdr_obj->party_b.snapshot;
if (!strcasecmp(name, "clid")) {
- ast_callerid_merge(value, length, party_a->caller_name, party_a->caller_number, "");
+ ast_callerid_merge(value, length, party_a->caller->name, party_a->caller->number, "");
} else if (!strcasecmp(name, "src")) {
- ast_copy_string(value, party_a->caller_number, length);
+ ast_copy_string(value, party_a->caller->number, length);
} else if (!strcasecmp(name, "dst")) {
- ast_copy_string(value, party_a->exten, length);
+ ast_copy_string(value, party_a->dialplan->exten, length);
} else if (!strcasecmp(name, "dcontext")) {
- ast_copy_string(value, party_a->context, length);
+ ast_copy_string(value, party_a->dialplan->context, length);
} else if (!strcasecmp(name, "channel")) {
- ast_copy_string(value, party_a->name, length);
+ ast_copy_string(value, party_a->base->name, length);
} else if (!strcasecmp(name, "dstchannel")) {
if (party_b) {
- ast_copy_string(value, party_b->name, length);
+ ast_copy_string(value, party_b->base->name, length);
} else {
ast_copy_string(value, "", length);
}
} else if (!strcasecmp(name, "lastapp")) {
- ast_copy_string(value, party_a->appl, length);
+ ast_copy_string(value, party_a->dialplan->appl, length);
} else if (!strcasecmp(name, "lastdata")) {
- ast_copy_string(value, party_a->data, length);
+ ast_copy_string(value, party_a->dialplan->data, length);
} else if (!strcasecmp(name, "start")) {
cdr_get_tv(cdr_obj->start, NULL, value, length);
} else if (!strcasecmp(name, "answer")) {
} else if (!strcasecmp(name, "amaflags")) {
snprintf(value, length, "%d", party_a->amaflags);
} else if (!strcasecmp(name, "accountcode")) {
- ast_copy_string(value, party_a->accountcode, length);
+ ast_copy_string(value, party_a->base->accountcode, length);
} else if (!strcasecmp(name, "peeraccount")) {
if (party_b) {
- ast_copy_string(value, party_b->accountcode, length);
+ ast_copy_string(value, party_b->base->accountcode, length);
} else {
ast_copy_string(value, "", length);
}
} else if (!strcasecmp(name, "uniqueid")) {
- ast_copy_string(value, party_a->uniqueid, length);
+ ast_copy_string(value, party_a->base->uniqueid, length);
} else if (!strcasecmp(name, "linkedid")) {
ast_copy_string(value, cdr_obj->linkedid, length);
} else if (!strcasecmp(name, "userfield")) {
* is consistent with the key.
*/
ast_assert(cdr->party_b.snapshot
- && !strcasecmp(cdr->party_b.snapshot->name, info->channel_name));
+ && !strcasecmp(cdr->party_b.snapshot->base->name, info->channel_name));
ast_copy_string(cdr->party_b.userfield, info->userfield,
sizeof(cdr->party_b.userfield));
/* Copy over the basic CDR information. The Party A information is
* copied over automatically as part of the append
*/
- ast_debug(1, "Forking CDR for channel %s\n", cdr->party_a.snapshot->name);
+ ast_debug(1, "Forking CDR for channel %s\n", cdr->party_a.snapshot->base->name);
new_cdr = cdr_object_create_and_append(cdr);
if (!new_cdr) {
return -1;
it_cdrs = ao2_iterator_init(active_cdrs_master, 0);
while ((cdr = ao2_iterator_next(&it_cdrs))) {
- if (!strncasecmp(a->word, cdr->party_a.snapshot->name, wordlen)) {
- if (ast_cli_completion_add(ast_strdup(cdr->party_a.snapshot->name))) {
+ if (!strncasecmp(a->word, cdr->party_a.snapshot->base->name, wordlen)) {
+ if (ast_cli_completion_add(ast_strdup(cdr->party_a.snapshot->base->name))) {
ao2_ref(cdr, -1);
break;
}
cdr_get_tv(start_time, "%T", start_time_buffer, sizeof(start_time_buffer));
cdr_get_tv(answer_time, "%T", answer_time_buffer, sizeof(answer_time_buffer));
cdr_get_tv(end_time, "%T", end_time_buffer, sizeof(end_time_buffer));
- ast_cli(a->fd, FORMAT_STRING, it_cdr->party_a.snapshot->name,
- it_cdr->party_b.snapshot ? it_cdr->party_b.snapshot->name : "<none>",
+ ast_cli(a->fd, FORMAT_STRING, it_cdr->party_a.snapshot->base->name,
+ it_cdr->party_b.snapshot ? it_cdr->party_b.snapshot->base->name : "<none>",
it_cdr->appl,
start_time_buffer,
answer_time_buffer,
if (snapshot_is_dialed(it_cdr->party_a.snapshot)) {
continue;
}
- ast_callerid_merge(clid, sizeof(clid), it_cdr->party_a.snapshot->caller_name, it_cdr->party_a.snapshot->caller_number, "");
+ ast_callerid_merge(clid, sizeof(clid), it_cdr->party_a.snapshot->caller->name, it_cdr->party_a.snapshot->caller->number, "");
if (ast_tvzero(it_cdr->end)) {
end = ast_tvnow();
} else {
cdr_get_tv(it_cdr->answer, "%T", answer_time_buffer, sizeof(answer_time_buffer));
cdr_get_tv(end, "%T", end_time_buffer, sizeof(end_time_buffer));
ast_cli(a->fd, FORMAT_STRING,
- it_cdr->party_a.snapshot->accountcode,
+ it_cdr->party_a.snapshot->base->accountcode,
clid,
- it_cdr->party_b.snapshot ? it_cdr->party_b.snapshot->name : "<none>",
+ it_cdr->party_b.snapshot ? it_cdr->party_b.snapshot->base->name : "<none>",
it_cdr->appl,
it_cdr->data,
start_time_buffer,
}
for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
prnt(where, "Party A: %s; Party B: %s; Bridge %s\n",
- it_cdr->party_a.snapshot->name,
- it_cdr->party_b.snapshot ? it_cdr->party_b.snapshot->name : "<unknown>",
+ it_cdr->party_a.snapshot->base->name,
+ it_cdr->party_b.snapshot ? it_cdr->party_b.snapshot->base->name : "<unknown>",
it_cdr->bridge);
}
}
return;
}
prnt(where, "Party A: %s; Party B: %s; Bridge %s",
- cdr->party_a.snapshot->name,
- cdr->party_b.snapshot ? cdr->party_b.snapshot->name : "<unknown>",
+ cdr->party_a.snapshot->base->name,
+ cdr->party_b.snapshot ? cdr->party_b.snapshot->base->name : "<unknown>",
cdr->bridge);
}
AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec,
AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec,
AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, S_OR(userdefevname, ""),
- AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR, snapshot->caller_name,
- AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR, snapshot->caller_number,
- AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR, snapshot->caller_ani,
- AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR, snapshot->caller_rdnis,
- AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR, snapshot->caller_dnid,
- AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, snapshot->exten,
- AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, snapshot->context,
- AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, snapshot->name,
- AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, snapshot->appl,
- AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, snapshot->data,
+ AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR, snapshot->caller->name,
+ AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR, snapshot->caller->number,
+ AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR, snapshot->caller->ani,
+ AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR, snapshot->caller->rdnis,
+ AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR, snapshot->caller->dnid,
+ AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, snapshot->dialplan->exten,
+ AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, snapshot->dialplan->context,
+ AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, snapshot->base->name,
+ AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, snapshot->dialplan->appl,
+ AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, snapshot->dialplan->data,
AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_PLTYPE_UINT, snapshot->amaflags,
- AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, snapshot->accountcode,
- AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, snapshot->peeraccount,
- AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, snapshot->uniqueid,
- AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, snapshot->linkedid,
- AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, snapshot->userfield,
+ AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, snapshot->base->accountcode,
+ AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, snapshot->peer->account,
+ AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, snapshot->base->uniqueid,
+ AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, snapshot->peer->linkedid,
+ AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, snapshot->base->userfield,
AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, S_OR(extra_txt, ""),
AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, S_OR(peer, ""),
AST_EVENT_IE_END);
* reporting on CHANNEL_START so we can track when to send LINKEDID_END */
if (event_type == AST_CEL_CHANNEL_START
&& ast_cel_track_event(AST_CEL_LINKEDID_END)) {
- if (cel_linkedid_ref(snapshot->linkedid)) {
+ if (cel_linkedid_ref(snapshot->peer->linkedid)) {
return -1;
}
}
}
if ((event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END)
- && !cel_track_app(snapshot->appl)) {
+ && !cel_track_app(snapshot->dialplan->appl)) {
return 0;
}
RAII_VAR(struct ao2_container *, linkedids, ao2_global_obj_ref(cel_linkedids), ao2_cleanup);
struct cel_linkedid *lid;
- if (!linkedids || ast_strlen_zero(snapshot->linkedid)) {
+ if (!linkedids || ast_strlen_zero(snapshot->peer->linkedid)) {
/* The CEL module is shutdown. Abort. */
return;
}
ao2_lock(linkedids);
- lid = ao2_find(linkedids, (void *) snapshot->linkedid, OBJ_SEARCH_KEY);
+ lid = ao2_find(linkedids, (void *) snapshot->peer->linkedid, OBJ_SEARCH_KEY);
if (!lid) {
ao2_unlock(linkedids);
* of change to make after starting Asterisk.
*/
ast_log(LOG_ERROR, "Something weird happened, couldn't find linkedid %s\n",
- snapshot->linkedid);
+ snapshot->peer->linkedid);
return;
}
if (!was_hungup && is_hungup) {
struct ast_json *extra;
- struct cel_dialstatus *dialstatus = get_dialstatus(new_snapshot->uniqueid);
+ struct cel_dialstatus *dialstatus = get_dialstatus(new_snapshot->base->uniqueid);
extra = ast_json_pack("{s: i, s: s, s: s}",
- "hangupcause", new_snapshot->hangupcause,
- "hangupsource", new_snapshot->hangupsource,
+ "hangupcause", new_snapshot->hangup->cause,
+ "hangupsource", new_snapshot->hangup->source,
"dialstatus", dialstatus ? dialstatus->dialstatus : "");
cel_report_event(new_snapshot, AST_CEL_HANGUP, NULL, extra, NULL);
ast_json_unref(extra);
return;
}
- ast_assert(!ast_strlen_zero(new_snapshot->linkedid));
- ast_assert(!ast_strlen_zero(old_snapshot->linkedid));
+ ast_assert(!ast_strlen_zero(new_snapshot->peer->linkedid));
+ ast_assert(!ast_strlen_zero(old_snapshot->peer->linkedid));
if (ast_cel_track_event(AST_CEL_LINKEDID_END)
- && strcmp(old_snapshot->linkedid, new_snapshot->linkedid)) {
- cel_linkedid_ref(new_snapshot->linkedid);
+ && strcmp(old_snapshot->peer->linkedid, new_snapshot->peer->linkedid)) {
+ cel_linkedid_ref(new_snapshot->peer->linkedid);
check_retire_linkedid(old_snapshot);
}
}
struct ast_channel_snapshot *old_snapshot,
struct ast_channel_snapshot *new_snapshot)
{
- if (old_snapshot && !strcmp(old_snapshot->appl, new_snapshot->appl)) {
+ if (old_snapshot && !strcmp(old_snapshot->dialplan->appl, new_snapshot->dialplan->appl)) {
return;
}
/* old snapshot has an application, end it */
- if (old_snapshot && !ast_strlen_zero(old_snapshot->appl)) {
+ if (old_snapshot && !ast_strlen_zero(old_snapshot->dialplan->appl)) {
cel_report_event(old_snapshot, AST_CEL_APP_END, NULL, NULL, NULL);
}
/* new snapshot has an application, start it */
- if (!ast_strlen_zero(new_snapshot->appl)) {
+ if (!ast_strlen_zero(new_snapshot->dialplan->appl)) {
cel_report_event(new_snapshot, AST_CEL_APP_START, NULL, NULL, NULL);
}
}
if (!snapshot) {
return 0;
}
- return snapshot->tech_properties & AST_CHAN_TP_INTERNAL;
+ return snapshot->base->tech_properties & AST_CHAN_TP_INTERNAL;
}
static void cel_snapshot_update_cb(void *data, struct stasis_subscription *sub,
struct ast_channel_snapshot *current_snapshot;
/* Don't add the channel for which this message is being generated */
- if (!strcmp(current_chan, chan->uniqueid)) {
+ if (!strcmp(current_chan, chan->base->uniqueid)) {
continue;
}
continue;
}
- ast_str_append(&peer_str, 0, "%s,", current_snapshot->name);
+ ast_str_append(&peer_str, 0, "%s,", current_snapshot->base->name);
ao2_cleanup(current_snapshot);
}
ao2_iterator_destroy(&i);
if (parked_payload->retriever) {
extra = ast_json_pack("{s: s, s: s}",
"reason", reason ?: "",
- "retriever", parked_payload->retriever->name);
+ "retriever", parked_payload->retriever->base->name);
} else {
extra = ast_json_pack("{s: s}", "reason", reason ?: "");
}
return;
}
- dialstatus = ao2_find(dial_statuses, snapshot->uniqueid, OBJ_SEARCH_KEY);
+ dialstatus = ao2_find(dial_statuses, snapshot->base->uniqueid, OBJ_SEARCH_KEY);
if (dialstatus) {
if (!strcasecmp(dialstatus_string, "ANSWER") && strcasecmp(dialstatus->dialstatus, "ANSWER")) {
/* In the case of an answer after we already have a dial status we give
return;
}
- ast_copy_string(dialstatus->uniqueid, snapshot->uniqueid, sizeof(dialstatus->uniqueid));
+ ast_copy_string(dialstatus->uniqueid, snapshot->base->uniqueid, sizeof(dialstatus->uniqueid));
ast_copy_string(dialstatus->dialstatus, dialstatus_string, dialstatus_string_len);
ao2_link(dial_statuses, dialstatus);
"extension", transfer_msg->exten,
"context", transfer_msg->context,
"bridge_id", bridge_snapshot->uniqueid,
- "transferee_channel_name", transfer_msg->transferee ? transfer_msg->transferee->name : "N/A",
- "transferee_channel_uniqueid", transfer_msg->transferee ? transfer_msg->transferee->uniqueid : "N/A");
+ "transferee_channel_name", transfer_msg->transferee ? transfer_msg->transferee->base->name : "N/A",
+ "transferee_channel_uniqueid", transfer_msg->transferee ? transfer_msg->transferee->base->uniqueid : "N/A");
if (extra) {
cel_report_event(chan_snapshot, AST_CEL_BLINDTRANSFER, NULL, extra, NULL);
ast_json_unref(extra);
case AST_ATTENDED_TRANSFER_DEST_THREEWAY:
extra = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: s, s: s}",
"bridge1_id", bridge1->uniqueid,
- "channel2_name", channel2->name,
- "channel2_uniqueid", channel2->uniqueid,
+ "channel2_name", channel2->base->name,
+ "channel2_uniqueid", channel2->base->uniqueid,
"bridge2_id", bridge2->uniqueid,
- "transferee_channel_name", xfer->transferee ? xfer->transferee->name : "N/A",
- "transferee_channel_uniqueid", xfer->transferee ? xfer->transferee->uniqueid : "N/A",
- "transfer_target_channel_name", xfer->target ? xfer->target->name : "N/A",
- "transfer_target_channel_uniqueid", xfer->target ? xfer->target->uniqueid : "N/A");
+ "transferee_channel_name", xfer->transferee ? xfer->transferee->base->name : "N/A",
+ "transferee_channel_uniqueid", xfer->transferee ? xfer->transferee->base->uniqueid : "N/A",
+ "transfer_target_channel_name", xfer->target ? xfer->target->base->name : "N/A",
+ "transfer_target_channel_uniqueid", xfer->target ? xfer->target->base->uniqueid : "N/A");
if (!extra) {
return;
}
case AST_ATTENDED_TRANSFER_DEST_LOCAL_APP:
extra = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: s, s: s}",
"bridge1_id", bridge1->uniqueid,
- "channel2_name", channel2->name,
- "channel2_uniqueid", channel2->uniqueid,
+ "channel2_name", channel2->base->name,
+ "channel2_uniqueid", channel2->base->uniqueid,
"app", xfer->dest.app,
- "transferee_channel_name", xfer->transferee ? xfer->transferee->name : "N/A",
- "transferee_channel_uniqueid", xfer->transferee ? xfer->transferee->uniqueid : "N/A",
- "transfer_target_channel_name", xfer->target ? xfer->target->name : "N/A",
- "transfer_target_channel_uniqueid", xfer->target ? xfer->target->uniqueid : "N/A");
+ "transferee_channel_name", xfer->transferee ? xfer->transferee->base->name : "N/A",
+ "transferee_channel_uniqueid", xfer->transferee ? xfer->transferee->base->uniqueid : "N/A",
+ "transfer_target_channel_name", xfer->target ? xfer->target->base->name : "N/A",
+ "transfer_target_channel_uniqueid", xfer->target ? xfer->target->base->uniqueid : "N/A");
if (!extra) {
return;
}
}
extra = ast_json_pack("{s: s, s: s}",
- "pickup_channel", channel->name,
- "pickup_channel_uniqueid", channel->uniqueid);
+ "pickup_channel", channel->base->name,
+ "pickup_channel_uniqueid", channel->base->uniqueid);
if (!extra) {
return;
}
}
extra = ast_json_pack("{s: s, s: s}",
- "local_two", localtwo->name,
- "local_two_uniqueid", localtwo->uniqueid);
+ "local_two", localtwo->base->name,
+ "local_two_uniqueid", localtwo->base->uniqueid);
if (!extra) {
return;
}
ast_channel_name(clonechan), ast_channel_state(clonechan),
ast_channel_name(original), ast_channel_state(original));
+ /* When all is said and done force new snapshot segments so they are
+ * up to date.
+ */
+ ast_set_flag(ast_channel_snapshot_segment_flags(original), AST_FLAGS_ALL);
+ ast_set_flag(ast_channel_snapshot_segment_flags(clonechan), AST_FLAGS_ALL);
+
/*
* Remember the original read/write formats. We turn off any
* translation on either one
ast_channel_lock(chan);
ast_party_caller_set(ast_channel_caller(chan), caller, update);
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_CALLER);
ast_channel_unlock(chan);
}
ast_channel_lock(chan);
ast_party_caller_set(ast_channel_caller(chan), caller, update);
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_CALLER);
ast_channel_publish_snapshot(chan);
ast_channel_unlock(chan);
}
ast_channel_lock(chan);
ast_party_connected_line_set(ast_channel_connected(chan), connected, update);
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_CONNECTED);
ast_channel_publish_snapshot(chan);
ast_channel_unlock(chan);
}
ast_channel_lock(chan);
ast_party_redirecting_set(ast_channel_redirecting(chan), redirecting, update);
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_CALLER);
ast_channel_unlock(chan);
}
void *stream_topology_change_source; /*!< Source that initiated a stream topology change */
struct ast_stream *default_streams[AST_MEDIA_TYPE_END]; /*!< Default streams indexed by media type */
struct ast_channel_snapshot *snapshot; /*!< The current up to date snapshot of the channel */
+ struct ast_flags snapshot_segment_flags; /*!< Flags regarding the segments of the snapshot */
};
/*! \brief The monotonically increasing integer counter for channel uniqueids */
/* ACCESSORS */
-#define DEFINE_STRINGFIELD_SETTERS_FOR(field, publish, assert_on_null) \
+#define DEFINE_STRINGFIELD_SETTERS_FOR(field, assert_on_null) \
void ast_channel_##field##_set(struct ast_channel *chan, const char *value) \
{ \
if ((assert_on_null)) ast_assert(!ast_strlen_zero(value)); \
if (!strcmp(value, chan->field)) return; \
ast_string_field_set(chan, field, value); \
+} \
+ \
+void ast_channel_##field##_build_va(struct ast_channel *chan, const char *fmt, va_list ap) \
+{ \
+ ast_string_field_build_va(chan, field, fmt, ap); \
+} \
+void ast_channel_##field##_build(struct ast_channel *chan, const char *fmt, ...) \
+{ \
+ va_list ap; \
+ va_start(ap, fmt); \
+ ast_channel_##field##_build_va(chan, fmt, ap); \
+ va_end(ap); \
+}
+
+#define DEFINE_STRINGFIELD_SETTERS_AND_INVALIDATE_FOR(field, publish, assert_on_null, invalidate) \
+void ast_channel_##field##_set(struct ast_channel *chan, const char *value) \
+{ \
+ if ((assert_on_null)) ast_assert(!ast_strlen_zero(value)); \
+ if (!strcmp(value, chan->field)) return; \
+ ast_string_field_set(chan, field, value); \
+ ast_channel_snapshot_invalidate_segment(chan, invalidate); \
if (publish && ast_channel_internal_is_finalized(chan)) ast_channel_publish_snapshot(chan); \
} \
\
void ast_channel_##field##_build_va(struct ast_channel *chan, const char *fmt, va_list ap) \
{ \
ast_string_field_build_va(chan, field, fmt, ap); \
+ ast_channel_snapshot_invalidate_segment(chan, invalidate); \
if (publish && ast_channel_internal_is_finalized(chan)) ast_channel_publish_snapshot(chan); \
} \
void ast_channel_##field##_build(struct ast_channel *chan, const char *fmt, ...) \
va_end(ap); \
}
-DEFINE_STRINGFIELD_SETTERS_FOR(name, 0, 1);
-DEFINE_STRINGFIELD_SETTERS_FOR(language, 1, 0);
-DEFINE_STRINGFIELD_SETTERS_FOR(musicclass, 0, 0);
-DEFINE_STRINGFIELD_SETTERS_FOR(latest_musicclass, 0, 0);
-DEFINE_STRINGFIELD_SETTERS_FOR(accountcode, 1, 0);
-DEFINE_STRINGFIELD_SETTERS_FOR(peeraccount, 1, 0);
-DEFINE_STRINGFIELD_SETTERS_FOR(userfield, 0, 0);
-DEFINE_STRINGFIELD_SETTERS_FOR(call_forward, 0, 0);
-DEFINE_STRINGFIELD_SETTERS_FOR(parkinglot, 0, 0);
-DEFINE_STRINGFIELD_SETTERS_FOR(hangupsource, 0, 0);
-DEFINE_STRINGFIELD_SETTERS_FOR(dialcontext, 0, 0);
+DEFINE_STRINGFIELD_SETTERS_AND_INVALIDATE_FOR(name, 0, 1, AST_CHANNEL_SNAPSHOT_INVALIDATE_BASE);
+DEFINE_STRINGFIELD_SETTERS_AND_INVALIDATE_FOR(language, 1, 0, AST_CHANNEL_SNAPSHOT_INVALIDATE_BASE);
+DEFINE_STRINGFIELD_SETTERS_FOR(musicclass, 0);
+DEFINE_STRINGFIELD_SETTERS_FOR(latest_musicclass, 0);
+DEFINE_STRINGFIELD_SETTERS_AND_INVALIDATE_FOR(accountcode, 1, 0, AST_CHANNEL_SNAPSHOT_INVALIDATE_BASE);
+DEFINE_STRINGFIELD_SETTERS_AND_INVALIDATE_FOR(peeraccount, 1, 0, AST_CHANNEL_SNAPSHOT_INVALIDATE_PEER);
+DEFINE_STRINGFIELD_SETTERS_AND_INVALIDATE_FOR(userfield, 0, 0, AST_CHANNEL_SNAPSHOT_INVALIDATE_BASE);
+DEFINE_STRINGFIELD_SETTERS_FOR(call_forward, 0);
+DEFINE_STRINGFIELD_SETTERS_FOR(parkinglot, 0);
+DEFINE_STRINGFIELD_SETTERS_AND_INVALIDATE_FOR(hangupsource, 0, 0, AST_CHANNEL_SNAPSHOT_INVALIDATE_HANGUP);
+DEFINE_STRINGFIELD_SETTERS_FOR(dialcontext, 0);
#define DEFINE_STRINGFIELD_GETTER_FOR(field) const char *ast_channel_##field(const struct ast_channel *chan) \
{ \
void ast_channel_appl_set(struct ast_channel *chan, const char *value)
{
chan->appl = value;
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_DIALPLAN);
}
const char *ast_channel_blockproc(const struct ast_channel *chan)
{
void ast_channel_data_set(struct ast_channel *chan, const char *value)
{
chan->data = value;
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_DIALPLAN);
}
const char *ast_channel_context(const struct ast_channel *chan)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
{
ast_copy_string(chan->context, value, sizeof(chan->context));
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_DIALPLAN);
}
const char *ast_channel_exten(const struct ast_channel *chan)
{
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
{
ast_copy_string(chan->exten, value, sizeof(chan->exten));
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_DIALPLAN);
}
const char *ast_channel_macrocontext(const struct ast_channel *chan)
{
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
{
chan->hangupcause = value;
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_HANGUP);
}
int ast_channel_macropriority(const struct ast_channel *chan)
{
void ast_channel_priority_set(struct ast_channel *chan, int value)
{
chan->priority = value;
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_DIALPLAN);
}
int ast_channel_rings(const struct ast_channel *chan)
{
void ast_channel_caller_set(struct ast_channel *chan, struct ast_party_caller *value)
{
chan->caller = *value;
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_CALLER);
}
void ast_channel_connected_set(struct ast_channel *chan, struct ast_party_connected_line *value)
{
chan->connected = *value;
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_CONNECTED);
}
void ast_channel_dialed_set(struct ast_channel *chan, struct ast_party_dialed *value)
{
chan->dialed = *value;
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_CALLER);
}
void ast_channel_redirecting_set(struct ast_channel *chan, struct ast_party_redirecting *value)
{
chan->redirecting = *value;
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_CALLER);
}
void ast_channel_dtmf_tv_set(struct ast_channel *chan, struct timeval *value)
{
void ast_channel_creationtime_set(struct ast_channel *chan, struct timeval *value)
{
chan->creationtime = *value;
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_BASE);
}
struct timeval ast_channel_answertime(struct ast_channel *chan)
void ast_channel_internal_bridge_set(struct ast_channel *chan, struct ast_bridge *value)
{
chan->bridge = value;
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_BRIDGE);
ast_channel_publish_snapshot(chan);
}
AST_VECTOR_INIT(&tmp->fds, AST_MAX_FDS);
+ /* Force all channel snapshot segments to be created on first use, so we don't have to check if
+ * an old snapshot exists.
+ */
+ ast_set_flag(&tmp->snapshot_segment_flags, AST_FLAGS_ALL);
+
return tmp;
}
return;
}
dest->linkedid = source->linkedid;
+ ast_channel_snapshot_invalidate_segment(dest, AST_CHANNEL_SNAPSHOT_INVALIDATE_PEER);
ast_channel_publish_snapshot(dest);
}
{
struct ast_channel_id temp;
+ /* This operation is used as part of masquerading and so does not invalidate the peer
+ * segment. This is due to the masquerade process invalidating all segments.
+ */
+
temp = a->uniqueid;
a->uniqueid = b->uniqueid;
b->uniqueid = temp;
ao2_cleanup(chan->snapshot);
chan->snapshot = ao2_bump(snapshot);
}
+
+struct ast_flags *ast_channel_snapshot_segment_flags(struct ast_channel *chan)
+{
+ return &chan->snapshot_segment_flags;
+}
char durbuf[16] = "-";
if (!count) {
- if ((concise || verbose) && !ast_tvzero(cs->creationtime)) {
- int duration = (int)(ast_tvdiff_ms(ast_tvnow(), cs->creationtime) / 1000);
+ if ((concise || verbose) && !ast_tvzero(cs->base->creationtime)) {
+ int duration = (int)(ast_tvdiff_ms(ast_tvnow(), cs->base->creationtime) / 1000);
if (verbose) {
int durh = duration / 3600;
int durm = (duration % 3600) / 60;
}
}
if (concise) {
- 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,
+ ast_cli(a->fd, CONCISE_FORMAT_STRING, cs->base->name, cs->dialplan->context, cs->dialplan->exten, cs->dialplan->priority, ast_state2str(cs->state),
+ S_OR(cs->dialplan->appl, "(None)"),
+ cs->dialplan->data,
+ cs->caller->number,
+ cs->base->accountcode,
+ cs->peer->account,
cs->amaflags,
durbuf,
- cs->bridgeid,
- cs->uniqueid);
+ cs->bridge->id,
+ cs->base->uniqueid);
} else if (verbose) {
- 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,
+ ast_cli(a->fd, VERBOSE_FORMAT_STRING, cs->base->name, cs->dialplan->context, cs->dialplan->exten, cs->dialplan->priority, ast_state2str(cs->state),
+ S_OR(cs->dialplan->appl, "(None)"),
+ S_OR(cs->dialplan->data, "(Empty)"),
+ cs->caller->number,
durbuf,
- cs->accountcode,
- cs->peeraccount,
- cs->bridgeid);
+ cs->base->accountcode,
+ cs->peer->account,
+ cs->bridge->id);
} else {
char locbuf[40] = "(None)";
char appdata[40] = "(None)";
- if (!ast_strlen_zero(cs->context) && !ast_strlen_zero(cs->exten)) {
- snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", cs->exten, cs->context, cs->priority);
+ if (!ast_strlen_zero(cs->dialplan->context) && !ast_strlen_zero(cs->dialplan->exten)) {
+ snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", cs->dialplan->exten, cs->dialplan->context, cs->dialplan->priority);
}
- if (!ast_strlen_zero(cs->appl)) {
- snprintf(appdata, sizeof(appdata), "%s(%s)", cs->appl, S_OR(cs->data, ""));
+ if (!ast_strlen_zero(cs->dialplan->appl)) {
+ snprintf(appdata, sizeof(appdata), "%s(%s)", cs->dialplan->appl, S_OR(cs->dialplan->data, ""));
}
- ast_cli(a->fd, FORMAT_STRING, cs->name, locbuf, ast_state2str(cs->state), appdata);
+ ast_cli(a->fd, FORMAT_STRING, cs->base->name, locbuf, ast_state2str(cs->state), appdata);
}
}
}
iter = ao2_iterator_init(cached_channels, 0);
for (; (snapshot = ao2_iterator_next(&iter)); ao2_ref(snapshot, -1)) {
- if (!strncasecmp(word, snapshot->name, wordlen) && (++which > state)) {
+ if (!strncasecmp(word, snapshot->base->name, wordlen) && (++which > state)) {
if (state != -1) {
- ret = ast_strdup(snapshot->name);
+ ret = ast_strdup(snapshot->base->name);
ao2_ref(snapshot, -1);
break;
}
- if (ast_cli_completion_add(ast_strdup(snapshot->name))) {
+ if (ast_cli_completion_add(ast_strdup(snapshot->base->name))) {
ao2_ref(snapshot, -1);
break;
}
}
dest_uniqueid = ast_json_object_get(blob, "dest") == AST_UNREAL_OWNER ?
- local_snapshot_one->uniqueid : local_snapshot_two->uniqueid;
+ local_snapshot_one->base->uniqueid : local_snapshot_two->base->uniqueid;
event = "LocalOptimizationBegin";
if (source_str) {
ast_assert(endpoint != NULL);
ao2_lock(endpoint);
- ast_str_container_remove(endpoint->channel_ids, update->new_snapshot->uniqueid);
+ ast_str_container_remove(endpoint->channel_ids, update->new_snapshot->base->uniqueid);
ao2_unlock(endpoint);
endpoint_publish_snapshot(endpoint);
}
continue;
}
- if (!ast_tvzero(cs->creationtime)) {
+ if (!ast_tvzero(cs->base->creationtime)) {
int duration, durh, durm, durs;
- duration = (int)(ast_tvdiff_ms(ast_tvnow(), cs->creationtime) / 1000);
+ duration = (int)(ast_tvdiff_ms(ast_tvnow(), cs->base->creationtime) / 1000);
durh = duration / 3600;
durm = (duration % 3600) / 60;
durs = duration % 60;
"\r\n",
idText,
ast_str_buffer(built),
- cs->appl,
- cs->data,
+ cs->dialplan->appl,
+ cs->dialplan->data,
durbuf,
- cs->bridgeid);
+ cs->bridge->id);
numchans++;
return 0;
}
- if (snapshot->tech_properties & AST_CHAN_TP_INTERNAL) {
+ if (snapshot->base->tech_properties & AST_CHAN_TP_INTERNAL) {
return 0;
}
char *connected_name;
int res;
- if (snapshot->tech_properties & AST_CHAN_TP_INTERNAL) {
+ if (snapshot->base->tech_properties & AST_CHAN_TP_INTERNAL) {
return NULL;
}
return NULL;
}
- caller_name = ast_escape_c_alloc(snapshot->caller_name);
- connected_name = ast_escape_c_alloc(snapshot->connected_name);
+ caller_name = ast_escape_c_alloc(snapshot->caller->name);
+ connected_name = ast_escape_c_alloc(snapshot->connected->name);
res = ast_str_set(&out, 0,
"%sChannel: %s\r\n"
"%sPriority: %d\r\n"
"%sUniqueid: %s\r\n"
"%sLinkedid: %s\r\n",
- prefix, snapshot->name,
+ prefix, snapshot->base->name,
prefix, snapshot->state,
prefix, ast_state2str(snapshot->state),
- prefix, S_OR(snapshot->caller_number, "<unknown>"),
+ prefix, S_OR(snapshot->caller->number, "<unknown>"),
prefix, S_OR(caller_name, "<unknown>"),
- prefix, S_OR(snapshot->connected_number, "<unknown>"),
+ prefix, S_OR(snapshot->connected->number, "<unknown>"),
prefix, S_OR(connected_name, "<unknown>"),
- prefix, snapshot->language,
- prefix, snapshot->accountcode,
- prefix, snapshot->context,
- prefix, snapshot->exten,
- prefix, snapshot->priority,
- prefix, snapshot->uniqueid,
- prefix, snapshot->linkedid);
+ prefix, snapshot->base->language,
+ prefix, snapshot->base->accountcode,
+ prefix, snapshot->dialplan->context,
+ prefix, snapshot->dialplan->exten,
+ prefix, snapshot->dialplan->priority,
+ prefix, snapshot->base->uniqueid,
+ prefix, snapshot->peer->linkedid);
ast_free(caller_name);
ast_free(connected_name);
EVENT_FLAG_CALL, "Hangup",
"Cause: %d\r\n"
"Cause-txt: %s\r\n",
- new_snapshot->hangupcause,
- ast_cause2str(new_snapshot->hangupcause));
+ new_snapshot->hangup->cause,
+ ast_cause2str(new_snapshot->hangup->cause));
}
if (old_snapshot->state != new_snapshot->state) {
struct ast_channel_snapshot *new_snapshot)
{
/* Empty application is not valid for a Newexten event */
- if (ast_strlen_zero(new_snapshot->appl)) {
+ if (ast_strlen_zero(new_snapshot->dialplan->appl)) {
return NULL;
}
"Extension: %s\r\n"
"Application: %s\r\n"
"AppData: %s\r\n",
- new_snapshot->exten,
- new_snapshot->appl,
- new_snapshot->data);
+ new_snapshot->dialplan->exten,
+ new_snapshot->dialplan->appl,
+ new_snapshot->dialplan->data);
}
static struct ast_manager_event_blob *channel_new_callerid(
}
if (!(callerid = ast_escape_c_alloc(
- ast_describe_caller_presentation(new_snapshot->caller_pres)))) {
+ ast_describe_caller_presentation(new_snapshot->caller->pres)))) {
return NULL;
}
res = ast_manager_event_blob_create(
EVENT_FLAG_CALL, "NewCallerid",
"CID-CallingPres: %d (%s)\r\n",
- new_snapshot->caller_pres,
+ new_snapshot->caller->pres,
callerid);
ast_free(callerid);
return NULL;
}
- if (!strcmp(old_snapshot->accountcode, new_snapshot->accountcode)) {
+ if (!strcmp(old_snapshot->base->accountcode, new_snapshot->base->accountcode)) {
return NULL;
}
return ast_manager_event_blob_create(
EVENT_FLAG_CALL, "NewAccountCode",
- "OldAccountCode: %s\r\n", old_snapshot->accountcode);
+ "OldAccountCode: %s\r\n", old_snapshot->base->accountcode);
}
channel_snapshot_monitor channel_monitors[] = {
case AST_ATTENDED_TRANSFER_DEST_THREEWAY:
ast_str_append(&variable_data, 0, "DestType: Threeway\r\n");
ast_str_append(&variable_data, 0, "DestBridgeUniqueid: %s\r\n", transfer_msg->dest.threeway.bridge_snapshot->uniqueid);
- ast_str_append(&variable_data, 0, "DestTransfererChannel: %s\r\n", transfer_msg->dest.threeway.channel_snapshot->name);
+ ast_str_append(&variable_data, 0, "DestTransfererChannel: %s\r\n", transfer_msg->dest.threeway.channel_snapshot->base->name);
break;
case AST_ATTENDED_TRANSFER_DEST_FAIL:
ast_str_append(&variable_data, 0, "DestType: Fail\r\n");
{
transfer_msg->dest_type = AST_ATTENDED_TRANSFER_DEST_THREEWAY;
- if (!strcmp(ast_channel_uniqueid(survivor_channel), transfer_msg->to_transferee.channel_snapshot->uniqueid)) {
+ if (!strcmp(ast_channel_uniqueid(survivor_channel), transfer_msg->to_transferee.channel_snapshot->base->uniqueid)) {
transfer_msg->dest.threeway.channel_snapshot = transfer_msg->to_transferee.channel_snapshot;
} else {
transfer_msg->dest.threeway.channel_snapshot = transfer_msg->to_transfer_target.channel_snapshot;
key = obj;
break;
case OBJ_SEARCH_OBJECT:
- key = object->name;
+ key = object->base->name;
break;
default:
ast_assert(0);
switch (flags & OBJ_SEARCH_MASK) {
case OBJ_SEARCH_OBJECT:
- right_key = object_right->name;
+ right_key = object_right->base->name;
case OBJ_SEARCH_KEY:
- cmp = strcasecmp(object_left->name, right_key);
+ cmp = strcasecmp(object_left->base->name, right_key);
break;
case OBJ_SEARCH_PARTIAL_KEY:
- cmp = strncasecmp(object_left->name, right_key, strlen(right_key));
+ cmp = strncasecmp(object_left->base->name, right_key, strlen(right_key));
break;
default:
cmp = 0;
key = obj;
break;
case OBJ_SEARCH_OBJECT:
- key = object->uniqueid;
+ key = object->base->uniqueid;
break;
default:
ast_assert(0);
switch (flags & OBJ_SEARCH_MASK) {
case OBJ_SEARCH_OBJECT:
- right_key = object_right->uniqueid;
+ right_key = object_right->base->uniqueid;
case OBJ_SEARCH_KEY:
- cmp = strcasecmp(object_left->uniqueid, right_key);
+ cmp = strcasecmp(object_left->base->uniqueid, right_key);
break;
case OBJ_SEARCH_PARTIAL_KEY:
- cmp = strncasecmp(object_left->uniqueid, right_key, strlen(right_key));
+ cmp = strncasecmp(object_left->base->uniqueid, right_key, strlen(right_key));
break;
default:
cmp = 0;
{
struct ast_channel_snapshot *snapshot = obj;
- ast_string_field_free_memory(snapshot);
+ ao2_cleanup(snapshot->base);
+ ao2_cleanup(snapshot->peer);
+ ao2_cleanup(snapshot->caller);
+ ao2_cleanup(snapshot->connected);
+ ao2_cleanup(snapshot->bridge);
+ ao2_cleanup(snapshot->dialplan);
+ ao2_cleanup(snapshot->hangup);
ao2_cleanup(snapshot->manager_vars);
ao2_cleanup(snapshot->ari_vars);
}
-struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *chan)
+static void channel_snapshot_base_dtor(void *obj)
{
- struct ast_channel_snapshot *snapshot;
- struct ast_bridge *bridge;
+ struct ast_channel_snapshot_base *snapshot = obj;
- /* no snapshots for dummy channels */
- if (!ast_channel_tech(chan)) {
+ ast_string_field_free_memory(snapshot);
+}
+
+static struct ast_channel_snapshot_base *channel_snapshot_base_create(struct ast_channel *chan)
+{
+ struct ast_channel_snapshot_base *snapshot;
+
+ snapshot = ao2_alloc_options(sizeof(*snapshot), channel_snapshot_base_dtor,
+ AO2_ALLOC_OPT_LOCK_NOLOCK);
+ if (!snapshot) {
return NULL;
}
- snapshot = ao2_alloc_options(sizeof(*snapshot), channel_snapshot_dtor,
- AO2_ALLOC_OPT_LOCK_NOLOCK);
- if (!snapshot || ast_string_field_init(snapshot, 1024)) {
- ao2_cleanup(snapshot);
+ if (ast_string_field_init(snapshot, 256)) {
+ ao2_ref(snapshot, -1);
return NULL;
}
ast_string_field_set(snapshot, name, ast_channel_name(chan));
ast_string_field_set(snapshot, type, ast_channel_tech(chan)->type);
ast_string_field_set(snapshot, accountcode, ast_channel_accountcode(chan));
- ast_string_field_set(snapshot, peeraccount, ast_channel_peeraccount(chan));
ast_string_field_set(snapshot, userfield, ast_channel_userfield(chan));
ast_string_field_set(snapshot, uniqueid, ast_channel_uniqueid(chan));
- ast_string_field_set(snapshot, linkedid, ast_channel_linkedid(chan));
- ast_string_field_set(snapshot, hangupsource, ast_channel_hangupsource(chan));
- if (ast_channel_appl(chan)) {
- ast_string_field_set(snapshot, appl, ast_channel_appl(chan));
+ ast_string_field_set(snapshot, language, ast_channel_language(chan));
+
+ snapshot->creationtime = ast_channel_creationtime(chan);
+ snapshot->tech_properties = ast_channel_tech(chan)->properties;
+
+ return snapshot;
+}
+
+static struct ast_channel_snapshot_peer *channel_snapshot_peer_create(struct ast_channel *chan)
+{
+ const char *linkedid = S_OR(ast_channel_linkedid(chan), "");
+ const char *peeraccount = S_OR(ast_channel_peeraccount(chan), "");
+ size_t linkedid_len = strlen(linkedid) + 1;
+ size_t peeraccount_len = strlen(peeraccount) + 1;
+ struct ast_channel_snapshot_peer *snapshot;
+
+ snapshot = ao2_alloc_options(sizeof(*snapshot) + linkedid_len + peeraccount_len, NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
+ if (!snapshot) {
+ return NULL;
}
- if (ast_channel_data(chan)) {
- ast_string_field_set(snapshot, data, ast_channel_data(chan));
+
+ strcpy(snapshot->account, peeraccount); /* Safe */
+ snapshot->linkedid = snapshot->account + peeraccount_len;
+ strcpy(snapshot->linkedid, linkedid); /* Safe */
+
+ return snapshot;
+}
+
+static void channel_snapshot_caller_dtor(void *obj)
+{
+ struct ast_channel_snapshot_caller *snapshot = obj;
+
+ ast_string_field_free_memory(snapshot);
+}
+
+static struct ast_channel_snapshot_caller *channel_snapshot_caller_create(struct ast_channel *chan)
+{
+ struct ast_channel_snapshot_caller *snapshot;
+
+ snapshot = ao2_alloc_options(sizeof(*snapshot), channel_snapshot_caller_dtor,
+ AO2_ALLOC_OPT_LOCK_NOLOCK);
+ if (!snapshot) {
+ return NULL;
+ }
+
+ if (ast_string_field_init(snapshot, 256)) {
+ ao2_ref(snapshot, -1);
+ return NULL;
}
- ast_string_field_set(snapshot, context, ast_channel_context(chan));
- ast_string_field_set(snapshot, exten, ast_channel_exten(chan));
- ast_string_field_set(snapshot, caller_name,
+ ast_string_field_set(snapshot, name,
S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, ""));
- ast_string_field_set(snapshot, caller_number,
+ ast_string_field_set(snapshot, number,
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, ""));
- ast_string_field_set(snapshot, caller_subaddr,
+ ast_string_field_set(snapshot, subaddr,
S_COR(ast_channel_caller(chan)->id.subaddress.valid, ast_channel_caller(chan)->id.subaddress.str, ""));
- ast_string_field_set(snapshot, caller_ani,
+ ast_string_field_set(snapshot, ani,
S_COR(ast_channel_caller(chan)->ani.number.valid, ast_channel_caller(chan)->ani.number.str, ""));
- ast_string_field_set(snapshot, caller_rdnis,
+ ast_string_field_set(snapshot, rdnis,
S_COR(ast_channel_redirecting(chan)->from.number.valid, ast_channel_redirecting(chan)->from.number.str, ""));
- ast_string_field_set(snapshot, caller_dnid,
+ ast_string_field_set(snapshot, dnid,
S_OR(ast_channel_dialed(chan)->number.str, ""));
ast_string_field_set(snapshot, dialed_subaddr,
S_COR(ast_channel_dialed(chan)->subaddress.valid, ast_channel_dialed(chan)->subaddress.str, ""));
- ast_string_field_set(snapshot, connected_name,
- S_COR(ast_channel_connected(chan)->id.name.valid, ast_channel_connected(chan)->id.name.str, ""));
- ast_string_field_set(snapshot, connected_number,
- S_COR(ast_channel_connected(chan)->id.number.valid, ast_channel_connected(chan)->id.number.str, ""));
+ snapshot->pres = ast_party_id_presentation(&ast_channel_caller(chan)->id);
- ast_string_field_set(snapshot, language, ast_channel_language(chan));
+ return snapshot;
+}
+
+static struct ast_channel_snapshot_connected *channel_snapshot_connected_create(struct ast_channel *chan)
+{
+ const char *name = S_COR(ast_channel_connected(chan)->id.name.valid, ast_channel_connected(chan)->id.name.str, "");
+ const char *number = S_COR(ast_channel_connected(chan)->id.number.valid, ast_channel_connected(chan)->id.number.str, "");
+ size_t name_len = strlen(name) + 1;
+ size_t number_len = strlen(number) + 1;
+ struct ast_channel_snapshot_connected *snapshot;
+
+ snapshot = ao2_alloc_options(sizeof(*snapshot) + name_len + number_len, NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
+ if (!snapshot) {
+ return NULL;
+ }
+
+ strcpy(snapshot->name, name); /* Safe */
+ snapshot->number = snapshot->name + name_len;
+ strcpy(snapshot->number, number); /* Safe */
+
+ return snapshot;
+}
+
+static struct ast_channel_snapshot_bridge *channel_snapshot_bridge_create(struct ast_channel *chan)
+{
+ const char *uniqueid = "";
+ struct ast_bridge *bridge;
+ struct ast_channel_snapshot_bridge *snapshot;
+
+ bridge = ast_channel_get_bridge(chan);
+ if (bridge && !ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
+ uniqueid = bridge->uniqueid;
+ }
+ ao2_cleanup(bridge);
+
+ snapshot = ao2_alloc_options(sizeof(*snapshot) + strlen(uniqueid) + 1, NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
+ if (!snapshot) {
+ return NULL;
+ }
+
+ strcpy(snapshot->id, uniqueid); /* Safe */
+
+ return snapshot;
+}
+
+static void channel_snapshot_dialplan_dtor(void *obj)
+{
+ struct ast_channel_snapshot_dialplan *snapshot = obj;
+
+ ast_string_field_free_memory(snapshot);
+}
+
+static struct ast_channel_snapshot_dialplan *channel_snapshot_dialplan_create(struct ast_channel *chan)
+{
+ struct ast_channel_snapshot_dialplan *snapshot;
+
+ snapshot = ao2_alloc_options(sizeof(*snapshot), channel_snapshot_dialplan_dtor,
+ AO2_ALLOC_OPT_LOCK_NOLOCK);
+ if (!snapshot) {
+ return NULL;
+ }
- if ((bridge = ast_channel_get_bridge(chan))) {
- if (!ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
- ast_string_field_set(snapshot, bridgeid, bridge->uniqueid);
+ if (ast_string_field_init(snapshot, 256)) {
+ ao2_ref(snapshot, -1);
+ return NULL;
+ }
+
+ if (ast_channel_appl(chan)) {
+ ast_string_field_set(snapshot, appl, ast_channel_appl(chan));
+ }
+ if (ast_channel_data(chan)) {
+ ast_string_field_set(snapshot, data, ast_channel_data(chan));
+ }
+ ast_string_field_set(snapshot, context, ast_channel_context(chan));
+ ast_string_field_set(snapshot, exten, ast_channel_exten(chan));
+ snapshot->priority = ast_channel_priority(chan);
+
+ return snapshot;
+}
+
+static struct ast_channel_snapshot_hangup *channel_snapshot_hangup_create(struct ast_channel *chan)
+{
+ const char *hangupsource = S_OR(ast_channel_hangupsource(chan), "");
+ struct ast_channel_snapshot_hangup *snapshot;
+
+ snapshot = ao2_alloc_options(sizeof(*snapshot) + strlen(hangupsource) + 1, NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
+ if (!snapshot) {
+ return NULL;
+ }
+
+ snapshot->cause = ast_channel_hangupcause(chan);
+ strcpy(snapshot->source, hangupsource); /* Safe */
+
+ return snapshot;
+}
+
+struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *chan)
+{
+ struct ast_channel_snapshot *old_snapshot;
+ struct ast_channel_snapshot *snapshot;
+
+ /* no snapshots for dummy channels */
+ if (!ast_channel_tech(chan)) {
+ return NULL;
+ }
+
+ snapshot = ao2_alloc_options(sizeof(*snapshot), channel_snapshot_dtor,
+ AO2_ALLOC_OPT_LOCK_NOLOCK);
+ if (!snapshot) {
+ return NULL;
+ }
+
+ old_snapshot = ast_channel_snapshot(chan);
+
+ /* Channels automatically have all segments invalidated on them initially so a check for an old
+ * snapshot existing before usage is not done here, as it can not happen. If the stored snapshot
+ * on the channel is updated as a result of this then all segments marked as invalidated will be
+ * cleared.
+ */
+ if (ast_test_flag(ast_channel_snapshot_segment_flags(chan), AST_CHANNEL_SNAPSHOT_INVALIDATE_BASE)) {
+ /* The base information has changed so update our snapshot */
+ snapshot->base = channel_snapshot_base_create(chan);
+ if (!snapshot->base) {
+ ao2_ref(snapshot, -1);
+ return NULL;
}
- ao2_cleanup(bridge);
+ } else {
+ snapshot->base = ao2_bump(old_snapshot->base);
+ }
+
+ if (ast_test_flag(ast_channel_snapshot_segment_flags(chan), AST_CHANNEL_SNAPSHOT_INVALIDATE_PEER)) {
+ /* The peer information has changed so update our snapshot */
+ snapshot->peer = channel_snapshot_peer_create(chan);
+ if (!snapshot->peer) {
+ ao2_ref(snapshot, -1);
+ return NULL;
+ }
+ } else {
+ snapshot->peer = ao2_bump(old_snapshot->peer);
+ }
+
+ /* Unfortunately both caller and connected information do not have an enforced contract with
+ * the channel API. This has allowed consumers to directly get the caller or connected structure
+ * and manipulate it. Until such time as there is an enforced contract (which is being tracked under
+ * ASTERISK-28164) they are each regenerated every time a channel snapshot is created.
+ */
+ snapshot->caller = channel_snapshot_caller_create(chan);
+ if (!snapshot->caller) {
+ ao2_ref(snapshot, -1);
+ return NULL;
+ }
+
+ snapshot->connected = channel_snapshot_connected_create(chan);
+ if (!snapshot->connected) {
+ ao2_ref(snapshot, -1);
+ return NULL;
+ }
+
+ if (ast_test_flag(ast_channel_snapshot_segment_flags(chan), AST_CHANNEL_SNAPSHOT_INVALIDATE_BRIDGE)) {
+ /* The bridge has changed so update our snapshot */
+ snapshot->bridge = channel_snapshot_bridge_create(chan);
+ if (!snapshot->bridge) {
+ ao2_ref(snapshot, -1);
+ return NULL;
+ }
+ } else {
+ snapshot->bridge = ao2_bump(old_snapshot->bridge);
+ }
+
+ if (ast_test_flag(ast_channel_snapshot_segment_flags(chan), AST_CHANNEL_SNAPSHOT_INVALIDATE_DIALPLAN)) {
+ /* The dialplan information has changed so update our snapshot */
+ snapshot->dialplan = channel_snapshot_dialplan_create(chan);
+ if (!snapshot->dialplan) {
+ ao2_ref(snapshot, -1);
+ return NULL;
+ }
+ } else {
+ snapshot->dialplan = ao2_bump(old_snapshot->dialplan);
+ }
+
+ if (ast_test_flag(ast_channel_snapshot_segment_flags(chan), AST_CHANNEL_SNAPSHOT_INVALIDATE_HANGUP)) {
+ /* The hangup information has changed so update our snapshot */
+ snapshot->hangup = channel_snapshot_hangup_create(chan);
+ if (!snapshot->hangup) {
+ ao2_ref(snapshot, -1);
+ return NULL;
+ }
+ } else {
+ snapshot->hangup = ao2_bump(old_snapshot->hangup);
}
- snapshot->creationtime = ast_channel_creationtime(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);
ast_set_flag(&snapshot->softhangup_flags, ast_channel_softhangup_internal_flag(chan));
+ /* These have to be recreated as they may have changed, unfortunately */
snapshot->manager_vars = ast_channel_get_manager_vars(chan);
snapshot->ari_vars = ast_channel_get_ari_vars(chan);
- snapshot->tech_properties = ast_channel_tech(chan)->properties;
return snapshot;
}
ast_channel_publish_snapshot(chan);
}
+void ast_channel_snapshot_invalidate_segment(struct ast_channel *chan,
+ enum ast_channel_snapshot_segment_invalidation segment)
+{
+ ast_set_flag(ast_channel_snapshot_segment_flags(chan), segment);
+}
+
void ast_channel_publish_snapshot(struct ast_channel *chan)
{
struct ast_channel_snapshot_update *update;
return;
}
+ /* If an old snapshot exists and is the same as this newly created one don't bother
+ * raising a message as it hasn't changed.
+ */
+ if (update->old_snapshot && !memcmp(update->old_snapshot, update->new_snapshot, sizeof(struct ast_channel_snapshot))) {
+ ao2_ref(update, -1);
+ return;
+ }
+
message = stasis_message_create(ast_channel_snapshot_type(), update);
/* In the success path message holds a reference to update so it will be valid
* for the lifetime of this function until the end.
ast_channel_snapshot_set(chan, update->new_snapshot);
+ /* As this is now the new snapshot any existing invalidated segments have been
+ * created fresh and are up to date.
+ */
+ ast_clear_flag(ast_channel_snapshot_segment_flags(chan), AST_FLAGS_ALL);
+
ast_assert(ast_channel_topic(chan) != NULL);
stasis_publish(ast_channel_topic(chan), message);
ao2_ref(message, -1);
" s: o, s: o, s: s,"
" s: o, s: o, s: s }",
/* First line */
- "id", snapshot->uniqueid,
- "name", snapshot->name,
+ "id", snapshot->base->uniqueid,
+ "name", snapshot->base->name,
"state", ast_state2str(snapshot->state),
/* Second line */
"caller", ast_json_name_number(
- snapshot->caller_name, snapshot->caller_number),
+ snapshot->caller->name, snapshot->caller->number),
"connected", ast_json_name_number(
- snapshot->connected_name, snapshot->connected_number),
- "accountcode", snapshot->accountcode,
+ snapshot->connected->name, snapshot->connected->number),
+ "accountcode", snapshot->base->accountcode,
/* Third line */
"dialplan", ast_json_dialplan_cep(
- snapshot->context, snapshot->exten, snapshot->priority),
- "creationtime", ast_json_timeval(snapshot->creationtime, NULL),
- "language", snapshot->language);
+ snapshot->dialplan->context, snapshot->dialplan->exten, snapshot->dialplan->priority),
+ "creationtime", ast_json_timeval(snapshot->base->creationtime, NULL),
+ "language", snapshot->base->language);
if (snapshot->ari_vars && !AST_LIST_EMPTY(snapshot->ari_vars)) {
ast_json_object_set(json_chan, "channelvars", ast_json_channel_vars(snapshot->ari_vars));
* application is set. Since empty application is invalid, we treat
* setting the application from nothing as a CEP change.
*/
- if (ast_strlen_zero(old_snapshot->appl) &&
- !ast_strlen_zero(new_snapshot->appl)) {
+ if (ast_strlen_zero(old_snapshot->dialplan->appl) &&
+ !ast_strlen_zero(new_snapshot->dialplan->appl)) {
return 0;
}
- return old_snapshot->priority == new_snapshot->priority &&
- strcmp(old_snapshot->context, new_snapshot->context) == 0 &&
- strcmp(old_snapshot->exten, new_snapshot->exten) == 0;
+ return old_snapshot->dialplan->priority == new_snapshot->dialplan->priority &&
+ strcmp(old_snapshot->dialplan->context, new_snapshot->dialplan->context) == 0 &&
+ strcmp(old_snapshot->dialplan->exten, new_snapshot->dialplan->exten) == 0;
}
int ast_channel_snapshot_caller_id_equal(
{
ast_assert(old_snapshot != NULL);
ast_assert(new_snapshot != NULL);
- return strcmp(old_snapshot->caller_number, new_snapshot->caller_number) == 0 &&
- strcmp(old_snapshot->caller_name, new_snapshot->caller_name) == 0;
+ return strcmp(old_snapshot->caller->number, new_snapshot->caller->number) == 0 &&
+ strcmp(old_snapshot->caller->name, new_snapshot->caller->name) == 0;
}
int ast_channel_snapshot_connected_line_equal(
{
ast_assert(old_snapshot != NULL);
ast_assert(new_snapshot != NULL);
- return strcmp(old_snapshot->connected_number, new_snapshot->connected_number) == 0 &&
- strcmp(old_snapshot->connected_name, new_snapshot->connected_name) == 0;
+ return strcmp(old_snapshot->connected->number, new_snapshot->connected->number) == 0 &&
+ strcmp(old_snapshot->connected->name, new_snapshot->connected->name) == 0;
}
static struct ast_json *channel_blob_to_json(
term_color(tmp3, S_OR(appdata, ""), COLOR_BRMAGENTA, 0, sizeof(tmp3)));
if (ast_channel_snapshot_type()) {
ast_channel_lock(chan);
+ /* Force a new dialplan segment that will be unique to use so we can update it with the
+ * information we want. In the future when a channel snapshot is published this will
+ * occur again and unset this flag.
+ */
+ ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_DIALPLAN);
snapshot = ast_channel_snapshot_create(chan);
ast_channel_unlock(chan);
}
/* pbx_exec sets application name and data, but we don't want to log
* every exec. Just update the snapshot here instead.
*/
- ast_string_field_set(snapshot, appl, app);
- ast_string_field_set(snapshot, data, !ast_strlen_zero(appdata) ? appdata : "(NULL)");
+ ast_string_field_set(snapshot->dialplan, appl, app);
+ ast_string_field_set(snapshot->dialplan, data, !ast_strlen_zero(appdata) ? appdata : "(NULL)");
msg = stasis_message_create(ast_channel_snapshot_type(), snapshot);
if (msg) {
stasis_publish(ast_channel_topic(chan), msg);
return -1;
}
- language = S_OR(args_lang, snapshot->language);
+ language = S_OR(args_lang, snapshot->base->language);
playback = stasis_app_control_play_uri(control, args_media, args_media_count,
language, bridge->uniqueid, STASIS_PLAYBACK_TARGET_BRIDGE, args_skipms,
}
if (ast_strlen_zero(args->context)) {
- context = snapshot->context;
- exten = S_OR(args->extension, snapshot->exten);
+ context = snapshot->dialplan->context;
+ exten = S_OR(args->extension, snapshot->dialplan->exten);
} else {
context = args->context;
exten = S_OR(args->extension, "s");
ipri = args->priority;
} else if (ast_strlen_zero(args->context) && ast_strlen_zero(args->extension)) {
/* Special case. No exten, context, or priority provided, then move on to the next priority */
- ipri = snapshot->priority + 1;
+ ipri = snapshot->dialplan->priority + 1;
} else {
ipri = 1;
}
return;
}
- if (strncasecmp(chan_snapshot->type, tech, tech_len)) {
+ if (strncasecmp(chan_snapshot->base->type, tech, tech_len)) {
ast_ari_response_error(response, 422, "Unprocessable Entity",
"Endpoint technology '%s' does not match channel technology '%s'",
- tech, chan_snapshot->type);
+ tech, chan_snapshot->base->type);
return;
}
return;
}
- language = S_OR(args_lang, snapshot->language);
+ language = S_OR(args_lang, snapshot->base->language);
playback = stasis_app_control_play_uri(control, args_media, args_media_count, language,
args_channel_id, STASIS_PLAYBACK_TARGET_CHANNEL, args_skipms, args_offsetms, args_playback_id);
snprintf(buf, sizeof(buf), "%d", parkingspace);
oh.vars = ast_variable_new("_PARKEDAT", buf, "");
- inherit_channel_vars_from_id(&oh, parkee_snapshot->uniqueid);
+ inherit_channel_vars_from_id(&oh, parkee_snapshot->base->uniqueid);
dchan = __ast_request_and_dial(dial_tech, cap_slin, NULL, NULL, dial_string, 30000,
&outstate,
- parkee_snapshot->caller_number,
- parkee_snapshot->caller_name,
+ parkee_snapshot->caller->number,
+ parkee_snapshot->caller->name,
&oh);
ast_variables_destroy(oh.vars);
return;
}
- if (strcmp(payload->parkee->uniqueid, pa_data->parkee_uuid)) {
+ if (strcmp(payload->parkee->base->uniqueid, pa_data->parkee_uuid)) {
/* We are only concerned with the parkee we are subscribed for. */
return;
}
RAII_VAR(struct ast_channel *, parker, NULL, ast_channel_cleanup);
RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
- if (strcmp(parkee_to_act_on, parkee_snapshot->uniqueid)) {
+ if (strcmp(parkee_to_act_on, parkee_snapshot->base->uniqueid)) {
return;
}
int64_t age;
age = ast_tvdiff_ms(*stasis_message_timestamp(message),
- update->new_snapshot->creationtime);
+ update->new_snapshot->base->creationtime);
ast_statsd_log("channels.calltime", AST_STATSD_TIMER, age);
/* And decrement the channel count */
{
const struct ast_channel_snapshot *snapshot = object;
struct ast_str **buf = arg;
- ast_str_append(buf, 0, "%s,", snapshot->name);
+ ast_str_append(buf, 0, "%s,", snapshot->base->name);
return 0;
}
}
enter_blob = stasis_message_data(message);
- if (strcmp(enter_blob->channel->uniqueid, progress->transferee)) {
+ if (strcmp(enter_blob->channel->base->uniqueid, progress->transferee)) {
/* Don't care */
return;
}
}
if (replace_channel_snapshot) {
- app_unsubscribe_channel_id(app, replace_channel_snapshot->uniqueid);
+ app_unsubscribe_channel_id(app, replace_channel_snapshot->base->uniqueid);
}
stasis_publish(ast_app_get_topic(app), msg);
ao2_ref(msg, -1);
/* \brief Sanitization callback for channel snapshots */
static int channel_snapshot_sanitizer(const struct ast_channel_snapshot *snapshot)
{
- if (!snapshot || !(snapshot->tech_properties & AST_CHAN_TP_INTERNAL)) {
+ if (!snapshot || !(snapshot->base->tech_properties & AST_CHAN_TP_INTERNAL)) {
return 0;
}
return 1;
return;
}
- chan = ast_channel_get_by_name(snapshot->uniqueid);
+ chan = ast_channel_get_by_name(snapshot->base->uniqueid);
if (!chan) {
return;
}
return ast_json_pack("{s: s, s: o, s: i, s: s, s: o}",
"type", "ChannelDestroyed",
"timestamp", ast_json_timeval(*tv, NULL),
- "cause", snapshot->hangupcause,
- "cause_txt", ast_cause2str(snapshot->hangupcause),
+ "cause", snapshot->hangup->cause,
+ "cause_txt", ast_cause2str(snapshot->hangup->cause),
"channel", json_channel);
}
}
/* Empty application is not valid for a Newexten event */
- if (ast_strlen_zero(new_snapshot->appl)) {
+ if (ast_strlen_zero(new_snapshot->dialplan->appl)) {
return NULL;
}
return ast_json_pack("{s: s, s: o, s: s, s: s, s: o}",
"type", "ChannelDialplan",
"timestamp", ast_json_timeval(*tv, NULL),
- "dialplan_app", new_snapshot->appl,
- "dialplan_app_data", AST_JSON_UTF8_VALIDATE(new_snapshot->data),
+ "dialplan_app", new_snapshot->dialplan->appl,
+ "dialplan_app_data", AST_JSON_UTF8_VALIDATE(new_snapshot->dialplan->data),
"channel", json_channel);
}
return ast_json_pack("{s: s, s: o, s: i, s: s, s: o}",
"type", "ChannelCallerId",
"timestamp", ast_json_timeval(*tv, NULL),
- "caller_presentation", new_snapshot->caller_pres,
+ "caller_presentation", new_snapshot->caller->pres,
"caller_presentation_txt", ast_describe_caller_presentation(
- new_snapshot->caller_pres),
+ new_snapshot->caller->pres),
"channel", json_channel);
}
}
if (ast_test_flag(&update->new_snapshot->flags, AST_FLAG_DEAD)) {
- unsubscribe(app, "channel", update->new_snapshot->uniqueid, 1);
+ unsubscribe(app, "channel", update->new_snapshot->base->uniqueid, 1);
}
}
struct ast_blind_transfer_message *transfer_msg = stasis_message_data(message);
struct ast_bridge_snapshot *bridge = transfer_msg->bridge;
- if (bridge_app_subscribed(app, transfer_msg->transferer->uniqueid) ||
+ if (bridge_app_subscribed(app, transfer_msg->transferer->base->uniqueid) ||
(bridge && bridge_app_subscribed_involved(app, bridge))) {
stasis_publish(app->topic, message);
}
struct ast_attended_transfer_message *transfer_msg = stasis_message_data(message);
int subscribed = 0;
- subscribed = bridge_app_subscribed(app, transfer_msg->to_transferee.channel_snapshot->uniqueid);
+ subscribed = bridge_app_subscribed(app, transfer_msg->to_transferee.channel_snapshot->base->uniqueid);
if (!subscribed) {
- subscribed = bridge_app_subscribed(app, transfer_msg->to_transfer_target.channel_snapshot->uniqueid);
+ subscribed = bridge_app_subscribed(app, transfer_msg->to_transfer_target.channel_snapshot->base->uniqueid);
}
if (!subscribed && transfer_msg->to_transferee.bridge_snapshot) {
subscribed = bridge_app_subscribed_involved(app, transfer_msg->to_transferee.bridge_snapshot);
subscribed = bridge_app_subscribed(app, transfer_msg->dest.bridge);
break;
case AST_ATTENDED_TRANSFER_DEST_LINK:
- subscribed = bridge_app_subscribed(app, transfer_msg->dest.links[0]->uniqueid);
+ subscribed = bridge_app_subscribed(app, transfer_msg->dest.links[0]->base->uniqueid);
if (!subscribed) {
- subscribed = bridge_app_subscribed(app, transfer_msg->dest.links[1]->uniqueid);
+ subscribed = bridge_app_subscribed(app, transfer_msg->dest.links[1]->base->uniqueid);
}
break;
break;
case AST_ATTENDED_TRANSFER_DEST_THREEWAY:
subscribed = bridge_app_subscribed_involved(app, transfer_msg->dest.threeway.bridge_snapshot);
if (!subscribed) {
- subscribed = bridge_app_subscribed(app, transfer_msg->dest.threeway.channel_snapshot->uniqueid);
+ subscribed = bridge_app_subscribed(app, transfer_msg->dest.threeway.channel_snapshot->base->uniqueid);
}
break;
default:
ao2_cleanup);
/* Don't add the channel for which this message is being generated */
- if (!strcmp(current_chan, chan->uniqueid)) {
+ if (!strcmp(current_chan, chan->base->uniqueid)) {
continue;
}
continue;
}
- ast_str_append(&peer_str, 0, "%s,", current_snapshot->name);
+ ast_str_append(&peer_str, 0, "%s,", current_snapshot->base->name);
}
ao2_iterator_destroy(&i);
stasis_publish(ast_channel_topic(chan_alice), local_opt_begin);
stasis_publish(ast_channel_topic(chan_alice), local_opt_end);
- extra = ast_json_pack("{s: s, s: s}", "local_two", bob_snapshot->name,
- "local_two_uniqueid", bob_snapshot->uniqueid);
+ extra = ast_json_pack("{s: s, s: s}", "local_two", bob_snapshot->base->name,
+ "local_two_uniqueid", bob_snapshot->base->uniqueid);
ast_test_validate(test, extra != NULL);
APPEND_EVENT_SNAPSHOT(alice_snapshot, AST_CEL_LOCAL_OPTIMIZE, NULL, extra, NULL);
/* Test for single match */
snapshot = ast_multi_channel_blob_get_channel(blob, "Caller");
ast_test_validate(test, NULL != snapshot);
- ast_test_validate(test, 0 == strcmp("TEST/Alice", snapshot->name));
+ ast_test_validate(test, 0 == strcmp("TEST/Alice", snapshot->base->name));
/* Test for single match, multiple possibilities */
snapshot = ast_multi_channel_blob_get_channel(blob, "Peer");
ast_test_validate(test, NULL != snapshot);
- ast_test_validate(test, 0 != strcmp("TEST/Alice", snapshot->name));
+ ast_test_validate(test, 0 != strcmp("TEST/Alice", snapshot->base->name));
/* Multi-match */
matches = ast_multi_channel_blob_get_channels(blob, "Peer");