From c1235f2639023a9e450cafcdf8bd35cc304d9e53 Mon Sep 17 00:00:00 2001 From: Joshua Colp Date: Wed, 2 Oct 2013 16:23:34 +0000 Subject: [PATCH] Reduce channel snapshot creation and publishing by up to 50%. This change introduces the ability to stage channel snapshot creation and publishing by suppressing the implicit creation and publishing that some functions have. Once all operations are executed the staging is marked as done and a single snapshot is created and published. Review: https://reviewboard.asterisk.org/r/2889/ ........ Merged revisions 400265 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@400266 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_dial.c | 13 +++++++++++++ channels/chan_alsa.c | 6 ++++++ channels/chan_console.c | 5 +++++ channels/chan_dahdi.c | 4 ++++ channels/chan_gtalk.c | 6 ++++++ channels/chan_iax2.c | 5 +++++ channels/chan_jingle.c | 7 +++++++ channels/chan_mgcp.c | 5 +++++ channels/chan_motif.c | 5 +++++ channels/chan_pjsip.c | 4 ++++ channels/chan_sip.c | 19 +++++++++++++++++++ channels/chan_skinny.c | 4 ++++ channels/chan_unistim.c | 7 ++++++- channels/sig_pri.c | 5 +++++ channels/sig_ss7.c | 4 ++++ include/asterisk/channel.h | 5 +++++ include/asterisk/stasis_channels.h | 16 ++++++++++++++++ main/bridge.c | 2 ++ main/channel.c | 9 ++++++++- main/dial.c | 4 ++++ main/pbx.c | 4 +++- main/stasis_channels.c | 15 +++++++++++++++ 22 files changed, 151 insertions(+), 3 deletions(-) diff --git a/apps/app_dial.c b/apps/app_dial.c index cd675fad96..2fb7fc9acc 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -1958,10 +1958,12 @@ static void end_bridge_callback(void *data) time(&end); ast_channel_lock(chan); + ast_channel_stage_snapshot(chan); snprintf(buf, sizeof(buf), "%d", ast_channel_get_up_time(chan)); pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf); snprintf(buf, sizeof(buf), "%d", ast_channel_get_duration(chan)); pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf); + ast_channel_stage_snapshot_done(chan); ast_channel_unlock(chan); } @@ -2096,11 +2098,13 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast struct ast_party_caller caller; /* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */ + ast_channel_stage_snapshot(chan); pbx_builtin_setvar_helper(chan, "DIALSTATUS", ""); pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", ""); pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", ""); pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", ""); pbx_builtin_setvar_helper(chan, "DIALEDTIME", ""); + ast_channel_stage_snapshot_done(chan); if (ast_strlen_zero(data)) { ast_log(LOG_WARNING, "Dial requires an argument (technology/resource)\n"); @@ -2431,6 +2435,9 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast chanlist_free(tmp); continue; } + + ast_channel_stage_snapshot(tc); + ast_channel_get_device_name(tc, device_name, sizeof(device_name)); if (!ignore_cc) { ast_cc_extension_monitor_add_dialstring(chan, tmp->interface, device_name); @@ -2540,6 +2547,8 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast else ast_channel_exten_set(tc, ast_channel_exten(chan)); + ast_channel_stage_snapshot_done(tc); + ast_channel_unlock(tc); ast_channel_unlock(chan); @@ -2690,6 +2699,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast ast_answer(chan); strcpy(pa.status, "ANSWER"); + ast_channel_stage_snapshot(chan); pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status); /* Ah ha! Someone answered within the desired timeframe. Of course after this we will always return with -1 so that it is hung up properly after the @@ -2708,6 +2718,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast } ast_channel_unlock(peer); pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number); + ast_channel_stage_snapshot_done(chan); if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) { ast_debug(1, "app_dial: sendurl=%s.\n", args.url); @@ -2793,6 +2804,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast /* chan and peer are going into the PBX; as such neither are considered * outgoing channels any longer */ ast_clear_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING); + ast_channel_stage_snapshot(peer); ast_clear_flag(ast_channel_flags(peer), AST_FLAG_OUTGOING); ast_replace_subargument_delimiter(opt_args[OPT_ARG_GOTO]); @@ -2801,6 +2813,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast ast_channel_context_set(peer, ast_channel_context(chan)); ast_channel_exten_set(peer, ast_channel_exten(chan)); ast_channel_priority_set(peer, ast_channel_priority(chan) + 2); + ast_channel_stage_snapshot_done(peer); if (ast_pbx_start(peer)) { ast_autoservice_chan_hangup_peer(chan, peer); } diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c index 7f54d6cfae..f1720ba8ce 100644 --- a/channels/chan_alsa.c +++ b/channels/chan_alsa.c @@ -62,6 +62,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/abstract_jb.h" #include "asterisk/musiconhold.h" #include "asterisk/poll-compat.h" +#include "asterisk/stasis_channels.h" /*! Global jitterbuffer configuration - by default, jb is disabled * \note Values shown here match the defaults shown in alsa.conf.sample */ @@ -580,6 +581,8 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const ch if (!(tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, linkedid, 0, "ALSA/%s", indevname))) return NULL; + ast_channel_stage_snapshot(tmp); + ast_channel_tech_set(tmp, &alsa_tech); ast_channel_set_fd(tmp, 0, readdev); ast_format_set(ast_channel_readformat(tmp), AST_FORMAT_SLINEAR, 0); @@ -596,6 +599,9 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const ch p->owner = tmp; ast_module_ref(ast_module_info->self); ast_jb_configure(tmp, &global_jbconf); + + ast_channel_stage_snapshot_done(tmp); + if (state != AST_STATE_DOWN) { if (ast_pbx_start(tmp)) { ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp)); diff --git a/channels/chan_console.c b/channels/chan_console.c index 0f4d01ebd0..76571d2098 100644 --- a/channels/chan_console.c +++ b/channels/chan_console.c @@ -76,6 +76,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/musiconhold.h" #include "asterisk/callerid.h" #include "asterisk/astobj2.h" +#include "asterisk/stasis_channels.h" /*! * \brief The sample rate to request from PortAudio @@ -427,6 +428,8 @@ static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext, return NULL; } + ast_channel_stage_snapshot(chan); + ast_channel_tech_set(chan, &console_tech); ast_format_set(ast_channel_readformat(chan), AST_FORMAT_SLINEAR16, 0); ast_format_set(ast_channel_writeformat(chan), AST_FORMAT_SLINEAR16, 0); @@ -440,6 +443,8 @@ static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext, ast_jb_configure(chan, &global_jbconf); + ast_channel_stage_snapshot_done(chan); + if (state != AST_STATE_DOWN) { if (ast_pbx_start(chan)) { ast_channel_hangupcause_set(chan, AST_CAUSE_SWITCH_CONGESTION); diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 853c5f4e78..65a9758f26 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -8910,6 +8910,8 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb return NULL; } + ast_channel_stage_snapshot(tmp); + if (callid) { ast_channel_callid_set(tmp, callid); } @@ -9087,6 +9089,8 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb for (v = i->vars ; v ; v = v->next) pbx_builtin_setvar_helper(tmp, v->name, v->value); + ast_channel_stage_snapshot_done(tmp); + ast_module_ref(ast_module_info->self); dahdi_ami_channel_event(i, tmp); diff --git a/channels/chan_gtalk.c b/channels/chan_gtalk.c index fc1b75a53e..a44ca57f46 100644 --- a/channels/chan_gtalk.c +++ b/channels/chan_gtalk.c @@ -1149,6 +1149,9 @@ static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i, ast_log(LOG_WARNING, "Unable to allocate Gtalk channel structure!\n"); return NULL; } + + ast_channel_stage_snapshot(tmp); + ast_channel_tech_set(tmp, >alk_tech); /* Select our native format based on codec preference until we receive @@ -1221,6 +1224,9 @@ static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i, ast_channel_priority_set(tmp, 1); if (i->rtp) ast_jb_configure(tmp, &global_jbconf); + + ast_channel_stage_snapshot_done(tmp); + if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp)); ast_channel_hangupcause_set(tmp, AST_CAUSE_SWITCH_CONGESTION); diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index b880f5d948..62888615fb 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -116,6 +116,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/bridge.h" #include "asterisk/stasis.h" #include "asterisk/stasis_system.h" +#include "asterisk/stasis_channels.h" #include "iax2/include/iax2.h" #include "iax2/include/firmware.h" @@ -5702,6 +5703,8 @@ static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capab return NULL; } + ast_channel_stage_snapshot(tmp); + if ((callid = iaxs[callno]->callid)) { ast_channel_callid_set(tmp, callid); } @@ -5799,6 +5802,8 @@ static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capab } } + ast_channel_stage_snapshot_done(tmp); + if (state != AST_STATE_DOWN) { if (ast_pbx_start(tmp)) { ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp)); diff --git a/channels/chan_jingle.c b/channels/chan_jingle.c index e5fd025069..a8cab62383 100644 --- a/channels/chan_jingle.c +++ b/channels/chan_jingle.c @@ -79,6 +79,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/abstract_jb.h" #include "asterisk/jabber.h" #include "asterisk/jingle.h" +#include "asterisk/stasis_channels.h" #define JINGLE_CONFIG "jingle.conf" @@ -862,6 +863,9 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt * ast_log(LOG_WARNING, "Unable to allocate Jingle channel structure!\n"); return NULL; } + + ast_channel_stage_snapshot(tmp); + ast_channel_tech_set(tmp, &jingle_tech); /* Select our native format based on codec preference until we receive @@ -935,6 +939,9 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt * ast_channel_priority_set(tmp, 1); if (i->rtp) ast_jb_configure(tmp, &global_jbconf); + + ast_channel_stage_snapshot_done(tmp); + if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp)); ast_channel_hangupcause_set(tmp, AST_CAUSE_SWITCH_CONGESTION); diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c index 8fcdebfad7..7c91200882 100644 --- a/channels/chan_mgcp.c +++ b/channels/chan_mgcp.c @@ -85,6 +85,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/bridge.h" #include "asterisk/features_config.h" #include "asterisk/parking.h" +#include "asterisk/stasis_channels.h" /* * Define to work around buggy dlink MGCP phone firmware which @@ -1506,6 +1507,7 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state, cons tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, linkedid, i->accountcode, i->exten, i->context, i->amaflags, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id); if (tmp) { + ast_channel_stage_snapshot(tmp); ast_channel_tech_set(tmp, &mgcp_tech); ast_format_cap_copy(ast_channel_nativeformats(tmp), i->cap); if (ast_format_cap_is_empty(ast_channel_nativeformats(tmp))) { @@ -1566,6 +1568,9 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state, cons if (sub->rtp) { ast_jb_configure(tmp, &global_jbconf); } + + ast_channel_stage_snapshot_done(tmp); + if (state != AST_STATE_DOWN) { if (ast_pbx_start(tmp)) { ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp)); diff --git a/channels/chan_motif.c b/channels/chan_motif.c index 72118ce104..e13c66c6fe 100644 --- a/channels/chan_motif.c +++ b/channels/chan_motif.c @@ -76,6 +76,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/astobj.h" #include "asterisk/abstract_jb.h" #include "asterisk/xmpp.h" +#include "asterisk/stasis_channels.h" /*** DOCUMENTATION @@ -785,6 +786,8 @@ static struct ast_channel *jingle_new(struct jingle_endpoint *endpoint, struct j return NULL; } + ast_channel_stage_snapshot(chan); + ast_channel_tech_set(chan, &jingle_tech); ast_channel_tech_pvt_set(chan, session); jingle_set_owner(session, chan); @@ -848,6 +851,8 @@ static struct ast_channel *jingle_new(struct jingle_endpoint *endpoint, struct j ao2_unlock(endpoint); + ast_channel_stage_snapshot_done(chan); + return chan; } diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index 42e329e50a..fcca25c8d1 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -577,6 +577,8 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s return NULL; } + ast_channel_stage_snapshot(chan); + /* If res_pjsip_session is ever updated to create/destroy ast_sip_session_media * during a call such as if multiple same-type stream support is introduced, * these will need to be recaptured as well */ @@ -632,6 +634,8 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s ast_endpoint_add_channel(session->endpoint->persistent, chan); + ast_channel_stage_snapshot_done(chan); + return chan; } diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 2a821dd73f..497fb6e616 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -7285,6 +7285,10 @@ static int sip_hangup(struct ast_channel *ast) } while (sip_pvt_trylock(p)); } + if (p->rtp || p->vrtp || p->trtp) { + ast_channel_stage_snapshot(oldowner); + } + if (p->rtp) { ast_rtp_instance_set_stats_vars(oldowner, p->rtp); } @@ -7320,6 +7324,9 @@ static int sip_hangup(struct ast_channel *ast) } pbx_builtin_setvar_helper(oldowner, "RTPTEXTQOS", quality); } + if (p->rtp || p->vrtp || p->trtp) { + ast_channel_stage_snapshot_done(oldowner); + } /* Send a hangup */ if (ast_channel_state(oldowner) == AST_STATE_UP) { @@ -8092,6 +8099,8 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit } } + ast_channel_stage_snapshot(tmp); + /* If we sent in a callid, bind it to the channel. */ if (callid) { ast_channel_callid_set(tmp, callid); @@ -8287,6 +8296,8 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit append_history(i, "NewChan", "Channel %s - from %s", ast_channel_name(tmp), i->callid); } + ast_channel_stage_snapshot_done(tmp); + return tmp; } @@ -26531,6 +26542,10 @@ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req) } } + if ((p->rtp || p->vrtp || p->trtp) && p->owner) { + ast_channel_stage_snapshot(p->owner); + } + /* Get RTCP quality before end of call */ if (p->rtp) { if (p->do_history) { @@ -26595,6 +26610,10 @@ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req) } } + if ((p->rtp || p->vrtp || p->trtp) && p->owner) { + ast_channel_stage_snapshot_done(p->owner); + } + stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ stop_session_timer(p); /* Stop Session-Timer */ diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c index 7cf592a261..496de18667 100644 --- a/channels/chan_skinny.c +++ b/channels/chan_skinny.c @@ -82,6 +82,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/stasis_endpoints.h" #include "asterisk/bridge.h" #include "asterisk/parking.h" +#include "asterisk/stasis_channels.h" /*** DOCUMENTATION @@ -5423,6 +5424,7 @@ static struct ast_channel *skinny_new(struct skinny_line *l, struct skinny_subli AST_LIST_INSERT_HEAD(&l->sub, sub, list); //l->activesub = sub; } + ast_channel_stage_snapshot(tmp); ast_channel_tech_set(tmp, &skinny_tech); ast_channel_tech_pvt_set(tmp, sub); ast_format_cap_copy(ast_channel_nativeformats(tmp), l->cap); @@ -5496,6 +5498,8 @@ static struct ast_channel *skinny_new(struct skinny_line *l, struct skinny_subli for (v = l->chanvars ; v ; v = v->next) pbx_builtin_setvar_helper(tmp, v->name, v->value); + ast_channel_stage_snapshot_done(tmp); + if (state != AST_STATE_DOWN) { if (ast_pbx_start(tmp)) { ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp)); diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c index adb5cb9c83..5238679880 100644 --- a/channels/chan_unistim.c +++ b/channels/chan_unistim.c @@ -77,7 +77,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/astdb.h" #include "asterisk/features_config.h" #include "asterisk/bridge.h" - +#include "asterisk/stasis_channels.h" #define DEFAULTCONTEXT "default" #define DEFAULTCALLERID "Unknown" @@ -5563,6 +5563,8 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state return NULL; } + ast_channel_stage_snapshot(tmp); + ast_format_cap_copy(ast_channel_nativeformats(tmp), l->cap); if (ast_format_cap_is_empty(ast_channel_nativeformats(tmp))) { ast_format_cap_copy(ast_channel_nativeformats(tmp), global_cap); @@ -5623,6 +5625,9 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state } } ast_channel_priority_set(tmp, 1); + + ast_channel_stage_snapshot_done(tmp); + if (state != AST_STATE_DOWN) { if (unistimdebug) { ast_verb(0, "Starting pbx in unistim_new\n"); diff --git a/channels/sig_pri.c b/channels/sig_pri.c index 9f40077237..5def34c238 100644 --- a/channels/sig_pri.c +++ b/channels/sig_pri.c @@ -6473,6 +6473,7 @@ static void *pri_dchannel(void *vpri) ast_mutex_lock(&pri->lock); sig_pri_lock_private(pri->pvts[chanpos]); if (c) { + ast_channel_stage_snapshot(c); #if defined(HAVE_PRI_SUBADDR) if (e->ring.calling.subaddress.valid) { /* Set Calling Subaddress */ @@ -6557,6 +6558,7 @@ static void *pri_dchannel(void *vpri) PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); #endif } + ast_channel_stage_snapshot_done(c); } if (c && !ast_pthread_create_detached(&threadid, NULL, pri_ss_thread, pri->pvts[chanpos])) { ast_verb(3, "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n", @@ -6602,6 +6604,7 @@ static void *pri_dchannel(void *vpri) * will do anything with the channel we have just * created. */ + ast_channel_stage_snapshot(c); #if defined(HAVE_PRI_SUBADDR) if (e->ring.calling.subaddress.valid) { /* Set Calling Subaddress */ @@ -6670,6 +6673,8 @@ static void *pri_dchannel(void *vpri) sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.subcmds, e->ring.call); + + ast_channel_stage_snapshot_done(c); } if (c && !ast_pbx_start(c)) { ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n", diff --git a/channels/sig_ss7.c b/channels/sig_ss7.c index e6e11bed60..166fda2f78 100644 --- a/channels/sig_ss7.c +++ b/channels/sig_ss7.c @@ -621,6 +621,8 @@ static void ss7_start_call(struct sig_ss7_chan *p, struct sig_ss7_linkset *links sig_ss7_set_echocanceller(p, 1); + ast_channel_stage_snapshot(c); + /* * It is reasonably safe to set the following * channel variables while the channel private @@ -700,6 +702,8 @@ static void ss7_start_call(struct sig_ss7_chan *p, struct sig_ss7_linkset *links p->generic_name[0] = 0; } + ast_channel_stage_snapshot_done(c); + sig_ss7_unlock_private(p); ast_channel_unlock(c); diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index 24dc53f6bb..e952b93b86 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -923,6 +923,11 @@ enum { * occur. */ AST_FLAG_DEAD = (1 << 24), + /*! + * Channel snapshot should not be published, it is being staged for an explicit + * publish. + */ + AST_FLAG_SNAPSHOT_STAGE = (1 << 25), }; /*! \brief ast_bridge_config flags */ diff --git a/include/asterisk/stasis_channels.h b/include/asterisk/stasis_channels.h index c0b596ac97..7d9c3efdcf 100644 --- a/include/asterisk/stasis_channels.h +++ b/include/asterisk/stasis_channels.h @@ -314,6 +314,22 @@ void ast_multi_channel_blob_add_channel(struct ast_multi_channel_blob *obj, void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob); +/*! + * \since 12 + * \brief Set flag to indicate channel snapshot is being staged. + * + * \param chan Channel being staged. + */ +void ast_channel_stage_snapshot(struct ast_channel *chan); + +/*! + * \since 12 + * \brief Clear flag to indicate channel snapshot is being staged, and publish snapshot. + * + * \param chan Channel being staged. + */ +void ast_channel_stage_snapshot_done(struct ast_channel *chan); + /*! * \since 12 * \brief Publish a \ref ast_channel_snapshot for a channel. diff --git a/main/bridge.c b/main/bridge.c index 19350ed845..a972fe7363 100644 --- a/main/bridge.c +++ b/main/bridge.c @@ -1151,8 +1151,10 @@ static void check_bridge_play_sounds(struct ast_bridge *bridge) static void update_bridge_vars_set(struct ast_channel *chan, const char *name, const char *pvtid) { + ast_channel_stage_snapshot(chan); pbx_builtin_setvar_helper(chan, "BRIDGEPEER", name); pbx_builtin_setvar_helper(chan, "BRIDGEPVTCALLID", pvtid); + ast_channel_stage_snapshot_done(chan); } /*! diff --git a/main/channel.c b/main/channel.c index e8ce5e0c53..36528f5df8 100644 --- a/main/channel.c +++ b/main/channel.c @@ -876,6 +876,9 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char /* Channel structure allocation failure. */ return NULL; } + + ast_channel_stage_snapshot(tmp); + if (!(nativeformats = ast_format_cap_alloc())) { ao2_ref(tmp, -1); /* format capabilities structure allocation failure */ @@ -1020,7 +1023,7 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char * And now, since the channel structure is built, and has its name, let * the world know of its existance */ - ast_channel_publish_snapshot(tmp); + ast_channel_stage_snapshot_done(tmp); return tmp; } @@ -7716,8 +7719,12 @@ void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars) { struct ast_variable *cur; + ast_channel_stage_snapshot(chan); + for (cur = vars; cur; cur = cur->next) pbx_builtin_setvar_helper(chan, cur->name, cur->value); + + ast_channel_stage_snapshot_done(chan); } static void *silence_generator_alloc(struct ast_channel *chan, void *data) diff --git a/main/dial.c b/main/dial.c index 3b720fb9ff..6d796e2b9d 100644 --- a/main/dial.c +++ b/main/dial.c @@ -286,6 +286,8 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe cap_request = NULL; cap_all_audio = ast_format_cap_destroy(cap_all_audio); + ast_channel_stage_snapshot(channel->owner); + ast_channel_appl_set(channel->owner, "AppDial2"); ast_channel_data_set(channel->owner, "(Outgoing Line)"); ast_publish_channel_state(channel->owner); @@ -312,6 +314,8 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe ast_channel_transfercapability_set(channel->owner, ast_channel_transfercapability(chan)); } + ast_channel_stage_snapshot_done(channel->owner); + return 0; } diff --git a/main/pbx.c b/main/pbx.c index 2a415401f1..6b71c54b9c 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -10050,7 +10050,9 @@ static int pbx_outgoing_attempt(const char *type, struct ast_format_cap *cap, co return -1; } - ast_set_variables(dialed, vars); + if (vars) { + ast_set_variables(dialed, vars); + } if (account) { ast_channel_accountcode_set(dialed, account); diff --git a/main/stasis_channels.c b/main/stasis_channels.c index 0fbbf5d967..e1a3853e0f 100644 --- a/main/stasis_channels.c +++ b/main/stasis_channels.c @@ -600,11 +600,26 @@ struct ast_json *ast_multi_channel_blob_get_json(struct ast_multi_channel_blob * return obj->blob; } +void ast_channel_stage_snapshot(struct ast_channel *chan) +{ + ast_set_flag(ast_channel_flags(chan), AST_FLAG_SNAPSHOT_STAGE); +} + +void ast_channel_stage_snapshot_done(struct ast_channel *chan) +{ + ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SNAPSHOT_STAGE); + ast_channel_publish_snapshot(chan); +} + void ast_channel_publish_snapshot(struct ast_channel *chan) { RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); + if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_SNAPSHOT_STAGE)) { + return; + } + snapshot = ast_channel_snapshot_create(chan); if (!snapshot) { return;