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
changes/97/197/1
Joshua Colp 12 years ago
parent 424c0f2eb7
commit c1235f2639

@ -1958,10 +1958,12 @@ static void end_bridge_callback(void *data)
time(&end); time(&end);
ast_channel_lock(chan); ast_channel_lock(chan);
ast_channel_stage_snapshot(chan);
snprintf(buf, sizeof(buf), "%d", ast_channel_get_up_time(chan)); snprintf(buf, sizeof(buf), "%d", ast_channel_get_up_time(chan));
pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf); pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
snprintf(buf, sizeof(buf), "%d", ast_channel_get_duration(chan)); snprintf(buf, sizeof(buf), "%d", ast_channel_get_duration(chan));
pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf); pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
ast_channel_stage_snapshot_done(chan);
ast_channel_unlock(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; struct ast_party_caller caller;
/* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */ /* 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, "DIALSTATUS", "");
pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", ""); pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", ""); pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", ""); pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
pbx_builtin_setvar_helper(chan, "DIALEDTIME", ""); pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
ast_channel_stage_snapshot_done(chan);
if (ast_strlen_zero(data)) { if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "Dial requires an argument (technology/resource)\n"); 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); chanlist_free(tmp);
continue; continue;
} }
ast_channel_stage_snapshot(tc);
ast_channel_get_device_name(tc, device_name, sizeof(device_name)); ast_channel_get_device_name(tc, device_name, sizeof(device_name));
if (!ignore_cc) { if (!ignore_cc) {
ast_cc_extension_monitor_add_dialstring(chan, tmp->interface, device_name); 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 else
ast_channel_exten_set(tc, ast_channel_exten(chan)); ast_channel_exten_set(tc, ast_channel_exten(chan));
ast_channel_stage_snapshot_done(tc);
ast_channel_unlock(tc); ast_channel_unlock(tc);
ast_channel_unlock(chan); 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); ast_answer(chan);
strcpy(pa.status, "ANSWER"); strcpy(pa.status, "ANSWER");
ast_channel_stage_snapshot(chan);
pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status); pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
/* Ah ha! Someone answered within the desired timeframe. Of course after this /* 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 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); ast_channel_unlock(peer);
pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number); pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
ast_channel_stage_snapshot_done(chan);
if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) { if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
ast_debug(1, "app_dial: sendurl=%s.\n", args.url); 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 /* chan and peer are going into the PBX; as such neither are considered
* outgoing channels any longer */ * outgoing channels any longer */
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING); 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_clear_flag(ast_channel_flags(peer), AST_FLAG_OUTGOING);
ast_replace_subargument_delimiter(opt_args[OPT_ARG_GOTO]); 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_context_set(peer, ast_channel_context(chan));
ast_channel_exten_set(peer, ast_channel_exten(chan)); ast_channel_exten_set(peer, ast_channel_exten(chan));
ast_channel_priority_set(peer, ast_channel_priority(chan) + 2); ast_channel_priority_set(peer, ast_channel_priority(chan) + 2);
ast_channel_stage_snapshot_done(peer);
if (ast_pbx_start(peer)) { if (ast_pbx_start(peer)) {
ast_autoservice_chan_hangup_peer(chan, peer); ast_autoservice_chan_hangup_peer(chan, peer);
} }

@ -62,6 +62,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/abstract_jb.h" #include "asterisk/abstract_jb.h"
#include "asterisk/musiconhold.h" #include "asterisk/musiconhold.h"
#include "asterisk/poll-compat.h" #include "asterisk/poll-compat.h"
#include "asterisk/stasis_channels.h"
/*! Global jitterbuffer configuration - by default, jb is disabled /*! Global jitterbuffer configuration - by default, jb is disabled
* \note Values shown here match the defaults shown in alsa.conf.sample */ * \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))) if (!(tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, linkedid, 0, "ALSA/%s", indevname)))
return NULL; return NULL;
ast_channel_stage_snapshot(tmp);
ast_channel_tech_set(tmp, &alsa_tech); ast_channel_tech_set(tmp, &alsa_tech);
ast_channel_set_fd(tmp, 0, readdev); ast_channel_set_fd(tmp, 0, readdev);
ast_format_set(ast_channel_readformat(tmp), AST_FORMAT_SLINEAR, 0); 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; p->owner = tmp;
ast_module_ref(ast_module_info->self); ast_module_ref(ast_module_info->self);
ast_jb_configure(tmp, &global_jbconf); ast_jb_configure(tmp, &global_jbconf);
ast_channel_stage_snapshot_done(tmp);
if (state != AST_STATE_DOWN) { if (state != AST_STATE_DOWN) {
if (ast_pbx_start(tmp)) { if (ast_pbx_start(tmp)) {
ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp)); ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));

@ -76,6 +76,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/musiconhold.h" #include "asterisk/musiconhold.h"
#include "asterisk/callerid.h" #include "asterisk/callerid.h"
#include "asterisk/astobj2.h" #include "asterisk/astobj2.h"
#include "asterisk/stasis_channels.h"
/*! /*!
* \brief The sample rate to request from PortAudio * \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; return NULL;
} }
ast_channel_stage_snapshot(chan);
ast_channel_tech_set(chan, &console_tech); ast_channel_tech_set(chan, &console_tech);
ast_format_set(ast_channel_readformat(chan), AST_FORMAT_SLINEAR16, 0); ast_format_set(ast_channel_readformat(chan), AST_FORMAT_SLINEAR16, 0);
ast_format_set(ast_channel_writeformat(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_jb_configure(chan, &global_jbconf);
ast_channel_stage_snapshot_done(chan);
if (state != AST_STATE_DOWN) { if (state != AST_STATE_DOWN) {
if (ast_pbx_start(chan)) { if (ast_pbx_start(chan)) {
ast_channel_hangupcause_set(chan, AST_CAUSE_SWITCH_CONGESTION); ast_channel_hangupcause_set(chan, AST_CAUSE_SWITCH_CONGESTION);

@ -8910,6 +8910,8 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
return NULL; return NULL;
} }
ast_channel_stage_snapshot(tmp);
if (callid) { if (callid) {
ast_channel_callid_set(tmp, 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) for (v = i->vars ; v ; v = v->next)
pbx_builtin_setvar_helper(tmp, v->name, v->value); pbx_builtin_setvar_helper(tmp, v->name, v->value);
ast_channel_stage_snapshot_done(tmp);
ast_module_ref(ast_module_info->self); ast_module_ref(ast_module_info->self);
dahdi_ami_channel_event(i, tmp); dahdi_ami_channel_event(i, tmp);

@ -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"); ast_log(LOG_WARNING, "Unable to allocate Gtalk channel structure!\n");
return NULL; return NULL;
} }
ast_channel_stage_snapshot(tmp);
ast_channel_tech_set(tmp, &gtalk_tech); ast_channel_tech_set(tmp, &gtalk_tech);
/* Select our native format based on codec preference until we receive /* 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); ast_channel_priority_set(tmp, 1);
if (i->rtp) if (i->rtp)
ast_jb_configure(tmp, &global_jbconf); ast_jb_configure(tmp, &global_jbconf);
ast_channel_stage_snapshot_done(tmp);
if (state != AST_STATE_DOWN && ast_pbx_start(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_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
ast_channel_hangupcause_set(tmp, AST_CAUSE_SWITCH_CONGESTION); ast_channel_hangupcause_set(tmp, AST_CAUSE_SWITCH_CONGESTION);

@ -116,6 +116,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/bridge.h" #include "asterisk/bridge.h"
#include "asterisk/stasis.h" #include "asterisk/stasis.h"
#include "asterisk/stasis_system.h" #include "asterisk/stasis_system.h"
#include "asterisk/stasis_channels.h"
#include "iax2/include/iax2.h" #include "iax2/include/iax2.h"
#include "iax2/include/firmware.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; return NULL;
} }
ast_channel_stage_snapshot(tmp);
if ((callid = iaxs[callno]->callid)) { if ((callid = iaxs[callno]->callid)) {
ast_channel_callid_set(tmp, 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 (state != AST_STATE_DOWN) {
if (ast_pbx_start(tmp)) { if (ast_pbx_start(tmp)) {
ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp)); ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));

@ -79,6 +79,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/abstract_jb.h" #include "asterisk/abstract_jb.h"
#include "asterisk/jabber.h" #include "asterisk/jabber.h"
#include "asterisk/jingle.h" #include "asterisk/jingle.h"
#include "asterisk/stasis_channels.h"
#define JINGLE_CONFIG "jingle.conf" #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"); ast_log(LOG_WARNING, "Unable to allocate Jingle channel structure!\n");
return NULL; return NULL;
} }
ast_channel_stage_snapshot(tmp);
ast_channel_tech_set(tmp, &jingle_tech); ast_channel_tech_set(tmp, &jingle_tech);
/* Select our native format based on codec preference until we receive /* 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); ast_channel_priority_set(tmp, 1);
if (i->rtp) if (i->rtp)
ast_jb_configure(tmp, &global_jbconf); ast_jb_configure(tmp, &global_jbconf);
ast_channel_stage_snapshot_done(tmp);
if (state != AST_STATE_DOWN && ast_pbx_start(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_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
ast_channel_hangupcause_set(tmp, AST_CAUSE_SWITCH_CONGESTION); ast_channel_hangupcause_set(tmp, AST_CAUSE_SWITCH_CONGESTION);

@ -85,6 +85,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/bridge.h" #include "asterisk/bridge.h"
#include "asterisk/features_config.h" #include "asterisk/features_config.h"
#include "asterisk/parking.h" #include "asterisk/parking.h"
#include "asterisk/stasis_channels.h"
/* /*
* Define to work around buggy dlink MGCP phone firmware which * 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); 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) { if (tmp) {
ast_channel_stage_snapshot(tmp);
ast_channel_tech_set(tmp, &mgcp_tech); ast_channel_tech_set(tmp, &mgcp_tech);
ast_format_cap_copy(ast_channel_nativeformats(tmp), i->cap); ast_format_cap_copy(ast_channel_nativeformats(tmp), i->cap);
if (ast_format_cap_is_empty(ast_channel_nativeformats(tmp))) { 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) { if (sub->rtp) {
ast_jb_configure(tmp, &global_jbconf); ast_jb_configure(tmp, &global_jbconf);
} }
ast_channel_stage_snapshot_done(tmp);
if (state != AST_STATE_DOWN) { if (state != AST_STATE_DOWN) {
if (ast_pbx_start(tmp)) { if (ast_pbx_start(tmp)) {
ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp)); ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));

@ -76,6 +76,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/astobj.h" #include "asterisk/astobj.h"
#include "asterisk/abstract_jb.h" #include "asterisk/abstract_jb.h"
#include "asterisk/xmpp.h" #include "asterisk/xmpp.h"
#include "asterisk/stasis_channels.h"
/*** DOCUMENTATION /*** DOCUMENTATION
<configInfo name="chan_motif" language="en_US"> <configInfo name="chan_motif" language="en_US">
@ -785,6 +786,8 @@ static struct ast_channel *jingle_new(struct jingle_endpoint *endpoint, struct j
return NULL; return NULL;
} }
ast_channel_stage_snapshot(chan);
ast_channel_tech_set(chan, &jingle_tech); ast_channel_tech_set(chan, &jingle_tech);
ast_channel_tech_pvt_set(chan, session); ast_channel_tech_pvt_set(chan, session);
jingle_set_owner(session, chan); jingle_set_owner(session, chan);
@ -848,6 +851,8 @@ static struct ast_channel *jingle_new(struct jingle_endpoint *endpoint, struct j
ao2_unlock(endpoint); ao2_unlock(endpoint);
ast_channel_stage_snapshot_done(chan);
return chan; return chan;
} }

@ -577,6 +577,8 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s
return NULL; return NULL;
} }
ast_channel_stage_snapshot(chan);
/* If res_pjsip_session is ever updated to create/destroy ast_sip_session_media /* 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, * during a call such as if multiple same-type stream support is introduced,
* these will need to be recaptured as well */ * 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_endpoint_add_channel(session->endpoint->persistent, chan);
ast_channel_stage_snapshot_done(chan);
return chan; return chan;
} }

@ -7285,6 +7285,10 @@ static int sip_hangup(struct ast_channel *ast)
} while (sip_pvt_trylock(p)); } while (sip_pvt_trylock(p));
} }
if (p->rtp || p->vrtp || p->trtp) {
ast_channel_stage_snapshot(oldowner);
}
if (p->rtp) { if (p->rtp) {
ast_rtp_instance_set_stats_vars(oldowner, 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); pbx_builtin_setvar_helper(oldowner, "RTPTEXTQOS", quality);
} }
if (p->rtp || p->vrtp || p->trtp) {
ast_channel_stage_snapshot_done(oldowner);
}
/* Send a hangup */ /* Send a hangup */
if (ast_channel_state(oldowner) == AST_STATE_UP) { 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 we sent in a callid, bind it to the channel. */
if (callid) { if (callid) {
ast_channel_callid_set(tmp, 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); append_history(i, "NewChan", "Channel %s - from %s", ast_channel_name(tmp), i->callid);
} }
ast_channel_stage_snapshot_done(tmp);
return 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 */ /* Get RTCP quality before end of call */
if (p->rtp) { if (p->rtp) {
if (p->do_history) { 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_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
stop_session_timer(p); /* Stop Session-Timer */ stop_session_timer(p); /* Stop Session-Timer */

@ -82,6 +82,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/stasis_endpoints.h" #include "asterisk/stasis_endpoints.h"
#include "asterisk/bridge.h" #include "asterisk/bridge.h"
#include "asterisk/parking.h" #include "asterisk/parking.h"
#include "asterisk/stasis_channels.h"
/*** DOCUMENTATION /*** DOCUMENTATION
<manager name="SKINNYdevices" language="en_US"> <manager name="SKINNYdevices" language="en_US">
@ -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); AST_LIST_INSERT_HEAD(&l->sub, sub, list);
//l->activesub = sub; //l->activesub = sub;
} }
ast_channel_stage_snapshot(tmp);
ast_channel_tech_set(tmp, &skinny_tech); ast_channel_tech_set(tmp, &skinny_tech);
ast_channel_tech_pvt_set(tmp, sub); ast_channel_tech_pvt_set(tmp, sub);
ast_format_cap_copy(ast_channel_nativeformats(tmp), l->cap); 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) for (v = l->chanvars ; v ; v = v->next)
pbx_builtin_setvar_helper(tmp, v->name, v->value); pbx_builtin_setvar_helper(tmp, v->name, v->value);
ast_channel_stage_snapshot_done(tmp);
if (state != AST_STATE_DOWN) { if (state != AST_STATE_DOWN) {
if (ast_pbx_start(tmp)) { if (ast_pbx_start(tmp)) {
ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp)); ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));

@ -77,7 +77,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/astdb.h" #include "asterisk/astdb.h"
#include "asterisk/features_config.h" #include "asterisk/features_config.h"
#include "asterisk/bridge.h" #include "asterisk/bridge.h"
#include "asterisk/stasis_channels.h"
#define DEFAULTCONTEXT "default" #define DEFAULTCONTEXT "default"
#define DEFAULTCALLERID "Unknown" #define DEFAULTCALLERID "Unknown"
@ -5563,6 +5563,8 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
return NULL; return NULL;
} }
ast_channel_stage_snapshot(tmp);
ast_format_cap_copy(ast_channel_nativeformats(tmp), l->cap); ast_format_cap_copy(ast_channel_nativeformats(tmp), l->cap);
if (ast_format_cap_is_empty(ast_channel_nativeformats(tmp))) { if (ast_format_cap_is_empty(ast_channel_nativeformats(tmp))) {
ast_format_cap_copy(ast_channel_nativeformats(tmp), global_cap); 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_priority_set(tmp, 1);
ast_channel_stage_snapshot_done(tmp);
if (state != AST_STATE_DOWN) { if (state != AST_STATE_DOWN) {
if (unistimdebug) { if (unistimdebug) {
ast_verb(0, "Starting pbx in unistim_new\n"); ast_verb(0, "Starting pbx in unistim_new\n");

@ -6473,6 +6473,7 @@ static void *pri_dchannel(void *vpri)
ast_mutex_lock(&pri->lock); ast_mutex_lock(&pri->lock);
sig_pri_lock_private(pri->pvts[chanpos]); sig_pri_lock_private(pri->pvts[chanpos]);
if (c) { if (c) {
ast_channel_stage_snapshot(c);
#if defined(HAVE_PRI_SUBADDR) #if defined(HAVE_PRI_SUBADDR)
if (e->ring.calling.subaddress.valid) { if (e->ring.calling.subaddress.valid) {
/* Set Calling Subaddress */ /* Set Calling Subaddress */
@ -6557,6 +6558,7 @@ static void *pri_dchannel(void *vpri)
PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
#endif #endif
} }
ast_channel_stage_snapshot_done(c);
} }
if (c && !ast_pthread_create_detached(&threadid, NULL, pri_ss_thread, pri->pvts[chanpos])) { 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", 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 * will do anything with the channel we have just
* created. * created.
*/ */
ast_channel_stage_snapshot(c);
#if defined(HAVE_PRI_SUBADDR) #if defined(HAVE_PRI_SUBADDR)
if (e->ring.calling.subaddress.valid) { if (e->ring.calling.subaddress.valid) {
/* Set Calling Subaddress */ /* Set Calling Subaddress */
@ -6670,6 +6673,8 @@ static void *pri_dchannel(void *vpri)
sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.subcmds, sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.subcmds,
e->ring.call); e->ring.call);
ast_channel_stage_snapshot_done(c);
} }
if (c && !ast_pbx_start(c)) { if (c && !ast_pbx_start(c)) {
ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n", ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",

@ -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); sig_ss7_set_echocanceller(p, 1);
ast_channel_stage_snapshot(c);
/* /*
* It is reasonably safe to set the following * It is reasonably safe to set the following
* channel variables while the channel private * 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; p->generic_name[0] = 0;
} }
ast_channel_stage_snapshot_done(c);
sig_ss7_unlock_private(p); sig_ss7_unlock_private(p);
ast_channel_unlock(c); ast_channel_unlock(c);

@ -923,6 +923,11 @@ enum {
* occur. * occur.
*/ */
AST_FLAG_DEAD = (1 << 24), 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 */ /*! \brief ast_bridge_config flags */

@ -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, void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_type *type,
struct ast_json *blob); 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 * \since 12
* \brief Publish a \ref ast_channel_snapshot for a channel. * \brief Publish a \ref ast_channel_snapshot for a channel.

@ -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) 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, "BRIDGEPEER", name);
pbx_builtin_setvar_helper(chan, "BRIDGEPVTCALLID", pvtid); pbx_builtin_setvar_helper(chan, "BRIDGEPVTCALLID", pvtid);
ast_channel_stage_snapshot_done(chan);
} }
/*! /*!

@ -876,6 +876,9 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char
/* Channel structure allocation failure. */ /* Channel structure allocation failure. */
return NULL; return NULL;
} }
ast_channel_stage_snapshot(tmp);
if (!(nativeformats = ast_format_cap_alloc())) { if (!(nativeformats = ast_format_cap_alloc())) {
ao2_ref(tmp, -1); ao2_ref(tmp, -1);
/* format capabilities structure allocation failure */ /* 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 * And now, since the channel structure is built, and has its name, let
* the world know of its existance * the world know of its existance
*/ */
ast_channel_publish_snapshot(tmp); ast_channel_stage_snapshot_done(tmp);
return tmp; return tmp;
} }
@ -7716,8 +7719,12 @@ void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
{ {
struct ast_variable *cur; struct ast_variable *cur;
ast_channel_stage_snapshot(chan);
for (cur = vars; cur; cur = cur->next) for (cur = vars; cur; cur = cur->next)
pbx_builtin_setvar_helper(chan, cur->name, cur->value); 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) static void *silence_generator_alloc(struct ast_channel *chan, void *data)

@ -286,6 +286,8 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe
cap_request = NULL; cap_request = NULL;
cap_all_audio = ast_format_cap_destroy(cap_all_audio); 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_appl_set(channel->owner, "AppDial2");
ast_channel_data_set(channel->owner, "(Outgoing Line)"); ast_channel_data_set(channel->owner, "(Outgoing Line)");
ast_publish_channel_state(channel->owner); 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_transfercapability_set(channel->owner, ast_channel_transfercapability(chan));
} }
ast_channel_stage_snapshot_done(channel->owner);
return 0; return 0;
} }

@ -10050,7 +10050,9 @@ static int pbx_outgoing_attempt(const char *type, struct ast_format_cap *cap, co
return -1; return -1;
} }
if (vars) {
ast_set_variables(dialed, vars); ast_set_variables(dialed, vars);
}
if (account) { if (account) {
ast_channel_accountcode_set(dialed, account); ast_channel_accountcode_set(dialed, account);

@ -600,11 +600,26 @@ struct ast_json *ast_multi_channel_blob_get_json(struct ast_multi_channel_blob *
return obj->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) void ast_channel_publish_snapshot(struct ast_channel *chan)
{ {
RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
RAII_VAR(struct stasis_message *, message, 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); snapshot = ast_channel_snapshot_create(chan);
if (!snapshot) { if (!snapshot) {
return; return;

Loading…
Cancel
Save