diff --git a/apps/confbridge/conf_chan_announce.c b/apps/confbridge/conf_chan_announce.c index 19224254da..df48aed330 100644 --- a/apps/confbridge/conf_chan_announce.c +++ b/apps/confbridge/conf_chan_announce.c @@ -134,7 +134,7 @@ static struct ast_channel_tech announce_tech = { .send_text = ast_unreal_sendtext, .queryoption = ast_unreal_queryoption, .setoption = ast_unreal_setoption, - .properties = AST_CHAN_TP_ANNOUNCER, + .properties = AST_CHAN_TP_INTERNAL, }; struct ast_channel_tech *conf_announce_get_tech(void) diff --git a/apps/confbridge/conf_chan_record.c b/apps/confbridge/conf_chan_record.c index c3f717074a..7080d118c9 100644 --- a/apps/confbridge/conf_chan_record.c +++ b/apps/confbridge/conf_chan_record.c @@ -86,7 +86,7 @@ static struct ast_channel_tech record_tech = { .call = rec_call, .read = rec_read, .write = rec_write, - .properties = AST_CHAN_TP_RECORDER, + .properties = AST_CHAN_TP_INTERNAL, }; struct ast_channel_tech *conf_record_get_tech(void) diff --git a/channels/chan_bridge_media.c b/channels/chan_bridge_media.c index 3abee98323..663578033e 100644 --- a/channels/chan_bridge_media.c +++ b/channels/chan_bridge_media.c @@ -89,7 +89,7 @@ static struct ast_channel_tech announce_tech = { .send_text = ast_unreal_sendtext, .queryoption = ast_unreal_queryoption, .setoption = ast_unreal_setoption, - .properties = AST_CHAN_TP_ANNOUNCER, + .properties = AST_CHAN_TP_INTERNAL, }; static struct ast_channel_tech record_tech = { @@ -111,7 +111,7 @@ static struct ast_channel_tech record_tech = { .send_text = ast_unreal_sendtext, .queryoption = ast_unreal_queryoption, .setoption = ast_unreal_setoption, - .properties = AST_CHAN_TP_RECORDER, + .properties = AST_CHAN_TP_INTERNAL, }; static struct ast_channel *media_request_helper(struct ast_format_cap *cap, diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index cc60debfdb..ad229a9322 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -864,15 +864,11 @@ enum { */ AST_CHAN_TP_CREATESJITTER = (1 << 1), /*! - * \brief Channels have this property if they are an implementation detail - * used for announcing messages; i.e. to a bridge + * \brief Channels with this particular technology are an implementation detail of + * Asterisk and should generally not be exposed or manipulated by the outside + * world */ - AST_CHAN_TP_ANNOUNCER = (1 << 2), - /*! - * \brief Channels have this property if they are an implementation detail - * used for recording audio; i.e. from a bridge - */ - AST_CHAN_TP_RECORDER = (1 << 3), + AST_CHAN_TP_INTERNAL = (1 << 2), }; /*! \brief ast_channel flags */ diff --git a/main/cel.c b/main/cel.c index ae42a443dd..d9e1d81dfe 100644 --- a/main/cel.c +++ b/main/cel.c @@ -1103,7 +1103,7 @@ static int cel_filter_channel_snapshot(struct ast_channel_snapshot *snapshot) if (!snapshot) { return 0; } - return snapshot->tech_properties & (AST_CHAN_TP_ANNOUNCER | AST_CHAN_TP_RECORDER); + return snapshot->tech_properties & AST_CHAN_TP_INTERNAL; } static void cel_snapshot_update_cb(void *data, struct stasis_subscription *sub, diff --git a/main/channel.c b/main/channel.c index 8e6a4c945c..9bfe2fabe8 100644 --- a/main/channel.c +++ b/main/channel.c @@ -830,6 +830,16 @@ struct ast_format *ast_best_codec(struct ast_format_cap *cap, struct ast_format return NULL; } +/*! \brief Channel technology used to extract a channel from a running application. The + * channel created with this technology will be immediately hung up - most external + * applications won't ever want to see this. + */ +static const struct ast_channel_tech surrogate_tech = { + .type = "Surrogate", + .description = "Surrogate channel used to pull channel from an application", + .properties = AST_CHAN_TP_INTERNAL, +}; + static const struct ast_channel_tech null_tech = { .type = "NULL", .description = "Null channel (should not see this)", @@ -852,6 +862,7 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char struct ast_sched_context *schedctx; struct ast_timer *timer; struct timeval now; + const struct ast_channel_tech *channel_tech; /* If shutting down, don't allocate any new channels */ if (ast_shutting_down()) { @@ -965,9 +976,6 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char ast_channel_name_set(tmp, "-**Unknown**"); } - /* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */ - - /* These 4 variables need to be set up for the cdr_init() to work right */ if (amaflag != AST_AMA_NONE) { ast_channel_amaflags_set(tmp, amaflag); } else { @@ -977,39 +985,39 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char if (!ast_strlen_zero(acctcode)) { ast_channel_accountcode_set(tmp, acctcode); } + ast_channel_language_set(tmp, ast_defaultlanguage); ast_channel_context_set(tmp, S_OR(context, "default")); ast_channel_exten_set(tmp, S_OR(exten, "s")); ast_channel_priority_set(tmp, 1); - ast_atomic_fetchadd_int(&chancount, +1); - headp = ast_channel_varshead(tmp); AST_LIST_HEAD_INIT_NOLOCK(headp); ast_pbx_hangup_handler_init(tmp); AST_LIST_HEAD_INIT_NOLOCK(ast_channel_datastores(tmp)); - AST_LIST_HEAD_INIT_NOLOCK(ast_channel_autochans(tmp)); - ast_channel_language_set(tmp, ast_defaultlanguage); - - ast_channel_tech_set(tmp, &null_tech); - - ao2_link(channels, tmp); - - /* - * And now, since the channel structure is built, and has its name, let's - * call the manager event generator with this Newchannel event. This is the - * proper and correct place to make this call, but you sure do have to pass - * a lot of data into this func to do it here! - */ - if (ast_get_channel_tech(tech) || (tech2 && ast_get_channel_tech(tech2))) { - ast_channel_publish_snapshot(tmp); + channel_tech = ast_get_channel_tech(tech); + if (!channel_tech && !ast_strlen_zero(tech2)) { + channel_tech = ast_get_channel_tech(tech2); + } + if (channel_tech) { + ast_channel_tech_set(tmp, channel_tech); + } else { + ast_channel_tech_set(tmp, &null_tech); } ast_channel_internal_finalize(tmp); - ast_publish_channel_state(tmp); + + ast_atomic_fetchadd_int(&chancount, +1); + ao2_link(channels, tmp); + + /* + * And now, since the channel structure is built, and has its name, let + * the world know of its existance + */ + ast_channel_publish_snapshot(tmp); return tmp; } @@ -6376,7 +6384,7 @@ void ast_do_masquerade(struct ast_channel *original) struct ast_party_connected_line connected; struct ast_party_redirecting redirecting; } exchange; - struct ast_channel *clonechan, *chans[2]; + struct ast_channel *clonechan; struct ast_channel *bridged; struct ast_format rformat; struct ast_format wformat; @@ -6459,42 +6467,6 @@ void ast_do_masquerade(struct ast_channel *original) ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", ast_channel_name(clonechan), ast_channel_state(clonechan), ast_channel_name(original), ast_channel_state(original)); - chans[0] = clonechan; - chans[1] = original; - /*** DOCUMENTATION - - Raised when a masquerade occurs between two channels, wherein the Clone channel's internal information replaces the Original channel's information. - - - The name of the channel whose information will be going into the Original channel. - - - The uniqueid of the channel whose information will be going into the Original channel. - - - The current state of the clone channel. - - - The name of the channel whose information will be replaced by the Clone channel's information. - - - The uniqueid of the channel whose information will be replaced by the Clone channel's information. - - - The current state of the original channel. - - - - ***/ - ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans, - "Clone: %s\r\n" - "CloneUniqueid: %s\r\n" - "CloneState: %s\r\n" - "Original: %s\r\n" - "OriginalUniqueid: %s\r\n" - "OriginalState: %s\r\n", - ast_channel_name(clonechan), ast_channel_uniqueid(clonechan), ast_state2str(ast_channel_state(clonechan)), ast_channel_name(original), ast_channel_uniqueid(original), ast_state2str(ast_channel_state(original))); - /* * Remember the original read/write formats. We turn off any * translation on either one @@ -7549,6 +7521,7 @@ static void channels_shutdown(void) ao2_ref(channels, -1); channels = NULL; } + ast_channel_unregister(&surrogate_tech); } void ast_channels_init(void) @@ -7559,6 +7532,8 @@ void ast_channels_init(void) ao2_container_register("channels", channels, prnt_channel_key); } + ast_channel_register(&surrogate_tech); + ast_stasis_channels_init(); ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel)); diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c index 698783707a..f40852f0bd 100644 --- a/main/channel_internal_api.c +++ b/main/channel_internal_api.c @@ -426,13 +426,13 @@ 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); \ - if (publish) ast_channel_publish_snapshot(chan); \ + 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); \ - if (publish) ast_channel_publish_snapshot(chan); \ + 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, ...) \ { \ @@ -1481,7 +1481,6 @@ int ast_channel_internal_setup_topics(struct ast_channel *chan) chan->topics = stasis_cp_single_create( ast_channel_cache_all(), topic_name); - if (!chan->topics) { return -1; } diff --git a/main/manager_bridges.c b/main/manager_bridges.c index d563c2bc81..b045ca5b5e 100644 --- a/main/manager_bridges.c +++ b/main/manager_bridges.c @@ -381,7 +381,7 @@ static int send_bridge_info_item_cb(void *obj, void *arg, void *data, int flags) } snapshot = stasis_message_data(msg); - if (snapshot->tech_properties & (AST_CHAN_TP_ANNOUNCER | AST_CHAN_TP_RECORDER)) { + if (snapshot->tech_properties & AST_CHAN_TP_INTERNAL) { return 0; } diff --git a/main/manager_channels.c b/main/manager_channels.c index 23418e6a28..485841b69f 100644 --- a/main/manager_channels.c +++ b/main/manager_channels.c @@ -383,7 +383,7 @@ struct ast_str *ast_manager_build_channel_state_string_prefix( return NULL; } - if (snapshot->tech_properties & (AST_CHAN_TP_ANNOUNCER | AST_CHAN_TP_RECORDER)) { + if (snapshot->tech_properties & AST_CHAN_TP_INTERNAL) { ast_free(out); return NULL; }