[asterisk-commits] file: trunk r404210 - in /trunk: ./ addons/ apps/ apps/confbridge/ channels/ ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Dec 18 13:28:14 CST 2013


Author: file
Date: Wed Dec 18 13:28:05 2013
New Revision: 404210

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=404210
Log:
channels: Return allocated channels locked.

This change makes ast_channel_alloc return allocated channels
locked. By doing so no other thread can acquire, lock, and manipulate
the channel before it is completely set up.

(closes issue AST-1256)

Review: https://reviewboard.asterisk.org/r/3067/
........

Merged revisions 404204 from http://svn.asterisk.org/svn/asterisk/branches/12

Modified:
    trunk/   (props changed)
    trunk/addons/chan_mobile.c
    trunk/addons/chan_ooh323.c
    trunk/apps/app_meetme.c
    trunk/apps/app_voicemail.c
    trunk/apps/confbridge/conf_chan_record.c
    trunk/channels/chan_alsa.c
    trunk/channels/chan_console.c
    trunk/channels/chan_dahdi.c
    trunk/channels/chan_gtalk.c
    trunk/channels/chan_h323.c
    trunk/channels/chan_iax2.c
    trunk/channels/chan_jingle.c
    trunk/channels/chan_mgcp.c
    trunk/channels/chan_misdn.c
    trunk/channels/chan_motif.c
    trunk/channels/chan_multicast_rtp.c
    trunk/channels/chan_nbs.c
    trunk/channels/chan_oss.c
    trunk/channels/chan_phone.c
    trunk/channels/chan_pjsip.c
    trunk/channels/chan_sip.c
    trunk/channels/chan_skinny.c
    trunk/channels/chan_unistim.c
    trunk/channels/chan_vpb.cc
    trunk/include/asterisk/channel.h
    trunk/main/channel.c
    trunk/main/core_unreal.c
    trunk/main/message.c
    trunk/main/pbx.c
    trunk/res/parking/parking_tests.c
    trunk/res/res_calendar.c
    trunk/res/res_stasis_snoop.c
    trunk/tests/test_app.c
    trunk/tests/test_cdr.c
    trunk/tests/test_cel.c
    trunk/tests/test_stasis_channels.c
    trunk/tests/test_substitution.c
    trunk/tests/test_voicemail_api.c

Propchange: trunk/
------------------------------------------------------------------------------
--- branch-12-merged (original)
+++ branch-12-merged Wed Dec 18 13:28:05 2013
@@ -1,1 +1,1 @@
-/branches/12:1-398558,398560-398577,398579-399305,399307-401390,401392-403290,403292-403778,403781-404006,404027,404029,404042,404046,404048,404050,404099,404137,404184
+/branches/12:1-398558,398560-398577,398579-399305,399307-401390,401392-403290,403292-403778,403781-404006,404027,404029,404042,404046,404048,404050,404099,404137,404184,404204

Modified: trunk/addons/chan_mobile.c
URL: http://svnview.digium.com/svn/asterisk/trunk/addons/chan_mobile.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/addons/chan_mobile.c (original)
+++ trunk/addons/chan_mobile.c Wed Dec 18 13:28:05 2013
@@ -878,6 +878,8 @@
 	if (pvt->sco_socket != -1) {
 		ast_channel_set_fd(chn, 0, pvt->sco_socket);
 	}
+
+	ast_channel_unlock(chn);
 
 	return chn;
 

Modified: trunk/addons/chan_ooh323.c
URL: http://svnview.digium.com/svn/asterisk/trunk/addons/chan_ooh323.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/addons/chan_ooh323.c (original)
+++ trunk/addons/chan_ooh323.c Wed Dec 18 13:28:05 2013
@@ -395,7 +395,6 @@
 	ast_mutex_lock(&i->lock);
 
 	if (ch) {
-		ast_channel_lock(ch);
 		ast_channel_tech_set(ch, &ooh323_tech);
 
 		if (cap)

Modified: trunk/apps/app_meetme.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_meetme.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/apps/app_meetme.c (original)
+++ trunk/apps/app_meetme.c Wed Dec 18 13:28:05 2013
@@ -8140,6 +8140,8 @@
 		return AST_TEST_FAIL;
 	}
 
+	ast_channel_unlock(chan);
+
 	cnf = build_conf("9898", "", "1234", 1, 1, 1, chan, test);
 	if (!cnf) {
 		ast_test_status_update(test, "Build of test conference 9898 failed\n");

Modified: trunk/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_voicemail.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/apps/app_voicemail.c (original)
+++ trunk/apps/app_voicemail.c Wed Dec 18 13:28:05 2013
@@ -13744,6 +13744,8 @@
 	ast_format_set(ast_channel_rawreadformat(test_channel1), AST_FORMAT_GSM, 0);
 	ast_channel_tech_set(test_channel1, &fake_tech);
 
+	ast_channel_unlock(test_channel1);
+
 	ast_test_status_update(test, "Test playing of extension when greeting is not available...\n");
 	snprintf(dir, sizeof(dir), "%s@%s", TEST_EXTENSION, TEST_CONTEXT); /* not a dir, don't get confused */
 	if (!(res = vmsayname_exec(test_channel1, dir))) {

Modified: trunk/apps/confbridge/conf_chan_record.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/confbridge/conf_chan_record.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/apps/confbridge/conf_chan_record.c (original)
+++ trunk/apps/confbridge/conf_chan_record.c Wed Dec 18 13:28:05 2013
@@ -66,6 +66,7 @@
 		return NULL;
 	}
 	if (ast_channel_add_bridge_role(chan, "recorder")) {
+		ast_channel_unlock(chan);
 		ast_channel_release(chan);
 		return NULL;
 	}
@@ -76,6 +77,7 @@
 	ast_format_copy(ast_channel_rawwriteformat(chan), &format);
 	ast_format_copy(ast_channel_readformat(chan), &format);
 	ast_format_copy(ast_channel_rawreadformat(chan), &format);
+	ast_channel_unlock(chan);
 	return chan;
 }
 

Modified: trunk/channels/chan_alsa.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_alsa.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_alsa.c (original)
+++ trunk/channels/chan_alsa.c Wed Dec 18 13:28:05 2013
@@ -602,6 +602,8 @@
 
 	ast_channel_stage_snapshot_done(tmp);
 
+	ast_channel_unlock(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));

Modified: trunk/channels/chan_console.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_console.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_console.c (original)
+++ trunk/channels/chan_console.c Wed Dec 18 13:28:05 2013
@@ -445,6 +445,8 @@
 
 	ast_channel_stage_snapshot_done(chan);
 
+	ast_channel_unlock(chan);
+
 	if (state != AST_STATE_DOWN) {
 		if (ast_pbx_start(chan)) {
 			ast_channel_hangupcause_set(chan, AST_CAUSE_SWITCH_CONGESTION);

Modified: trunk/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_dahdi.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_dahdi.c (original)
+++ trunk/channels/chan_dahdi.c Wed Dec 18 13:28:05 2013
@@ -9096,6 +9096,8 @@
 		pbx_builtin_setvar_helper(tmp, v->name, v->value);
 
 	ast_channel_stage_snapshot_done(tmp);
+
+	ast_channel_unlock(tmp);
 
 	ast_module_ref(ast_module_info->self);
 

Modified: trunk/channels/chan_gtalk.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_gtalk.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_gtalk.c (original)
+++ trunk/channels/chan_gtalk.c Wed Dec 18 13:28:05 2013
@@ -1226,6 +1226,8 @@
 		ast_jb_configure(tmp, &global_jbconf);
 
 	ast_channel_stage_snapshot_done(tmp);
+
+	ast_channel_unlock(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));

Modified: trunk/channels/chan_h323.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_h323.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_h323.c (original)
+++ trunk/channels/chan_h323.c Wed Dec 18 13:28:05 2013
@@ -1139,6 +1139,7 @@
 		}
 		if (pvt->cd.transfer_capability >= 0)
 			ast_channel_transfercapability_set(ch, pvt->cd.transfer_capability);
+		ast_channel_unlock(ch);
 		if (state != AST_STATE_DOWN) {
 			if (ast_pbx_start(ch)) {
 				ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(ch));

Modified: trunk/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_iax2.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_iax2.c (original)
+++ trunk/channels/chan_iax2.c Wed Dec 18 13:28:05 2013
@@ -5694,6 +5694,7 @@
 		if (tmp) {
 			/* unlock and relock iaxsl[callno] to preserve locking order */
 			ast_mutex_unlock(&iaxsl[callno]);
+			ast_channel_unlock(tmp);
 			tmp = ast_channel_release(tmp);
 			ast_mutex_lock(&iaxsl[callno]);
 		}
@@ -5803,6 +5804,8 @@
 	}
 
 	ast_channel_stage_snapshot_done(tmp);
+
+	ast_channel_unlock(tmp);
 
 	if (state != AST_STATE_DOWN) {
 		if (ast_pbx_start(tmp)) {

Modified: trunk/channels/chan_jingle.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_jingle.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_jingle.c (original)
+++ trunk/channels/chan_jingle.c Wed Dec 18 13:28:05 2013
@@ -941,6 +941,8 @@
 		ast_jb_configure(tmp, &global_jbconf);
 
 	ast_channel_stage_snapshot_done(tmp);
+
+	ast_channel_unlock(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));

Modified: trunk/channels/chan_mgcp.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_mgcp.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_mgcp.c (original)
+++ trunk/channels/chan_mgcp.c Wed Dec 18 13:28:05 2013
@@ -1571,6 +1571,8 @@
 
 		ast_channel_stage_snapshot_done(tmp);
 
+		ast_channel_unlock(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));

Modified: trunk/channels/chan_misdn.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_misdn.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_misdn.c (original)
+++ trunk/channels/chan_misdn.c Wed Dec 18 13:28:05 2013
@@ -8226,6 +8226,8 @@
 		ast_channel_rings_set(tmp, (state == AST_STATE_RING) ? 1 : 0);
 
 		ast_jb_configure(tmp, misdn_get_global_jbconf());
+
+		ast_channel_unlock(tmp);
 	} else {
 		chan_misdn_log(-1, 0, "Unable to allocate channel structure\n");
 	}
@@ -8948,6 +8950,8 @@
 	ast_channel_priority_set(chan, notify->priority);
 	ast_free(ast_channel_dialed(chan)->number.str);
 	ast_channel_dialed(chan)->number.str = ast_strdup(notify->exten);
+
+	ast_channel_unlock(chan);
 
 	if (ast_pbx_start(chan)) {
 		ast_log(LOG_WARNING, "Unable to start pbx channel %s!\n", ast_channel_name(chan));

Modified: trunk/channels/chan_motif.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_motif.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_motif.c (original)
+++ trunk/channels/chan_motif.c Wed Dec 18 13:28:05 2013
@@ -853,6 +853,8 @@
 
 	ast_channel_stage_snapshot_done(chan);
 
+	ast_channel_unlock(chan);
+
 	return chan;
 }
 

Modified: trunk/channels/chan_multicast_rtp.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_multicast_rtp.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_multicast_rtp.c (original)
+++ trunk/channels/chan_multicast_rtp.c Wed Dec 18 13:28:05 2013
@@ -166,6 +166,8 @@
 
 	ast_channel_tech_pvt_set(chan, instance);
 
+	ast_channel_unlock(chan);
+
 	return chan;
 
 failure:

Modified: trunk/channels/chan_nbs.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_nbs.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_nbs.c (original)
+++ trunk/channels/chan_nbs.c Wed Dec 18 13:28:05 2013
@@ -239,6 +239,7 @@
 		ast_channel_language_set(tmp, "");
 		i->owner = tmp;
 		i->u = ast_module_user_add(tmp);
+		ast_channel_unlock(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));

Modified: trunk/channels/chan_oss.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_oss.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_oss.c (original)
+++ trunk/channels/chan_oss.c Wed Dec 18 13:28:05 2013
@@ -829,6 +829,7 @@
 	o->owner = c;
 	ast_module_ref(ast_module_info->self);
 	ast_jb_configure(c, &global_jbconf);
+	ast_channel_unlock(c);
 	if (state != AST_STATE_DOWN) {
 		if (ast_pbx_start(c)) {
 			ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(c));

Modified: trunk/channels/chan_phone.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_phone.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_phone.c (original)
+++ trunk/channels/chan_phone.c Wed Dec 18 13:28:05 2013
@@ -901,6 +901,7 @@
 
 		i->owner = tmp;
 		ast_module_ref(ast_module_info->self);
+		ast_channel_unlock(tmp);
 		if (state != AST_STATE_DOWN) {
 			if (state == AST_STATE_RING) {
 				ioctl(ast_channel_fd(tmp, 0), PHONE_RINGBACK);

Modified: trunk/channels/chan_pjsip.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_pjsip.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_pjsip.c (original)
+++ trunk/channels/chan_pjsip.c Wed Dec 18 13:28:05 2013
@@ -359,18 +359,63 @@
 	ast_channel_tech_set(chan, &chan_pjsip_tech);
 
 	if (!(channel = ast_sip_channel_pvt_alloc(pvt, session))) {
+		ast_channel_unlock(chan);
 		ast_hangup(chan);
 		return NULL;
 	}
 
 	ast_channel_stage_snapshot(chan);
+
+	ast_channel_tech_pvt_set(chan, channel);
+
+	if (ast_format_cap_is_empty(session->req_caps) || !ast_format_cap_has_joint(session->req_caps, session->endpoint->media.codecs)) {
+		ast_format_cap_copy(ast_channel_nativeformats(chan), session->endpoint->media.codecs);
+	} else {
+		ast_format_cap_copy(ast_channel_nativeformats(chan), session->req_caps);
+	}
+
+	ast_codec_choose(&session->endpoint->media.prefs, ast_channel_nativeformats(chan), 1, &fmt);
+	ast_format_copy(ast_channel_writeformat(chan), &fmt);
+	ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
+	ast_format_copy(ast_channel_readformat(chan), &fmt);
+	ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
+
+	if (state == AST_STATE_RING) {
+		ast_channel_rings_set(chan, 1);
+	}
+
+	ast_channel_adsicpe_set(chan, AST_ADSI_UNAVAILABLE);
+
+	ast_channel_context_set(chan, session->endpoint->context);
+	ast_channel_exten_set(chan, S_OR(exten, "s"));
+	ast_channel_priority_set(chan, 1);
+
+	ast_channel_callgroup_set(chan, session->endpoint->pickup.callgroup);
+	ast_channel_pickupgroup_set(chan, session->endpoint->pickup.pickupgroup);
+
+	ast_channel_named_callgroups_set(chan, session->endpoint->pickup.named_callgroups);
+	ast_channel_named_pickupgroups_set(chan, session->endpoint->pickup.named_pickupgroups);
+
+	if (!ast_strlen_zero(session->endpoint->language)) {
+		ast_channel_language_set(chan, session->endpoint->language);
+	}
+
+	if (!ast_strlen_zero(session->endpoint->zone)) {
+		struct ast_tone_zone *zone = ast_get_indication_zone(session->endpoint->zone);
+		if (!zone) {
+			ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", session->endpoint->zone);
+		}
+		ast_channel_zone_set(chan, zone);
+	}
+
+	ast_channel_stage_snapshot_done(chan);
+	ast_channel_unlock(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 */
 	pvt->media[SIP_MEDIA_AUDIO] = ao2_find(session->media, "audio", OBJ_KEY);
 	pvt->media[SIP_MEDIA_VIDEO] = ao2_find(session->media, "video", OBJ_KEY);
-	ast_channel_tech_pvt_set(chan, channel);
 	if (pvt->media[SIP_MEDIA_AUDIO] && pvt->media[SIP_MEDIA_AUDIO]->rtp) {
 		ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_AUDIO]->rtp, ast_channel_uniqueid(chan));
 	}
@@ -378,49 +423,7 @@
 		ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_VIDEO]->rtp, ast_channel_uniqueid(chan));
 	}
 
-	if (ast_format_cap_is_empty(session->req_caps) || !ast_format_cap_has_joint(session->req_caps, session->endpoint->media.codecs)) {
-		ast_format_cap_copy(ast_channel_nativeformats(chan), session->endpoint->media.codecs);
-	} else {
-		ast_format_cap_copy(ast_channel_nativeformats(chan), session->req_caps);
-	}
-
-	ast_codec_choose(&session->endpoint->media.prefs, ast_channel_nativeformats(chan), 1, &fmt);
-	ast_format_copy(ast_channel_writeformat(chan), &fmt);
-	ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
-	ast_format_copy(ast_channel_readformat(chan), &fmt);
-	ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
-
-	if (state == AST_STATE_RING) {
-		ast_channel_rings_set(chan, 1);
-	}
-
-	ast_channel_adsicpe_set(chan, AST_ADSI_UNAVAILABLE);
-
-	ast_channel_context_set(chan, session->endpoint->context);
-	ast_channel_exten_set(chan, S_OR(exten, "s"));
-	ast_channel_priority_set(chan, 1);
-
-	ast_channel_callgroup_set(chan, session->endpoint->pickup.callgroup);
-	ast_channel_pickupgroup_set(chan, session->endpoint->pickup.pickupgroup);
-
-	ast_channel_named_callgroups_set(chan, session->endpoint->pickup.named_callgroups);
-	ast_channel_named_pickupgroups_set(chan, session->endpoint->pickup.named_pickupgroups);
-
-	if (!ast_strlen_zero(session->endpoint->language)) {
-		ast_channel_language_set(chan, session->endpoint->language);
-	}
-
-	if (!ast_strlen_zero(session->endpoint->zone)) {
-		struct ast_tone_zone *zone = ast_get_indication_zone(session->endpoint->zone);
-		if (!zone) {
-			ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", session->endpoint->zone);
-		}
-		ast_channel_zone_set(chan, zone);
-	}
-
 	ast_endpoint_add_channel(session->endpoint->persistent, chan);
-
-	ast_channel_stage_snapshot_done(chan);
 
 	return chan;
 }

Modified: trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_sip.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Wed Dec 18 13:28:05 2013
@@ -8100,6 +8100,7 @@
 
 	if (i->relatedpeer && i->relatedpeer->endpoint) {
 		if (ast_endpoint_add_channel(i->relatedpeer->endpoint, tmp)) {
+			ast_channel_unlock(tmp);
 			ast_channel_unref(tmp);
 			sip_pvt_lock(i);
 			return NULL;
@@ -8113,7 +8114,6 @@
 		ast_channel_callid_set(tmp, callid);
 	}
 
-	ast_channel_lock(tmp);
 	sip_pvt_lock(i);
 	ast_channel_cc_params_init(tmp, i->cc_params);
 	ast_channel_caller(tmp)->id.tag = ast_strdup(i->cid_tag);

Modified: trunk/channels/chan_skinny.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_skinny.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_skinny.c (original)
+++ trunk/channels/chan_skinny.c Wed Dec 18 13:28:05 2013
@@ -5393,6 +5393,8 @@
 		sub = ast_calloc(1, sizeof(*sub));
 		if (!sub) {
 			ast_log(LOG_WARNING, "Unable to allocate Skinny subchannel\n");
+			ast_channel_unlock(tmp);
+			ast_channel_unref(tmp);
 			return NULL;
 		} else {
 			ast_mutex_init(&sub->lock);
@@ -5499,6 +5501,8 @@
 			pbx_builtin_setvar_helper(tmp, v->name, v->value);
 
 		ast_channel_stage_snapshot_done(tmp);
+
+		ast_channel_unlock(tmp);
 
 		if (state != AST_STATE_DOWN) {
 			if (ast_pbx_start(tmp)) {

Modified: trunk/channels/chan_unistim.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_unistim.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_unistim.c (original)
+++ trunk/channels/chan_unistim.c Wed Dec 18 13:28:05 2013
@@ -5628,6 +5628,8 @@
 
 	ast_channel_stage_snapshot_done(tmp);
 
+	ast_channel_unlock(tmp);
+
 	if (state != AST_STATE_DOWN) {
 		if (unistimdebug) {
 			ast_verb(0, "Starting pbx in unistim_new\n");

Modified: trunk/channels/chan_vpb.cc
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_vpb.cc?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/channels/chan_vpb.cc (original)
+++ trunk/channels/chan_vpb.cc Wed Dec 18 13:28:05 2013
@@ -2472,6 +2472,8 @@
 		if (!ast_strlen_zero(me->language))
 			ast_channel_language_set(tmp, me->language);
 
+		ast_channel_unlock(tmp);
+
 		me->owner = tmp;
 
 		me->bridge = NULL;

Modified: trunk/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/channel.h?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/include/asterisk/channel.h (original)
+++ trunk/include/asterisk/channel.h Wed Dec 18 13:28:05 2013
@@ -791,7 +791,8 @@
  * active channels in the system.  The hash key is based on the channel name.  Because
  * of this, if you want to change the name, you _must_ use ast_change_name(), not change
  * the name field directly.  When ast_channel_alloc() returns a channel pointer, you now
- * hold a reference to that channel.  In most cases this reference is given to ast_pbx_run().
+ * hold both a reference to that channel and a lock on the channel. Once the channel has
+ * been set up the lock can be released. In most cases the reference is given to ast_pbx_run().
  *
  * \par Channel Locking
  * There is a lock associated with every ast_channel.  It is allocated internally via astobj2.
@@ -1122,6 +1123,7 @@
  * \note Absolutely _NO_ channel locks should be held before calling this function.
  * \note By default, new channels are set to the "s" extension
  *       and "default" context.
+ * \note Since 12.0.0 this function returns with the newly created channel locked.
  */
 struct ast_channel * attribute_malloc __attribute__((format(printf, 13, 14)))
 	__ast_channel_alloc(int needqueue, int state, const char *cid_num,
@@ -1140,6 +1142,7 @@
  * \note Absolutely _NO_ channel locks should be held before calling this function.
  * \note By default, new channels are set to the "s" extension
  *       and "default" context.
+ * \note Since 12.0.0 this function returns with the newly created channel locked.
  */
 #define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, linkedid, amaflag, ...) \
 	__ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, linkedid, amaflag, \

Modified: trunk/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/channel.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Wed Dec 18 13:28:05 2013
@@ -1017,6 +1017,12 @@
 	ast_channel_internal_finalize(tmp);
 
 	ast_atomic_fetchadd_int(&chancount, +1);
+
+	/* You might scream "locking inversion" at seeing this but it is actually perfectly fine.
+	 * Since the channel was just created nothing can know about it yet or even acquire it.
+	 */
+	ast_channel_lock(tmp);
+
 	ao2_link(channels, tmp);
 
 	/*

Modified: trunk/main/core_unreal.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/core_unreal.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/main/core_unreal.c (original)
+++ trunk/main/core_unreal.c Wed Dec 18 13:28:05 2013
@@ -906,57 +906,72 @@
 	 */
 	if (!(owner = ast_channel_alloc(1, semi1_state, NULL, NULL, NULL,
 			exten, context, linkedid, 0,
-			"%s/%s-%08x;1", tech->type, p->name, generated_seqno))
-		|| !(chan = ast_channel_alloc(1, semi2_state, NULL, NULL, NULL,
-			exten, context, ast_channel_linkedid(owner), 0,
-			"%s/%s-%08x;2", tech->type, p->name, generated_seqno))) {
-		if (owner) {
-			owner = ast_channel_release(owner);
-		}
-		ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
+			"%s/%s-%08x;1", tech->type, p->name, generated_seqno))) {
+		ast_log(LOG_WARNING, "Unable to allocate owner channel structure\n");
 		return NULL;
 	}
 
 	if (callid) {
 		ast_channel_callid_set(owner, callid);
-		ast_channel_callid_set(chan, callid);
 	}
 
 	ast_channel_tech_set(owner, tech);
-	ast_channel_tech_set(chan, tech);
+	ao2_ref(p, +1);
 	ast_channel_tech_pvt_set(owner, p);
-	ast_channel_tech_pvt_set(chan, p);
 
 	ast_format_cap_copy(ast_channel_nativeformats(owner), p->reqcap);
-	ast_format_cap_copy(ast_channel_nativeformats(chan), p->reqcap);
 
 	/* Determine our read/write format and set it on each channel */
 	ast_best_codec(p->reqcap, &fmt);
 	ast_format_copy(ast_channel_writeformat(owner), &fmt);
-	ast_format_copy(ast_channel_writeformat(chan), &fmt);
 	ast_format_copy(ast_channel_rawwriteformat(owner), &fmt);
-	ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
 	ast_format_copy(ast_channel_readformat(owner), &fmt);
-	ast_format_copy(ast_channel_readformat(chan), &fmt);
 	ast_format_copy(ast_channel_rawreadformat(owner), &fmt);
-	ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
 
 	ast_set_flag(ast_channel_flags(owner), AST_FLAG_DISABLE_DEVSTATE_CACHE);
-	ast_set_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE);
 
 	ast_jb_configure(owner, &p->jb_conf);
 
 	if (ast_channel_cc_params_init(owner, requestor
 		? ast_channel_get_cc_config_params((struct ast_channel *) requestor) : NULL)) {
+		ao2_ref(p, -1);
+		ast_channel_unlock(owner);
 		ast_channel_release(owner);
-		ast_channel_release(chan);
 		return NULL;
 	}
 
-	/* Give the private a ref for each channel. */
-	ao2_ref(p, +2);
 	p->owner = owner;
+	ast_channel_unlock(owner);
+
+	if (!(chan = ast_channel_alloc(1, semi2_state, NULL, NULL, NULL,
+			exten, context, ast_channel_linkedid(owner), 0,
+			"%s/%s-%08x;2", tech->type, p->name, generated_seqno))) {
+		ast_log(LOG_WARNING, "Unable to allocate chan channel structure\n");
+		ao2_ref(p, -1);
+		ast_channel_release(owner);
+		return NULL;
+	}
+
+	if (callid) {
+		ast_channel_callid_set(chan, callid);
+	}
+
+	ast_channel_tech_set(chan, tech);
+	ao2_ref(p, +1);
+	ast_channel_tech_pvt_set(chan, p);
+
+	ast_format_cap_copy(ast_channel_nativeformats(chan), p->reqcap);
+
+	/* Format was already determined when setting up owner */
+	ast_format_copy(ast_channel_writeformat(chan), &fmt);
+	ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
+	ast_format_copy(ast_channel_readformat(chan), &fmt);
+	ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
+
+	ast_set_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+
 	p->chan = chan;
+	ast_channel_unlock(chan);
 
 	return owner;
 }

Modified: trunk/main/message.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/message.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/main/message.c (original)
+++ trunk/main/message.c Wed Dec 18 13:28:05 2013
@@ -678,9 +678,9 @@
 		return NULL;
 	}
 
+	ast_channel_tech_set(chan, &msg_chan_tech_hack);
+	ast_channel_unlock(chan);
 	ast_channel_unlink(chan);
-
-	ast_channel_tech_set(chan, &msg_chan_tech_hack);
 
 	if (!(ds = ast_datastore_alloc(&msg_datastore, NULL))) {
 		ast_hangup(chan);

Modified: trunk/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/pbx.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/main/pbx.c (original)
+++ trunk/main/pbx.c Wed Dec 18 13:28:05 2013
@@ -10365,6 +10365,8 @@
 			snprintf(failed_reason, sizeof(failed_reason), "%d", ast_dial_reason(outgoing->dial, 0));
 			pbx_builtin_setvar_helper(failed, "REASON", failed_reason);
 
+			ast_channel_unlock(failed);
+
 			if (ast_pbx_run(failed)) {
 				ast_log(LOG_ERROR, "Unable to run PBX on '%s'\n", ast_channel_name(failed));
 				ast_hangup(failed);

Modified: trunk/res/parking/parking_tests.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/parking/parking_tests.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/res/parking/parking_tests.c (original)
+++ trunk/res/parking/parking_tests.c Wed Dec 18 13:28:05 2013
@@ -63,6 +63,8 @@
 
 	ast_channel_set_caller(alice, &alice_callerid, NULL);
 
+	ast_channel_unlock(alice);
+
 	return alice;
 }
 

Modified: trunk/res/res_calendar.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_calendar.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/res/res_calendar.c (original)
+++ trunk/res/res_calendar.c Wed Dec 18 13:28:05 2013
@@ -766,6 +766,8 @@
 	/* clear native formats and set to slinear. write format is signlear so just use that to set it */
 	ast_format_cap_set(ast_channel_nativeformats(chan), ast_channel_writeformat(chan));
 
+	ast_channel_unlock(chan);
+
 	if (!(datastore = ast_datastore_alloc(&event_notification_datastore, NULL))) {
 		ast_log(LOG_ERROR, "Could not allocate datastore, notification not being sent!\n");
 		goto notify_cleanup;

Modified: trunk/res/res_stasis_snoop.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_stasis_snoop.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/res/res_stasis_snoop.c (original)
+++ trunk/res/res_stasis_snoop.c Wed Dec 18 13:28:05 2013
@@ -274,12 +274,21 @@
 	return ast_audiohook_attach(chan, audiohook);
 }
 
+/*! \brief Helper function which gets the format for a Snoop channel based on the channel being snooped on */
+static void snoop_determine_format(struct ast_channel *chan, struct stasis_app_snoop *snoop)
+{
+	SCOPED_CHANNELLOCK(lock, chan);
+	unsigned int rate = MAX(ast_format_rate(ast_channel_rawwriteformat(chan)),
+		ast_format_rate(ast_channel_rawreadformat(chan)));
+
+	ast_format_set(&snoop->spy_format, ast_format_slin_by_rate(rate), 0);
+}
+
 struct ast_channel *stasis_app_control_snoop(struct ast_channel *chan,
 	enum stasis_app_snoop_direction spy, enum stasis_app_snoop_direction whisper,
 	const char *app, const char *app_args)
 {
 	RAII_VAR(struct stasis_app_snoop *, snoop, NULL, ao2_cleanup);
-	unsigned int rate;
 	pthread_t thread;
 
 	if (spy == STASIS_SNOOP_DIRECTION_NONE &&
@@ -309,6 +318,9 @@
 		return NULL;
 	}
 	ast_timer_set_rate(snoop->timer, 1000 / SNOOP_INTERVAL);
+
+	/* Determine which signed linear format should be used */
+	snoop_determine_format(chan, snoop);
 
 	/* Allocate a Snoop channel and set up various parameters */
 	snoop->chan = ast_channel_alloc(1, AST_STATE_UP, "", "", "", "", "", "", 0, "Snoop/%s-%08x", ast_channel_uniqueid(chan),
@@ -327,39 +339,33 @@
 	ast_channel_tech_pvt_set(snoop->chan, snoop);
 	ast_channel_set_fd(snoop->chan, 0, ast_timer_fd(snoop->timer));
 
-	{
-		SCOPED_CHANNELLOCK(lock, chan);
-
-		/* Determine the "best" signed linear format capable by the channel we are snooping on */
-		rate = MAX(ast_format_rate(ast_channel_rawwriteformat(chan)), ast_format_rate(ast_channel_rawreadformat(chan)));
-		ast_format_set(&snoop->spy_format, ast_format_slin_by_rate(rate), 0);
-
-		/* The format on the Snoop channel will be this signed linear format, and it will never change */
-		ast_format_cap_set(ast_channel_nativeformats(snoop->chan), &snoop->spy_format);
-		ast_format_copy(ast_channel_writeformat(snoop->chan), &snoop->spy_format);
-		ast_format_copy(ast_channel_rawwriteformat(snoop->chan), &snoop->spy_format);
-		ast_format_copy(ast_channel_readformat(snoop->chan), &snoop->spy_format);
-		ast_format_copy(ast_channel_rawreadformat(snoop->chan), &snoop->spy_format);
-
-		if (spy != STASIS_SNOOP_DIRECTION_NONE) {
-			if (snoop_setup_audiohook(chan, AST_AUDIOHOOK_TYPE_SPY, spy, &snoop->spy_direction, &snoop->spy)) {
-				ast_hangup(snoop->chan);
-				return NULL;
-			}
-
-			snoop->spy_samples = rate / (1000 / SNOOP_INTERVAL);
-			snoop->spy_active = 1;
+	/* The format on the Snoop channel will be this signed linear format, and it will never change */
+	ast_format_cap_set(ast_channel_nativeformats(snoop->chan), &snoop->spy_format);
+	ast_format_copy(ast_channel_writeformat(snoop->chan), &snoop->spy_format);
+	ast_format_copy(ast_channel_rawwriteformat(snoop->chan), &snoop->spy_format);
+	ast_format_copy(ast_channel_readformat(snoop->chan), &snoop->spy_format);
+	ast_format_copy(ast_channel_rawreadformat(snoop->chan), &snoop->spy_format);
+
+	ast_channel_unlock(snoop->chan);
+
+	if (spy != STASIS_SNOOP_DIRECTION_NONE) {
+		if (snoop_setup_audiohook(chan, AST_AUDIOHOOK_TYPE_SPY, spy, &snoop->spy_direction, &snoop->spy)) {
+			ast_hangup(snoop->chan);
+			return NULL;
 		}
 
-		/* If whispering is enabled set up the audiohook */
-		if (whisper != STASIS_SNOOP_DIRECTION_NONE) {
-			if (snoop_setup_audiohook(chan, AST_AUDIOHOOK_TYPE_WHISPER, whisper, &snoop->whisper_direction, &snoop->whisper)) {
-				ast_hangup(snoop->chan);
-				return NULL;
-			}
-
-			snoop->whisper_active = 1;
+		snoop->spy_samples = ast_format_rate(&snoop->spy_format) / (1000 / SNOOP_INTERVAL);
+		snoop->spy_active = 1;
+	}
+
+	/* If whispering is enabled set up the audiohook */
+	if (whisper != STASIS_SNOOP_DIRECTION_NONE) {
+		if (snoop_setup_audiohook(chan, AST_AUDIOHOOK_TYPE_WHISPER, whisper, &snoop->whisper_direction, &snoop->whisper)) {
+			ast_hangup(snoop->chan);
+			return NULL;
 		}
+
+		snoop->whisper_active = 1;
 	}
 
 	/* Create the thread which services the Snoop channel */

Modified: trunk/tests/test_app.c
URL: http://svnview.digium.com/svn/asterisk/trunk/tests/test_app.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/tests/test_app.c (original)
+++ trunk/tests/test_app.c Wed Dec 18 13:28:05 2013
@@ -175,21 +175,25 @@
 		"'%s', '%s', '%s', '%s'\n", group1_full, group2_full, category1_full, category2_full);
 
 	if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
-        NULL, NULL, 0, 0, "TestChannel1"))) {
-		goto exit_group_test;
-	}
+		NULL, NULL, 0, 0, "TestChannel1"))) {
+		goto exit_group_test;
+	}
+	ast_channel_unlock(test_channel1);
 	if (!(test_channel2 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
-        NULL, NULL, 0, 0, "TestChannel2"))) {
-		goto exit_group_test;
-	}
+		NULL, NULL, 0, 0, "TestChannel2"))) {
+		goto exit_group_test;
+	}
+	ast_channel_unlock(test_channel2);
 	if (!(test_channel3 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
-        NULL, NULL, 0, 0, "TestChannel3"))) {
-		goto exit_group_test;
-	}
+		NULL, NULL, 0, 0, "TestChannel3"))) {
+		goto exit_group_test;
+	}
+	ast_channel_unlock(test_channel3);
 	if (!(test_channel4 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
-        NULL, NULL, 0, 0, "TestChannel4"))) {
-		goto exit_group_test;
-	}
+		NULL, NULL, 0, 0, "TestChannel4"))) {
+		goto exit_group_test;
+	}
+	ast_channel_unlock(test_channel4);
 
 	ast_app_group_set_channel(test_channel1, group1_full);
 	ast_app_group_set_channel(test_channel2, group2_full);

Modified: trunk/tests/test_cdr.c
URL: http://svnview.digium.com/svn/asterisk/trunk/tests/test_cdr.c?view=diff&rev=404210&r1=404209&r2=404210
==============================================================================
--- trunk/tests/test_cdr.c (original)
+++ trunk/tests/test_cdr.c Wed Dec 18 13:28:05 2013
@@ -238,6 +238,7 @@
 	ast_channel_set_caller((channel_var), (caller_id), NULL); \
 	ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
 	ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
+	ast_channel_unlock((channel_var)); \
 	} while (0)
 
 /*! \brief Create a \ref test_cdr_chan_tech for Bob, and set the expected
@@ -247,6 +248,7 @@
 	ast_channel_set_caller((channel_var), (caller_id), NULL); \
 	ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
 	ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
+	ast_channel_unlock((channel_var)); \
 	} while (0)
 
 /*! \brief Create a \ref test_cdr_chan_tech for Charlie, and set the expected
@@ -256,6 +258,7 @@
 	ast_channel_set_caller((channel_var), (caller_id), NULL); \
 	ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
 	ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
+	ast_channel_unlock((channel_var)); \
 	} while (0)
 
 /*! \brief Create a \ref test_cdr_chan_tech for Charlie, and set the expected
@@ -265,6 +268,7 @@
 	ast_channel_set_caller((channel_var), (caller_id), NULL); \
 	ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
 	ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
+	ast_channel_unlock((channel_var)); \
 	} while (0)
 
 /*! \brief Emulate a channel entering into an application */
@@ -563,6 +567,7 @@
 	ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
 
 	chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_alice), 0, CHANNEL_TECH_NAME "/Bob");
+	ast_channel_unlock(chan_bob);
 	ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_bob), sizeof(bob_expected.linkedid));
 	ast_copy_string(bob_expected.uniqueid, ast_channel_uniqueid(chan_bob), sizeof(bob_expected.uniqueid));
 	ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING);
@@ -1133,6 +1138,7 @@
 	EMULATE_APP_DATA(chan_caller, 1, "Dial", "CDRTestChannel/Bob");
 
 	chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
+	ast_channel_unlock(chan_callee);
 	ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
 	EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
 
@@ -1194,6 +1200,7 @@
 	EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
 
 	chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
+	ast_channel_unlock(chan_callee);
 	ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
 	EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
 
@@ -1254,6 +1261,7 @@
 	EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
 
 	chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
+	ast_channel_unlock(chan_callee);
 	ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
 	EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
 

[... 189 lines stripped ...]



More information about the asterisk-commits mailing list