[asterisk-commits] dlee: branch dlee/stasis-http r385746 - in /team/dlee/stasis-http: ./ apps/ b...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Apr 15 12:12:28 CDT 2013


Author: dlee
Date: Mon Apr 15 12:12:23 2013
New Revision: 385746

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=385746
Log:
Merged revisions 385142-385718 from http://svn.asterisk.org/svn/asterisk/trunk

Modified:
    team/dlee/stasis-http/   (props changed)
    team/dlee/stasis-http/BSDmakefile   (props changed)
    team/dlee/stasis-http/apps/app_queue.c
    team/dlee/stasis-http/apps/app_saycounted.c   (props changed)
    team/dlee/stasis-http/apps/app_voicemail.c
    team/dlee/stasis-http/build_tools/sha1sum-sh   (props changed)
    team/dlee/stasis-http/channels/chan_alsa.c
    team/dlee/stasis-http/channels/chan_iax2.c
    team/dlee/stasis-http/channels/chan_multicast_rtp.c   (props changed)
    team/dlee/stasis-http/channels/chan_sip.c
    team/dlee/stasis-http/channels/sig_ss7.c   (props changed)
    team/dlee/stasis-http/channels/sig_ss7.h   (props changed)
    team/dlee/stasis-http/channels/sip/include/security_events.h   (props changed)
    team/dlee/stasis-http/channels/sip/security_events.c   (props changed)
    team/dlee/stasis-http/codecs/codec_resample.c
    team/dlee/stasis-http/configs/cli_aliases.conf.sample
    team/dlee/stasis-http/configs/res_curl.conf.sample   (props changed)
    team/dlee/stasis-http/contrib/realtime/mysql/musiconhold.sql   (props changed)
    team/dlee/stasis-http/contrib/realtime/mysql/queue_log.sql   (props changed)
    team/dlee/stasis-http/contrib/realtime/mysql/voicemail_data.sql   (props changed)
    team/dlee/stasis-http/contrib/realtime/mysql/voicemail_messages.sql   (props changed)
    team/dlee/stasis-http/doc/Makefile   (props changed)
    team/dlee/stasis-http/include/asterisk/bridging_features.h   (props changed)
    team/dlee/stasis-http/include/asterisk/bridging_technology.h   (props changed)
    team/dlee/stasis-http/include/asterisk/manager.h
    team/dlee/stasis-http/include/asterisk/select.h   (props changed)
    team/dlee/stasis-http/include/asterisk/sorcery.h
    team/dlee/stasis-http/main/features.c
    team/dlee/stasis-http/main/manager.c
    team/dlee/stasis-http/main/manager_channels.c
    team/dlee/stasis-http/main/stasis_channels.c
    team/dlee/stasis-http/res/res_config_ldap.c
    team/dlee/stasis-http/res/res_mutestream.c   (contents, props changed)
    team/dlee/stasis-http/res/res_rtp_multicast.c   (contents, props changed)
    team/dlee/stasis-http/res/res_timing_kqueue.c   (props changed)
    team/dlee/stasis-http/tests/test_expr.c   (props changed)
    team/dlee/stasis-http/tests/test_func_file.c   (props changed)
    team/dlee/stasis-http/tests/test_locale.c   (props changed)
    team/dlee/stasis-http/tests/test_poll.c   (props changed)

Propchange: team/dlee/stasis-http/
------------------------------------------------------------------------------
--- branch-11-blocked (original)
+++ branch-11-blocked Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-/branches/11:373240,375247,375702
+/branches/11:373240,375247,375702,385356

Propchange: team/dlee/stasis-http/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.

Propchange: team/dlee/stasis-http/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-/trunk:1-385119
+/trunk:1-385718

Propchange: team/dlee/stasis-http/BSDmakefile
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Date Author Id Revision Yoyo'
+Author Date Id Revision

Modified: team/dlee/stasis-http/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/apps/app_queue.c?view=diff&rev=385746&r1=385745&r2=385746
==============================================================================
--- team/dlee/stasis-http/apps/app_queue.c (original)
+++ team/dlee/stasis-http/apps/app_queue.c Mon Apr 15 12:12:23 2013
@@ -9857,6 +9857,9 @@
 	res |= ast_manager_unregister("QueuePause");
 	res |= ast_manager_unregister("QueueLog");
 	res |= ast_manager_unregister("QueuePenalty");
+	res |= ast_manager_unregister("QueueReload");
+	res |= ast_manager_unregister("QueueReset");
+	res |= ast_manager_unregister("QueueMemberRingInUse");
 	res |= ast_unregister_application(app_aqm);
 	res |= ast_unregister_application(app_rqm);
 	res |= ast_unregister_application(app_pqm);

Propchange: team/dlee/stasis-http/apps/app_saycounted.c
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Date Author Id Revision Yoyo'
+Author Date Id Revision

Modified: team/dlee/stasis-http/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/apps/app_voicemail.c?view=diff&rev=385746&r1=385745&r2=385746
==============================================================================
--- team/dlee/stasis-http/apps/app_voicemail.c (original)
+++ team/dlee/stasis-http/apps/app_voicemail.c Mon Apr 15 12:12:23 2013
@@ -1719,6 +1719,14 @@
 	return res;
 }
 
+/*!
+ * \brief Check if configuration file is valid
+ */
+static inline int valid_config(const struct ast_config *cfg)
+{
+	return cfg && cfg != CONFIG_STATUS_FILEINVALID;
+}
+
 /*! 
  * \brief The handler for the change password option.
  * \param vmu The voicemail user to work with.
@@ -1755,7 +1763,7 @@
 		}
 		/* Fall-through */
 	case OPT_PWLOC_VOICEMAILCONF:
-		if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) {
+		if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && valid_config(cfg)) {
 			while ((category = ast_category_browse(cfg, category))) {
 				if (!strcasecmp(category, vmu->context)) {
 					if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) {
@@ -1784,14 +1792,17 @@
 				reset_user_pw(vmu->context, vmu->mailbox, newpassword);
 				ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
 				ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
+				ast_config_destroy(cfg);
 				break;
 			}
+
+			ast_config_destroy(cfg);
 		}
 		/* Fall-through */
 	case OPT_PWLOC_USERSCONF:
 		/* check users.conf and update the password stored for the mailbox */
 		/* if no vmsecret entry exists create one. */
-		if ((cfg = ast_config_load("users.conf", config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) {
+		if ((cfg = ast_config_load("users.conf", config_flags)) && valid_config(cfg)) {
 			ast_debug(4, "we are looking for %s\n", vmu->mailbox);
 			for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) {
 				ast_debug(4, "users.conf: %s\n", category);
@@ -1825,6 +1836,8 @@
 				ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
 				ast_config_text_file_save("users.conf", cfg, "AppVoicemail");
 			}
+
+			ast_config_destroy(cfg);
 		}
 	}
 }
@@ -4179,7 +4192,7 @@
 			res = -1;
 			break;
 		}
-		if (cfg && cfg != CONFIG_STATUS_FILEINVALID) {
+		if (valid_config(cfg)) {
 			if (!(idata.context = ast_variable_retrieve(cfg, "message", "context"))) {
 				idata.context = "";
 			}
@@ -4235,7 +4248,7 @@
 	if (obj) {
 		ast_odbc_release_obj(obj);
 	}
-	if (cfg)
+	if (valid_config(cfg))
 		ast_config_destroy(cfg);
 	if (fdm != MAP_FAILED)
 		munmap(fdm, fdlen);
@@ -4714,7 +4727,7 @@
 	if (strlen(fromfile) < sizeof(fromfile) - 5) {
 		strcat(fromfile, ".txt");
 	}
-	if (!(msg_cfg = ast_config_load(fromfile, config_flags))) {
+	if (!(msg_cfg = ast_config_load(fromfile, config_flags)) || !(valid_config(msg_cfg))) {
 		ast_debug(1, "Config load for message text file '%s' failed\n", fromfile);
 		return;
 	}
@@ -5106,7 +5119,7 @@
 			if (strlen(fromfile) < sizeof(fromfile) - 5) {
 				strcat(fromfile, ".txt");
 			}
-			if ((msg_cfg = ast_config_load(fromfile, config_flags))) {
+			if ((msg_cfg = ast_config_load(fromfile, config_flags)) && valid_config(msg_cfg)) {
 				if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
 					ast_copy_string(origcallerid, v, sizeof(origcallerid));
 				}
@@ -7592,7 +7605,7 @@
 	strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
 	strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1);
 
-	if ((msg_cfg = ast_config_load(textfile, config_flags)) && msg_cfg != CONFIG_STATUS_FILEINVALID && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) {
+	if ((msg_cfg = ast_config_load(textfile, config_flags)) && valid_config(msg_cfg) && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) {
 		*duration = atoi(duration_str);
 	} else {
 		*duration = 0;
@@ -7628,7 +7641,7 @@
 			*duration = 0;
 
 			/* if we can't read the message metadata, stop now */
-			if (!msg_cfg) {
+			if (!valid_config(msg_cfg)) {
 				cmd = 0;
 				break;
 			}
@@ -7712,7 +7725,7 @@
 		}
 	}
 
-	if (msg_cfg)
+	if (valid_config(msg_cfg))
 		ast_config_destroy(msg_cfg);
 	if (prepend_duration)
 		*duration = prepend_duration;
@@ -8463,7 +8476,7 @@
 	snprintf(filename, sizeof(filename), "%s.txt", vms->fn);
 	RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context);
 	msg_cfg = ast_config_load(filename, config_flags);
-	if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) {
+	if (!valid_config(msg_cfg)) {
 		ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
 		return 0;
 	}
@@ -8541,7 +8554,7 @@
 		}
 	}
 
-	if (!msg_cfg) {
+	if (!valid_config(msg_cfg)) {
 		ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
 		return 0;
 	}
@@ -13637,7 +13650,7 @@
 	struct ast_flags config_flags = { 0 };
 
 	pwconf = ast_config_load(secretfn, config_flags);
-	if (pwconf) {
+	if (valid_config(pwconf)) {
 		const char *val = ast_variable_retrieve(pwconf, "general", "password");
 		if (val) {
 			ast_copy_string(password, val, passwordlen);
@@ -14124,7 +14137,7 @@
 	fputs("00000002 => 9999,Mrs. Test\n", file);
 	fclose(file);
 
-	if (!(cfg = ast_config_load(config_filename, config_flags))) {
+	if (!(cfg = ast_config_load(config_filename, config_flags)) || !valid_config(cfg)) {
 		res = AST_TEST_FAIL;
 		goto cleanup;
 	}
@@ -14454,7 +14467,7 @@
 	RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context);
 	msg_cfg = ast_config_load(filename, config_flags);
 	DISPOSE(vms->curdir, vms->curmsg);
-	if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) {
+	if (!valid_config(msg_cfg)) {
 		ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
 		return 0;
 	}
@@ -14616,9 +14629,9 @@
 		break;
 	}
 
+	ast_config_destroy(msg_cfg);
+
 #ifndef IMAP_STORAGE
-	ast_config_destroy(msg_cfg);
-
 	if (!res) {
 		make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
 		vms->heard[msg] = 1;

Propchange: team/dlee/stasis-http/build_tools/sha1sum-sh
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Date Author Id Revision Yoyo'
+Author Date Id Revision

Modified: team/dlee/stasis-http/channels/chan_alsa.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/channels/chan_alsa.c?view=diff&rev=385746&r1=385745&r2=385746
==============================================================================
--- team/dlee/stasis-http/channels/chan_alsa.c (original)
+++ team/dlee/stasis-http/channels/chan_alsa.c Mon Apr 15 12:12:23 2013
@@ -483,6 +483,13 @@
 	} else if (r < 0) {
 		ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r));
 	}
+
+	/* Return NULL frame on error */
+	if (r < 0) {
+		ast_mutex_unlock(&alsalock);
+		return &f;
+	}
+
 	/* Update positions */
 	readpos += r;
 	left -= r;

Modified: team/dlee/stasis-http/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/channels/chan_iax2.c?view=diff&rev=385746&r1=385745&r2=385746
==============================================================================
--- team/dlee/stasis-http/channels/chan_iax2.c (original)
+++ team/dlee/stasis-http/channels/chan_iax2.c Mon Apr 15 12:12:23 2013
@@ -9514,6 +9514,9 @@
 
 	if (!cur_pkt_buf)
 		AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
+
+	to_here->iostate = IAX_IOSTATE_READY;
+	ast_cond_signal(&to_here->cond);
 
 	ast_mutex_unlock(&to_here->lock);
 }
@@ -12232,16 +12235,26 @@
 			ast_cond_init(&thread->cond, NULL);
 			ast_mutex_init(&thread->init_lock);
 			ast_cond_init(&thread->init_cond, NULL);
+
+			ast_mutex_lock(&thread->init_lock);
+
 			if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
 				ast_log(LOG_WARNING, "Failed to create new thread!\n");
 				ast_mutex_destroy(&thread->lock);
 				ast_cond_destroy(&thread->cond);
+				ast_mutex_unlock(&thread->init_lock);
 				ast_mutex_destroy(&thread->init_lock);
 				ast_cond_destroy(&thread->init_cond);
 				ast_free(thread);
 				thread = NULL;
 				continue;
 			}
+			/* Wait for the thread to be ready */
+			ast_cond_wait(&thread->init_cond, &thread->init_lock);
+
+			/* Done with init_lock */
+			ast_mutex_unlock(&thread->init_lock);
+
 			AST_LIST_LOCK(&idle_list);
 			AST_LIST_INSERT_TAIL(&idle_list, thread, list);
 			AST_LIST_UNLOCK(&idle_list);

Propchange: team/dlee/stasis-http/channels/chan_multicast_rtp.c
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Author Date Id Revision'
+Author Date Id Revision

Modified: team/dlee/stasis-http/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/channels/chan_sip.c?view=diff&rev=385746&r1=385745&r2=385746
==============================================================================
--- team/dlee/stasis-http/channels/chan_sip.c (original)
+++ team/dlee/stasis-http/channels/chan_sip.c Mon Apr 15 12:12:23 2013
@@ -1273,6 +1273,8 @@
 static void ast_quiet_chan(struct ast_channel *chan);
 static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target);
 static int do_magic_pickup(struct ast_channel *channel, const char *extension, const char *context);
+static void set_peer_nat(const struct sip_pvt *p, struct sip_peer *peer);
+static void check_for_nat(const struct ast_sockaddr *them, struct sip_pvt *p);
 
 /*--- Device monitoring and Device/extension state/event handling */
 static int extensionstate_update(const char *context, const char *exten, struct state_notify_data *data, struct sip_pvt *p, int force);
@@ -7352,6 +7354,11 @@
 	int res = 0;
 	struct sip_pvt *p = ast_channel_tech_pvt(ast);
 
+	if (!p) {
+		ast_debug(1, "Asked to answer channel %s without tech pvt; ignoring\n",
+				ast_channel_name(ast));
+		return res;
+	}
 	sip_pvt_lock(p);
 	if (ast_channel_state(ast) != AST_STATE_UP) {
 		try_suggested_sip_codec(p);
@@ -7521,6 +7528,12 @@
 	struct sip_pvt *p = ast_channel_tech_pvt(ast);
 	int res = 0;
 
+	if (!p) {
+		ast_debug(1, "Asked to begin DTMF digit on channel %s with no pvt; ignoring\n",
+				ast_channel_name(ast));
+		return res;
+	}
+
 	sip_pvt_lock(p);
 	switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
 	case SIP_DTMF_INBAND:
@@ -7544,6 +7557,12 @@
 {
 	struct sip_pvt *p = ast_channel_tech_pvt(ast);
 	int res = 0;
+
+	if (!p) {
+		ast_debug(1, "Asked to end DTMF digit on channel %s with no pvt; ignoring\n",
+				ast_channel_name(ast));
+		return res;
+	}
 
 	sip_pvt_lock(p);
 	switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
@@ -7570,6 +7589,12 @@
 	struct sip_pvt *p = ast_channel_tech_pvt(ast);
 	int res;
 
+	if (!p) {
+		ast_debug(1, "Asked to transfer channel %s with no pvt; ignoring\n",
+				ast_channel_name(ast));
+		return -1;
+	}
+
 	if (dest == NULL)	/* functions below do not take a NULL */
 		dest = "";
 	sip_pvt_lock(p);
@@ -7764,6 +7789,12 @@
 {
 	struct sip_pvt *p = ast_channel_tech_pvt(ast);
 	int res = 0;
+
+	if (!p) {
+		ast_debug(1, "Asked to indicate condition on channel %s with no pvt; ignoring\n",
+				ast_channel_name(ast));
+		return res;
+	}
 
 	sip_pvt_lock(p);
 	switch(condition) {
@@ -17078,22 +17109,12 @@
 			ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
 			res = AUTH_PEER_NOT_DYNAMIC;
 		} else {
-			if (ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
-				if (p->natdetected) {
-					ast_set_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT);
-				} else {
-					ast_clear_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT);
-				}
-			}
-			if (ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA)) {
-				if (p->natdetected) {
-					ast_set_flag(&peer->flags[1], SIP_PAGE2_SYMMETRICRTP);
-				} else {
-					ast_clear_flag(&peer->flags[1], SIP_PAGE2_SYMMETRICRTP);
-				}
-			}
-
-			ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT_FORCE_RPORT);
+
+			set_peer_nat(p, peer);
+			if (p->natdetected && ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
+				ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT_FORCE_RPORT);
+			}
+
 			if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri2, XMIT_UNRELIABLE))) {
 				if (sip_cancel_destroy(p))
 					ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
@@ -18122,6 +18143,67 @@
 	return -1;
 }
 
+/*! \brief Set the peers nat flags if they are using auto_* settings */
+static void set_peer_nat(const struct sip_pvt *p, struct sip_peer *peer)
+{
+
+	if (!p || !peer) {
+		return;
+	}
+
+	if (ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
+		if (p->natdetected) {
+			ast_set_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT);
+		} else {
+			ast_clear_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT);
+		}
+	}
+
+	if (ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA)) {
+		if (p->natdetected) {
+			ast_set_flag(&peer->flags[1], SIP_PAGE2_SYMMETRICRTP);
+		} else {
+			ast_clear_flag(&peer->flags[1], SIP_PAGE2_SYMMETRICRTP);
+		}
+	}
+}
+
+/*! \brief Check and see if the requesting UA is likely to be behind a NAT.
+ *
+ * If the requesting NAT is behind NAT, set the * natdetected flag so that
+ * later, peers with nat=auto_* can use the value. Also, set the flags so
+ * that Asterisk responds identically whether or not a peer exists so as
+ * not to leak peer name information.
+ */
+static void check_for_nat(const struct ast_sockaddr *addr, struct sip_pvt *p)
+{
+
+	if (!addr || !p) {
+		return;
+	}
+
+	if (ast_sockaddr_cmp(addr, &p->recv)) {
+		char *tmp_str = ast_strdupa(ast_sockaddr_stringify(addr));
+		ast_debug(3, "NAT detected for %s / %s\n", tmp_str, ast_sockaddr_stringify(&p->recv));
+		p->natdetected = 1;
+		if (ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
+			ast_set_flag(&p->flags[0], SIP_NAT_FORCE_RPORT);
+		}
+		if (ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA)) {
+			ast_set_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
+		}
+	} else {
+		p->natdetected = 0;
+		if (ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
+			ast_clear_flag(&p->flags[0], SIP_NAT_FORCE_RPORT);
+		}
+		if (ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA)) {
+			ast_clear_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
+		}
+	}
+
+}
+
 /*! \brief check Via: header for hostname, port and rport request/answer */
 static void check_via(struct sip_pvt *p, const struct sip_request *req)
 {
@@ -18185,29 +18267,7 @@
 
 		ast_sockaddr_set_port(&p->sa, port);
 
-		/* Check and see if the requesting UA is likely to be behind a NAT. If they are, set the
-		 * natdetected flag so that later, peers with nat=auto_* can use the value. Also
-		 * set the flags so that Asterisk responds identically whether or not a peer exists
-		 * so as not to leak peer name information. */
-		if (ast_sockaddr_cmp(&tmp, &p->recv)) {
-			char *tmp_str = ast_strdupa(ast_sockaddr_stringify(&tmp));
-			ast_debug(3, "NAT detected for %s / %s\n", tmp_str, ast_sockaddr_stringify(&p->recv));
-			p->natdetected = 1;
-			if (ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
-				ast_set_flag(&p->flags[0], SIP_NAT_FORCE_RPORT);
-			}
-			if (ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA)) {
-				ast_set_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
-			}
-		} else {
-			p->natdetected = 0;
-			if (ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
-				ast_clear_flag(&p->flags[0], SIP_NAT_FORCE_RPORT);
-			}
-			if (ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA)) {
-				ast_clear_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
-			}
-		}
+		check_for_nat(&tmp, p);
 
 		if (sip_debug_test_pvt(p)) {
 			ast_verbose("Sending to %s (%s)\n",
@@ -18275,13 +18335,10 @@
 	 *  are set on the peer.  So we check for that here and set the peer's
 	 *  address accordingly.
 	 */
+	set_peer_nat(p, peer);
+
 	if (p->natdetected && ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
-		ast_set_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT);
 		ast_sockaddr_copy(&peer->addr, &p->recv);
-	}
-
-	if (p->natdetected && ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA)) {
-		ast_set_flag(&peer->flags[1], SIP_PAGE2_SYMMETRICRTP);
 	}
 
 	if (!ast_apply_acl(peer->acl, addr, "SIP Peer ACL: ")) {
@@ -29982,6 +30039,22 @@
 		ast_string_field_set(p, peername, ext);
 	/* Recalculate our side, and recalculate Call ID */
 	ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
+	/* When chan_sip is first loaded, we may have a peer entry but it hasn't re-registered yet.
+	   If the peer hasn't re-registered, we have not checked for NAT yet.  With the new
+	   auto_* settings, we need to check for NAT so we do not have one-way audio. */
+	check_for_nat(&p->ourip, p);
+	set_peer_nat(p, p->relatedpeer);
+
+	if (p->natdetected && ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
+		ast_copy_flags(&p->flags[0], &p->relatedpeer->flags[0], SIP_NAT_FORCE_RPORT);
+	}
+
+	if (p->natdetected && ast_test_flag(&p->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA)) {
+		ast_copy_flags(&p->flags[1], &p->relatedpeer->flags[1], SIP_PAGE2_SYMMETRICRTP);
+	}
+
+	do_setnat(p);
+
 	build_via(p);
 
 	/* Change the dialog callid. */

Propchange: team/dlee/stasis-http/channels/sig_ss7.c
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Author Date Id Revision'
+Author Date Id Revision

Propchange: team/dlee/stasis-http/channels/sig_ss7.h
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Author Date Id Revision'
+Author Date Id Revision

Propchange: team/dlee/stasis-http/channels/sip/include/security_events.h
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-"Author Date Id Rev URL"
+Author Date Id Revision

Propchange: team/dlee/stasis-http/channels/sip/security_events.c
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-"Author Date Id Rev URL"
+Author Date Id Revision

Modified: team/dlee/stasis-http/codecs/codec_resample.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/codecs/codec_resample.c?view=diff&rev=385746&r1=385745&r2=385746
==============================================================================
--- team/dlee/stasis-http/codecs/codec_resample.c (original)
+++ team/dlee/stasis-http/codecs/codec_resample.c Mon Apr 15 12:12:23 2013
@@ -113,7 +113,7 @@
 	int res = 0;
 	int x, y, idx = 0;
 
-	trans_size = ARRAY_LEN(id_list) * ARRAY_LEN(id_list);
+	trans_size = ARRAY_LEN(id_list) * (ARRAY_LEN(id_list) - 1);
 	if (!(translators = ast_calloc(1, sizeof(struct ast_translator) * trans_size))) {
 		return AST_MODULE_LOAD_FAILURE;
 	}

Modified: team/dlee/stasis-http/configs/cli_aliases.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/configs/cli_aliases.conf.sample?view=diff&rev=385746&r1=385745&r2=385746
==============================================================================
--- team/dlee/stasis-http/configs/cli_aliases.conf.sample (original)
+++ team/dlee/stasis-http/configs/cli_aliases.conf.sample Mon Apr 15 12:12:23 2013
@@ -26,7 +26,7 @@
 hangup request=channel request hangup
 originate=channel originate
 help=core show help
-pri intense debug span=pri set debug 2 span
+pri intense debug span=pri set debug intense span
 reload=module reload
 
 ; CLI Alias Templates

Propchange: team/dlee/stasis-http/configs/res_curl.conf.sample
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Date Author Id Revision Yoyo'
+Author Date Id Revision

Propchange: team/dlee/stasis-http/contrib/realtime/mysql/musiconhold.sql
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Date Author Id Revision Yoyo'
+Author Date Id Revision

Propchange: team/dlee/stasis-http/contrib/realtime/mysql/queue_log.sql
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Date Author Id Revision Yoyo'
+Author Date Id Revision

Propchange: team/dlee/stasis-http/contrib/realtime/mysql/voicemail_data.sql
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Date Author Id Revision Yoyo'
+Author Date Id Revision

Propchange: team/dlee/stasis-http/contrib/realtime/mysql/voicemail_messages.sql
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Date Author Id Revision Yoyo'
+Author Date Id Revision

Propchange: team/dlee/stasis-http/doc/Makefile
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Date Author Id Revision Yoyo'
+Author Date Id Revision

Propchange: team/dlee/stasis-http/include/asterisk/bridging_features.h
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Author Date Id Revision'
+Author Date Id Revision

Propchange: team/dlee/stasis-http/include/asterisk/bridging_technology.h
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Author Date Id Revision'
+Author Date Id Revision

Modified: team/dlee/stasis-http/include/asterisk/manager.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/include/asterisk/manager.h?view=diff&rev=385746&r1=385745&r2=385746
==============================================================================
--- team/dlee/stasis-http/include/asterisk/manager.h (original)
+++ team/dlee/stasis-http/include/asterisk/manager.h Mon Apr 15 12:12:23 2013
@@ -316,6 +316,37 @@
  */
 struct ast_datastore *astman_datastore_find(struct mansession *s, const struct ast_datastore_info *info, const char *uid);
 
+/*! \brief Struct representing a snapshot of channel state */
+struct ast_channel_snapshot;
+
+/*!
+ * \brief Generate the AMI message body from a channel snapshot
+ * \since 12
+ *
+ * \param snapshot the channel snapshot for which to generate an AMI message
+ *                 body
+ * \param suffix the suffix to append to the channel fields
+ *
+ * \retval NULL on error
+ * \retval ast_str* on success (must be ast_freed by caller)
+ */
+struct ast_str *ast_manager_build_channel_state_string_suffix(
+		const struct ast_channel_snapshot *snapshot,
+		const char *suffix);
+
+/*!
+ * \brief Generate the AMI message body from a channel snapshot
+ * \since 12
+ *
+ * \param snapshot the channel snapshot for which to generate an AMI message
+ *                 body
+ *
+ * \retval NULL on error
+ * \retval ast_str* on success (must be ast_freed by caller)
+ */
+struct ast_str *ast_manager_build_channel_state_string(
+		const struct ast_channel_snapshot *snapshot);
+
 /*!
  * \brief Initialize support for AMI channel events.
  * \return 0 on success.

Propchange: team/dlee/stasis-http/include/asterisk/select.h
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Mon Apr 15 12:12:23 2013
@@ -1,1 +1,1 @@
-'Date Author Id Revision Yoyo'
+Author Date Id Revision

Modified: team/dlee/stasis-http/include/asterisk/sorcery.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/include/asterisk/sorcery.h?view=diff&rev=385746&r1=385745&r2=385746
==============================================================================
--- team/dlee/stasis-http/include/asterisk/sorcery.h (original)
+++ team/dlee/stasis-http/include/asterisk/sorcery.h Mon Apr 15 12:12:23 2013
@@ -44,7 +44,7 @@
  * override configured mappings. They are only used in the case where no configured mapping exists.
  *
  * Configuring object mappings implicitly creates a basic version of an object type. The object type
- * must be fully registered, however, using the \ref ast_sorcery_object_type_register API call before any
+ * must be fully registered, however, using the \ref ast_sorcery_object_register API call before any
  * objects of the type can be allocated, created, or retrieved.
  *
  * Once the object type itself has been fully registered the individual fields within the object must

Modified: team/dlee/stasis-http/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/main/features.c?view=diff&rev=385746&r1=385745&r2=385746
==============================================================================
--- team/dlee/stasis-http/main/features.c (original)
+++ team/dlee/stasis-http/main/features.c Mon Apr 15 12:12:23 2013
@@ -879,17 +879,9 @@
 	return df_copy;
 }
 
-static void dial_features_destroy(void *data)
-{
-	struct ast_dial_features *df = data;
-	if (df) {
-		ast_free(df);
-	}
-}
-
 static const struct ast_datastore_info dial_features_info = {
 	.type = "dial-features",
-	.destroy = dial_features_destroy,
+	.destroy = ast_free_ptr,
 	.duplicate = dial_features_duplicate,
 };
 
@@ -3126,6 +3118,25 @@
 
 AST_RWLOCK_DEFINE_STATIC(features_lock);
 
+/*! \note This is protected by features_lock. */
+static AST_LIST_HEAD_NOLOCK_STATIC(feature_list, ast_call_feature);
+
+static void ast_wrlock_call_features(void)
+{
+	ast_rwlock_wrlock(&features_lock);
+}
+
+void ast_rdlock_call_features(void)
+{
+	ast_rwlock_rdlock(&features_lock);
+}
+
+void ast_unlock_call_features(void)
+{
+	ast_rwlock_unlock(&features_lock);
+}
+
+/*! \note This is protected by features_lock. */
 static struct ast_call_feature builtin_features[] = {
 	{ AST_FEATURE_REDIRECT, "Blind Transfer", "blindxfer", "#", "#", builtin_blindtransfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
 	{ AST_FEATURE_REDIRECT, "Attended Transfer", "atxfer", "", "", builtin_atxfer, AST_FEATURE_FLAG_NEEDSDTMF, "" },
@@ -3135,10 +3146,7 @@
 	{ AST_FEATURE_AUTOMIXMON, "One Touch MixMonitor", "automixmon", "", "", builtin_automixmonitor, AST_FEATURE_FLAG_NEEDSDTMF, "" },
 };
 
-
-static AST_RWLIST_HEAD_STATIC(feature_list, ast_call_feature);
-
-/*! \brief register new feature into feature_list*/
+/*! \brief register new feature into feature_list */
 void ast_register_feature(struct ast_call_feature *feature)
 {
 	if (!feature) {
@@ -3146,9 +3154,9 @@
 		return;
 	}
 
-	AST_RWLIST_WRLOCK(&feature_list);
-	AST_RWLIST_INSERT_HEAD(&feature_list,feature,feature_entry);
-	AST_RWLIST_UNLOCK(&feature_list);
+	ast_wrlock_call_features();
+	AST_LIST_INSERT_HEAD(&feature_list, feature, feature_entry);
+	ast_unlock_call_features();
 
 	ast_verb(2, "Registered Feature '%s'\n",feature->sname);
 }
@@ -3225,9 +3233,9 @@
 		return;
 	}
 
-	AST_RWLIST_WRLOCK(&feature_list);
-	AST_RWLIST_REMOVE(&feature_list, feature, feature_entry);
-	AST_RWLIST_UNLOCK(&feature_list);
+	ast_wrlock_call_features();
+	AST_LIST_REMOVE(&feature_list, feature, feature_entry);
+	ast_unlock_call_features();
 
 	ast_free(feature);
 }
@@ -3237,19 +3245,23 @@
 {
 	struct ast_call_feature *feature;
 
-	AST_RWLIST_WRLOCK(&feature_list);
-	while ((feature = AST_RWLIST_REMOVE_HEAD(&feature_list, feature_entry))) {
+	ast_wrlock_call_features();
+	while ((feature = AST_LIST_REMOVE_HEAD(&feature_list, feature_entry))) {
 		ast_free(feature);
 	}
-	AST_RWLIST_UNLOCK(&feature_list);
-}
-
-/*! \brief find a call feature by name */
+	ast_unlock_call_features();
+}
+
+/*!
+ * \internal
+ * \brief find a dynamic call feature by name
+ * \pre Expects features_lock to be at least readlocked
+ */
 static struct ast_call_feature *find_dynamic_feature(const char *name)
 {
 	struct ast_call_feature *tmp;
 
-	AST_RWLIST_TRAVERSE(&feature_list, tmp, feature_entry) {
+	AST_LIST_TRAVERSE(&feature_list, tmp, feature_entry) {
 		if (!strcasecmp(tmp->sname, name)) {
 			break;
 		}
@@ -3295,19 +3307,9 @@
 	return fg;
 }
 
-void ast_rdlock_call_features(void)
-{
-	ast_rwlock_rdlock(&features_lock);
-}
-
-void ast_unlock_call_features(void)
-{
-	ast_rwlock_unlock(&features_lock);
-}
-
 /*!
  * \internal
- * \pre Expects feature_lock to be readlocked
+ * \pre Expects features_lock to be at least readlocked
  */
 struct ast_call_feature *ast_find_call_feature(const char *name)
 {
@@ -3325,7 +3327,7 @@
 	char exten[FEATURE_MAX_LEN];
 };
 
-struct feature_ds {
+struct feature_datastore {
 	struct ao2_container *feature_map;
 
 	/*!
@@ -3361,7 +3363,7 @@
 
 static void feature_ds_destroy(void *data)
 {
-	struct feature_ds *feature_ds = data;
+	struct feature_datastore *feature_ds = data;
 
 	if (feature_ds->feature_map) {
 		ao2_ref(feature_ds->feature_map, -1);
@@ -3373,8 +3375,8 @@
 
 static void *feature_ds_duplicate(void *data)
 {
-	struct feature_ds *old_ds = data;
-	struct feature_ds *new_ds;
+	struct feature_datastore *old_ds = data;
+	struct feature_datastore *new_ds;
 
 	if (!(new_ds = ast_calloc(1, sizeof(*new_ds)))) {
 		return NULL;
@@ -3405,9 +3407,9 @@
  *
  * \return the data on the FEATURE datastore, or NULL on error
  */
-static struct feature_ds *get_feature_ds(struct ast_channel *chan)
-{
-	struct feature_ds *feature_ds;
+static struct feature_datastore *get_feature_ds(struct ast_channel *chan)
+{
+	struct feature_datastore *feature_ds;
 	struct ast_datastore *ds;
 
 	if ((ds = ast_channel_datastore_find(chan, &feature_ds_info, NULL))) {
@@ -3453,7 +3455,7 @@
  * \internal
  * \brief Get the extension for a given builtin feature
  *
- * \pre expects feature_lock to be readlocked
+ * \pre expects features_lock to be readlocked
  *
  * \retval 0 success
  * \retval non-zero failiure
@@ -3462,7 +3464,7 @@
 		char *buf, size_t len)
 {
 	struct ast_call_feature *feature;
-	struct feature_ds *feature_ds;
+	struct feature_datastore *feature_ds;
 	struct feature_exten *fe = NULL;
 
 	*buf = '\0';
@@ -3570,17 +3572,17 @@
 {
 	int x;
 
-	ast_rwlock_wrlock(&features_lock);
+	ast_wrlock_call_features();
 	for (x = 0; x < FEATURES_COUNT; x++)
 		strcpy(builtin_features[x].exten, builtin_features[x].default_exten);
-	ast_rwlock_unlock(&features_lock);
+	ast_unlock_call_features();
 }
 
 static int remap_feature(const char *name, const char *value)
 {
 	int x, res = -1;
 
-	ast_rwlock_wrlock(&features_lock);
+	ast_wrlock_call_features();
 	for (x = 0; x < FEATURES_COUNT; x++) {
 		if (strcasecmp(builtin_features[x].sname, name))
 			continue;
@@ -3589,7 +3591,7 @@
 		res = 0;
 		break;
 	}
-	ast_rwlock_unlock(&features_lock);
+	ast_unlock_call_features();
 
 	return res;
 }
@@ -3620,7 +3622,7 @@
 		return -1; /* can not run feature operation */
 	}
 
-	ast_rwlock_rdlock(&features_lock);
+	ast_rdlock_call_features();
 	for (x = 0; x < FEATURES_COUNT; x++) {
 		char feature_exten[FEATURE_MAX_LEN] = "";
 
@@ -3662,7 +3664,7 @@
 				"Result: fail");
 	}
 
-	ast_rwlock_unlock(&features_lock);
+	ast_unlock_call_features();
 
 	if (!dynamic_features_buf || !ast_str_strlen(dynamic_features_buf) || feature_detected) {
 		return res;
@@ -3672,9 +3674,7 @@
 
 	while ((tok = strsep(&tmp, "#"))) {
 		AST_RWLIST_RDLOCK(&feature_groups);
-
 		fg = find_group(tok);
-
 		if (fg) {
 			AST_LIST_TRAVERSE(&fg->features, fge, entry) {
 				if (!strcmp(fge->exten, code)) {
@@ -3697,13 +3697,12 @@
 				break;
 			}
 		}
-
 		AST_RWLIST_UNLOCK(&feature_groups);
 
-		AST_RWLIST_RDLOCK(&feature_list);
+		ast_rdlock_call_features();
 
 		if (!(tmpfeature = find_dynamic_feature(tok))) {
-			AST_RWLIST_UNLOCK(&feature_list);
+			ast_unlock_call_features();
 			continue;
 		}
 
@@ -3719,14 +3718,14 @@
 				memcpy(feature, tmpfeature, sizeof(*feature));
 			}
 			if (res != AST_FEATURE_RETURN_KEEPTRYING) {
-				AST_RWLIST_UNLOCK(&feature_list);
+				ast_unlock_call_features();
 				break;
 			}
 			res = AST_FEATURE_RETURN_PASSDIGITS;
 		} else if (!strncmp(tmpfeature->exten, code, strlen(code)))
 			res = AST_FEATURE_RETURN_STOREDIGITS;
 
-		AST_RWLIST_UNLOCK(&feature_list);
+		ast_unlock_call_features();
 	}
 
 	return res;
@@ -3809,7 +3808,7 @@
 
 	ast_clear_flag(config, AST_FLAGS_ALL);
 
-	ast_rwlock_rdlock(&features_lock);
+	ast_rdlock_call_features();
 	for (x = 0; x < FEATURES_COUNT; x++) {
 		if (!ast_test_flag(builtin_features + x, AST_FEATURE_FLAG_NEEDSDTMF))
 			continue;
@@ -3820,7 +3819,7 @@
 		if (ast_test_flag(&(config->features_callee), builtin_features[x].feature_mask))
 			ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
 	}
-	ast_rwlock_unlock(&features_lock);
+	ast_unlock_call_features();
 
 	if (!(ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_0) && ast_test_flag(config, AST_BRIDGE_DTMF_CHANNEL_1))) {
 		const char *dynamic_features = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
@@ -3835,7 +3834,8 @@
 				struct feature_group *fg;
 
 				AST_RWLIST_RDLOCK(&feature_groups);
-				AST_RWLIST_TRAVERSE(&feature_groups, fg, entry) {
+				fg = find_group(tok);
+				if (fg) {
 					struct feature_group_exten *fge;
 
 					AST_LIST_TRAVERSE(&fg->features, fge, entry) {
@@ -3849,7 +3849,7 @@
 				}
 				AST_RWLIST_UNLOCK(&feature_groups);
 
-				AST_RWLIST_RDLOCK(&feature_list);
+				ast_rdlock_call_features();
 				if ((feature = find_dynamic_feature(tok)) && ast_test_flag(feature, AST_FEATURE_FLAG_NEEDSDTMF)) {
 					if (ast_test_flag(feature, AST_FEATURE_FLAG_BYCALLER)) {
 						ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_0);
@@ -3858,7 +3858,7 @@
 						ast_set_flag(config, AST_BRIDGE_DTMF_CHANNEL_1);
 					}
 				}
-				AST_RWLIST_UNLOCK(&feature_list);
+				ast_unlock_call_features();
 			}
 		}
 	}
@@ -3974,7 +3974,7 @@
 	}
 
 	/* support dialing of the featuremap disconnect code while performing an attended tranfer */
-	ast_rwlock_rdlock(&features_lock);
+	ast_rdlock_call_features();
 	for (x = 0; x < FEATURES_COUNT; x++) {
 		if (strcasecmp(builtin_features[x].sname, "disconnect"))
 			continue;
@@ -3985,7 +3985,7 @@
 		memset(dialed_code, 0, len);
 		break;
 	}
-	ast_rwlock_unlock(&features_lock);
+	ast_unlock_call_features();
 	x = 0;
 	started = ast_tvnow();
 	to = timeout;
@@ -6247,14 +6247,14 @@
 		return;
 	}
 
-	AST_RWLIST_RDLOCK(&feature_list);
+	ast_rdlock_call_features();
 	if (find_dynamic_feature(var->name)) {
-		AST_RWLIST_UNLOCK(&feature_list);
+		ast_unlock_call_features();
 		ast_log(LOG_WARNING, "Dynamic Feature '%s' specified more than once!\n",
 			var->name);
 		return;
 	}
-	AST_RWLIST_UNLOCK(&feature_list);
+	ast_unlock_call_features();
 
 	if (!(feature = ast_calloc(1, sizeof(*feature)))) {
 		return;
@@ -6456,14 +6456,13 @@

[... 464 lines stripped ...]



More information about the asterisk-commits mailing list