[asterisk-commits] file: branch file/res_xmpp r369035 - in /team/file/res_xmpp: ./ apps/ apps/co...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jun 15 16:19:35 CDT 2012


Author: file
Date: Fri Jun 15 16:19:29 2012
New Revision: 369035

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=369035
Log:
I need more configuration goodies!

Added:
    team/file/res_xmpp/build_tools/find_missing_support_level
      - copied unchanged from r369028, trunk/build_tools/find_missing_support_level
Removed:
    team/file/res_xmpp/include/asterisk/app_voicemail.h
Modified:
    team/file/res_xmpp/   (props changed)
    team/file/res_xmpp/Makefile
    team/file/res_xmpp/UPGRADE.txt
    team/file/res_xmpp/apps/app_celgenuserevent.c
    team/file/res_xmpp/apps/app_dial.c
    team/file/res_xmpp/apps/app_directory.c
    team/file/res_xmpp/apps/app_followme.c
    team/file/res_xmpp/apps/app_queue.c
    team/file/res_xmpp/apps/app_stack.c
    team/file/res_xmpp/apps/app_system.c
    team/file/res_xmpp/apps/app_voicemail.c
    team/file/res_xmpp/apps/app_voicemail.exports.in
    team/file/res_xmpp/apps/confbridge/conf_config_parser.c
    team/file/res_xmpp/channels/chan_dahdi.c
    team/file/res_xmpp/channels/chan_iax2.c
    team/file/res_xmpp/channels/chan_misdn.c
    team/file/res_xmpp/channels/chan_sip.c
    team/file/res_xmpp/channels/chan_skinny.c
    team/file/res_xmpp/channels/console_board.c
    team/file/res_xmpp/channels/console_gui.c
    team/file/res_xmpp/channels/console_video.c
    team/file/res_xmpp/channels/iax2-parser.c
    team/file/res_xmpp/channels/iax2-provision.c
    team/file/res_xmpp/channels/misdn/ie.c
    team/file/res_xmpp/channels/misdn/isdn_lib.c
    team/file/res_xmpp/channels/misdn/isdn_msg_parser.c
    team/file/res_xmpp/channels/misdn/portinfo.c
    team/file/res_xmpp/channels/misdn_config.c
    team/file/res_xmpp/channels/sig_analog.c
    team/file/res_xmpp/channels/sig_pri.c
    team/file/res_xmpp/channels/sig_ss7.c
    team/file/res_xmpp/channels/sip/config_parser.c
    team/file/res_xmpp/channels/sip/dialplan_functions.c
    team/file/res_xmpp/channels/sip/include/sip.h
    team/file/res_xmpp/channels/sip/reqresp_parser.c
    team/file/res_xmpp/channels/sip/sdp_crypto.c
    team/file/res_xmpp/channels/sip/security_events.c
    team/file/res_xmpp/channels/sip/srtp.c
    team/file/res_xmpp/channels/sip/utils.c
    team/file/res_xmpp/channels/vcodecs.c
    team/file/res_xmpp/channels/vgrabbers.c
    team/file/res_xmpp/codecs/codec_dahdi.c
    team/file/res_xmpp/funcs/func_presencestate.c
    team/file/res_xmpp/funcs/func_realtime.c
    team/file/res_xmpp/funcs/func_volume.c
    team/file/res_xmpp/include/asterisk/app.h
    team/file/res_xmpp/include/asterisk/channel.h
    team/file/res_xmpp/include/asterisk/config_options.h
    team/file/res_xmpp/include/asterisk/frame.h
    team/file/res_xmpp/include/asterisk/strings.h
    team/file/res_xmpp/main/Makefile
    team/file/res_xmpp/main/abstract_jb.c
    team/file/res_xmpp/main/acl.c
    team/file/res_xmpp/main/alaw.c
    team/file/res_xmpp/main/aoc.c
    team/file/res_xmpp/main/app.c
    team/file/res_xmpp/main/asterisk.c
    team/file/res_xmpp/main/astfd.c
    team/file/res_xmpp/main/astmm.c
    team/file/res_xmpp/main/astobj2.c
    team/file/res_xmpp/main/audiohook.c
    team/file/res_xmpp/main/autochan.c
    team/file/res_xmpp/main/autoservice.c
    team/file/res_xmpp/main/bridging.c
    team/file/res_xmpp/main/callerid.c
    team/file/res_xmpp/main/ccss.c
    team/file/res_xmpp/main/cdr.c
    team/file/res_xmpp/main/cel.c
    team/file/res_xmpp/main/channel.c
    team/file/res_xmpp/main/channel_internal_api.c
    team/file/res_xmpp/main/chanvars.c
    team/file/res_xmpp/main/cli.c
    team/file/res_xmpp/main/config.c
    team/file/res_xmpp/main/config_options.c
    team/file/res_xmpp/main/data.c
    team/file/res_xmpp/main/datastore.c
    team/file/res_xmpp/main/db.c
    team/file/res_xmpp/main/devicestate.c
    team/file/res_xmpp/main/dial.c
    team/file/res_xmpp/main/dns.c
    team/file/res_xmpp/main/dnsmgr.c
    team/file/res_xmpp/main/dsp.c
    team/file/res_xmpp/main/enum.c
    team/file/res_xmpp/main/event.c
    team/file/res_xmpp/main/file.c
    team/file/res_xmpp/main/fixedjitterbuf.c
    team/file/res_xmpp/main/format.c
    team/file/res_xmpp/main/format_cap.c
    team/file/res_xmpp/main/format_pref.c
    team/file/res_xmpp/main/frame.c
    team/file/res_xmpp/main/framehook.c
    team/file/res_xmpp/main/fskmodem.c
    team/file/res_xmpp/main/fskmodem_float.c
    team/file/res_xmpp/main/fskmodem_int.c
    team/file/res_xmpp/main/global_datastores.c
    team/file/res_xmpp/main/hashtab.c
    team/file/res_xmpp/main/heap.c
    team/file/res_xmpp/main/image.c
    team/file/res_xmpp/main/indications.c
    team/file/res_xmpp/main/io.c
    team/file/res_xmpp/main/jitterbuf.c
    team/file/res_xmpp/main/libasteriskssl.c
    team/file/res_xmpp/main/loader.c
    team/file/res_xmpp/main/lock.c
    team/file/res_xmpp/main/logger.c
    team/file/res_xmpp/main/manager.c
    team/file/res_xmpp/main/message.c
    team/file/res_xmpp/main/netsock.c
    team/file/res_xmpp/main/netsock2.c
    team/file/res_xmpp/main/pbx.c
    team/file/res_xmpp/main/plc.c
    team/file/res_xmpp/main/presencestate.c
    team/file/res_xmpp/main/privacy.c
    team/file/res_xmpp/main/rtp_engine.c
    team/file/res_xmpp/main/say.c
    team/file/res_xmpp/main/sched.c
    team/file/res_xmpp/main/security_events.c
    team/file/res_xmpp/main/slinfactory.c
    team/file/res_xmpp/main/srv.c
    team/file/res_xmpp/main/stdtime/localtime.c
    team/file/res_xmpp/main/strcompat.c
    team/file/res_xmpp/main/strings.c
    team/file/res_xmpp/main/stun.c
    team/file/res_xmpp/main/syslog.c
    team/file/res_xmpp/main/taskprocessor.c
    team/file/res_xmpp/main/tcptls.c
    team/file/res_xmpp/main/tdd.c
    team/file/res_xmpp/main/term.c
    team/file/res_xmpp/main/test.c
    team/file/res_xmpp/main/threadstorage.c
    team/file/res_xmpp/main/timing.c
    team/file/res_xmpp/main/translate.c
    team/file/res_xmpp/main/udptl.c
    team/file/res_xmpp/main/ulaw.c
    team/file/res_xmpp/main/utils.c
    team/file/res_xmpp/main/xml.c
    team/file/res_xmpp/main/xmldoc.c
    team/file/res_xmpp/pbx/dundi-parser.c
    team/file/res_xmpp/pbx/pbx_config.c
    team/file/res_xmpp/res/ael/pval.c
    team/file/res_xmpp/res/res_adsi.c
    team/file/res_xmpp/res/res_config_odbc.c
    team/file/res_xmpp/res/res_fax.c
    team/file/res_xmpp/res/res_odbc.c
    team/file/res_xmpp/res/res_smdi.c
    team/file/res_xmpp/res/res_speech.c
    team/file/res_xmpp/res/snmp/agent.c
    team/file/res_xmpp/tests/test_voicemail_api.c
    team/file/res_xmpp/utils/astdb2bdb.c
    team/file/res_xmpp/utils/astdb2sqlite3.c

Propchange: team/file/res_xmpp/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri Jun 15 16:19:29 2012
@@ -1,1 +1,1 @@
-/trunk:1-368710
+/trunk:1-369033

Modified: team/file/res_xmpp/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/file/res_xmpp/Makefile?view=diff&rev=369035&r1=369034&r2=369035
==============================================================================
--- team/file/res_xmpp/Makefile (original)
+++ team/file/res_xmpp/Makefile Fri Jun 15 16:19:29 2012
@@ -497,40 +497,23 @@
 
 NEWHEADERS=$(notdir $(wildcard include/asterisk/*.h))
 OLDHEADERS=$(filter-out $(NEWHEADERS) $(notdir $(DESTDIR)$(ASTHEADERDIR)),$(notdir $(wildcard $(DESTDIR)$(ASTHEADERDIR)/*.h)))
+INSTALLDIRS="$(ASTLIBDIR)" "$(ASTMODDIR)" "$(ASTSBINDIR)" "$(ASTETCDIR)" "$(ASTVARRUNDIR)" \
+	"$(ASTSPOOLDIR)" "$(ASTSPOOLDIR)/dictate" "$(ASTSPOOLDIR)/meetme" \
+	"$(ASTSPOOLDIR)/monitor" "$(ASTSPOOLDIR)/system" "$(ASTSPOOLDIR)/tmp" \
+	"$(ASTSPOOLDIR)/voicemail" "$(ASTHEADERDIR)" "$(ASTHEADERDIR)/doxygen" \
+	"$(ASTLOGDIR)" "$(ASTLOGDIR)/cdr-csv" "$(ASTLOGDIR)/cdr-custom" \
+	"$(ASTLOGDIR)/cel-custom" "$(ASTDATADIR)" "$(ASTDATADIR)/documentation" \
+	"$(ASTDATADIR)/documentation/thirdparty" "$(ASTDATADIR)/firmware" \
+	"$(ASTDATADIR)/firmware/iax" "$(ASTDATADIR)/images" "$(ASTDATADIR)/keys" \
+	"$(ASTDATADIR)/phoneprov" "$(ASTDATADIR)/static-http" "$(ASTDATADIR)/sounds" \
+	"$(ASTDATADIR)/moh" "$(ASTMANDIR)/man8" "$(AGI_DIR)" "$(ASTDBDIR)"
 
 installdirs:
-	$(INSTALL) -d "$(DESTDIR)$(ASTLIBDIR)"
-	$(INSTALL) -d "$(DESTDIR)$(ASTMODDIR)"
-	$(INSTALL) -d "$(DESTDIR)$(ASTSBINDIR)"
-	$(INSTALL) -d "$(DESTDIR)$(ASTETCDIR)"
-	$(INSTALL) -d "$(DESTDIR)$(ASTVARRUNDIR)"
-	$(INSTALL) -d "$(DESTDIR)$(ASTSPOOLDIR)"
-	$(INSTALL) -d "$(DESTDIR)$(ASTSPOOLDIR)/dictate"
-	$(INSTALL) -d "$(DESTDIR)$(ASTSPOOLDIR)/meetme"
-	$(INSTALL) -d "$(DESTDIR)$(ASTSPOOLDIR)/monitor"
-	$(INSTALL) -d "$(DESTDIR)$(ASTSPOOLDIR)/system"
-	$(INSTALL) -d "$(DESTDIR)$(ASTSPOOLDIR)/tmp"
-	$(INSTALL) -d "$(DESTDIR)$(ASTSPOOLDIR)/voicemail"
-	$(INSTALL) -d "$(DESTDIR)$(ASTHEADERDIR)"
-	$(INSTALL) -d "$(DESTDIR)$(ASTHEADERDIR)/doxygen"
-	$(INSTALL) -d "$(DESTDIR)$(ASTLOGDIR)"
-	$(INSTALL) -d "$(DESTDIR)$(ASTLOGDIR)/cdr-csv"
-	$(INSTALL) -d "$(DESTDIR)$(ASTLOGDIR)/cdr-custom"
-	$(INSTALL) -d "$(DESTDIR)$(ASTLOGDIR)/cel-custom"
-	$(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)"
-	$(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/documentation"
-	$(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/documentation/thirdparty"
-	$(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/firmware"
-	$(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/firmware/iax"
-	$(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/images"
-	$(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/keys"
-	$(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/phoneprov"
-	$(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/static-http"
-	$(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/sounds"
-	$(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/moh"
-	$(INSTALL) -d "$(DESTDIR)$(ASTMANDIR)/man8"
-	$(INSTALL) -d "$(DESTDIR)$(AGI_DIR)"
-	$(INSTALL) -d "$(DESTDIR)$(ASTDBDIR)"
+	@for i in $(INSTALLDIRS); do \
+		if [ ! -z "$${i}" -a ! -d "$(DESTDIR)$${i}" ]; then \
+			$(INSTALL) -d "$(DESTDIR)$${i}"; \
+		fi; \
+	done
 
 main-bininstall:
 	+ at DESTDIR="$(DESTDIR)" ASTSBINDIR="$(ASTSBINDIR)" ASTLIBDIR="$(ASTLIBDIR)" $(SUBMAKE) -C main bininstall

Modified: team/file/res_xmpp/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/file/res_xmpp/UPGRADE.txt?view=diff&rev=369035&r1=369034&r2=369035
==============================================================================
--- team/file/res_xmpp/UPGRADE.txt (original)
+++ team/file/res_xmpp/UPGRADE.txt Fri Jun 15 16:19:29 2012
@@ -101,6 +101,10 @@
    should be vastly improved.  The HANGUPCAUSE hash should now be used instead
    of SIP_CAUSE. Because of this, the storesipcause option in sip.conf is also
    deprecated.
+ - The sip paramater for Originating Line Information (oli, isup-oli, and
+   ss7-oli) is now parsed out of the From header and copied into the channel's
+   ANI2 information field.  This is readable from the CALLERID(ani2) dialplan
+   function.
 
 chan_unistim
  - Due to massive update in chan_unistim phone keys functions and on-screen 

Modified: team/file/res_xmpp/apps/app_celgenuserevent.c
URL: http://svnview.digium.com/svn/asterisk/team/file/res_xmpp/apps/app_celgenuserevent.c?view=diff&rev=369035&r1=369034&r2=369035
==============================================================================
--- team/file/res_xmpp/apps/app_celgenuserevent.c (original)
+++ team/file/res_xmpp/apps/app_celgenuserevent.c Fri Jun 15 16:19:29 2012
@@ -22,6 +22,10 @@
  *
  * \ingroup applications
  */
+
+/*** MODULEINFO
+	<support_level>core</support_level>
+ ***/
 
 #include "asterisk.h"
 

Modified: team/file/res_xmpp/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/team/file/res_xmpp/apps/app_dial.c?view=diff&rev=369035&r1=369034&r2=369035
==============================================================================
--- team/file/res_xmpp/apps/app_dial.c (original)
+++ team/file/res_xmpp/apps/app_dial.c Fri Jun 15 16:19:29 2012
@@ -2280,7 +2280,7 @@
 	if (ast_test_flag64(&opts, OPT_PREDIAL_CALLER)
 		&& !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLER])) {
 		ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLER]);
-		ast_app_exec_sub(NULL, chan, opt_args[OPT_ARG_PREDIAL_CALLER]);
+		ast_app_exec_sub(NULL, chan, opt_args[OPT_ARG_PREDIAL_CALLER], 0);
 	}
 
 	/* loop through the list of dial destinations */
@@ -2550,12 +2550,18 @@
 	if (ast_test_flag64(&opts, OPT_PREDIAL_CALLEE)
 		&& !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLEE])
 		&& !AST_LIST_EMPTY(&out_chans)) {
-		ast_autoservice_start(chan);
+		const char *predial_callee;
+
 		ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLEE]);
-		AST_LIST_TRAVERSE(&out_chans, tmp, node) {
-			ast_pre_call(tmp->chan, opt_args[OPT_ARG_PREDIAL_CALLEE]);
-		}
-		ast_autoservice_stop(chan);
+		predial_callee = ast_app_expand_sub_args(chan, opt_args[OPT_ARG_PREDIAL_CALLEE]);
+		if (predial_callee) {
+			ast_autoservice_start(chan);
+			AST_LIST_TRAVERSE(&out_chans, tmp, node) {
+				ast_pre_call(tmp->chan, predial_callee);
+			}
+			ast_autoservice_stop(chan);
+			ast_free((char *) predial_callee);
+		}
 	}
 
 	/* Start all outgoing calls */
@@ -2884,7 +2890,7 @@
 				}
 			}
 			if (gosub_args) {
-				res9 = ast_app_exec_sub(chan, peer, gosub_args);
+				res9 = ast_app_exec_sub(chan, peer, gosub_args, 0);
 				ast_free(gosub_args);
 			} else {
 				ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");

Modified: team/file/res_xmpp/apps/app_directory.c
URL: http://svnview.digium.com/svn/asterisk/team/file/res_xmpp/apps/app_directory.c?view=diff&rev=369035&r1=369034&r2=369035
==============================================================================
--- team/file/res_xmpp/apps/app_directory.c (original)
+++ team/file/res_xmpp/apps/app_directory.c Fri Jun 15 16:19:29 2012
@@ -475,7 +475,8 @@
 		const char *ctx = ast_variable_retrieve(rtdata, mailbox, "context");
 
 		fullname = ast_variable_retrieve(rtdata, mailbox, "fullname");
-		if (ast_true((hidefromdir = ast_variable_retrieve(rtdata, mailbox, "hidefromdir")))) {
+		hidefromdir = ast_variable_retrieve(rtdata, mailbox, "hidefromdir");
+		if (ast_true(hidefromdir)) {
 			/* Skip hidden */
 			continue;
 		}

Modified: team/file/res_xmpp/apps/app_followme.c
URL: http://svnview.digium.com/svn/asterisk/team/file/res_xmpp/apps/app_followme.c?view=diff&rev=369035&r1=369034&r2=369035
==============================================================================
--- team/file/res_xmpp/apps/app_followme.c (original)
+++ team/file/res_xmpp/apps/app_followme.c Fri Jun 15 16:19:29 2012
@@ -1386,14 +1386,15 @@
 	if (ast_test_flag(&targs->followmeflags, FOLLOWMEFLAG_PREDIAL_CALLEE)
 		&& !ast_strlen_zero(opt_args[FOLLOWMEFLAG_ARG_PREDIAL_CALLEE])) {
 		ast_replace_subargument_delimiter(opt_args[FOLLOWMEFLAG_ARG_PREDIAL_CALLEE]);
-		targs->predial_callee = opt_args[FOLLOWMEFLAG_ARG_PREDIAL_CALLEE];
+		targs->predial_callee =
+			ast_app_expand_sub_args(chan, opt_args[FOLLOWMEFLAG_ARG_PREDIAL_CALLEE]);
 	}
 
 	/* PREDIAL: Run gosub on the caller's channel */
 	if (ast_test_flag(&targs->followmeflags, FOLLOWMEFLAG_PREDIAL_CALLER)
 		&& !ast_strlen_zero(opt_args[FOLLOWMEFLAG_ARG_PREDIAL_CALLER])) {
 		ast_replace_subargument_delimiter(opt_args[FOLLOWMEFLAG_ARG_PREDIAL_CALLER]);
-		ast_app_exec_sub(NULL, chan, opt_args[FOLLOWMEFLAG_ARG_PREDIAL_CALLER]);
+		ast_app_exec_sub(NULL, chan, opt_args[FOLLOWMEFLAG_ARG_PREDIAL_CALLER], 0);
 	}
 
 	/* Forget the 'N' option if the call is already up. */
@@ -1522,6 +1523,7 @@
 	if (!ast_strlen_zero(targs->namerecloc)) {
 		unlink(targs->namerecloc);
 	}
+	ast_free((char *) targs->predial_callee);
 	ast_party_connected_line_free(&targs->connected_in);
 	ast_party_connected_line_free(&targs->connected_out);
 	ast_free(targs);

Modified: team/file/res_xmpp/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/file/res_xmpp/apps/app_queue.c?view=diff&rev=369035&r1=369034&r2=369035
==============================================================================
--- team/file/res_xmpp/apps/app_queue.c (original)
+++ team/file/res_xmpp/apps/app_queue.c Fri Jun 15 16:19:29 2012
@@ -2502,7 +2502,7 @@
 	memset(tmpbuf, 0, sizeof(tmpbuf));
 	for (v = queue_vars; v; v = v->next) {
 		/* Convert to dashes `-' from underscores `_' as the latter are more SQL friendly. */
-		if ((tmp = strchr(v->name, '_'))) {
+		if (strchr(v->name, '_')) {
 			ast_copy_string(tmpbuf, v->name, sizeof(tmpbuf));
 			tmp_name = tmpbuf;
 			tmp = tmpbuf;
@@ -5352,7 +5352,7 @@
 				}
 			}
 			if (gosub_args) {
-				ast_app_exec_sub(qe->chan, peer, gosub_args);
+				ast_app_exec_sub(qe->chan, peer, gosub_args, 0);
 				ast_free(gosub_args);
 			} else {
 				ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");

Modified: team/file/res_xmpp/apps/app_stack.c
URL: http://svnview.digium.com/svn/asterisk/team/file/res_xmpp/apps/app_stack.c?view=diff&rev=369035&r1=369034&r2=369035
==============================================================================
--- team/file/res_xmpp/apps/app_stack.c (original)
+++ team/file/res_xmpp/apps/app_stack.c Fri Jun 15 16:19:29 2012
@@ -200,10 +200,10 @@
 	</agi>
  ***/
 
-static const char * const app_gosub = "Gosub";
-static const char * const app_gosubif = "GosubIf";
-static const char * const app_return = "Return";
-static const char * const app_pop = "StackPop";
+static const char app_gosub[] = "Gosub";
+static const char app_gosubif[] = "GosubIf";
+static const char app_return[] = "Return";
+static const char app_pop[] = "StackPop";
 
 static void gosub_free(void *data);
 
@@ -218,10 +218,13 @@
 	unsigned char arguments;
 	struct varshead varshead;
 	int priority;
-	unsigned int is_agi:1;
+	/*! TRUE if the return location marks the end of a special routine. */
+	unsigned int is_special:1;
 	char *context;
 	char extension[0];
 };
+
+AST_LIST_HEAD(gosub_stack_list, gosub_stack_frame);
 
 static int frame_set_var(struct ast_channel *chan, struct gosub_stack_frame *frame, const char *var, const char *value)
 {
@@ -290,8 +293,9 @@
 
 static void gosub_free(void *data)
 {
-	AST_LIST_HEAD(, gosub_stack_frame) *oldlist = data;
+	struct gosub_stack_list *oldlist = data;
 	struct gosub_stack_frame *oldframe;
+
 	AST_LIST_LOCK(oldlist);
 	while ((oldframe = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
 		gosub_release_frame(NULL, oldframe);
@@ -305,7 +309,8 @@
 {
 	struct ast_datastore *stack_store;
 	struct gosub_stack_frame *oldframe;
-	AST_LIST_HEAD(, gosub_stack_frame) *oldlist;
+	struct gosub_stack_list *oldlist;
+	int res = 0;
 
 	ast_channel_lock(chan);
 	if (!(stack_store = ast_channel_datastore_find(chan, &stack_info, NULL))) {
@@ -316,23 +321,30 @@
 
 	oldlist = stack_store->data;
 	AST_LIST_LOCK(oldlist);
-	oldframe = AST_LIST_REMOVE_HEAD(oldlist, entries);
-	AST_LIST_UNLOCK(oldlist);
-
+	oldframe = AST_LIST_FIRST(oldlist);
 	if (oldframe) {
-		gosub_release_frame(chan, oldframe);
+		if (oldframe->is_special) {
+			ast_debug(1, "%s attempted to pop special return location.\n", app_pop);
+
+			/* Abort the special routine dialplan execution.  Dialplan programming error. */
+			res = -1;
+		} else {
+			AST_LIST_REMOVE_HEAD(oldlist, entries);
+			gosub_release_frame(chan, oldframe);
+		}
 	} else {
 		ast_debug(1, "%s called with an empty gosub stack\n", app_pop);
 	}
-	ast_channel_unlock(chan);
-	return 0;
+	AST_LIST_UNLOCK(oldlist);
+	ast_channel_unlock(chan);
+	return res;
 }
 
 static int return_exec(struct ast_channel *chan, const char *data)
 {
 	struct ast_datastore *stack_store;
 	struct gosub_stack_frame *oldframe;
-	AST_LIST_HEAD(, gosub_stack_frame) *oldlist;
+	struct gosub_stack_list *oldlist;
 	const char *retval = data;
 	int res = 0;
 
@@ -352,12 +364,24 @@
 		ast_log(LOG_ERROR, "Return without Gosub: stack is empty\n");
 		ast_channel_unlock(chan);
 		return -1;
-	} else if (oldframe->is_agi) {
-		/* Exit from AGI */
+	}
+	if (oldframe->is_special) {
+		/* Exit from special routine. */
 		res = -1;
 	}
 
-	ast_explicit_goto(chan, oldframe->context, oldframe->extension, oldframe->priority);
+	/*
+	 * We cannot use ast_explicit_goto() because we MUST restore
+	 * what was there before.  Channels that do not have a PBX may
+	 * not have the context or exten set.
+	 */
+	ast_channel_context_set(chan, oldframe->context);
+	ast_channel_exten_set(chan, oldframe->extension);
+	if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP)) {
+		--oldframe->priority;
+	}
+	ast_channel_priority_set(chan, oldframe->priority);
+
 	gosub_release_frame(chan, oldframe);
 
 	/* Set a return value, if any */
@@ -366,10 +390,95 @@
 	return res;
 }
 
+/*!
+ * \internal
+ * \brief Add missing context and/or exten to Gosub application argument string.
+ * \since 11.0
+ *
+ * \param chan Channel to obtain context/exten.
+ * \param args Gosub application argument string.
+ *
+ * \details
+ * Fills in the optional context and exten from the given channel.
+ * Convert: [[context,]exten,]priority[(arg1[,...][,argN])]
+ * To: context,exten,priority[(arg1[,...][,argN])]
+ *
+ * \retval expanded Gosub argument string on success.  Must be freed.
+ * \retval NULL on error.
+ *
+ * \note The parsing needs to be kept in sync with the
+ * gosub_exec() argument format.
+ */
+static const char *expand_gosub_args(struct ast_channel *chan, const char *args)
+{
+	int len;
+	char *parse;
+	char *label;
+	char *new_args;
+	const char *context;
+	const char *exten;
+	const char *pri;
+
+	/* Separate the context,exten,pri from the optional routine arguments. */
+	parse = ast_strdupa(args);
+	label = strsep(&parse, "(");
+	if (parse) {
+		char *endparen;
+
+		endparen = strrchr(parse, ')');
+		if (endparen) {
+			*endparen = '\0';
+		} else {
+			ast_log(LOG_WARNING, "Ouch.  No closing paren: '%s'?\n", args);
+		}
+	}
+
+	/* Split context,exten,pri */
+	context = strsep(&label, ",");
+	exten = strsep(&label, ",");
+	pri = strsep(&label, ",");
+	if (!exten) {
+		/* Only a priority in this one */
+		pri = context;
+		exten = NULL;
+		context = NULL;
+	} else if (!pri) {
+		/* Only an extension and priority in this one */
+		pri = exten;
+		exten = context;
+		context = NULL;
+	}
+
+	ast_channel_lock(chan);
+	if (ast_strlen_zero(exten)) {
+		exten = ast_channel_exten(chan);
+	}
+	if (ast_strlen_zero(context)) {
+		context = ast_channel_context(chan);
+	}
+	len = strlen(context) + strlen(exten) + strlen(pri) + 3;
+	if (!ast_strlen_zero(parse)) {
+		len += 2 + strlen(parse);
+	}
+	new_args = ast_malloc(len);
+	if (new_args) {
+		if (ast_strlen_zero(parse)) {
+			snprintf(new_args, len, "%s,%s,%s", context, exten, pri);
+		} else {
+			snprintf(new_args, len, "%s,%s,%s(%s)", context, exten, pri, parse);
+		}
+	}
+	ast_channel_unlock(chan);
+
+	ast_debug(4, "Gosub args:%s new_args:%s\n", args, new_args ? new_args : "");
+
+	return new_args;
+}
+
 static int gosub_exec(struct ast_channel *chan, const char *data)
 {
 	struct ast_datastore *stack_store;
-	AST_LIST_HEAD(, gosub_stack_frame) *oldlist;
+	struct gosub_stack_list *oldlist;
 	struct gosub_stack_frame *newframe;
 	struct gosub_stack_frame *lastframe;
 	char argname[15];
@@ -560,7 +669,7 @@
 static int local_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 {
 	struct ast_datastore *stack_store;
-	AST_LIST_HEAD(, gosub_stack_frame) *oldlist;
+	struct gosub_stack_list *oldlist;
 	struct gosub_stack_frame *frame;
 	struct ast_var_t *variables;
 
@@ -595,7 +704,7 @@
 static int local_write(struct ast_channel *chan, const char *cmd, char *var, const char *value)
 {
 	struct ast_datastore *stack_store;
-	AST_LIST_HEAD(, gosub_stack_frame) *oldlist;
+	struct gosub_stack_list *oldlist;
 	struct gosub_stack_frame *frame;
 
 	ast_channel_lock(chan);
@@ -662,7 +771,7 @@
 static int stackpeek_read(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **str, ssize_t len)
 {
 	struct ast_datastore *stack_store;
-	AST_LIST_HEAD(, gosub_stack_frame) *oldlist;
+	struct gosub_stack_list *oldlist;
 	struct gosub_stack_frame *frame;
 	int n;
 	AST_DECLARE_APP_ARGS(args,
@@ -729,6 +838,7 @@
 		break;
 	default:
 		ast_log(LOG_ERROR, "Unknown argument '%s' to STACK_PEEK\n", args.which);
+		break;
 	}
 
 	AST_LIST_UNLOCK(oldlist);
@@ -742,11 +852,211 @@
 	.read2 = stackpeek_read,
 };
 
+/*!
+ * \internal
+ * \brief Pop stack frames until remove a special return location.
+ * \since 11.0
+ *
+ * \param chan Channel to balance stack on.
+ *
+ * \note The channel is already locked when called.
+ *
+ * \return Nothing
+ */
+static void balance_stack(struct ast_channel *chan)
+{
+	struct ast_datastore *stack_store;
+	struct gosub_stack_list *oldlist;
+	struct gosub_stack_frame *oldframe;
+	int found;
+
+	stack_store = ast_channel_datastore_find(chan, &stack_info, NULL);
+	if (!stack_store) {
+		ast_log(LOG_WARNING, "No %s stack allocated.\n", app_gosub);
+		return;
+	}
+
+	oldlist = stack_store->data;
+	AST_LIST_LOCK(oldlist);
+	do {
+		oldframe = AST_LIST_REMOVE_HEAD(oldlist, entries);
+		if (!oldframe) {
+			break;
+		}
+		found = oldframe->is_special;
+		gosub_release_frame(chan, oldframe);
+	} while (!found);
+	AST_LIST_UNLOCK(oldlist);
+}
+
+/*!
+ * \internal
+ * \brief Run a subroutine on a channel.
+ * \since 11.0
+ *
+ * \note Absolutely _NO_ channel locks should be held before calling this function.
+ *
+ * \param chan Channel to execute subroutine on.
+ * \param sub_args Gosub application argument string.
+ * \param ignore_hangup TRUE if a hangup does not stop execution of the routine.
+ *
+ * \retval 0 success
+ * \retval -1 on error
+ */
+static int gosub_run(struct ast_channel *chan, const char *sub_args, int ignore_hangup)
+{
+	const char *saved_context;
+	const char *saved_exten;
+	int saved_priority;
+	int saved_hangup_flags;
+	int saved_autoloopflag;
+	int res;
+
+	ast_channel_lock(chan);
+
+	ast_verb(3, "%s Internal %s(%s) start\n",
+		ast_channel_name(chan), app_gosub, sub_args);
+
+	/* Save non-hangup softhangup flags. */
+	saved_hangup_flags = ast_channel_softhangup_internal_flag(chan)
+		& (AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE);
+	if (saved_hangup_flags) {
+		ast_channel_clear_softhangup(chan,
+			AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE);
+	}
+
+	/* Save autoloop flag */
+	saved_autoloopflag = ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP);
+	ast_set_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP);
+
+	/* Save current dialplan location */
+	saved_context = ast_strdupa(ast_channel_context(chan));
+	saved_exten = ast_strdupa(ast_channel_exten(chan));
+	saved_priority = ast_channel_priority(chan);
+
+	ast_debug(4, "%s Original location: %s,%s,%d\n", ast_channel_name(chan),
+		saved_context, saved_exten, saved_priority);
+
+	ast_channel_unlock(chan);
+	res = gosub_exec(chan, sub_args);
+	ast_debug(4, "%s exited with status %d\n", app_gosub, res);
+	ast_channel_lock(chan);
+	if (!res) {
+		struct ast_datastore *stack_store;
+
+		/* Mark the return location as special. */
+		stack_store = ast_channel_datastore_find(chan, &stack_info, NULL);
+		if (!stack_store) {
+			/* Should never happen! */
+			ast_log(LOG_ERROR, "No %s stack!\n", app_gosub);
+			res = -1;
+		} else {
+			struct gosub_stack_list *oldlist;
+			struct gosub_stack_frame *cur;
+
+			oldlist = stack_store->data;
+			cur = AST_LIST_FIRST(oldlist);
+			cur->is_special = 1;
+		}
+	}
+	if (!res) {
+		int found = 0;	/* set if we find at least one match */
+
+		/*
+		 * Run gosub body autoloop.
+		 *
+		 * Note that this loop is inverted from the normal execution
+		 * loop because we just executed the Gosub application as the
+		 * first extension of the autoloop.
+		 */
+		do {
+			/* Check for hangup. */
+			if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_UNBRIDGE) {
+				saved_hangup_flags |= AST_SOFTHANGUP_UNBRIDGE;
+				ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_UNBRIDGE);
+			}
+			if (ast_check_hangup(chan)) {
+				if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO) {
+					ast_log(LOG_ERROR, "%s An async goto just messed up our execution location.\n",
+						ast_channel_name(chan));
+					break;
+				}
+				if (!ignore_hangup) {
+					break;
+				}
+			}
+
+			/* Next dialplan priority. */
+			ast_channel_priority_set(chan, ast_channel_priority(chan) + 1);
+
+			ast_channel_unlock(chan);
+			res = ast_spawn_extension(chan, ast_channel_context(chan),
+				ast_channel_exten(chan), ast_channel_priority(chan),
+				S_COR(ast_channel_caller(chan)->id.number.valid,
+					ast_channel_caller(chan)->id.number.str, NULL),
+				&found, 1);
+			ast_channel_lock(chan);
+		} while (!res);
+		if (found && res) {
+			/* Something bad happened, or a hangup has been requested. */
+			ast_debug(1, "Spawn extension (%s,%s,%d) exited with %d on '%s'\n",
+				ast_channel_context(chan), ast_channel_exten(chan),
+				ast_channel_priority(chan), res, ast_channel_name(chan));
+			ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n",
+				ast_channel_context(chan), ast_channel_exten(chan),
+				ast_channel_priority(chan), ast_channel_name(chan));
+		}
+
+		/* Did the routine return? */
+		if (ast_channel_priority(chan) == saved_priority
+			&& !strcmp(ast_channel_context(chan), saved_context)
+			&& !strcmp(ast_channel_exten(chan), saved_exten)) {
+			ast_verb(3, "%s Internal %s(%s) complete GOSUB_RETVAL=%s\n",
+				ast_channel_name(chan), app_gosub, sub_args,
+				S_OR(pbx_builtin_getvar_helper(chan, "GOSUB_RETVAL"), ""));
+		} else {
+			ast_log(LOG_NOTICE, "%s Abnormal '%s(%s)' exit.  Popping routine return locations.\n",
+				ast_channel_name(chan), app_gosub, sub_args);
+			balance_stack(chan);
+			pbx_builtin_setvar_helper(chan, "GOSUB_RETVAL", "");
+		}
+
+		/* We executed the requested subroutine to the best of our ability. */
+		res = 0;
+	}
+
+	ast_debug(4, "%s Ending location: %s,%s,%d\n", ast_channel_name(chan),
+		ast_channel_context(chan), ast_channel_exten(chan),
+		ast_channel_priority(chan));
+
+	/* Restore dialplan location */
+	if (!(ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO)) {
+		ast_channel_context_set(chan, saved_context);
+		ast_channel_exten_set(chan, saved_exten);
+		ast_channel_priority_set(chan, saved_priority);
+	}
+
+	/* Restore autoloop flag */
+	ast_set2_flag(ast_channel_flags(chan), saved_autoloopflag, AST_FLAG_IN_AUTOLOOP);
+
+	/* Restore non-hangup softhangup flags. */
+	if (saved_hangup_flags) {
+		ast_softhangup_nolock(chan, saved_hangup_flags);
+	}
+
+	ast_channel_unlock(chan);
+
+	return res;
+}
+
 static int handle_gosub(struct ast_channel *chan, AGI *agi, int argc, const char * const *argv)
 {
-	int old_priority, priority;
-	char old_context[AST_MAX_CONTEXT], old_extension[AST_MAX_EXTENSION];
-	struct ast_app *theapp;
+	int res;
+	int priority;
+	int old_autoloopflag;
+	int old_priority;
+	const char *old_context;
+	const char *old_extension;
 	char *gosub_args;
 
 	if (argc < 4 || argc > 5) {
@@ -770,80 +1080,125 @@
 		return RESULT_FAILURE;
 	}
 
-	/* Save previous location, since we're going to change it */
-	ast_copy_string(old_context, ast_channel_context(chan), sizeof(old_context));
-	ast_copy_string(old_extension, ast_channel_exten(chan), sizeof(old_extension));
-	old_priority = ast_channel_priority(chan);
-
-	if (!(theapp = pbx_findapp("Gosub"))) {
-		ast_log(LOG_ERROR, "Gosub() cannot be found in the list of loaded applications\n");
-		ast_agi_send(agi->fd, chan, "503 result=-2 Gosub is not loaded\n");
-		return RESULT_FAILURE;
-	}
-
-	/* Apparently, if you run ast_pbx_run on a channel that already has a pbx
-	 * structure, you need to add 1 to the priority to get it to go to the
-	 * right place.  But if it doesn't have a pbx structure, then leaving off
-	 * the 1 is the right thing to do.  See how this code differs when we
-	 * call a Gosub for the CALLEE channel in Dial or Queue.
-	 */
 	if (argc == 5) {
-		if (asprintf(&gosub_args, "%s,%s,%d(%s)", argv[1], argv[2], priority + (ast_channel_pbx(chan) ? 1 : 0), argv[4]) < 0) {
+		if (asprintf(&gosub_args, "%s,%s,%d(%s)", argv[1], argv[2], priority, argv[4]) < 0) {
 			ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
 			gosub_args = NULL;
 		}
 	} else {
-		if (asprintf(&gosub_args, "%s,%s,%d", argv[1], argv[2], priority + (ast_channel_pbx(chan) ? 1 : 0)) < 0) {
+		if (asprintf(&gosub_args, "%s,%s,%d", argv[1], argv[2], priority) < 0) {
 			ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
 			gosub_args = NULL;
 		}
 	}
-
-	if (gosub_args) {
-		int res;
-
-		ast_debug(1, "Trying gosub with arguments '%s'\n", gosub_args);
-
-		if ((res = pbx_exec(chan, theapp, gosub_args)) == 0) {
-			struct ast_pbx *pbx = ast_channel_pbx(chan);
-			struct ast_pbx_args args;
-			struct ast_datastore *stack_store = ast_channel_datastore_find(chan, &stack_info, NULL);
-			AST_LIST_HEAD(,gosub_stack_frame) *oldlist;
+	if (!gosub_args) {
+		ast_agi_send(agi->fd, chan, "503 result=-2 Memory allocation failure\n");
+		return RESULT_FAILURE;
+	}
+
+	ast_channel_lock(chan);
+
+	ast_verb(3, "%s AGI %s(%s) start\n", ast_channel_name(chan), app_gosub, gosub_args);
+
+	/* Save autoloop flag */
+	old_autoloopflag = ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP);
+	ast_set_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP);
+
+	/* Save previous location, since we're going to change it */
+	old_context = ast_strdupa(ast_channel_context(chan));
+	old_extension = ast_strdupa(ast_channel_exten(chan));
+	old_priority = ast_channel_priority(chan);
+
+	ast_debug(4, "%s Original location: %s,%s,%d\n", ast_channel_name(chan),
+		old_context, old_extension, old_priority);
+	ast_channel_unlock(chan);
+
+	res = gosub_exec(chan, gosub_args);
+	if (!res) {
+		struct ast_datastore *stack_store;
+
+		/* Mark the return location as special. */
+		ast_channel_lock(chan);
+		stack_store = ast_channel_datastore_find(chan, &stack_info, NULL);
+		if (!stack_store) {
+			/* Should never happen! */
+			ast_log(LOG_ERROR, "No %s stack!\n", app_gosub);
+			res = -1;
+		} else {
+			struct gosub_stack_list *oldlist;
 			struct gosub_stack_frame *cur;
-			if (!stack_store) {
-				ast_log(LOG_WARNING, "No GoSub stack remaining after AGI GoSub execution.\n");
-				ast_free(gosub_args);
-				return RESULT_FAILURE;
-			}
+
 			oldlist = stack_store->data;
 			cur = AST_LIST_FIRST(oldlist);
-			cur->is_agi = 1;
-
-			memset(&args, 0, sizeof(args));
-			args.no_hangup_chan = 1;
-			/* Suppress warning about PBX already existing */
-			ast_channel_pbx_set(chan, NULL);
-			ast_agi_send(agi->fd, chan, "100 result=0 Trying...\n");
-			ast_pbx_run_args(chan, &args);
-			ast_agi_send(agi->fd, chan, "200 result=0 Gosub complete\n");
-			if (ast_channel_pbx(chan)) {
-				ast_free(ast_channel_pbx(chan));
-			}
-			ast_channel_pbx_set(chan, pbx);
+			cur->is_special = 1;
+		}
+		ast_channel_unlock(chan);
+	}
+	if (!res) {
+		struct ast_pbx *pbx;
+		struct ast_pbx_args args;
+		int abnormal_exit;
+
+		memset(&args, 0, sizeof(args));
+		args.no_hangup_chan = 1;
+
+		ast_channel_lock(chan);
+
+		/* Next dialplan priority. */
+		ast_channel_priority_set(chan, ast_channel_priority(chan) + 1);
+
+		/* Suppress warning about PBX already existing */
+		pbx = ast_channel_pbx(chan);
+		ast_channel_pbx_set(chan, NULL);
+		ast_channel_unlock(chan);
+
+		ast_agi_send(agi->fd, chan, "100 result=0 Trying...\n");
+		ast_pbx_run_args(chan, &args);
+
+		ast_channel_lock(chan);
+		ast_free(ast_channel_pbx(chan));
+		ast_channel_pbx_set(chan, pbx);
+
+		/* Did the routine return? */
+		if (ast_channel_priority(chan) == old_priority
+			&& !strcmp(ast_channel_context(chan), old_context)
+			&& !strcmp(ast_channel_exten(chan), old_extension)) {
+			ast_verb(3, "%s AGI %s(%s) complete GOSUB_RETVAL=%s\n",
+				ast_channel_name(chan), app_gosub, gosub_args,
+				S_OR(pbx_builtin_getvar_helper(chan, "GOSUB_RETVAL"), ""));
+			abnormal_exit = 0;
 		} else {
-			ast_agi_send(agi->fd, chan, "200 result=%d Gosub failed\n", res);
-		}
-		ast_free(gosub_args);
+			ast_log(LOG_NOTICE, "%s Abnormal AGI %s(%s) exit.  Popping routine return locations.\n",
+				ast_channel_name(chan), app_gosub, gosub_args);
+			balance_stack(chan);
+			pbx_builtin_setvar_helper(chan, "GOSUB_RETVAL", "");
+			abnormal_exit = 1;
+		}
+		ast_channel_unlock(chan);
+
+		ast_agi_send(agi->fd, chan, "200 result=0 Gosub complete%s\n",
+			abnormal_exit ? " (abnormal exit)" : "");
 	} else {
-		ast_agi_send(agi->fd, chan, "503 result=-2 Memory allocation failure\n");
-		return RESULT_FAILURE;
-	}
+		ast_agi_send(agi->fd, chan, "200 result=%d Gosub failed\n", res);
+	}
+
+	/* Must use free because the memory was allocated by asprintf(). */
+	free(gosub_args);
+
+	ast_channel_lock(chan);
+	ast_debug(4, "%s Ending location: %s,%s,%d\n", ast_channel_name(chan),
+		ast_channel_context(chan), ast_channel_exten(chan),
+		ast_channel_priority(chan));
 
 	/* Restore previous location */
 	ast_channel_context_set(chan, old_context);
 	ast_channel_exten_set(chan, old_extension);
 	ast_channel_priority_set(chan, old_priority);
 
+	/* Restore autoloop flag */
+	ast_set2_flag(ast_channel_flags(chan), old_autoloopflag, AST_FLAG_IN_AUTOLOOP);
+	ast_channel_unlock(chan);
+
 	return RESULT_SUCCESS;
 }
 
@@ -852,7 +1207,7 @@
 
 static int unload_module(void)
 {
-	struct ast_context *con;
+	ast_install_stack_functions(NULL);
 
 	ast_agi_unregister(ast_module_info->self, &gosub_agi_command);
 
@@ -864,29 +1219,16 @@
 	ast_custom_function_unregister(&peek_function);
 	ast_custom_function_unregister(&stackpeek_function);
 
-	con = ast_context_find("gosub_virtual_context");
-	if (con) {
-		/* leave nothing behind */
-		ast_context_remove_extension2(con, "s", 1, NULL, 0);
-		ast_context_destroy(con, "app_stack");
-	}
-
 	return 0;
 }
 
 static int load_module(void)
 {
-	struct ast_context *con;
-
-	/* Create internal gosub return target to indicate successful completion. */
-	con = ast_context_find_or_create(NULL, NULL, "gosub_virtual_context", "app_stack");
-	if (!con) {
-		ast_log(LOG_ERROR, "'gosub_virtual_context' does not exist and unable to create\n");
-	} else {
-		ast_add_extension2(con, 1, "s", 1, NULL, NULL, "NoOp",
-			ast_strdup("Internal Gosub call complete GOSUB_RETVAL=${GOSUB_RETVAL}"),
-			ast_free_ptr, "app_stack");
-	}
+	/* Setup the stack application callback functions. */
+	static struct ast_app_stack_funcs funcs = {
+		.run_sub = gosub_run,
+		.expand_sub_args = expand_gosub_args,
+	};
 
 	ast_agi_register(ast_module_info->self, &gosub_agi_command);
 
@@ -898,6 +1240,9 @@
 	ast_custom_function_register(&peek_function);
 	ast_custom_function_register(&stackpeek_function);
 
+	funcs.module = ast_module_info->self,
+	ast_install_stack_functions(&funcs);
+
 	return 0;
 }
 

Modified: team/file/res_xmpp/apps/app_system.c
URL: http://svnview.digium.com/svn/asterisk/team/file/res_xmpp/apps/app_system.c?view=diff&rev=369035&r1=369034&r2=369035
==============================================================================
--- team/file/res_xmpp/apps/app_system.c (original)
+++ team/file/res_xmpp/apps/app_system.c Fri Jun 15 16:19:29 2012
@@ -24,6 +24,10 @@
  * 
  * \ingroup applications
  */
+
+/*** MODULEINFO
+	<support_level>core</support_level>
+ ***/
 
 #include "asterisk.h"
 

Modified: team/file/res_xmpp/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/team/file/res_xmpp/apps/app_voicemail.c?view=diff&rev=369035&r1=369034&r2=369035
==============================================================================
--- team/file/res_xmpp/apps/app_voicemail.c (original)
+++ team/file/res_xmpp/apps/app_voicemail.c Fri Jun 15 16:19:29 2012
@@ -113,7 +113,6 @@
 #include "asterisk/module.h"
 #include "asterisk/adsi.h"
 #include "asterisk/app.h"
-#include "asterisk/app_voicemail.h"
 #include "asterisk/manager.h"
 #include "asterisk/dsp.h"
 #include "asterisk/localtime.h"
@@ -1041,7 +1040,6 @@
 static int is_valid_dtmf(const char *key);
 static void read_password_from_file(const char *secretfn, char *password, int passwordlen);
 static int write_password_to_file(const char *secretfn, const char *password);

[... 4992 lines stripped ...]



More information about the asterisk-commits mailing list