diff --git a/apps/app_queue.c b/apps/app_queue.c index 17e35f9bbb03545f4a9044f2cd2e5315ca6eed7a..2e59bf67430d572f8f4b569eb4e1b9c19cb869ea 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -5890,13 +5890,13 @@ static void queue_agent_cb(void *userdata, struct stasis_subscription *sub, 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"))); } } @@ -6088,8 +6088,8 @@ static void log_attended_transfer(struct queue_stasis_data *queue_data, struct a 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: @@ -6098,7 +6098,7 @@ static void log_attended_transfer(struct queue_stasis_data *queue_data, struct a 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); @@ -6131,11 +6131,11 @@ static void handle_bridge_enter(void *userdata, struct stasis_subscription *sub, 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); } } @@ -6186,7 +6186,7 @@ static void handle_blind_transfer(void *userdata, struct stasis_subscription *su 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), @@ -6302,9 +6302,9 @@ static void handle_local_optimization_begin(void *userdata, struct stasis_subscr 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; @@ -6313,9 +6313,9 @@ static void handle_local_optimization_begin(void *userdata, struct stasis_subscr /* 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")); @@ -6354,10 +6354,10 @@ static void handle_local_optimization_end(void *userdata, struct stasis_subscrip 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 { @@ -6420,16 +6420,16 @@ static void handle_hangup(void *userdata, struct stasis_subscription *sub, 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")))) { @@ -6446,9 +6446,9 @@ static void handle_hangup(void *userdata, struct stasis_subscription *sub, 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); diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index d0a74cd40e638597076eeb4295a59025ae05ff00..e44f3283dc9c6ffedd1857e04028c90b4adb7fbf 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -1169,7 +1169,7 @@ static int chan_pjsip_devicestate(const char *data) 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)); diff --git a/channels/pjsip/cli_commands.c b/channels/pjsip/cli_commands.c index 9a8dc2938afe01c14566a97a40cc9c041cb02faf..2ce236997ac259c301467483c7bacbc77f88fd0b 100644 --- a/channels/pjsip/cli_commands.c +++ b/channels/pjsip/cli_commands.c @@ -61,13 +61,13 @@ static int cli_channel_sort(const void *obj, const void *arg, int flags) 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; @@ -86,17 +86,17 @@ static int cli_channelstats_sort(const void *obj, const void *arg, int flags) 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; @@ -115,15 +115,15 @@ static int cli_channel_compare(void *obj, void *arg, int flags) 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; @@ -144,18 +144,18 @@ static int cli_channelstats_compare(void *obj, void *arg, int flags) 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; @@ -172,7 +172,7 @@ static int cli_message_to_snapshot(void *obj, void *arg, int flags) 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; } @@ -185,8 +185,8 @@ static int cli_filter_channels(void *obj, void *arg, int flags) 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; } @@ -236,7 +236,7 @@ static const char *cli_channel_get_id(const void *obj) { const struct ast_channel_snapshot *snapshot = obj; - return snapshot->name; + return snapshot->base->name; } static void *cli_channel_retrieve_by_id(const char *id) @@ -280,16 +280,16 @@ static int cli_channel_print_body(void *obj, void *arg, int flags) 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", @@ -307,9 +307,9 @@ static int cli_channel_print_body(void *obj, void *arg, int flags) "%*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) { @@ -338,7 +338,7 @@ static int cli_channelstats_print_body(void *obj, void *arg, int flags) { 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; @@ -351,7 +351,7 @@ static int cli_channelstats_print_body(void *obj, void *arg, int flags) 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; } @@ -359,7 +359,7 @@ static int cli_channelstats_print_body(void *obj, void *arg, int flags) 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; @@ -367,7 +367,7 @@ static int cli_channelstats_print_body(void *obj, void *arg, int flags) 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; @@ -383,18 +383,18 @@ static int cli_channelstats_print_body(void *obj, void *arg, int flags) 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, diff --git a/configs/samples/ari.conf.sample b/configs/samples/ari.conf.sample index 8729b1e09e84f3499d00858bb692e3c917dcdb44..5ce3166bfa77ffdf7c8aa8786b8902e72047578b 100644 --- a/configs/samples/ari.conf.sample +++ b/configs/samples/ari.conf.sample @@ -17,6 +17,8 @@ enabled = yes ; When set to no, ARI support is disabled. ; 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] diff --git a/configs/samples/manager.conf.sample b/configs/samples/manager.conf.sample index 989441a615bb6b1ec47a5dc507a57d533b798720..405e0d32c55044416c1aac5b88944a6796f4944d 100644 --- a/configs/samples/manager.conf.sample +++ b/configs/samples/manager.conf.sample @@ -55,6 +55,8 @@ bindaddr = 0.0.0.0 ; 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). diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index 9627ae216f98d8ecd473f6b95119d24fcecebeb5..58a4879b00a9dc4318553726524a7432fb8ec0bd 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -4258,6 +4258,7 @@ enum ast_channel_state ast_channel_state(const struct ast_channel *chan); 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 diff --git a/include/asterisk/stasis_channels.h b/include/asterisk/stasis_channels.h index 2aeff6f0b1c507c4ecb2d177634c4270cc91f0c6..c90470a73d4edb350d7337f5e7e5075fc4c169ed 100644 --- a/include/asterisk/stasis_channels.h +++ b/include/asterisk/stasis_channels.h @@ -28,51 +28,134 @@ * @{ */ +/*! + * \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 */ }; /*! @@ -359,6 +442,18 @@ void ast_channel_stage_snapshot(struct ast_channel *chan); */ 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. diff --git a/main/bridge.c b/main/bridge.c index 024c6abfeae94a115db6bbbbc6dcea44d1d87136..a65927d4b558f308e7faece7741dd4b9596bd5c9 100644 --- a/main/bridge.c +++ b/main/bridge.c @@ -5157,7 +5157,7 @@ static int bridge_show_specific_print_channel(void *obj, void *arg, int flags) 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; diff --git a/main/cdr.c b/main/cdr.c index e321c2215d80ace726b1b2f68c7fd0e9cb46d428..2e3b2058a93ed1442a79b0a6325474b738b23ea9 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -803,7 +803,7 @@ static void cdr_object_snapshot_copy(struct cdr_object_snapshot *dst, struct cdr 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) { @@ -938,9 +938,9 @@ static void cdr_all_relink(struct cdr_object *cdr) { 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 { @@ -1039,16 +1039,16 @@ static struct cdr_object *cdr_object_alloc(struct ast_channel_snapshot *chan) 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); @@ -1145,11 +1145,11 @@ static int snapshot_cep_changed(struct ast_channel_snapshot *old_snapshot, * 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; } @@ -1196,11 +1196,11 @@ static struct cdr_object_snapshot *cdr_object_pick_party_a(struct cdr_object_sna /* 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 */ @@ -1285,7 +1285,7 @@ static struct ast_cdr *cdr_object_create_public_records(struct cdr_object *cdr) /* 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; } @@ -1300,12 +1300,12 @@ static struct ast_cdr *cdr_object_create_public_records(struct cdr_object *cdr) /* 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)); @@ -1313,8 +1313,8 @@ static struct ast_cdr *cdr_object_create_public_records(struct cdr_object *cdr) /* 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); } @@ -1375,8 +1375,8 @@ static void cdr_object_dispatch(struct cdr_object *cdr) 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); } @@ -1434,10 +1434,10 @@ static void cdr_object_finalize(struct cdr_object *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; } @@ -1445,7 +1445,7 @@ static void cdr_object_finalize(struct cdr_object *cdr) /* 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, @@ -1491,19 +1491,19 @@ static void cdr_object_check_party_a_answer(struct cdr_object *cdr) 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); } } @@ -1524,7 +1524,7 @@ static void cdr_object_swap_snapshot(struct cdr_object_snapshot *old_snapshot, 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) @@ -1539,11 +1539,11 @@ static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snaps */ 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); } } @@ -1555,13 +1555,13 @@ static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snaps * 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 @@ -1569,13 +1569,13 @@ static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snaps * 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); @@ -1603,7 +1603,7 @@ static int base_process_parked_channel(struct cdr_object *cdr, struct ast_parked { 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); @@ -1637,25 +1637,25 @@ static void single_state_process_party_b(struct cdr_object *cdr, struct ast_chan 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); @@ -1680,15 +1680,15 @@ static int single_state_bridge_enter_comparison(struct cdr_object *cdr, 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) { @@ -1703,13 +1703,13 @@ static int single_state_bridge_enter_comparison(struct cdr_object *cdr, /* 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; @@ -1788,7 +1788,7 @@ static void dial_state_process_party_b(struct cdr_object *cdr, struct ast_channe { 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); @@ -1839,11 +1839,11 @@ static int dial_state_process_dial_end(struct cdr_object *cdr, struct ast_channe } 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; } @@ -1901,7 +1901,7 @@ static enum process_bridge_enter_results dial_state_process_bridge_enter(struct } /* 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); @@ -1982,7 +1982,7 @@ static int dialed_pending_state_process_dial_begin(struct cdr_object *cdr, struc 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); @@ -1997,9 +1997,9 @@ static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_ 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); @@ -2011,7 +2011,7 @@ static int bridge_state_process_bridge_leave(struct cdr_object *cdr, struct ast_ 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); @@ -2043,7 +2043,7 @@ static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_ch */ 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; } /*! @@ -2114,19 +2114,19 @@ static void handle_dial_message(void *data, struct stasis_subscription *sub, str 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; } @@ -2139,8 +2139,8 @@ static void handle_dial_message(void *data, struct stasis_subscription *sub, str } 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); @@ -2150,8 +2150,8 @@ static void handle_dial_message(void *data, struct stasis_subscription *sub, str } 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, @@ -2185,7 +2185,7 @@ static int cdr_object_finalize_party_b(void *obj, void *arg, void *data, int fla * 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 @@ -2210,11 +2210,11 @@ static int cdr_object_update_party_b(void *obj, void *arg, void *data, int flags * 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; } @@ -2236,7 +2236,7 @@ static int check_new_cdr_needed(struct ast_channel_snapshot *old_snapshot, } /* 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; } @@ -2272,12 +2272,12 @@ static void handle_channel_snapshot_update_message(void *data, struct stasis_sub 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; @@ -2303,7 +2303,7 @@ static void handle_channel_snapshot_update_message(void *data, struct stasis_sub 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); } @@ -2317,12 +2317,12 @@ static void handle_channel_snapshot_update_message(void *data, struct stasis_sub /* 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); @@ -2347,7 +2347,7 @@ static int cdr_object_party_b_left_bridge_cb(void *obj, void *arg, void *data, i * 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. @@ -2399,13 +2399,13 @@ static void handle_bridge_leave_message(void *data, struct stasis_subscription * } 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; } @@ -2417,7 +2417,7 @@ static void handle_bridge_leave_message(void *data, struct stasis_subscription * 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; @@ -2429,7 +2429,7 @@ static void handle_bridge_leave_message(void *data, struct stasis_subscription * 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); } @@ -2457,8 +2457,8 @@ static void bridge_candidate_add_to_cdr(struct cdr_object *cdr, 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); } /*! @@ -2487,16 +2487,16 @@ static void bridge_candidate_process(struct cdr_object *cdr, struct cdr_object * } /* 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; } @@ -2504,12 +2504,12 @@ static void bridge_candidate_process(struct cdr_object *cdr, struct cdr_object * /* 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 @@ -2572,7 +2572,7 @@ static void handle_parking_bridge_enter_message(struct cdr_object *cdr, } 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); } } @@ -2609,14 +2609,14 @@ try_again: 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: @@ -2689,13 +2689,13 @@ static void handle_bridge_enter_message(void *data, struct stasis_subscription * } 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; } @@ -2739,13 +2739,13 @@ static void handle_parked_call_message(void *data, struct stasis_subscription *s } 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; } @@ -3094,8 +3094,8 @@ static int cdr_object_select_all_by_name_cb(void *obj, void *arg, int flags) 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; @@ -3110,7 +3110,7 @@ static int cdr_object_get_by_name_cb(void *obj, void *arg, int flags) 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; @@ -3170,10 +3170,10 @@ int ast_cdr_setvar(const char *channel_name, const char *name, const char *value 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) { @@ -3212,25 +3212,25 @@ static int cdr_object_format_property(struct cdr_object *cdr_obj, const char *na 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")) { @@ -3246,15 +3246,15 @@ static int cdr_object_format_property(struct cdr_object *cdr_obj, const char *na } 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")) { @@ -3431,7 +3431,7 @@ static int cdr_object_update_party_b_userfield_cb(void *obj, void *arg, void *da * 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)); @@ -3624,7 +3624,7 @@ int ast_cdr_fork(const char *channel_name, struct ast_flags *options) /* 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; @@ -3938,8 +3938,8 @@ static char *cli_complete_show(struct ast_cli_args *a) 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; } @@ -4001,8 +4001,8 @@ static void cli_show_channels(struct ast_cli_args *a) 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, @@ -4046,7 +4046,7 @@ static void cli_show_channel(struct ast_cli_args *a) 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 { @@ -4056,9 +4056,9 @@ static void cli_show_channel(struct ast_cli_args *a) 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, @@ -4415,8 +4415,8 @@ static void cdr_master_print_fn(void *v_obj, void *where, ao2_prnt_fn *prnt) } 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); } } @@ -4440,8 +4440,8 @@ static void cdr_all_print_fn(void *v_obj, void *where, ao2_prnt_fn *prnt) 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); } diff --git a/main/cel.c b/main/cel.c index 97e35adf55abe7af094ceb74f4a40c61db80c868..242aeffa6be8a50cb94b291555cfd3a739a0460f 100644 --- a/main/cel.c +++ b/main/cel.c @@ -528,22 +528,22 @@ struct ast_event *ast_cel_create_event(struct ast_channel_snapshot *snapshot, 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); @@ -573,7 +573,7 @@ static int cel_report_event(struct ast_channel_snapshot *snapshot, * 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; } } @@ -583,7 +583,7 @@ static int cel_report_event(struct ast_channel_snapshot *snapshot, } 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; } @@ -606,14 +606,14 @@ static void check_retire_linkedid(struct ast_channel_snapshot *snapshot) 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); @@ -623,7 +623,7 @@ static void check_retire_linkedid(struct ast_channel_snapshot *snapshot) * 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; } @@ -898,11 +898,11 @@ static void cel_channel_state_change( 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); @@ -929,12 +929,12 @@ static void cel_channel_linkedid_change( 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); } } @@ -943,17 +943,17 @@ static void cel_channel_app_change( 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); } } @@ -974,7 +974,7 @@ static int cel_filter_channel_snapshot(struct ast_channel_snapshot *snapshot) 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, @@ -1010,7 +1010,7 @@ static struct ast_str *cel_generate_peer_str( 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; } @@ -1019,7 +1019,7 @@ static struct ast_str *cel_generate_peer_str( 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); @@ -1125,7 +1125,7 @@ static void cel_parking_cb( 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 ?: ""); } @@ -1147,7 +1147,7 @@ static void save_dialstatus(struct ast_multi_channel_blob *blob, struct ast_chan 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 @@ -1171,7 +1171,7 @@ static void save_dialstatus(struct ast_multi_channel_blob *blob, struct ast_chan 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); @@ -1273,8 +1273,8 @@ static void cel_blind_transfer_cb( "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); @@ -1312,13 +1312,13 @@ static void cel_attended_transfer_cb( 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; } @@ -1327,13 +1327,13 @@ static void cel_attended_transfer_cb( 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; } @@ -1357,8 +1357,8 @@ static void cel_pickup_cb( } 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; } @@ -1381,8 +1381,8 @@ static void cel_local_cb( } 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; } diff --git a/main/channel.c b/main/channel.c index 3d8e244fd8c2228fdd94833f08d93d53d1990f0a..7e12f304923f337917fd16141380c4fef185e1f2 100644 --- a/main/channel.c +++ b/main/channel.c @@ -6761,6 +6761,12 @@ static void channel_do_masquerade(struct ast_channel *original, struct ast_chann 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 @@ -7183,6 +7189,7 @@ void ast_channel_set_caller(struct ast_channel *chan, const struct ast_party_cal 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); } @@ -7195,6 +7202,7 @@ void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_par 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); } @@ -8120,6 +8128,7 @@ void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_p 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); } @@ -8930,6 +8939,7 @@ void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_part 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); } diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c index 436ba23034700b9aff2cacc277dd9eeb66031042..30d39097e0a7dde03839f9c1db9a14844289ca31 100644 --- a/main/channel_internal_api.c +++ b/main/channel_internal_api.c @@ -221,6 +221,7 @@ struct ast_channel { 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 */ @@ -228,18 +229,40 @@ static int uniqueint; /* 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, ...) \ @@ -250,17 +273,17 @@ 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) \ { \ @@ -298,6 +321,7 @@ const char *ast_channel_appl(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) { @@ -314,6 +338,7 @@ const char *ast_channel_data(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) @@ -323,6 +348,7 @@ 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) { @@ -331,6 +357,7 @@ 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) { @@ -404,6 +431,7 @@ int ast_channel_hangupcause(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) { @@ -420,6 +448,7 @@ int ast_channel_priority(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) { @@ -909,18 +938,22 @@ void ast_channel_jb_set(struct ast_channel *chan, struct ast_jb *value) 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) { @@ -941,6 +974,7 @@ struct timeval ast_channel_creationtime(struct ast_channel *chan) 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) @@ -1204,6 +1238,7 @@ struct ast_bridge *ast_channel_internal_bridge(const 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); } @@ -1335,6 +1370,11 @@ struct ast_channel *__ast_channel_internal_alloc(void (*destructor)(void *obj), 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; } @@ -1363,6 +1403,7 @@ void ast_channel_internal_copy_linkedid(struct ast_channel *dest, struct ast_cha return; } dest->linkedid = source->linkedid; + ast_channel_snapshot_invalidate_segment(dest, AST_CHANNEL_SNAPSHOT_INVALIDATE_PEER); ast_channel_publish_snapshot(dest); } @@ -1370,6 +1411,10 @@ void ast_channel_internal_swap_uniqueid_and_linkedid(struct ast_channel *a, stru { 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; @@ -1584,3 +1629,8 @@ void ast_channel_snapshot_set(struct ast_channel *chan, struct ast_channel_snaps 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; +} diff --git a/main/cli.c b/main/cli.c index 5484e47e7ef2986a7b1a3d600bfe428111819acd..e2224f7ddb0b13a607286e6c833f499e6ce0d989 100644 --- a/main/cli.c +++ b/main/cli.c @@ -1004,8 +1004,8 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar 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; @@ -1016,36 +1016,36 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar } } 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); } } } @@ -1684,14 +1684,14 @@ char *ast_complete_channels(const char *line, const char *word, int pos, int sta 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; } diff --git a/main/core_local.c b/main/core_local.c index c3fa15f6c273c13f672a1ea63443fbca4b5f6e98..f56aac76b1395961dbe76cbc2b9a5970e978291c 100644 --- a/main/core_local.c +++ b/main/core_local.c @@ -493,7 +493,7 @@ static struct ast_manager_event_blob *local_message_to_ami(struct stasis_message } 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) { diff --git a/main/endpoints.c b/main/endpoints.c index f3e337225d662dec94602ce18ccdfb950cf58897..b95893270b904598566a1b6a3a3a8453a5826bd1 100644 --- a/main/endpoints.c +++ b/main/endpoints.c @@ -195,7 +195,7 @@ static void endpoint_cache_clear(void *data, 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); } diff --git a/main/manager.c b/main/manager.c index 76a827c09c85578354288e5f410a7cfa6eb95dda..3e41198c0f03b81c8653b5f2753f8fd2bb86213e 100644 --- a/main/manager.c +++ b/main/manager.c @@ -6271,10 +6271,10 @@ static int action_coreshowchannels(struct mansession *s, const struct message *m 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; @@ -6292,10 +6292,10 @@ static int action_coreshowchannels(struct mansession *s, const struct message *m "\r\n", idText, ast_str_buffer(built), - cs->appl, - cs->data, + cs->dialplan->appl, + cs->dialplan->data, durbuf, - cs->bridgeid); + cs->bridge->id); numchans++; diff --git a/main/manager_bridges.c b/main/manager_bridges.c index 1b5704968f087582adf18bd214d4fd046288c730..4f2cb35306c24927577ad290ce5cb7d374dd4e0b 100644 --- a/main/manager_bridges.c +++ b/main/manager_bridges.c @@ -536,7 +536,7 @@ static int send_bridge_info_item_cb(void *obj, void *arg, void *data, int flags) return 0; } - if (snapshot->tech_properties & AST_CHAN_TP_INTERNAL) { + if (snapshot->base->tech_properties & AST_CHAN_TP_INTERNAL) { return 0; } diff --git a/main/manager_channels.c b/main/manager_channels.c index 887f77e19351244bf7ae713b860c03dc1f171761..edbc770a075ae9a9a59c8dcb13f0f863874fac6e 100644 --- a/main/manager_channels.c +++ b/main/manager_channels.c @@ -493,7 +493,7 @@ struct ast_str *ast_manager_build_channel_state_string_prefix( char *connected_name; int res; - if (snapshot->tech_properties & AST_CHAN_TP_INTERNAL) { + if (snapshot->base->tech_properties & AST_CHAN_TP_INTERNAL) { return NULL; } @@ -502,8 +502,8 @@ struct ast_str *ast_manager_build_channel_state_string_prefix( 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" @@ -520,20 +520,20 @@ struct ast_str *ast_manager_build_channel_state_string_prefix( "%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); @@ -594,8 +594,8 @@ static struct ast_manager_event_blob *channel_state_change( 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) { @@ -612,7 +612,7 @@ static struct ast_manager_event_blob *channel_newexten( 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; } @@ -632,9 +632,9 @@ static struct ast_manager_event_blob *channel_newexten( "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( @@ -654,14 +654,14 @@ 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); @@ -693,13 +693,13 @@ static struct ast_manager_event_blob *channel_new_accountcode( 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[] = { diff --git a/main/stasis_bridges.c b/main/stasis_bridges.c index 59b9685ef3191492d425057b2739f1207e8d88ab..42bf6bc2dae899c79b32deafc5f6ae4855edb94f 100644 --- a/main/stasis_bridges.c +++ b/main/stasis_bridges.c @@ -1069,7 +1069,7 @@ static struct ast_manager_event_blob *attended_transfer_to_ami(struct stasis_mes 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"); @@ -1189,7 +1189,7 @@ int ast_attended_transfer_message_add_threeway(struct ast_attended_transfer_mess { 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; diff --git a/main/stasis_channels.c b/main/stasis_channels.c index ec8d70cd22f284a01840a5f30918b13fcd01cc8d..d39fb08fbf41570fd74e895e725b370a53190b4d 100644 --- a/main/stasis_channels.c +++ b/main/stasis_channels.c @@ -149,7 +149,7 @@ static int channel_snapshot_hash_cb(const void *obj, const int flags) key = obj; break; case OBJ_SEARCH_OBJECT: - key = object->name; + key = object->base->name; break; default: ast_assert(0); @@ -171,12 +171,12 @@ static int channel_snapshot_cmp_cb(void *obj, void *arg, int flags) 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; @@ -202,7 +202,7 @@ static int channel_snapshot_uniqueid_hash_cb(const void *obj, const int flags) key = obj; break; case OBJ_SEARCH_OBJECT: - key = object->uniqueid; + key = object->base->uniqueid; break; default: ast_assert(0); @@ -224,12 +224,12 @@ static int channel_snapshot_uniqueid_cmp_cb(void *obj, void *arg, int flags) 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; @@ -245,88 +245,312 @@ static void channel_snapshot_dtor(void *obj) { 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; } @@ -822,6 +1046,12 @@ void ast_channel_stage_snapshot_done(struct ast_channel *chan) 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; @@ -840,6 +1070,14 @@ void ast_channel_publish_snapshot(struct ast_channel *chan) 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. @@ -869,6 +1107,11 @@ void ast_channel_publish_snapshot(struct ast_channel *chan) 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); @@ -1028,20 +1271,20 @@ struct ast_json *ast_channel_snapshot_to_json( " 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)); @@ -1061,14 +1304,14 @@ int ast_channel_snapshot_cep_equal( * 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( @@ -1077,8 +1320,8 @@ 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( @@ -1087,8 +1330,8 @@ 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( diff --git a/pbx/pbx_realtime.c b/pbx/pbx_realtime.c index 75e6654f07be863946f078e0290a0de7d346910b..970bb3cbb5f8217bb11fe007944fbf425ed32b06 100644 --- a/pbx/pbx_realtime.c +++ b/pbx/pbx_realtime.c @@ -344,6 +344,11 @@ static int realtime_exec(struct ast_channel *chan, const char *context, const ch 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); } @@ -351,8 +356,8 @@ static int realtime_exec(struct ast_channel *chan, const char *context, const ch /* 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); diff --git a/res/ari/resource_bridges.c b/res/ari/resource_bridges.c index e5fa41c1d9a21e1a9929935f850156352b034d97..3c0eeb7751e2dc8268796abf78c0501c0bafb482 100644 --- a/res/ari/resource_bridges.c +++ b/res/ari/resource_bridges.c @@ -377,7 +377,7 @@ static int ari_bridges_play_helper(const char **args_media, 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, diff --git a/res/ari/resource_channels.c b/res/ari/resource_channels.c index f96192b52fa05049eebcf48cb97c594ae3e73122..311358ef4db03fec7ef10cc0371129a8dc09d9d0 100644 --- a/res/ari/resource_channels.c +++ b/res/ari/resource_channels.c @@ -170,8 +170,8 @@ void ast_ari_channels_continue_in_dialplan( } 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"); @@ -203,7 +203,7 @@ void ast_ari_channels_continue_in_dialplan( 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; } @@ -263,10 +263,10 @@ void ast_ari_channels_redirect(struct ast_variable *headers, 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; } @@ -628,7 +628,7 @@ static void ari_channels_handle_play( 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); diff --git a/res/parking/parking_applications.c b/res/parking/parking_applications.c index f9b3e85d26a19e9132c4d0a8159c5b2e2c3168d4..46dbedf38d07a7c2b4a763c227bf8645665b5dd9 100644 --- a/res/parking/parking_applications.c +++ b/res/parking/parking_applications.c @@ -819,12 +819,12 @@ static void announce_to_dial(char *dial_string, char *announce_string, int parki 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); @@ -877,7 +877,7 @@ static void park_announce_update_cb(void *data, struct stasis_subscription *sub, 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; } diff --git a/res/parking/parking_bridge_features.c b/res/parking/parking_bridge_features.c index 1d3b9e4da8f9b2f27d30dda6ea3f09c88cfc8fee..d61947189e35cdd54e05702742a4a0f376f040e7 100644 --- a/res/parking/parking_bridge_features.c +++ b/res/parking/parking_bridge_features.c @@ -111,7 +111,7 @@ static void parker_parked_call_message_response(struct ast_parked_call_payload * 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; } diff --git a/res/res_chan_stats.c b/res/res_chan_stats.c index bed95a03fb067d807ad6c09d3e97265a20bf70a4..e32498bab904c81685c12c77e7d3d4da2d3d9139 100644 --- a/res/res_chan_stats.c +++ b/res/res_chan_stats.c @@ -110,7 +110,7 @@ static void updates(void *data, struct stasis_subscription *sub, 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 */ diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index 41195be2b793796e46b6ed5e0d4eda4ebf889ead..d88024a80b074a23cfbf92b3e0f7c22cad6ee4de 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -1351,7 +1351,7 @@ static int active_channels_to_str_cb(void *object, void *arg, int flags) { 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; } diff --git a/res/res_pjsip_refer.c b/res/res_pjsip_refer.c index 3dfaabc445ab8b4dad6d8389aef4a09a5f1888f7..9b751469384888bc5f066362a8ccbfb2f0ba5d11 100644 --- a/res/res_pjsip_refer.c +++ b/res/res_pjsip_refer.c @@ -179,7 +179,7 @@ static void refer_progress_bridge(void *data, struct stasis_subscription *sub, } 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; } diff --git a/res/res_stasis.c b/res/res_stasis.c index 704d779c48485b835750b8b89efe06b151135a15..43833e17cd3d785369bd68e017eea891548d6db9 100644 --- a/res/res_stasis.c +++ b/res/res_stasis.c @@ -1019,7 +1019,7 @@ static int send_start_msg_snapshots(struct ast_channel *chan, struct stasis_app } 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); @@ -2051,7 +2051,7 @@ static int unload_module(void) /* \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; diff --git a/res/stasis/app.c b/res/stasis/app.c index b4f3bc6cfc422413ede0122fb23dcd0e16b7572c..78f5765809d085fd67cf1cfa89959997efb26266 100644 --- a/res/stasis/app.c +++ b/res/stasis/app.c @@ -315,7 +315,7 @@ static void call_forwarded_handler(struct stasis_app *app, struct stasis_message return; } - chan = ast_channel_get_by_name(snapshot->uniqueid); + chan = ast_channel_get_by_name(snapshot->base->uniqueid); if (!chan) { return; } @@ -391,8 +391,8 @@ static struct ast_json *channel_destroyed_event( 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); } @@ -436,7 +436,7 @@ static struct ast_json *channel_dialplan( } /* 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; } @@ -452,8 +452,8 @@ static struct ast_json *channel_dialplan( 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); } @@ -481,9 +481,9 @@ static struct ast_json *channel_callerid( 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); } @@ -541,7 +541,7 @@ static void sub_channel_update_handler(void *data, } 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); } } @@ -768,7 +768,7 @@ static void bridge_blind_transfer_handler(void *data, struct stasis_subscription 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); } @@ -781,9 +781,9 @@ static void bridge_attended_transfer_handler(void *data, struct stasis_subscript 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); @@ -798,16 +798,16 @@ static void bridge_attended_transfer_handler(void *data, struct stasis_subscript 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: diff --git a/tests/test_cel.c b/tests/test_cel.c index c1e73403bd7d86c8e528565f5e15b77d2233f53b..6c8bd61866cf4a1b6ed42431cdc6b8b1ac5e76d1 100644 --- a/tests/test_cel.c +++ b/tests/test_cel.c @@ -329,7 +329,7 @@ static struct ast_str *__test_cel_generate_peer_str(struct ast_channel_snapshot 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; } @@ -338,7 +338,7 @@ static struct ast_str *__test_cel_generate_peer_str(struct ast_channel_snapshot 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); @@ -1668,8 +1668,8 @@ AST_TEST_DEFINE(test_cel_local_optimize) 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); diff --git a/tests/test_stasis_channels.c b/tests/test_stasis_channels.c index f73d882e3c3cfc361a9e0d70f957a107e8a1394d..f8d2a03f818495150f1c04eea0e1bd950f107edd 100644 --- a/tests/test_stasis_channels.c +++ b/tests/test_stasis_channels.c @@ -220,12 +220,12 @@ AST_TEST_DEFINE(multi_channel_blob_snapshots) /* 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");