[svn-commits] mmichelson: branch mmichelson/queue-reset r99025 - in /team/mmichelson/queue-...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Jan 18 10:58:32 CST 2008


Author: mmichelson
Date: Fri Jan 18 10:58:31 2008
New Revision: 99025

URL: http://svn.digium.com/view/asterisk?view=rev&rev=99025
Log:
Hmmm...automerge should have done this, but I guess the svn server's downtime
meant automerge was disabled. Luckily there were not conflicts to resolve. Just updating
the branch with the latest changes to trunk.


Added:
    team/mmichelson/queue-reset/res/res_config_curl.c
      - copied unchanged from r99018, trunk/res/res_config_curl.c
Modified:
    team/mmichelson/queue-reset/   (props changed)
    team/mmichelson/queue-reset/CHANGES
    team/mmichelson/queue-reset/CREDITS
    team/mmichelson/queue-reset/Makefile
    team/mmichelson/queue-reset/acinclude.m4
    team/mmichelson/queue-reset/apps/app_queue.c
    team/mmichelson/queue-reset/apps/app_voicemail.c
    team/mmichelson/queue-reset/build_tools/cflags.xml
    team/mmichelson/queue-reset/build_tools/menuselect-deps.in
    team/mmichelson/queue-reset/cdr/cdr_adaptive_odbc.c
    team/mmichelson/queue-reset/channels/chan_console.c
    team/mmichelson/queue-reset/channels/chan_iax2.c
    team/mmichelson/queue-reset/channels/chan_local.c
    team/mmichelson/queue-reset/channels/chan_sip.c
    team/mmichelson/queue-reset/channels/chan_zap.c
    team/mmichelson/queue-reset/codecs/codec_speex.c
    team/mmichelson/queue-reset/codecs/codec_zap.c
    team/mmichelson/queue-reset/configs/cdr_adaptive_odbc.conf.sample
    team/mmichelson/queue-reset/configs/phoneprov.conf.sample
    team/mmichelson/queue-reset/configs/sip.conf.sample
    team/mmichelson/queue-reset/configs/zapata.conf.sample
    team/mmichelson/queue-reset/configure
    team/mmichelson/queue-reset/configure.ac
    team/mmichelson/queue-reset/doc/tex/phoneprov.tex
    team/mmichelson/queue-reset/funcs/func_cut.c
    team/mmichelson/queue-reset/funcs/func_odbc.c
    team/mmichelson/queue-reset/include/asterisk/autoconfig.h.in
    team/mmichelson/queue-reset/include/asterisk/frame.h
    team/mmichelson/queue-reset/include/asterisk/translate.h
    team/mmichelson/queue-reset/main/abstract_jb.c
    team/mmichelson/queue-reset/main/ast_expr2.c
    team/mmichelson/queue-reset/main/ast_expr2.h
    team/mmichelson/queue-reset/main/ast_expr2.y
    team/mmichelson/queue-reset/main/asterisk.c
    team/mmichelson/queue-reset/main/channel.c
    team/mmichelson/queue-reset/main/dial.c
    team/mmichelson/queue-reset/main/dsp.c
    team/mmichelson/queue-reset/main/frame.c
    team/mmichelson/queue-reset/main/rtp.c
    team/mmichelson/queue-reset/main/translate.c
    team/mmichelson/queue-reset/main/utils.c
    team/mmichelson/queue-reset/makeopts.in
    team/mmichelson/queue-reset/res/res_odbc.c
    team/mmichelson/queue-reset/res/res_phoneprov.c

Propchange: team/mmichelson/queue-reset/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.

Propchange: team/mmichelson/queue-reset/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/mmichelson/queue-reset/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Fri Jan 18 10:58:31 2008
@@ -23,3 +23,4 @@
 autom4te.cache
 makeopts.embed_rules
 aclocal.m4
+update.log

Propchange: team/mmichelson/queue-reset/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri Jan 18 10:58:31 2008
@@ -1,1 +1,1 @@
-/trunk:1-98909
+/trunk:1-99024

Modified: team/mmichelson/queue-reset/CHANGES
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue-reset/CHANGES?view=diff&rev=99025&r1=99024&r2=99025
==============================================================================
--- team/mmichelson/queue-reset/CHANGES (original)
+++ team/mmichelson/queue-reset/CHANGES Fri Jan 18 10:58:31 2008
@@ -79,6 +79,9 @@
      output to make debugging on busy systems much easier.
   * New CLI commands "dialplan set extenpatternmatching true/false"
   * New CLI command: "core set chanvar" to set a channel variable from the CLI.
+  * Added an easy way to execute Asterisk CLI commands at startup.  Any commands
+    listed in the startup_commands file in the Asterisk configuration directory
+    will get executed.
 
 SIP changes
 -----------
@@ -448,6 +451,10 @@
      on as the channel's audio.  This is very useful for building custom
      vocoders or doing recording or analysis of the channel's audio in another
      application.
+  * Added a new module, res_config_curl, which permits using a HTTP POST url
+     to retrieve, create, update, and delete realtime information from a remote
+     web server.  Note that this module requires func_curl.so to be loaded for
+     backend functionality.
 
 Miscellaneous 
 -------------
@@ -480,4 +487,5 @@
   * A new option when starting a remote asterisk (rasterisk, asterisk -r) for
      specifying which socket to use to connect to the running Asterisk daemon
      (-s)
-
+  * Added logging to 'make update' command.  See update.log
+

Modified: team/mmichelson/queue-reset/CREDITS
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue-reset/CREDITS?view=diff&rev=99025&r1=99024&r2=99025
==============================================================================
--- team/mmichelson/queue-reset/CREDITS (original)
+++ team/mmichelson/queue-reset/CREDITS Fri Jan 18 10:58:31 2008
@@ -16,6 +16,9 @@
 nic.at - ENUM support in Asterisk
 
 Paul Bagyenda, Digital Solutions - for initial Voicetronix driver development
+
+John Todd, TalkPlus, Inc.  and JR Richardson, Ntegrated Solutions. - for funding
+    the development of SIP Session Timers support.
 
 === WISHLIST CONTRIBUTERS ===
 Jeremy McNamara - SpeeX support

Modified: team/mmichelson/queue-reset/Makefile
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue-reset/Makefile?view=diff&rev=99025&r1=99024&r2=99025
==============================================================================
--- team/mmichelson/queue-reset/Makefile (original)
+++ team/mmichelson/queue-reset/Makefile Fri Jan 18 10:58:31 2008
@@ -275,9 +275,7 @@
 
 # XXX MALLOC_DEBUG is probably unused, Makefile.moddir_rules adds the
 #	value directly to ASTCFLAGS
-# XXX BUSYDETECT is probably useless, the only similar reference is to
-#	#ifdef BUSYDETECT in main/dsp.c
-ASTCFLAGS+=$(MALLOC_DEBUG)$(BUSYDETECT)$(OPTIONS)
+ASTCFLAGS+=$(MALLOC_DEBUG)$(OPTIONS)
 
 MOD_SUBDIRS:=channels pbx apps codecs formats cdr funcs tests main res $(LOCAL_MOD_SUBDIRS)
 OTHER_SUBDIRS:=utils agi
@@ -474,7 +472,10 @@
 update: 
 	@if [ -d .svn ]; then \
 		echo "Updating from Subversion..." ; \
+		fromrev="`svn info | $(AWK) '/Revision: / {print $$2}'`"; \
 		svn update | tee update.out; \
+		torev="`svn info | $(AWK) '/Revision: / {print $$2}'`"; \
+		echo "`date`  Updated from revision $${fromrev} to $${torev}." >> update.log; \
 		rm -f .version; \
 		if [ `grep -c ^C update.out` -gt 0 ]; then \
 			echo ; echo "The following files have conflicts:" ; \

Modified: team/mmichelson/queue-reset/acinclude.m4
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue-reset/acinclude.m4?view=diff&rev=99025&r1=99024&r2=99025
==============================================================================
--- team/mmichelson/queue-reset/acinclude.m4 (original)
+++ team/mmichelson/queue-reset/acinclude.m4 Fri Jan 18 10:58:31 2008
@@ -210,9 +210,9 @@
 
 # Check for a package using $2-config. Similar to AST_EXT_LIB_CHECK,
 # but use $2-config to determine cflags and libraries to use.
-# $3 and $4 can be used to replace --cflags and --libs in the request 
-
-# AST_EXT_TOOL_CHECK([package], [tool name], [--cflags], [--libs])
+# $3 and $4 can be used to replace --cflags and --libs in the request
+
+# AST_EXT_TOOL_CHECK([package], [tool name], [--cflags], [--libs], [includes], [expression])
 AC_DEFUN([AST_EXT_TOOL_CHECK],
 [
     if test "x${PBX_$1}" != "x1" -a "${USE_$1}" != "no"; then
@@ -223,8 +223,27 @@
 	    $1_INCLUDE=$(${CONFIG_$1} $A)
 	    if test x"$4" = x ; then A=--libs ; else A="$4" ; fi
 	    $1_LIB=$(${CONFIG_$1} $A)
-	    PBX_$1=1
-	    AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 libraries.])
+	    if test x"$5" != x ; then
+		saved_cppflags="${CPPFLAGS}"
+		if test "x${$1_DIR}" != "x"; then
+		    $1_INCLUDE="-I${$1_DIR}/include"
+		fi
+		CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE}"
+
+		AC_COMPILE_IFELSE(
+		    [ AC_LANG_PROGRAM( [ $5 ],
+				       [ $6; ]
+				       )],
+		    [   PBX_$1=1
+			AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 headers.])
+		    ],
+		    []
+		)
+		CPPFLAGS="${saved_cppflags}"
+	    else
+		PBX_$1=1
+		AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 libraries.])
+	    fi
 	fi
     fi
 ])

Modified: team/mmichelson/queue-reset/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue-reset/apps/app_queue.c?view=diff&rev=99025&r1=99024&r2=99025
==============================================================================
--- team/mmichelson/queue-reset/apps/app_queue.c (original)
+++ team/mmichelson/queue-reset/apps/app_queue.c Fri Jan 18 10:58:31 2008
@@ -847,7 +847,7 @@
 			ast_copy_string(cur->membername, interface, sizeof(cur->membername));
 		if (!strchr(cur->interface, '/'))
 			ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
-		cur->status = ast_device_state(interface);
+		cur->status = ast_device_state(cur->state_interface);
 	}
 
 	return cur;

Modified: team/mmichelson/queue-reset/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue-reset/apps/app_voicemail.c?view=diff&rev=99025&r1=99024&r2=99025
==============================================================================
--- team/mmichelson/queue-reset/apps/app_voicemail.c (original)
+++ team/mmichelson/queue-reset/apps/app_voicemail.c Fri Jan 18 10:58:31 2008
@@ -3466,7 +3466,7 @@
 	if (box == 1) return 10;
 	/* get the real IMAP message number for this message */
 	snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
-	ast_debug(3, "Copying sequence %s to mailbox %s\n",sequence,dbox);
+	ast_debug(3, "Copying sequence %s to mailbox %s\n",sequence,mbox(box));
 	res = mail_copy(vms->mailstream,sequence,(char *) mbox(box));
 	if (res == 1) return 0;
 	return 1;
@@ -5030,11 +5030,6 @@
 		return -1;
 	}
 	
-	/* Check Quota (here for now to test) */
-	mail_parameters(NULL, SET_QUOTA, (void *) mm_parsequota);
-	imap_mailbox_name(dbox, sizeof(dbox), vms, box, 1);
-	imap_getquotaroot(vms->mailstream, dbox);
-
 	/* Check Quota */
 	if  (box == 0)  {
 		ast_debug(3, "Mailbox name set to: %s, about to check quotas\n", mbox(box));

Modified: team/mmichelson/queue-reset/build_tools/cflags.xml
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue-reset/build_tools/cflags.xml?view=diff&rev=99025&r1=99024&r2=99025
==============================================================================
--- team/mmichelson/queue-reset/build_tools/cflags.xml (original)
+++ team/mmichelson/queue-reset/build_tools/cflags.xml Fri Jan 18 10:58:31 2008
@@ -48,4 +48,15 @@
 		</member>
 		<member name="THREAD_CRASH" displayname="Crash on mutex errors">
 		</member>
+		<member name="BUSYDETECT_TONEONLY" displayname="Enable additional comparision of only the tone duration not the silence part">
+			<conflict>BUSYDETECT_COMPARE_TONE_AND_SILENCE</conflict>
+			<defaultenabled>no</defaultenabled>
+		</member>
+		<member name="BUSYDETECT_COMPARE_TONE_AND_SILENCE" displayname="Assume that tone and silence have the same duration">
+			<conflict>BUSYDETECT_TONEONLY</conflict>
+			<defaultenabled>no</defaultenabled>
+		</member>
+		<member name="BUSYDETECT_DEBUG" displayname="Enable additional busy detection debugging">
+			<defaultenabled>no</defaultenabled>
+		</member>
 	</category>

Modified: team/mmichelson/queue-reset/build_tools/menuselect-deps.in
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue-reset/build_tools/menuselect-deps.in?view=diff&rev=99025&r1=99024&r2=99025
==============================================================================
--- team/mmichelson/queue-reset/build_tools/menuselect-deps.in (original)
+++ team/mmichelson/queue-reset/build_tools/menuselect-deps.in Fri Jan 18 10:58:31 2008
@@ -29,6 +29,7 @@
 PRI=@PBX_PRI@
 RADIUS=@PBX_RADIUS@
 SPEEX=@PBX_SPEEX@
+SPEEXDSP=@PBX_SPEEXDSP@
 SQLITE3=@PBX_SQLITE3@
 SQLITE=@PBX_SQLITE@
 SS7=@PBX_SS7@

Modified: team/mmichelson/queue-reset/cdr/cdr_adaptive_odbc.c
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue-reset/cdr/cdr_adaptive_odbc.c?view=diff&rev=99025&r1=99024&r2=99025
==============================================================================
--- team/mmichelson/queue-reset/cdr/cdr_adaptive_odbc.c (original)
+++ team/mmichelson/queue-reset/cdr/cdr_adaptive_odbc.c Fri Jan 18 10:58:31 2008
@@ -56,6 +56,7 @@
 struct columns {
 	char *name;
 	char *cdrname;
+	char *filtervalue;
 	SQLSMALLINT type;
 	SQLINTEGER size;
 	SQLSMALLINT decimals;
@@ -152,6 +153,31 @@
 
 		ast_verb(3, "Found adaptive CDR table %s@%s.\n", tableptr->table, tableptr->connection);
 
+		/* Check for filters first */
+		for (var = ast_variable_browse(cfg, catg); var; var = var->next) {
+			if (strncmp(var->name, "filter", 6) == 0) {
+				char *cdrvar = ast_strdupa(var->name + 6);
+				cdrvar = ast_strip(cdrvar);
+				ast_verb(3, "Found filter %s for cdr variable %s in %s@%s\n", var->value, cdrvar, tableptr->table, tableptr->connection);
+
+				entry = ast_calloc(sizeof(char), sizeof(*entry) + strlen(cdrvar) + 1 + strlen(var->value) + 1);
+				if (!entry) {
+					ast_log(LOG_ERROR, "Out of memory creating filter entry for CDR variable '%s' in table '%s' on connection '%s'\n", cdrvar, table, connection);
+					res = -1;
+					break;
+				}
+
+				/* NULL column entry means this isn't a column in the database */
+				entry->name = NULL;
+				entry->cdrname = (char *)entry + sizeof(*entry);
+				entry->filtervalue = (char *)entry + sizeof(*entry) + strlen(cdrvar) + 1;
+				strcpy(entry->cdrname, cdrvar);
+				strcpy(entry->filtervalue, var->value);
+
+				AST_LIST_INSERT_TAIL(&(tableptr->columns), entry, list);
+			}
+		}
+
 		while ((res = SQLFetch(stmt)) != SQL_NO_DATA && res != SQL_ERROR) {
 			char *cdrvar = "";
 
@@ -164,13 +190,14 @@
 			 * really don't parse this file all that often, anyway.
 			 */
 			for (var = ast_variable_browse(cfg, catg); var; var = var->next) {
-				if (strcasecmp(var->value, columnname) == 0) {
+				if (strncmp(var->name, "alias", 5) == 0 && strcasecmp(var->value, columnname) == 0) {
 					char *tmp = ast_strdupa(var->name + 5);
 					cdrvar = ast_strip(tmp);
 					ast_verb(3, "Found alias %s for column %s in %s@%s\n", cdrvar, columnname, tableptr->table, tableptr->connection);
 					break;
 				}
 			}
+
 			entry = ast_calloc(sizeof(char), sizeof(*entry) + strlen(columnname) + 1 + strlen(cdrvar) + 1);
 			if (!entry) {
 				ast_log(LOG_ERROR, "Out of memory creating entry for column '%s' in table '%s' on connection '%s'\n", columnname, table, connection);
@@ -341,6 +368,21 @@
 				 strcasecmp(entry->cdrname, "end") == 0) ? 0 : 1);
 
 			if (colptr) {
+				/* Check first if the column filters this entry.  Note that this
+				 * is very specifically NOT ast_strlen_zero(), because the filter
+				 * could legitimately specify that the field is blank, which is
+				 * different from the field being unspecified (NULL). */
+				if (entry->filtervalue && strcasecmp(colptr, entry->filtervalue) != 0) {
+					ast_verb(4, "CDR column '%s' with value '%s' does not match filter of"
+						" '%s'.  Cancelling this CDR.\n",
+						entry->cdrname, colptr, entry->filtervalue);
+					goto early_release;
+				}
+
+				/* Only a filter? */
+				if (ast_strlen_zero(entry->name))
+					continue;
+
 				LENGTHEN_BUF1(strlen(entry->name));
 
 				switch (entry->type) {
@@ -567,6 +609,7 @@
 		if (rows == 0) {
 			ast_log(LOG_WARNING, "cdr_adaptive_odbc: Insert failed on '%s:%s'.  CDR failed: %s\n", tableptr->connection, tableptr->table, sql);
 		}
+early_release:
 		ast_odbc_release_obj(obj);
 	}
 	AST_RWLIST_UNLOCK(&odbc_tables);

Modified: team/mmichelson/queue-reset/channels/chan_console.c
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue-reset/channels/chan_console.c?view=diff&rev=99025&r1=99024&r2=99025
==============================================================================
--- team/mmichelson/queue-reset/channels/chan_console.c (original)
+++ team/mmichelson/queue-reset/channels/chan_console.c Fri Jan 18 10:58:31 2008
@@ -787,7 +787,11 @@
 	if (a->argc != e->args)
 		return CLI_SHOWUSAGE;
 
-	ast_cli(a->fd, "Available Devices:\n---------------------------------\n");
+	ast_cli(a->fd, "\n"
+	            "=============================================================\n"
+	            "=== Available Devices =======================================\n"
+	            "=============================================================\n"
+	            "===\n");
 
 	num = Pa_GetDeviceCount();
 	if (!num) {
@@ -801,12 +805,16 @@
 		const PaDeviceInfo *dev = Pa_GetDeviceInfo(index);
 		if (!dev)
 			continue;
-		ast_cli(a->fd, "Device Name: %s\n", dev->name);
-		if (index == def_input)
-			ast_cli(a->fd, "    ---> Default Input Device\n");
-		if (index == def_output)
-			ast_cli(a->fd, "    ---> Default Output Device\n");
-	}
+		ast_cli(a->fd, "=== ---------------------------------------------------------\n"
+		               "=== Device Name: %s\n", dev->name);
+		if (dev->maxInputChannels)
+			ast_cli(a->fd, "=== ---> %sInput Device\n", (index == def_input) ? "Default " : "");
+		if (dev->maxOutputChannels)
+			ast_cli(a->fd, "=== ---> %sOutput Device\n", (index == def_output) ? "Default " : "");
+		ast_cli(a->fd, "=== ---------------------------------------------------------\n===\n");
+	}
+
+	ast_cli(a->fd, "=============================================================\n\n");
 
 	return CLI_SUCCESS;
 }

Modified: team/mmichelson/queue-reset/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue-reset/channels/chan_iax2.c?view=diff&rev=99025&r1=99024&r2=99025
==============================================================================
--- team/mmichelson/queue-reset/channels/chan_iax2.c (original)
+++ team/mmichelson/queue-reset/channels/chan_iax2.c Fri Jan 18 10:58:31 2008
@@ -1935,7 +1935,7 @@
 	  the IAX thread with the iaxsl lock held. */
 	struct iax_frame *fr = data;
 	fr->retrans = -1;
-	fr->af.has_timing_info = 0;
+	ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
 	if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
 		iax2_queue_frame(fr->callno, &fr->af);
 	/* Free our iax frame */
@@ -2951,7 +2951,7 @@
 	if (peername) {
 		var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
 		if (!var && sin)
-			var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr));
+			var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
 	} else if (sin) {
 		char porta[25];
 		sprintf(porta, "%d", ntohs(sin->sin_port));
@@ -3068,7 +3068,7 @@
 
 	var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
 	if (!var)
-		var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr));
+		var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
 	if (!var && sin) {
 		char porta[6];
 		snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
@@ -3162,10 +3162,11 @@
 	char mohsuggest[MAX_MUSICCLASS];
 };
 
-static int create_addr(const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai)
+static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
 {
 	struct iax2_peer *peer;
 	int res = -1;
+	struct ast_codec_pref ourprefs;
 
 	ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
 	cai->sockfd = defaultsockfd;
@@ -3180,7 +3181,11 @@
 		}
 		sin->sin_port = htons(IAX_DEFAULT_PORTNO);
 		/* use global iax prefs for unknown peer/user */
-		ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1);
+		/* But move the calling channel's native codec to the top of the preference list */
+		memcpy(&ourprefs, &prefs, sizeof(ourprefs));
+		if (c)
+			ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
+		ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
 		return 0;
 	}
 
@@ -3200,7 +3205,13 @@
 	cai->encmethods = peer->encmethods;
 	cai->sockfd = peer->sockfd;
 	cai->adsi = peer->adsi;
-	ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1);
+	memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
+	/* Move the calling channel's native codec to the top of the preference list */
+	if (c) {
+		ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
+		ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
+	}
+	ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
 	ast_copy_string(cai->context, peer->context, sizeof(cai->context));
 	ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
 	ast_copy_string(cai->username, peer->username, sizeof(cai->username));
@@ -3378,7 +3389,7 @@
 	if (!pds.exten)
 		pds.exten = defaultrdest;
 
-	if (create_addr(pds.peer, &sin, &cai)) {
+	if (create_addr(pds.peer, c, &sin, &cai)) {
 		ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
 		return -1;
 	}
@@ -9289,7 +9300,7 @@
 	if (end) {
 		memcpy(&sin, end, sizeof(sin));
 		cai.sockfd = sockfd;
-	} else if (create_addr(dest, &sin, &cai))
+	} else if (create_addr(dest, NULL, &sin, &cai))
 		return -1;
 
 	/* Build the rest of the message */
@@ -9525,7 +9536,7 @@
 	       
 	
 	/* Populate our address from the given */
-	if (create_addr(pds.peer, &sin, &cai)) {
+	if (create_addr(pds.peer, NULL, &sin, &cai)) {
 		*cause = AST_CAUSE_UNREGISTERED;
 		return NULL;
 	}
@@ -10895,7 +10906,7 @@
 	parse_dial_string(tmpstr, &pds);
 
 	/* Populate our address from the given */
-	if (create_addr(pds.peer, &sin, &cai))
+	if (create_addr(pds.peer, NULL, &sin, &cai))
 		return -1;
 
 	ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",

Modified: team/mmichelson/queue-reset/channels/chan_local.c
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue-reset/channels/chan_local.c?view=diff&rev=99025&r1=99024&r2=99025
==============================================================================
--- team/mmichelson/queue-reset/channels/chan_local.c (original)
+++ team/mmichelson/queue-reset/channels/chan_local.c Fri Jan 18 10:58:31 2008
@@ -501,8 +501,16 @@
 	isoutbound = IS_OUTBOUND(ast, p);
 	if (isoutbound) {
 		const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
-		if ((status) && (p->owner))
+		if ((status) && (p->owner)) {
+			/* Deadlock avoidance */
+			while (ast_channel_trylock(p->owner)) {
+				ast_mutex_unlock(&p->lock);
+				usleep(1);
+				ast_mutex_lock(&p->lock);
+			}
 			pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
+			ast_channel_unlock(p->owner);
+		}
 		p->chan = NULL;
 		ast_clear_flag(p, LOCAL_LAUNCHED_PBX);
 		ast_module_user_remove(p->u_chan);

Modified: team/mmichelson/queue-reset/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue-reset/channels/chan_sip.c?view=diff&rev=99025&r1=99024&r2=99025
==============================================================================
--- team/mmichelson/queue-reset/channels/chan_sip.c (original)
+++ team/mmichelson/queue-reset/channels/chan_sip.c Fri Jan 18 10:58:31 2008
@@ -86,6 +86,45 @@
         <depend>res_features</depend>
  ***/
 
+/*!  \page sip_session_timers SIP Session Timers in Asterisk Chan_sip
+
+	The SIP Session-Timers is an extension of the SIP protocol that allows end-points and proxies to
+	refresh a session periodically. The sessions are kept alive by sending a RE-INVITE or UPDATE
+	request at a negotiated interval. If a session refresh fails then all the entities that support Session-
+	Timers clear their internal session state. In addition, UAs generate a BYE request in order to clear
+	the state in the proxies and the remote UA (this is done for the benefit of SIP entities in the path
+	that do not support Session-Timers).
+
+	The Session-Timers can be configured on a system-wide, per-user, or per-peer basis. The peruser/
+	per-peer settings override the global settings. The following new parameters have been
+	added to the sip.conf file.
+		session-timers=["accept", "originate", "refuse"]
+		session-expires=[integer]
+		session-minse=[integer]
+		session-refresher=["uas", "uac"]
+
+	The session-timers parameter in sip.conf defines the mode of operation of SIP session-timers feature in
+	Asterisk. The Asterisk can be configured in one of the following three modes:
+
+	1. Accept :: In the "accept" mode, the Asterisk server honors session-timers requests
+		made by remote end-points. A remote end-point can request Asterisk to engage
+		session-timers by either sending it an INVITE request with a "Supported: timer"
+		header in it or by responding to Asterisk's INVITE with a 200 OK that contains
+		Session-Expires: header in it. In this mode, the Asterisk server does not 
+		request session-timers from remote end-points. This is the default mode.
+	2. Originate :: In the "originate" mode, the Asterisk server requests the remote 
+		end-points to activate session-timers in addition to honoring such requests
+		made by the remote end-pints. In order to get as much protection as possible
+		against hanging SIP channels due to network or end-point failures, Asterisk
+		resends periodic re-INVITEs even if a remote end-point does not support
+		the session-timers feature.
+	3. Refuse :: In the "refuse" mode, Asterisk acts as if it does not support session-
+		timers for inbound or outbound requests. If a remote end-point requests
+		session-timers in a dialog, then Asterisk ignores that request unless it's
+		noted as a requirement (Require: header), in which case the INVITE is 
+		rejected with a 420 Bad Extension response.
+
+*/
 
 #include "asterisk.h"
 
@@ -198,6 +237,9 @@
 
 #define INITIAL_CSEQ                 101              /*!< our initial sip sequence number */
 
+#define DEFAULT_MAX_SE               1800             /*!< Session-Timer Default Session-Expires period (RFC 4028) */
+#define DEFAULT_MIN_SE               90               /*!< Session-Timer Default Min-SE period (RFC 4028) */
+
 /*! \brief Global jitterbuffer configuration - by default, jb is disabled */
 static struct ast_jb_conf default_jbconf =
 {
@@ -346,6 +388,22 @@
 	REG_STATE_FAILED,	/*!< Registration failed after several tries */
 		/* fatal - no chance to proceed */
 };
+
+/*! \brief Modes in which Asterisk can be configured to run SIP Session-Timers */
+enum st_mode {
+        SESSION_TIMER_MODE_INVALID = 0, /*!< Invalid value */ 
+        SESSION_TIMER_MODE_ACCEPT,      /*!< Honor inbound Session-Timer requests */
+        SESSION_TIMER_MODE_ORIGINATE,   /*!< Originate outbound and honor inbound requests */
+        SESSION_TIMER_MODE_REFUSE       /*!< Ignore inbound Session-Timers requests */
+};
+
+/*! \brief The entity playing the refresher role for Session-Timers */
+enum st_refresher {
+        SESSION_TIMER_REFRESHER_AUTO,    /*!< Negotiated                      */
+        SESSION_TIMER_REFRESHER_UAC,     /*!< Session is refreshed by the UAC */
+        SESSION_TIMER_REFRESHER_UAS      /*!< Session is refreshed by the UAS */
+};
+
 
 /*! \brief definition of a sip proxy server
  *
@@ -458,6 +516,8 @@
 #define SIP_OPT_NOREFERSUB	(1 << 14)
 #define SIP_OPT_HISTINFO	(1 << 15)
 #define SIP_OPT_RESPRIORITY	(1 << 16)
+#define SIP_OPT_UNKNOWN		(1 << 17)
+
 
 /*! \brief List of well-known SIP options. If we get this in a require,
    we should check the list and answer accordingly. */
@@ -472,8 +532,8 @@
 	{ SIP_OPT_REPLACES,	SUPPORTED,	"replace" },	
 	/* RFC3262: PRACK 100% reliability */
 	{ SIP_OPT_100REL,	NOT_SUPPORTED,	"100rel" },	
-	/* RFC4028: SIP Session Timers */
-	{ SIP_OPT_TIMER,	NOT_SUPPORTED,	"timer" },
+	/* RFC4028: SIP Session-Timers */
+	{ SIP_OPT_TIMER,	SUPPORTED,	"timer" },
 	/* RFC3959: SIP Early session support */
 	{ SIP_OPT_EARLY_SESSION, NOT_SUPPORTED,	"early-session" },
 	/* RFC3911: SIP Join header support */
@@ -512,7 +572,7 @@
 #define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY"
 
 /*! \brief SIP Extensions we support */
-#define SUPPORTED_EXTENSIONS "replaces" 
+#define SUPPORTED_EXTENSIONS "replaces, timer" 
 
 /*! \brief Standard SIP port from RFC 3261. DO NOT CHANGE THIS */
 #define STANDARD_SIP_PORT	5060
@@ -666,6 +726,12 @@
 static struct ast_flags global_flags[2] = {{0}};        /*!< global SIP_ flags */
 static char used_context[AST_MAX_CONTEXT]; /*!< name of automatically created context for unloading */
 
+static enum st_mode global_st_mode;           /*!< Mode of operation for Session-Timers           */
+static enum st_refresher global_st_refresher; /*!< Session-Timer refresher                        */
+static int global_min_se;                     /*!< Lowest threshold for session refresh interval  */
+static int global_max_se;                     /*!< Highest threshold for session refresh interval */
+
+
 AST_MUTEX_DEFINE_STATIC(netlock);
 
 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
@@ -1025,6 +1091,37 @@
 	int localtransfer;				/*!< Transfer to local domain? */
 	enum referstatus status;			/*!< REFER status */
 };
+
+
+/*! \brief Structure that encapsulates all attributes related to running 
+ *   SIP Session-Timers feature on a per dialog basis.
+ */
+struct sip_st_dlg {
+	int st_active;                          /*!< Session-Timers on/off */ 
+	int st_interval;                        /*!< Session-Timers negotiated session refresh interval */
+	int st_schedid;                         /*!< Session-Timers ast_sched scheduler id */
+	enum st_refresher st_ref;               /*!< Session-Timers session refresher */
+	int st_expirys;                         /*!< Session-Timers number of expirys */
+	int st_active_peer_ua;                  /*!< Session-Timers on/off in peer UA */
+	int st_cached_min_se;                   /*!< Session-Timers cached Min-SE */
+	int st_cached_max_se;                   /*!< Session-Timers cached Session-Expires */
+	enum st_mode st_cached_mode;            /*!< Session-Timers cached M.O. */
+	enum st_refresher st_cached_ref;        /*!< Session-Timers cached refresher */
+};
+
+
+/*! \brief Structure that encapsulates all attributes related to configuration 
+ *   of SIP Session-Timers feature on a per user/peer basis.
+ */
+struct sip_st_cfg {
+	enum st_mode st_mode_oper;      /*!< Mode of operation for Session-Timers           */
+	enum st_refresher st_ref;       /*!< Session-Timer refresher                        */
+	int st_min_se;                  /*!< Lowest threshold for session refresh interval  */
+	int st_max_se;                  /*!< Highest threshold for session refresh interval */
+};
+
+
+
 
 /*! \brief sip_pvt: structures used for each SIP dialog, ie. a call, a registration, a subscribe.
  * Created and initialized by sip_alloc(), the descriptor goes into the list of
@@ -1098,6 +1195,7 @@
 	int timer_t1;				/*!< SIP timer T1, ms rtt */
 	int timer_b;            /*!< SIP timer B, ms */
 	unsigned int sipoptions;		/*!< Supported SIP options on the other end */
+	unsigned int reqsipoptions;		/*!< Required SIP options on the other end */
 	struct ast_codec_pref prefs;		/*!< codec prefs */
 	int capability;				/*!< Special capability (codec) */
 	int jointcapability;			/*!< Supported capability at both ends (codecs) */
@@ -1118,6 +1216,8 @@
 	char tag[11];				/*!< Our tag for this session */
 	int sessionid;				/*!< SDP Session ID */
 	int sessionversion;			/*!< SDP Session Version */
+	int sessionversion_remote;		/*!< Remote UA's SDP Session Version */
+	int session_modify;			/*!< Session modification request true/false  */
 	struct sockaddr_in sa;			/*!< Our peer */
 	struct sockaddr_in redirip;		/*!< Where our RTP should be going if not to us */
 	struct sockaddr_in vredirip;		/*!< Where our Video RTP should be going if not to us */
@@ -1167,7 +1267,9 @@
 							before strolling to the Grokyzpå
 							(A bit unsure of this, please correct if
 							you know more) */
+	struct sip_st_dlg *stimer;		/*!< SIP Session-Timers */              
 };
+
 
 /*! Max entires in the history list for a sip_pvt */
 #define MAX_HISTORY_ENTRIES 50
@@ -1273,6 +1375,7 @@
 	struct ast_variable *chanvars;	/*!< Variables to set for channel created by user */
 	int maxcallbitrate;		/*!< Maximum Bitrate for a video call */
 	int autoframing;
+	struct sip_st_cfg stimer;	/*!< SIP Session-Timers */
 };
 
 /*!
@@ -1359,8 +1462,9 @@
 	struct ast_variable *chanvars;	/*!<  Variables to set for channel created by user */
 	struct sip_pvt *mwipvt;		/*!<  Subscription for MWI */
 	int autoframing;
-	int timer_t1;		/*!<  The maximum T1 value for the peer */
-	int timer_b;      /*!<  The maximum timer B (transaction timeouts) */
+	struct sip_st_cfg stimer;	/*!<  SIP Session-Timers */
+	int timer_t1;			/*!<  The maximum T1 value for the peer */
+	int timer_b;			/*!<  The maximum timer B (transaction timeouts) */
 };
 
 
@@ -1545,7 +1649,7 @@
 static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req);
 static int transmit_response_reliable(struct sip_pvt *p, const char *msg, const struct sip_request *req);
 static int transmit_response_with_date(struct sip_pvt *p, const char *msg, const struct sip_request *req);
-static int transmit_response_with_sdp(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable);
+static int transmit_response_with_sdp(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable, int oldsdp);
 static int transmit_response_with_unsupported(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported);
 static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *rand, enum xmittype reliable, const char *header, int stale);
 static int transmit_response_with_allow(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable);
@@ -1553,7 +1657,7 @@
 static int transmit_request(struct sip_pvt *p, int sipmethod, int inc, enum xmittype reliable, int newbranch);
 static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch);
 static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init);
-static int transmit_reinvite_with_sdp(struct sip_pvt *p, int t38version);
+static int transmit_reinvite_with_sdp(struct sip_pvt *p, int t38version, int oldsdp);
 static int transmit_info_with_digit(struct sip_pvt *p, const char digit, unsigned int duration);
 static int transmit_info_with_vidupdate(struct sip_pvt *p);
 static int transmit_message_with_text(struct sip_pvt *p, const char *text);
@@ -1607,7 +1711,7 @@
 static void add_noncodec_to_sdp(const struct sip_pvt *p, int format, int sample_rate,
 				struct ast_str **m_buf, struct ast_str **a_buf,
 				int debug);
-static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p);
+static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int oldsdp);
 static void do_setnat(struct sip_pvt *p, int natflags);
 static void stop_media_flows(struct sip_pvt *p);
 
@@ -1844,6 +1948,21 @@
 static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan);
 static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
 
+/*------ Session-Timers functions --------- */
+static void proc_422_rsp(struct sip_pvt *p, struct sip_request *rsp);
+static int  proc_session_timer(const void *vp);
+static void stop_session_timer(struct sip_pvt *p);
+static void start_session_timer(struct sip_pvt *p);
+static void restart_session_timer(struct sip_pvt *p);
+static const char *strefresher2str(enum st_refresher r);
+static int parse_session_expires(const char *p_hdrval, int *const p_interval, enum st_refresher *const p_ref);
+static int parse_minse(const char *p_hdrval, int *const p_interval);
+static int st_get_se(struct sip_pvt *, int max);
+static enum st_refresher st_get_refresher(struct sip_pvt *);
+static enum st_mode st_get_mode(struct sip_pvt *);
+static struct sip_st_dlg* sip_st_alloc(struct sip_pvt *const p);
+
+
 /*! \brief Definition of this channel for PBX channel registration */
 static const struct ast_channel_tech sip_tech = {
 	.type = "SIP",
@@ -2106,6 +2225,14 @@
 				break;
 			}
 		}
+
+		/* This function is used to parse both Suported: and Require: headers.
+		Let the caller of this function know that an unknown option tag was 
+		encountered, so that if the UAC requires it then the request can be 
+		rejected with a 420 response. */
+		if (!found)
+			profile |= SIP_OPT_UNKNOWN;
+
 		if (!found && sipdebug) {
 			if (!strncasecmp(next, "x-", 2))
 				ast_debug(3, "Found private SIP option, not supported: %s\n", next);
@@ -2526,6 +2653,9 @@
 	if (p->do_history)
 		append_history(p, "SchedDestroy", "%d ms", ms);
 	p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p));
+
+	if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > 0)
+		stop_session_timer(p);
 }
 
 /*! \brief Cancel destruction of SIP dialog.
@@ -2867,7 +2997,7 @@
 		break;
 	case AST_STATE_UP:
 		if (!p->pendinginvite) {		/* We are up, and have no outstanding invite */
-			transmit_reinvite_with_sdp(p, FALSE);
+			transmit_reinvite_with_sdp(p, FALSE, FALSE);
 		} else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
 			ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);	
 		}	
@@ -3298,6 +3428,7 @@
 static void sip_destroy_user(struct sip_user *user)
 {
 	ast_debug(3, "Destroying user object from memory: %s\n", user->name);
+
 	ast_free_ha(user->ha);
 	if (user->chanvars) {
 		ast_variables_destroy(user->chanvars);
@@ -3782,6 +3913,13 @@
 		if (p->registry->call == p)
 			p->registry->call = NULL;
 		p->registry = registry_unref(p->registry);
+	}
+
+	/* Destroy Session-Timers if allocated */
+	if (p->stimer) {
+		if (p->stimer->st_active == TRUE && p->stimer->st_schedid > -1)
+			ast_sched_del(sched, p->stimer->st_schedid);
+		ast_free(p->stimer);
 	}
 
 	/* Unlink us from the owner if we have one */
@@ -4338,7 +4476,7 @@
 			ast_debug(2,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
 			res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
 		} else 
-			res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
+			res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, FALSE);
 	}
 	sip_pvt_unlock(p);
 	return res;
@@ -4371,7 +4509,7 @@
 				if ((ast->_state != AST_STATE_UP) &&
 				    !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
 				    !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
-					transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
+					transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE, FALSE);
 					ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);	
 				}
 				p->lastrtptx = time(NULL);
@@ -4388,7 +4526,7 @@
 				if ((ast->_state != AST_STATE_UP) &&
 				    !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
 				    !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
-					transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
+					transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE, FALSE);
 					ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);	
 				}

[... 3651 lines stripped ...]



More information about the svn-commits mailing list