[asterisk-commits] dvossel: branch dvossel/fixtheworld_phase1_step3 r303287 - in /team/dvossel/f...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jan 21 15:51:04 CST 2011


Author: dvossel
Date: Fri Jan 21 15:50:58 2011
New Revision: 303287

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=303287
Log:
enable automerge 

Modified:
    team/dvossel/fixtheworld_phase1_step3/   (props changed)
    team/dvossel/fixtheworld_phase1_step3/CHANGES
    team/dvossel/fixtheworld_phase1_step3/apps/app_dial.c
    team/dvossel/fixtheworld_phase1_step3/apps/app_privacy.c
    team/dvossel/fixtheworld_phase1_step3/apps/app_queue.c
    team/dvossel/fixtheworld_phase1_step3/apps/app_voicemail.c
    team/dvossel/fixtheworld_phase1_step3/channels/chan_local.c
    team/dvossel/fixtheworld_phase1_step3/channels/chan_sip.c
    team/dvossel/fixtheworld_phase1_step3/configs/extensions.conf.sample
    team/dvossel/fixtheworld_phase1_step3/configs/queues.conf.sample
    team/dvossel/fixtheworld_phase1_step3/configure
    team/dvossel/fixtheworld_phase1_step3/configure.ac
    team/dvossel/fixtheworld_phase1_step3/contrib/scripts/install_prereq
    team/dvossel/fixtheworld_phase1_step3/funcs/func_db.c
    team/dvossel/fixtheworld_phase1_step3/include/asterisk/astdb.h
    team/dvossel/fixtheworld_phase1_step3/main/app.c
    team/dvossel/fixtheworld_phase1_step3/main/astobj2.c
    team/dvossel/fixtheworld_phase1_step3/main/ccss.c
    team/dvossel/fixtheworld_phase1_step3/main/config.c
    team/dvossel/fixtheworld_phase1_step3/main/features.c
    team/dvossel/fixtheworld_phase1_step3/main/manager.c
    team/dvossel/fixtheworld_phase1_step3/main/pbx.c
    team/dvossel/fixtheworld_phase1_step3/main/utils.c
    team/dvossel/fixtheworld_phase1_step3/res/res_agi.c
    team/dvossel/fixtheworld_phase1_step3/res/res_fax.c
    team/dvossel/fixtheworld_phase1_step3/res/res_timing_timerfd.c

Propchange: team/dvossel/fixtheworld_phase1_step3/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.

Propchange: team/dvossel/fixtheworld_phase1_step3/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri Jan 21 15:50:58 2011
@@ -1,1 +1,1 @@
-/trunk:1-302008
+/trunk:1-303283

Modified: team/dvossel/fixtheworld_phase1_step3/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/CHANGES?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/CHANGES (original)
+++ team/dvossel/fixtheworld_phase1_step3/CHANGES Fri Jan 21 15:50:58 2011
@@ -39,6 +39,11 @@
  * Added ASTETCDIR, ASTMODDIR, ASTVARLIBDIR, ASTDBDIR, ASTKEYDIR, ASTDATADIR,
    ASTAGIDIR, ASTSPOOLDIR, ASTRUNDIR, ASTLOGDIR which hold the equivalent
    variables from asterisk.conf.
+
+Dialplan Functions
+------------------
+ * Added DB_KEYS, which lists the next set of keys in the Asterisk database
+   hierarchy.
 
 libpri channel driver (chan_dahdi) DAHDI changes
 --------------------------

Modified: team/dvossel/fixtheworld_phase1_step3/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/apps/app_dial.c?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/apps/app_dial.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/apps/app_dial.c Fri Jan 21 15:50:58 2011
@@ -1879,7 +1879,7 @@
 			pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
 			goto done;
 		}
-		ast_verb(3, "Setting call duration limit to %.3lf seconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
+		ast_verb(3, "Setting call duration limit to %.3lf milliseconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
 	}
 
 	if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {

Modified: team/dvossel/fixtheworld_phase1_step3/apps/app_privacy.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/apps/app_privacy.c?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/apps/app_privacy.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/apps/app_privacy.c Fri Jan 21 15:50:58 2011
@@ -107,7 +107,7 @@
 			}
 		}
 
-		parse = ast_strdupa(S_OR(data, ""));
+		parse = ast_strdupa(data);
 
 		AST_STANDARD_APP_ARGS(args, parse);
 

Modified: team/dvossel/fixtheworld_phase1_step3/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/apps/app_queue.c?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/apps/app_queue.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/apps/app_queue.c Fri Jan 21 15:50:58 2011
@@ -680,7 +680,8 @@
 	QUEUE_STRATEGY_RANDOM,
 	QUEUE_STRATEGY_RRMEMORY,
 	QUEUE_STRATEGY_LINEAR,
-	QUEUE_STRATEGY_WRANDOM
+	QUEUE_STRATEGY_WRANDOM,
+	QUEUE_STRATEGY_RRORDERED,
 };
 
 enum {
@@ -708,6 +709,7 @@
 	{ QUEUE_STRATEGY_RRMEMORY, "roundrobin" },
 	{ QUEUE_STRATEGY_LINEAR, "linear" },
 	{ QUEUE_STRATEGY_WRANDOM, "wrandom"},
+	{ QUEUE_STRATEGY_RRORDERED, "rrordered"},
 };
 
 static const struct autopause {
@@ -1538,7 +1540,7 @@
 	q->autopause = QUEUE_AUTOPAUSE_OFF;
 	q->timeoutpriority = TIMEOUT_PRIORITY_APP;
 	if (!q->members) {
-		if (q->strategy == QUEUE_STRATEGY_LINEAR)
+		if (q->strategy == QUEUE_STRATEGY_LINEAR || q->strategy == QUEUE_STRATEGY_RRORDERED)
 			/* linear strategy depends on order, so we have to place all members in a single bucket */
 			q->members = ao2_container_alloc(1, member_hash_fn, member_cmp_fn);
 		else
@@ -3909,6 +3911,7 @@
 		}
 		tmp->metric += mem->penalty * 1000000 * usepenalty;
 		break;
+	case QUEUE_STRATEGY_RRORDERED:
 	case QUEUE_STRATEGY_RRMEMORY:
 		if (pos < q->rrpos) {
 			tmp->metric = 1000 + pos;
@@ -4231,7 +4234,7 @@
 			ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_PARKCALL);
 			break;
 		case 'n':
-			if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY || qe->parent->strategy == QUEUE_STRATEGY_LINEAR)
+			if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY || qe->parent->strategy == QUEUE_STRATEGY_LINEAR || qe->parent->strategy == QUEUE_STRATEGY_RRORDERED)
 				(*tries)++;
 			else
 				*tries = qe->parent->membercount;
@@ -4418,8 +4421,9 @@
 	}
 	ast_channel_unlock(qe->chan);
 	ao2_lock(qe->parent);
-	if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
+	if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY || qe->parent->strategy == QUEUE_STRATEGY_RRORDERED) {
 		store_next_rr(qe, outgoing);
+
 	}
 	if (qe->parent->strategy == QUEUE_STRATEGY_LINEAR) {
 		store_next_lin(qe, outgoing);

Modified: team/dvossel/fixtheworld_phase1_step3/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/apps/app_voicemail.c?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/apps/app_voicemail.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/apps/app_voicemail.c Fri Jan 21 15:50:58 2011
@@ -11698,6 +11698,9 @@
 		}
 		if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) {
 			ast_copy_string(greetingfolder, val, sizeof(greetingfolder));
+		} else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) {
+			/* Also support greetingsfolder as documented in voicemail.conf.sample */
+			ast_copy_string(greetingfolder, val, sizeof(greetingfolder));
 		} else {
 			ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder));
 		}

Modified: team/dvossel/fixtheworld_phase1_step3/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/channels/chan_local.c?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/channels/chan_local.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/channels/chan_local.c Fri Jan 21 15:50:58 2011
@@ -140,7 +140,7 @@
 	unsigned int flags;             /*!< Private flags */
 	char context[AST_MAX_CONTEXT];  /*!< Context to call */
 	char exten[AST_MAX_EXTENSION];  /*!< Extension to call */
-	struct ast_format_cap *reqcap;         /*!< Requested format capabilities */
+	struct ast_format_cap *reqcap;  /*!< Requested format capabilities */
 	struct ast_jb_conf jb_conf;     /*!< jitterbuffer configuration for this local channel */
 	struct ast_channel *owner;      /*!< Master Channel - Bridging happens here */
 	struct ast_channel *chan;       /*!< Outbound channel - PBX is run here */

Modified: team/dvossel/fixtheworld_phase1_step3/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/channels/chan_sip.c?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/channels/chan_sip.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/channels/chan_sip.c Fri Jan 21 15:50:58 2011
@@ -10670,7 +10670,9 @@
 static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int oldsdp, int add_audio, int add_t38)
 {
 	struct ast_format_cap *alreadysent = ast_format_cap_alloc_nolock();
+	struct ast_format_cap *tmpcap = ast_format_cap_alloc_nolock();
 	int res = AST_SUCCESS;
+	int doing_directmedia = FALSE;
 	struct ast_sockaddr addr = { {0,} };
 	struct ast_sockaddr vaddr = { {0,} };
 	struct ast_sockaddr taddr = { {0,} };
@@ -10702,7 +10704,6 @@
 
 	int x;
 	struct ast_format tmp_fmt;
-	struct ast_format_cap *capability = NULL; /* this holds a shallow copy and should never be destroyed */
 	int needaudio = FALSE;
 	int needvideo = FALSE;
 	int needtext = FALSE;
@@ -10718,7 +10719,7 @@
 	/* Set the SDP session name */
 	snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
 
-	if (!alreadysent) {
+	if (!alreadysent || !tmpcap) {
 		res = AST_FAILURE;
 		goto add_sdp_cleanup;
 	}
@@ -10742,6 +10743,7 @@
 	}
 
 	if (add_audio) {
+		doing_directmedia = (!ast_sockaddr_isnull(&p->redirip) && !(ast_format_cap_is_empty(p->redircaps))) ? TRUE : FALSE;
 		/* Check if we need video in this call */
 		if ((ast_format_cap_has_type(p->jointcaps, AST_FORMAT_TYPE_VIDEO)) && !p->novideo) {
 			if (p->vrtp) {
@@ -10781,15 +10783,30 @@
 		 ast_sockaddr_stringify_addr(&dest));
 
 	if (add_audio) {
-		capability = p->jointcaps; /* SHALLOW COPY DO NOT DESTROY */
+		if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) {
+			hold = "a=recvonly\r\n";
+			doing_directmedia = FALSE;
+		} else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) {
+			hold = "a=inactive\r\n";
+			doing_directmedia = FALSE;
+		} else {
+			hold = "a=sendrecv\r\n";
+		}
+
+		ast_format_cap_copy2(tmpcap, p->jointcaps);
 
 		/* XXX note, Video and Text are negated - 'true' means 'no' */
-		ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability),
+		ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), tmpcap),
 			  p->novideo ? "True" : "False", p->notext ? "True" : "False");
 		ast_debug(1, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcaps));
 
+		if (doing_directmedia) {
+			ast_format_cap_joint_copy(p->jointcaps, p->redircaps, tmpcap);
+			ast_debug(1, "** Our native-bridge filtered capablity: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), tmpcap));
+		}
+
 		/* Check if we need audio */
-		if (ast_format_cap_has_type(capability, AST_FORMAT_TYPE_AUDIO))
+		if (ast_format_cap_has_type(tmpcap, AST_FORMAT_TYPE_AUDIO))
 			needaudio = TRUE;
 
 		if (debug) {
@@ -10833,13 +10850,6 @@
 		ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ast_sockaddr_port(&dest),
 			a_crypto ? "SAVP" : "AVP");
 
-		if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR)
-			hold = "a=recvonly\r\n";
-		else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE)
-			hold = "a=inactive\r\n";
-		else
-			hold = "a=sendrecv\r\n";
-
 		/* Now, start adding audio codecs. These are added in this order:
 		   - First what was requested by the calling channel
 		   - Then preferences in order from sip.conf device config for this peer/user
@@ -10849,7 +10859,7 @@
 		/* Prefer the audio codec we were requested to use, first, no matter what
 		   Note that p->prefcodec can include video codecs, so mask them out
 		*/
-		if (ast_format_cap_has_joint(capability, p->prefcaps)) {
+		if (ast_format_cap_has_joint(tmpcap, p->prefcaps)) {
 			ast_format_cap_iter_start(p->prefcaps);
 			while (!(ast_format_cap_iter_next(p->prefcaps, &tmp_fmt))) {
 				if (AST_FORMAT_GET_TYPE(tmp_fmt.id) != AST_FORMAT_TYPE_AUDIO) {
@@ -10866,7 +10876,7 @@
 			if (!(ast_codec_pref_index(&p->prefs, x, &tmp_fmt)))
 				break;
 
-			if (!(ast_format_cap_iscompatible(capability, &tmp_fmt)))
+			if (!(ast_format_cap_iscompatible(tmpcap, &tmp_fmt)))
 				continue;
 
 			if (ast_format_cap_iscompatible(alreadysent, &tmp_fmt))
@@ -10884,8 +10894,8 @@
 		}
 
 		/* Now send any other common audio and video codecs, and non-codec formats: */
-		ast_format_cap_iter_start(capability);
-		while (!(ast_format_cap_iter_next(capability, &tmp_fmt))) {
+		ast_format_cap_iter_start(tmpcap);
+		while (!(ast_format_cap_iter_next(tmpcap, &tmp_fmt))) {
 			if (ast_format_cap_iscompatible(alreadysent, &tmp_fmt))
 				continue;
 
@@ -10897,7 +10907,7 @@
 				add_tcodec_to_sdp(p, &tmp_fmt, &m_text, &a_text, debug, &min_text_packet_size);
 			}
 		}
-		ast_format_cap_iter_end(capability);
+		ast_format_cap_iter_end(tmpcap);
 
 		/* Now add DTMF RFC2833 telephony-event as a codec */
 		for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) {
@@ -11050,10 +11060,11 @@
 	ao2_t_unlink(dialogs_rtpcheck, p, "unlink pvt into dialogs_rtpcheck container");
 	ao2_t_link(dialogs_rtpcheck, p, "link pvt into dialogs_rtpcheck container");
 
-	ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability));
+	ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmpcap));
 
 add_sdp_cleanup:
 	alreadysent = ast_format_cap_destroy(alreadysent);
+	tmpcap = ast_format_cap_destroy(tmpcap);
 
 	return res;
 }
@@ -11302,12 +11313,15 @@
 /*! \brief Build contact header - the contact header we send out */
 static void build_contact(struct sip_pvt *p)
 {
+	char tmp[SIPBUFSIZE];
+	char *user = ast_uri_encode(p->exten, tmp, sizeof(tmp), 1);
+
 	if (p->socket.type == SIP_TRANSPORT_UDP) {
-		ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten,
-			ast_strlen_zero(p->exten) ? "" : "@", ast_sockaddr_stringify(&p->ourip));
+		ast_string_field_build(p, our_contact, "<sip:%s%s%s>", user,
+			ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify(&p->ourip));
 	} else {
-		ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", p->exten,
-			ast_strlen_zero(p->exten) ? "" : "@", ast_sockaddr_stringify(&p->ourip),
+		ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", user,
+			ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify(&p->ourip),
 			get_transport(p->socket.type));
 	}
 }
@@ -13212,7 +13226,7 @@
 	char *firstcuri = NULL;
 	int start = 0;
 	int wildcard_found = 0;
-	int single_binding_found;
+	int single_binding_found = 0;
 
 	ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact));
 

Modified: team/dvossel/fixtheworld_phase1_step3/configs/extensions.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/configs/extensions.conf.sample?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/configs/extensions.conf.sample (original)
+++ team/dvossel/fixtheworld_phase1_step3/configs/extensions.conf.sample Fri Jan 21 15:50:58 2011
@@ -87,14 +87,6 @@
 ; they are not stored in the extensions.conf file.
 ;
 clearglobalvars=no
-;
-; If priorityjumping is set to 'yes', then applications that support
-; 'jumping' to a different priority based on the result of their operations
-; will do so (this is backwards compatible behavior with pre-1.2 releases
-; of Asterisk). Individual applications can also be requested to do this
-; by passing a 'j' option in their arguments.
-;
-;priorityjumping=yes
 ;
 ; User context is where entries from users.conf are registered.  The
 ; default value is 'default'

Modified: team/dvossel/fixtheworld_phase1_step3/configs/queues.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/configs/queues.conf.sample?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/configs/queues.conf.sample (original)
+++ team/dvossel/fixtheworld_phase1_step3/configs/queues.conf.sample Fri Jan 21 15:50:58 2011
@@ -87,6 +87,8 @@
 ; fewestcalls - ring the one with fewest completed calls from this queue
 ; random - ring random interface
 ; rrmemory - round robin with memory, remember where we left off last ring pass
+; rrordered - same as rrmemory, except the queue member order from config file 
+              is preserved
 ; linear - rings interfaces in the order specified in this configuration file.
 ;          If you use dynamic members, the members will be rung in the order in
 ;          which they were added

Modified: team/dvossel/fixtheworld_phase1_step3/configure.ac
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/configure.ac?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/configure.ac (original)
+++ team/dvossel/fixtheworld_phase1_step3/configure.ac Fri Jan 21 15:50:58 2011
@@ -36,6 +36,10 @@
 
 # specify output header file
 AC_CONFIG_HEADER(include/asterisk/autoconfig.h)
+
+# Note: AC_PROG_CC *must* be specified before AC_USE_SYSTEM_EXTENSIONS or any
+# other macro that uses the C compiler, or the default order will be used.
+AC_PROG_CC([llvm-gcc gcc cc])
 
 AC_USE_SYSTEM_EXTENSIONS	dnl note- does not work on FreeBSD
 
@@ -215,7 +219,6 @@
 fi
 
 # Checks for programs.
-AC_PROG_CC
 AC_PROG_CXX
 AC_PROG_CPP
 AC_PROG_CXXCPP

Modified: team/dvossel/fixtheworld_phase1_step3/contrib/scripts/install_prereq
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/contrib/scripts/install_prereq?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/contrib/scripts/install_prereq (original)
+++ team/dvossel/fixtheworld_phase1_step3/contrib/scripts/install_prereq Fri Jan 21 15:50:58 2011
@@ -27,7 +27,7 @@
 PACKAGES_DEBIAN="$PACKAGES_DEBIAN libpq-dev unixodbc-dev libsqlite0-dev libsqlite3-dev libmysqlclient15-dev libneon27-dev libgmime-2.0-2-dev libusb-dev liblua5.1-0-dev lua5.1"
 PACKAGES_DEBIAN="$PACKAGES_DEBIAN libopenh323-dev libvpb-dev libgtk2.0-dev libmysqlclient-dev libbluetooth-dev libradiusclient-ng-dev freetds-dev"
 PACKAGES_DEBIAN="$PACKAGES_DEBIAN libsnmp-dev libiksemel-dev libopenais-dev libnewt-dev libpopt-dev libical-dev libspandsp-dev libjack-dev"
-PACKAGES_DEBIAN="$PACKAGES_DEBIAN libresample-dev libc-client-dev"
+PACKAGES_DEBIAN="$PACKAGES_DEBIAN libresample-dev libc-client-dev binutils-dev"
 
 PACKAGES_RH="automake gcc gcc-c++ ncurses-devel openssl-devel libxml2-devel unixODBC-devel libcurl-devel libogg-devel libvorbis-devel speex-devel"
 PACKAGES_RH="$PACKAGES_RH spandsp-devel freetds-devel net-snmp-devel iksemel-devel openais-devel newt-devel popt-devel libtool-ltdl-devel lua-devel"

Modified: team/dvossel/fixtheworld_phase1_step3/funcs/func_db.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/funcs/func_db.c?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/funcs/func_db.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/funcs/func_db.c Fri Jan 21 15:50:58 2011
@@ -81,6 +81,19 @@
 			<ref type="function">DB</ref>
 		</see-also>
 	</function>
+	<function name="DB_KEYS" language="en_US">
+		<synopsis>
+			Obtain a list of keys within the Asterisk database.
+		</synopsis>
+		<syntax>
+			<parameter name="prefix" />
+		</syntax>
+		<description>
+			<para>This function will return a comma-separated list of keys existing
+			at the prefix specified within the Asterisk database.  If no argument is
+			provided, then a list of key families will be returned.</para>
+		</description>
+	</function>
 	<function name="DB_DELETE" language="en_US">
 		<synopsis>
 			Return a value from the database and delete it.
@@ -204,6 +217,61 @@
 	.read_max = 2,
 };
 
+static int function_db_keys(struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **result, ssize_t maxlen)
+{
+	size_t parselen = strlen(parse);
+	struct ast_db_entry *dbe, *orig_dbe;
+	struct ast_str *escape_buf = NULL;
+	const char *last = "";
+
+	/* Remove leading and trailing slashes */
+	while (parse[0] == '/') {
+		parse++;
+		parselen--;
+	}
+	while (parse[parselen - 1] == '/') {
+		parse[--parselen] = '\0';
+	}
+
+	ast_str_reset(*result);
+
+	/* Nothing within the database at that prefix? */
+	if (!(orig_dbe = dbe = ast_db_gettree(parse, NULL))) {
+		return 0;
+	}
+
+	for (; dbe; dbe = dbe->next) {
+		/* Find the current component */
+		char *curkey = &dbe->key[parselen + 1], *slash;
+		if (*curkey == '/') {
+			curkey++;
+		}
+		/* Remove everything after the current component */
+		if ((slash = strchr(curkey, '/'))) {
+			*slash = '\0';
+		}
+
+		/* Skip duplicates */
+		if (!strcasecmp(last, curkey)) {
+			continue;
+		}
+		last = curkey;
+
+		if (orig_dbe != dbe) {
+			ast_str_append(result, maxlen, ",");
+		}
+		ast_str_append_escapecommas(result, maxlen, curkey, strlen(curkey));
+	}
+	ast_db_freetree(orig_dbe);
+	ast_free(escape_buf);
+	return 0;
+}
+
+static struct ast_custom_function db_keys_function = {
+	.name = "DB_KEYS",
+	.read2 = function_db_keys,
+};
+
 static int function_db_delete(struct ast_channel *chan, const char *cmd,
 			      char *parse, char *buf, size_t len)
 {
@@ -252,6 +320,7 @@
 	res |= ast_custom_function_unregister(&db_function);
 	res |= ast_custom_function_unregister(&db_exists_function);
 	res |= ast_custom_function_unregister(&db_delete_function);
+	res |= ast_custom_function_unregister(&db_keys_function);
 
 	return res;
 }
@@ -263,6 +332,7 @@
 	res |= ast_custom_function_register(&db_function);
 	res |= ast_custom_function_register(&db_exists_function);
 	res |= ast_custom_function_register(&db_delete_function);
+	res |= ast_custom_function_register(&db_keys_function);
 
 	return res;
 }

Modified: team/dvossel/fixtheworld_phase1_step3/include/asterisk/astdb.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/include/asterisk/astdb.h?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/include/asterisk/astdb.h (original)
+++ team/dvossel/fixtheworld_phase1_step3/include/asterisk/astdb.h Fri Jan 21 15:50:58 2011
@@ -33,22 +33,37 @@
 	char data[0];
 };
 
-/*! \brief Get key value specified by family/key */
+/*!\brief Get key value specified by family/key */
 int ast_db_get(const char *family, const char *key, char *out, int outlen);
 
-/*! \brief Store value addressed by family/key*/
+/*!\brief Store value addressed by family/key */
 int ast_db_put(const char *family, const char *key, const char *value);
 
-/*! \brief Delete entry in astdb */
+/*!\brief Delete entry in astdb */
 int ast_db_del(const char *family, const char *key);
 
-/*! \brief Delete a whole family (for some reason also called "tree" */
+/*!\brief Delete one or more entries in astdb
+ * If both parameters are NULL, the entire database will be purged.  If
+ * only keytree is NULL, all entries within the family will be purged.
+ * It is an error for keytree to have a value when family is NULL.
+ *
+ * \retval 0 Entries were deleted
+ * \retval -1 An error occurred
+ */
 int ast_db_deltree(const char *family, const char *keytree);
 
-/*! \brief Get a whole family */
+/*!\brief Get a list of values within the astdb tree
+ * If family is specified, only those keys will be returned.  If keytree
+ * is specified, subkeys are expected to exist (separated from the key with
+ * a slash).  If subkeys do not exist and keytree is specified, the tree will
+ * consist of either a single entry or NULL will be returned.
+ *
+ * Resulting tree should be freed by passing the return value to ast_db_freetree()
+ * when usage is concluded.
+ */
 struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree);
 
-/*! \brief Free in-memory data */
+/*!\brief Free structure created by ast_db_gettree() */
 void ast_db_freetree(struct ast_db_entry *entry);
 
 #if defined(__cplusplus) || defined(c_plusplus)

Modified: team/dvossel/fixtheworld_phase1_step3/main/app.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/main/app.c?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/main/app.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/main/app.c Fri Jan 21 15:50:58 2011
@@ -30,10 +30,15 @@
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
-#include <regex.h>
-#include <sys/file.h> /* added this to allow to compile, sorry! */
-#include <signal.h>
+#include <regex.h>          /* for regcomp(3) */
+#include <sys/file.h>       /* for flock(2) */
+#include <signal.h>         /* for pthread_sigmask(3) */
 #include <stdlib.h>         /* for closefrom(3) */
+#include <sys/types.h>
+#include <sys/wait.h>       /* for waitpid(2) */
+#ifndef HAVE_CLOSEFROM
+#include <dirent.h>         /* for opendir(3)   */
+#endif
 #ifdef HAVE_CAP
 #include <sys/capability.h>
 #endif /* HAVE_CAP */
@@ -51,6 +56,41 @@
 #include "asterisk/threadstorage.h"
 
 AST_THREADSTORAGE_PUBLIC(ast_str_thread_global_buf);
+
+static pthread_t shaun_of_the_dead_thread = AST_PTHREADT_NULL;
+
+struct zombie {
+	pid_t pid;
+	AST_LIST_ENTRY(zombie) list;
+};
+
+static AST_LIST_HEAD_STATIC(zombies, zombie);
+
+static void *shaun_of_the_dead(void *data)
+{
+	struct zombie *cur;
+	int status;
+	for (;;) {
+		if (!AST_LIST_EMPTY(&zombies)) {
+			/* Don't allow cancellation while we have a lock. */
+			pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+			AST_LIST_LOCK(&zombies);
+			AST_LIST_TRAVERSE_SAFE_BEGIN(&zombies, cur, list) {
+				if (waitpid(cur->pid, &status, WNOHANG) != 0) {
+					AST_LIST_REMOVE_CURRENT(list);
+					ast_free(cur);
+				}
+			}
+			AST_LIST_TRAVERSE_SAFE_END
+			AST_LIST_UNLOCK(&zombies);
+			pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+		}
+		pthread_testcancel();
+		/* Wait for 60 seconds, without engaging in a busy loop. */
+		ast_poll(NULL, 0, AST_LIST_FIRST(&zombies) ? 5000 : 60000);
+	}
+	return NULL;
+}
 
 
 #define AST_MAX_FORMATS 10
@@ -2062,6 +2102,21 @@
 	if (pid != 0) {
 		/* Fork failed or parent */
 		pthread_sigmask(SIG_SETMASK, &old_set, NULL);
+		if (!stop_reaper && pid > 0) {
+			struct zombie *cur = ast_calloc(1, sizeof(*cur));
+			if (cur) {
+				cur->pid = pid;
+				AST_LIST_LOCK(&zombies);
+				AST_LIST_INSERT_TAIL(&zombies, cur, list);
+				AST_LIST_UNLOCK(&zombies);
+				if (shaun_of_the_dead_thread == AST_PTHREADT_NULL) {
+					if (ast_pthread_create_background(&shaun_of_the_dead_thread, NULL, shaun_of_the_dead, NULL)) {
+						ast_log(LOG_ERROR, "Shaun of the Dead wants to kill zombies, but can't?!!\n");
+						shaun_of_the_dead_thread = AST_PTHREADT_NULL;
+					}
+				}
+			}
+		}
 		return pid;
 	} else {
 		/* Child */

Modified: team/dvossel/fixtheworld_phase1_step3/main/astobj2.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/main/astobj2.c?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/main/astobj2.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/main/astobj2.c Fri Jan 21 15:50:58 2011
@@ -60,7 +60,7 @@
 };
 
 #ifdef AST_DEVMODE
-#define AO2_DEBUG 1
+/* #define AO2_DEBUG 1 */
 #endif
 
 #ifdef AO2_DEBUG

Modified: team/dvossel/fixtheworld_phase1_step3/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/main/ccss.c?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/main/ccss.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/main/ccss.c Fri Jan 21 15:50:58 2011
@@ -3197,10 +3197,14 @@
  * \param dialstring A new dialstring to add
  * \retval void
  */
-static void cc_unique_append(struct ast_str *str, const char * const dialstring)
+static void cc_unique_append(struct ast_str *str, const char *dialstring)
 {
 	char dialstring_search[AST_CHANNEL_NAME];
 
+	if (ast_strlen_zero(dialstring)) {
+		/* No dialstring to append. */
+		return;
+	}
 	snprintf(dialstring_search, sizeof(dialstring_search), "%s%c", dialstring, '&');
 	if (strstr(ast_str_buffer(str), dialstring_search)) {
 		return;
@@ -3229,6 +3233,10 @@
 	struct extension_child_dialstring *child_dialstring;
 	struct ast_cc_monitor *monitor_iter = starting_point;
 	int top_level_id = starting_point->id;
+	size_t length;
+
+	/* Init to an empty string. */
+	ast_str_truncate(str, 0);
 
 	/* First we need to take all of the is_valid child_dialstrings from
 	 * the extension monitor we found and add them to the CC_INTERFACES
@@ -3251,7 +3259,15 @@
 	/* str will have an extra '&' tacked onto the end of it, so we need
 	 * to get rid of that.
 	 */
-	ast_str_truncate(str, ast_str_strlen(str) - 1);
+	length = ast_str_strlen(str);
+	if (length) {
+		ast_str_truncate(str, length - 1);
+	}
+	if (length <= 1) {
+		/* Nothing to recall?  This should not happen. */
+		ast_log(LOG_ERROR, "CC_INTERFACES is empty. starting device_name:'%s'\n",
+			starting_point->interface->device_name);
+	}
 }
 
 int ast_cc_agent_set_interfaces_chanvar(struct ast_channel *chan)

Modified: team/dvossel/fixtheworld_phase1_step3/main/config.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/main/config.c?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/main/config.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/main/config.c Fri Jan 21 15:50:58 2011
@@ -947,9 +947,9 @@
 		 * [foo]	define a new category named 'foo'
 		 * [foo](!)	define a new template category named 'foo'
 		 * [foo](+)	append to category 'foo', error if foo does not exist.
-		 * [foo](a)	define a new category and inherit from template a.
-		 *		You can put a comma-separated list of templates and '!' and '+'
-		 *		between parentheses, with obvious meaning.
+		 * [foo](a)	define a new category and inherit from category or template a.
+		 *		You can put a comma-separated list of categories and templates
+		 *		and '!' and '+' between parentheses, with obvious meaning.
 		 */
 		struct ast_category *newcat = NULL;
 		char *catname;

Modified: team/dvossel/fixtheworld_phase1_step3/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/main/features.c?view=diff&rev=303287&r1=303286&r2=303287
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/main/features.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/main/features.c Fri Jan 21 15:50:58 2011
@@ -58,6 +58,56 @@
 #include "asterisk/astobj2.h"
 #include "asterisk/cel.h"
 #include "asterisk/test.h"
+
+/*
+ * Party A - transferee
+ * Party B - transferer
+ * Party C - target of transfer
+ *
+ * DTMF attended transfer works within the channel bridge.
+ * Unfortunately, when either party A or B in the channel bridge
+ * hangs up, that channel is not completely hung up until the
+ * transfer completes.  This is a real problem depending upon
+ * the channel technology involved.
+ *
+ * For chan_dahdi, the channel is crippled until the hangup is
+ * complete.  Either the channel is not useable (analog) or the
+ * protocol disconnect messages are held up (PRI/BRI/SS7) and
+ * the media is not released.
+ *
+ * For chan_sip, a call limit of one is going to block that
+ * endpoint from any further calls until the hangup is complete.
+ *
+ * For party A this is a minor problem.  The party A channel
+ * will only be in this condition while party B is dialing and
+ * when party B and C are conferring.  The conversation between
+ * party B and C is expected to be a short one.  Party B is
+ * either asking a question of party C or announcing party A.
+ * Also party A does not have much incentive to hangup at this
+ * point.
+ *
+ * For party B this can be a major problem during a blonde
+ * transfer.  (A blonde transfer is our term for an attended
+ * transfer that is converted into a blind transfer. :))  Party
+ * B could be the operator.  When party B hangs up, he assumes
+ * that he is out of the original call entirely.  The party B
+ * channel will be in this condition while party C is ringing,
+ * while attempting to recall party B, and while waiting between
+ * call attempts.
+ *
+ * WARNING:
+ * The ATXFER_NULL_TECH conditional is a hack to fix the
+ * problem.  It will replace the party B channel technology with
+ * a NULL channel driver.  The consequences of this code is that
+ * the 'h' extension will not be able to access any channel
+ * technology specific information like SIP statistics for the
+ * call.
+ *
+ * Uncomment the ATXFER_NULL_TECH define below to replace the
+ * party B channel technology in the channel bridge to complete
+ * hanging up the channel technology.
+ */
+//#define ATXFER_NULL_TECH	1
 
 /*** DOCUMENTATION
 	<application name="Bridge" language="en_US">
@@ -412,6 +462,124 @@
 	int is_caller;
 };
 
+#if defined(ATXFER_NULL_TECH)
+static struct ast_frame *null_read(struct ast_channel *chan)
+{
+	/* Hangup channel. */
+	return NULL;
+}
+
+static struct ast_frame *null_exception(struct ast_channel *chan)
+{
+	/* Hangup channel. */
+	return NULL;
+}
+
+static int null_write(struct ast_channel *chan, struct ast_frame *frame)
+{
+	/* Hangup channel. */
+	return -1;
+}
+
+static int null_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
+{
+	/* No problem fixing up the channel. */
+	return 0;
+}
+
+static int null_hangup(struct ast_channel *chan)
+{
+	chan->tech_pvt = NULL;
+	return 0;
+}
+
+static const struct ast_channel_tech null_tech = {
+	.type = "NULL",
+	.description = "NULL channel driver for atxfer",
+	.capabilities = -1,
+	.read = null_read,
+	.exception = null_exception,
+	.write = null_write,
+	.fixup = null_fixup,
+	.hangup = null_hangup,
+};
+#endif	/* defined(ATXFER_NULL_TECH) */
+
+#if defined(ATXFER_NULL_TECH)
+/*!
+ * \internal
+ * \brief Set the channel technology to the NULL technology.
+ *
+ * \param chan Channel to change technology.
+ *
+ * \return Nothing
+ */
+static void set_null_chan_tech(struct ast_channel *chan)
+{
+	int idx;
+
+	ast_channel_lock(chan);
+
+	/* Hangup the channel's physical side */
+	if (chan->tech->hangup) {
+		chan->tech->hangup(chan);
+	}
+	if (chan->tech_pvt) {
+		ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n",
+			chan->name);
+		ast_free(chan->tech_pvt);
+		chan->tech_pvt = NULL;
+	}
+
+	/* Install the NULL technology and wake up anyone waiting on it. */
+	chan->tech = &null_tech;
+	for (idx = 0; idx < AST_MAX_FDS; ++idx) {
+		switch (idx) {
+		case AST_ALERT_FD:
+		case AST_TIMING_FD:
+		case AST_GENERATOR_FD:
+			/* Don't clear these fd's. */
+			break;
+		default:
+			ast_channel_set_fd(chan, idx, -1);
+			break;
+		}
+	}
+	ast_queue_frame(chan, &ast_null_frame);
+
+	ast_channel_unlock(chan);
+}
+#endif	/* defined(ATXFER_NULL_TECH) */
+
+#if defined(ATXFER_NULL_TECH)
+/*!
+ * \internal
+ * \brief Set the channel name to something unique.
+ *
+ * \param chan Channel to change name.
+ *
+ * \return Nothing
+ */
+static void set_new_chan_name(struct ast_channel *chan)
+{
+	static int seq_num_last;
+	int seq_num;
+	int len;
+	char *chan_name;
+	char dummy[1];
+
+	/* Create the new channel name string. */
+	ast_channel_lock(chan);
+	seq_num = ast_atomic_fetchadd_int(&seq_num_last, +1);
+	len = snprintf(dummy, sizeof(dummy), "%s<XFER_%x>", chan->name, seq_num) + 1;
+	chan_name = alloca(len);
+	snprintf(chan_name, len, "%s<XFER_%x>", chan->name, seq_num);
+	ast_channel_unlock(chan);
+
+	ast_change_name(chan, chan_name);
+}
+#endif	/* defined(ATXFER_NULL_TECH) */
+
 static void *dial_features_duplicate(void *data)
 {
 	struct ast_dial_features *df = data, *df_copy;
@@ -573,7 +741,10 @@
 	}
 }
 
-static struct ast_channel *feature_request_and_dial(struct ast_channel *caller, struct ast_channel *transferee, const char *type, struct ast_format_cap *cap, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, int igncallerstate, const char *language);
+static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
+	const char *caller_name, struct ast_channel *requestor,
+	struct ast_channel *transferee, const char *type, struct ast_format_cap *cap, void *data,
+	int timeout, int *outstate, const char *language);
 
 /*!
  * \brief bridge the call 
@@ -1704,9 +1875,21 @@
 
 	ast_stopstream(transferer);
 	res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
-	if (res < 0) {  /* hangup, would be 0 for invalid and 1 for valid */
+	if (res < 0) {  /* hangup or error, (would be 0 for invalid and 1 for valid) */
 		finishup(transferee);
-		return res;
+		return -1;
+	}
+	if (res == 0) {
+		if (xferto[0]) {
+			ast_log(LOG_WARNING, "Extension '%s' does not exist in context '%s'\n",
+				xferto, transferer_real_context);
+		} else {
+			/* Does anyone care about this case? */
+			ast_log(LOG_WARNING, "No digits dialed.\n");
+		}
+		ast_stream_and_wait(transferer, "pbx-invalid", "");
+		finishup(transferee);
+		return AST_FEATURE_RETURN_SUCCESS;
 	}
 
 	found_lot = ao2_callback(parkinglots, 0, find_parkinglot_by_exten_cb, &xferto);
@@ -1715,9 +1898,8 @@
 			.parkinglot = found_lot,
 		};
 		res = finishup(transferee);
-		if (res)
-			res = -1;
-		else if (!(parkstatus = masq_park_call_announce(transferee, transferer, &args))) {	/* success */
+		if (res) {
+		} else if (!(parkstatus = masq_park_call_announce(transferee, transferer, &args))) {	/* success */
 			/* We return non-zero, but tell the PBX not to hang the channel when
 			   the thread dies -- We have to be careful now though.  We are responsible for 
 			   hanging up the channel, else it will never be hung up! */
@@ -1726,9 +1908,8 @@
 		} else {
 			ast_log(LOG_WARNING, "Unable to park call %s, parkstatus = %d\n", transferee->name, parkstatus);
 		}
-		/*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
-	} else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1,

[... 1685 lines stripped ...]



More information about the asterisk-commits mailing list