[svn-commits] oej: branch oej/moremanager r181649 - in /team/oej/moremanager: ./ apps/ auto...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Mar 12 09:32:33 CDT 2009


Author: oej
Date: Thu Mar 12 09:32:23 2009
New Revision: 181649

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=181649
Log:
Reset automerge, fix conflicts

Added:
    team/oej/moremanager/channels/h323/ast_ptlib.h
      - copied unchanged from r181436, branches/1.4/channels/h323/ast_ptlib.h
Modified:
    team/oej/moremanager/   (props changed)
    team/oej/moremanager/apps/app_dahdiras.c
    team/oej/moremanager/apps/app_meetme.c
    team/oej/moremanager/apps/app_queue.c
    team/oej/moremanager/apps/app_speech_utils.c
    team/oej/moremanager/apps/app_voicemail.c
    team/oej/moremanager/autoconf/ast_check_gnu_make.m4
    team/oej/moremanager/autoconf/ast_check_pwlib.m4
    team/oej/moremanager/autoconf/ast_prog_sed.m4
    team/oej/moremanager/channels/chan_dahdi.c
    team/oej/moremanager/channels/chan_iax2.c
    team/oej/moremanager/channels/chan_local.c
    team/oej/moremanager/channels/chan_sip.c
    team/oej/moremanager/channels/h323/ast_h323.cxx
    team/oej/moremanager/channels/h323/ast_h323.h
    team/oej/moremanager/channels/h323/caps_h323.cxx
    team/oej/moremanager/channels/h323/caps_h323.h
    team/oej/moremanager/channels/h323/chan_h323.h
    team/oej/moremanager/channels/h323/cisco-h225.cxx
    team/oej/moremanager/channels/h323/cisco-h225.h
    team/oej/moremanager/channels/h323/compat_h323.cxx
    team/oej/moremanager/channels/h323/compat_h323.h
    team/oej/moremanager/channels/iax2-parser.h
    team/oej/moremanager/codecs/codec_dahdi.c
    team/oej/moremanager/configs/extensions.conf.sample
    team/oej/moremanager/configs/features.conf.sample
    team/oej/moremanager/configs/queues.conf.sample
    team/oej/moremanager/configs/voicemail.conf.sample
    team/oej/moremanager/configure
    team/oej/moremanager/configure.ac
    team/oej/moremanager/doc/channelvariables.txt
    team/oej/moremanager/include/asterisk/astmm.h
    team/oej/moremanager/include/asterisk/channel.h
    team/oej/moremanager/include/asterisk/config.h
    team/oej/moremanager/include/asterisk/frame.h
    team/oej/moremanager/include/asterisk/threadstorage.h
    team/oej/moremanager/include/asterisk/utils.h
    team/oej/moremanager/main/Makefile
    team/oej/moremanager/main/app.c
    team/oej/moremanager/main/ast_expr2.c
    team/oej/moremanager/main/ast_expr2.fl
    team/oej/moremanager/main/ast_expr2.h
    team/oej/moremanager/main/ast_expr2.y
    team/oej/moremanager/main/ast_expr2f.c
    team/oej/moremanager/main/asterisk.c
    team/oej/moremanager/main/callerid.c
    team/oej/moremanager/main/channel.c
    team/oej/moremanager/main/editline/configure
    team/oej/moremanager/main/editline/configure.in
    team/oej/moremanager/main/editline/np/unvis.c
    team/oej/moremanager/main/editline/sys.h
    team/oej/moremanager/main/enum.c
    team/oej/moremanager/main/frame.c
    team/oej/moremanager/main/pbx.c
    team/oej/moremanager/main/rtp.c
    team/oej/moremanager/main/utils.c
    team/oej/moremanager/pbx/ael/ael.tab.c
    team/oej/moremanager/pbx/ael/ael.y
    team/oej/moremanager/pbx/pbx_ael.c
    team/oej/moremanager/pbx/pbx_config.c
    team/oej/moremanager/res/res_features.c
    team/oej/moremanager/res/res_musiconhold.c
    team/oej/moremanager/utils/Makefile
    team/oej/moremanager/utils/expr2.testinput

Propchange: team/oej/moremanager/
------------------------------------------------------------------------------
    automerge = http://www.codename-pineapple.org/

Propchange: team/oej/moremanager/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Mar 12 09:32:23 2009
@@ -1,1 +1,1 @@
-/branches/1.4:1-176396
+/branches/1.4:1-181614

Modified: team/oej/moremanager/apps/app_dahdiras.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/moremanager/apps/app_dahdiras.c?view=diff&rev=181649&r1=181648&r2=181649
==============================================================================
--- team/oej/moremanager/apps/app_dahdiras.c (original)
+++ team/oej/moremanager/apps/app_dahdiras.c Thu Mar 12 09:32:23 2009
@@ -49,6 +49,9 @@
 #include <errno.h>
 #include <stdio.h>
 #include <fcntl.h>
+
+#include "asterisk/dahdi_compat.h"
+
 #ifdef HAVE_CAP
 #include <sys/capability.h>
 #endif /* HAVE_CAP */
@@ -60,8 +63,6 @@
 #include "asterisk/pbx.h"
 #include "asterisk/module.h"
 #include "asterisk/options.h"
-
-#include "asterisk/dahdi_compat.h"
 
 static char *dahdi_app = "DAHDIRAS";
 static char *zap_app = "ZapRAS";

Modified: team/oej/moremanager/apps/app_meetme.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/moremanager/apps/app_meetme.c?view=diff&rev=181649&r1=181648&r2=181649
==============================================================================
--- team/oej/moremanager/apps/app_meetme.c (original)
+++ team/oej/moremanager/apps/app_meetme.c Thu Mar 12 09:32:23 2009
@@ -1914,12 +1914,9 @@
 						ast_waitstream(chan, "");
 			}
 
-			c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
-			
-			
 			/* Update the struct with the actual confflags */
 			user->userflags = confflags;
-			
+
 			if (confflags & CONFFLAG_WAITMARKED) {
 				if(currentmarked == 0) {
 					if (lastmarked != 0) {
@@ -2040,6 +2037,8 @@
 			/* Perform an extra hangup check just in case */
 			if (ast_check_hangup(chan))
 				break;
+
+			c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
 
 			if (c) {
 				char dtmfstr[2] = "";
@@ -4735,7 +4734,7 @@
 			return -1;
 		}
 		if (ast_add_extension2(context, 0 /* don't replace */, "s", 1,
-			NULL, NULL, slatrunk_app, ast_strdup(trunk->name), ast_free, sla_registrar)) {
+			NULL, NULL, slatrunk_app, ast_strdup(trunk->name), ast_free_ptr, sla_registrar)) {
 			ast_log(LOG_ERROR, "Failed to automatically create extension "
 				"for trunk '%s'!\n", trunk->name);
 			destroy_trunk(trunk);
@@ -4874,7 +4873,7 @@
 		/* The extension for when the handset goes off-hook.
 		 * exten => station1,1,SLAStation(station1) */
 		if (ast_add_extension2(context, 0 /* don't replace */, station->name, 1,
-			NULL, NULL, slastation_app, ast_strdup(station->name), ast_free, sla_registrar)) {
+			NULL, NULL, slastation_app, ast_strdup(station->name), ast_free_ptr, sla_registrar)) {
 			ast_log(LOG_ERROR, "Failed to automatically create extension "
 				"for trunk '%s'!\n", station->name);
 			destroy_station(station);
@@ -4889,7 +4888,7 @@
 			/* Extension for this line button 
 			 * exten => station1_line1,1,SLAStation(station1_line1) */
 			if (ast_add_extension2(context, 0 /* don't replace */, exten, 1,
-				NULL, NULL, slastation_app, ast_strdup(exten), ast_free, sla_registrar)) {
+				NULL, NULL, slastation_app, ast_strdup(exten), ast_free_ptr, sla_registrar)) {
 				ast_log(LOG_ERROR, "Failed to automatically create extension "
 					"for trunk '%s'!\n", station->name);
 				destroy_station(station);

Modified: team/oej/moremanager/apps/app_queue.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/moremanager/apps/app_queue.c?view=diff&rev=181649&r1=181648&r2=181649
==============================================================================
--- team/oej/moremanager/apps/app_queue.c (original)
+++ team/oej/moremanager/apps/app_queue.c Thu Mar 12 09:32:23 2009
@@ -1485,6 +1485,10 @@
 static int play_file(struct ast_channel *chan, char *filename)
 {
 	int res;
+
+	if (ast_strlen_zero(filename)) {
+		return 0;
+	}
 
 	ast_stopstream(chan);
 

Modified: team/oej/moremanager/apps/app_speech_utils.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/moremanager/apps/app_speech_utils.c?view=diff&rev=181649&r1=181648&r2=181649
==============================================================================
--- team/oej/moremanager/apps/app_speech_utils.c (original)
+++ team/oej/moremanager/apps/app_speech_utils.c Thu Mar 12 09:32:23 2009
@@ -377,6 +377,8 @@
 	}
 	datastore->data = speech;
 	ast_channel_datastore_add(chan, datastore);
+
+	pbx_builtin_setvar_helper(chan, "ERROR", NULL);
 
 	ast_module_user_remove(u);
 

Modified: team/oej/moremanager/apps/app_voicemail.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/moremanager/apps/app_voicemail.c?view=diff&rev=181649&r1=181648&r2=181649
==============================================================================
--- team/oej/moremanager/apps/app_voicemail.c (original)
+++ team/oej/moremanager/apps/app_voicemail.c Thu Mar 12 09:32:23 2009
@@ -107,6 +107,8 @@
 #endif
 
 #ifdef IMAP_STORAGE
+#include "asterisk/threadstorage.h"
+
 AST_MUTEX_DEFINE_STATIC(imaptemp_lock);
 static char imaptemp[1024];
 static char imapserver[48];
@@ -122,6 +124,8 @@
 
 struct vm_state;
 struct ast_vm_user;
+
+AST_THREADSTORAGE(ts_vmstate, ts_vmstate_init);
 
 static int init_mailstream (struct vm_state *vms, int box);
 static void write_file (char *filename, char *buffer, unsigned long len);
@@ -1225,6 +1229,7 @@
 		ast_mutex_lock(&vms_p->lock);
 		pgm = mail_newsearchpgm ();
 		hdr = mail_newsearchheader ("X-Asterisk-VM-Extension", (char *)(!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox));
+		hdr->next = mail_newsearchheader("X-Asterisk-VM-Context", (char *) S_OR(context, "default"));
 		pgm->header = hdr;
 		if (fold != 1) {
 			pgm->unseen = 1;
@@ -1569,6 +1574,7 @@
 
 	/* Check IMAP folder for Asterisk messages only... */
 	hdr = mail_newsearchheader ("X-Asterisk-VM-Extension", (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : vmu->mailbox));
+	hdr->next = mail_newsearchheader("X-Asterisk-VM-Context", vmu->context);
 	pgm->header = hdr;
 	pgm->deleted = 0;
 	pgm->undeleted = 1;
@@ -1613,6 +1619,9 @@
 	mailbox = stream->mailbox;
 	user = get_user_by_mailbox(mailbox);
 	vms = get_vm_state_by_imapuser(user,2);
+	if (!vms) {
+		vms = get_vm_state_by_imapuser(user, 0);
+	}
 	if (vms) {
 		if (option_debug > 2)
 			ast_log (LOG_DEBUG, "saving mailbox message number %lu as message %d. Interactive set to %d\n",number,vms->vmArrayIndex,vms->interactive);
@@ -1827,6 +1836,9 @@
 	mailbox = stream->mailbox;
 	user = get_user_by_mailbox(mailbox);
 	vms = get_vm_state_by_imapuser(user,2);
+	if (!vms) {
+		vms = get_vm_state_by_imapuser(user, 0);
+	}
 	if (vms) {
 		if (option_debug > 2)
 			ast_log (LOG_DEBUG, "User %s usage is %lu, limit is %lu\n",user,usage,limit);
@@ -1897,6 +1909,9 @@
 {
 	struct vm_state *vms_p;
 
+	if ((vms_p = pthread_getspecific(ts_vmstate.key)) && !strcmp(vms_p->imapuser, vmu->imapuser) && !strcmp(vms_p->username, vmu->mailbox)) {
+		return vms_p;
+	}
 	if (option_debug > 4)
 		ast_log(LOG_DEBUG,"Adding new vmstate for %s\n",vmu->imapuser);
 	if (!(vms_p = ast_calloc(1, sizeof(*vms_p))))
@@ -1918,6 +1933,12 @@
 static struct vm_state *get_vm_state_by_imapuser(char *user, int interactive)
 {
 	struct vmstate *vlist = NULL;
+
+	if (interactive) {
+		struct vm_state *vms;
+		vms = pthread_getspecific(ts_vmstate.key);
+		return vms;
+	}
 
 	ast_mutex_lock(&vmstate_lock);
 	vlist = vmstates;
@@ -1954,6 +1975,12 @@
 	struct vmstate *vlist = NULL;
 	const char *local_context = S_OR(context, "default");
 
+	if (interactive) {
+		struct vm_state *vms;
+		vms = pthread_getspecific(ts_vmstate.key);
+		return vms;
+	}
+
 	ast_mutex_lock(&vmstate_lock);
 	vlist = vmstates;
 	if (option_debug > 2) 
@@ -1963,7 +1990,7 @@
 			if (vlist->vms->username && vlist->vms->context) {
 				if (option_debug > 2)
 					ast_log(LOG_DEBUG, "	comparing mailbox %s (i=%d) to vmstate mailbox %s (i=%d)\n",mailbox,interactive,vlist->vms->username,vlist->vms->interactive);
-				if (!strcmp(vlist->vms->username,mailbox) && !(strcmp(vlist->vms->context, local_context)) && vlist->vms->interactive == interactive) {
+				if (!strcmp(vlist->vms->username,mailbox) && !(strcmp(vlist->vms->context, local_context))) {
 					if (option_debug > 2)
 						ast_log(LOG_DEBUG, "	Found it!\n");
 					ast_mutex_unlock(&vmstate_lock);
@@ -2008,9 +2035,13 @@
 			/* get a pointer to the persistent store */
 			vms->persist_vms = altvms;
 			/* Reuse the mailstream? */
+#ifdef REALLY_FAST_EVEN_IF_IT_MEANS_RESOURCE_LEAKS
 			vms->mailstream = altvms->mailstream;
-			/* vms->mailstream = NIL; */
-		}
+#else
+			vms->mailstream = NIL;
+#endif
+		}
+		return;
 	}
 
 	v = (struct vmstate *)malloc(sizeof(struct vmstate));
@@ -2042,6 +2073,10 @@
 			altvms->oldmessages = vms->oldmessages;
 			altvms->updated = 1;
 		}
+		vms->mailstream = mail_close(vms->mailstream);
+
+		/* Interactive states are not stored within the persistent list */
+		return;
 	}
 
 	ast_mutex_lock(&vmstate_lock);
@@ -7324,6 +7359,9 @@
 	adsi_begin(chan, &useadsi);
 
 #ifdef IMAP_STORAGE
+	pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
+	pthread_setspecific(ts_vmstate.key, &vms);
+
 	vms.interactive = 1;
 	vms.updated = 1;
 	if (vmu)
@@ -7756,8 +7794,11 @@
 		free(vms.deleted);
 	if (vms.heard)
 		free(vms.heard);
+
+#ifdef IMAP_STORAGE
+	pthread_setspecific(ts_vmstate.key, NULL);
+#endif
 	ast_module_user_remove(u);
-
 	return res;
 }
 
@@ -7864,18 +7905,26 @@
 {
 	struct ast_vm_user *vmu;
 	AST_LIST_TRAVERSE(&users, vmu, list) {
-		if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox))
-			break;
-		if (context && (!strcasecmp(context, vmu->context)) && (!strcasecmp(mbox, vmu->mailbox)))
-			break;
+		if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox)) {
+			if (strcasecmp(vmu->context, context)) {
+				ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\
+						\n\tcontexts and that you have the 'searchcontexts' option on. This type of\
+						\n\tconfiguration creates an ambiguity that you likely do not want. Please\
+						\n\tamend your voicemail.conf file to avoid this situation.\n", mbox);
+			}
+			ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", mbox);
+			return NULL;
+		}
+		if (!strcasecmp(context, vmu->context) && !strcasecmp(mbox, vmu->mailbox)) {
+			ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", mbox, context);
+			return NULL;
+		}
 	}
 	
-	if (!vmu) {
-		if ((vmu = ast_calloc(1, sizeof(*vmu)))) {
-			ast_copy_string(vmu->context, context, sizeof(vmu->context));
-			ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
-			AST_LIST_INSERT_TAIL(&users, vmu, list);
-		}
+	if ((vmu = ast_calloc(1, sizeof(*vmu)))) {
+		ast_copy_string(vmu->context, context, sizeof(vmu->context));
+		ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
+		AST_LIST_INSERT_TAIL(&users, vmu, list);
 	}
 	return vmu;
 }

Modified: team/oej/moremanager/autoconf/ast_check_gnu_make.m4
URL: http://svn.digium.com/svn-view/asterisk/team/oej/moremanager/autoconf/ast_check_gnu_make.m4?view=diff&rev=181649&r1=181648&r2=181649
==============================================================================
--- team/oej/moremanager/autoconf/ast_check_gnu_make.m4 (original)
+++ team/oej/moremanager/autoconf/ast_check_gnu_make.m4 Thu Mar 12 09:32:23 2009
@@ -1,20 +1,20 @@
-AC_DEFUN([AST_CHECK_GNU_MAKE], [AC_CACHE_CHECK(for GNU make, GNU_MAKE,
-   GNU_MAKE='Not Found' ;
-   GNU_MAKE_VERSION_MAJOR=0 ;
-   GNU_MAKE_VERSION_MINOR=0 ;
+AC_DEFUN([AST_CHECK_GNU_MAKE], [AC_CACHE_CHECK([for GNU make], [ac_cv_GNU_MAKE],
+   ac_cv_GNU_MAKE='Not Found' ;
+   ac_cv_GNU_MAKE_VERSION_MAJOR=0 ;
+   ac_cv_GNU_MAKE_VERSION_MINOR=0 ;
    for a in make gmake gnumake ; do
       if test -z "$a" ; then continue ; fi ;
       if ( sh -c "$a --version" 2> /dev/null | grep GNU  2>&1 > /dev/null ) ;  then
-         GNU_MAKE=$a ;
-         GNU_MAKE_VERSION_MAJOR=`$GNU_MAKE --version | grep "GNU Make" | cut -f3 -d' ' | cut -f1 -d'.'`
-         GNU_MAKE_VERSION_MINOR=`$GNU_MAKE --version | grep "GNU Make" | cut -f2 -d'.' | cut -c1-2`
+         ac_cv_GNU_MAKE=$a ;
+         ac_cv_GNU_MAKE_VERSION_MAJOR=`$ac_cv_GNU_MAKE --version | grep "GNU Make" | cut -f3 -d' ' | cut -f1 -d'.'`
+         ac_cv_GNU_MAKE_VERSION_MINOR=`$ac_cv_GNU_MAKE --version | grep "GNU Make" | cut -f2 -d'.' | cut -c1-2`
          break;
       fi
    done ;
 ) ;
-if test  "x$GNU_MAKE" = "xNot Found"  ; then
+if test  "x$ac_cv_GNU_MAKE" = "xNot Found"  ; then
    AC_MSG_ERROR( *** Please install GNU make.  It is required to build Asterisk!)
    exit 1
 fi
-AC_SUBST([GNU_MAKE])
+AC_SUBST([GNU_MAKE], [$ac_cv_GNU_MAKE])
 ])

Modified: team/oej/moremanager/autoconf/ast_check_pwlib.m4
URL: http://svn.digium.com/svn-view/asterisk/team/oej/moremanager/autoconf/ast_check_pwlib.m4?view=diff&rev=181649&r1=181648&r2=181649
==============================================================================
--- team/oej/moremanager/autoconf/ast_check_pwlib.m4 (original)
+++ team/oej/moremanager/autoconf/ast_check_pwlib.m4 Thu Mar 12 09:32:23 2009
@@ -103,12 +103,12 @@
     else
       AC_CHECK_HEADER(/usr/local/include/ptlib.h, HAS_PWLIB=1, )
       if test "${HAS_PWLIB:-unset}" != "unset" ; then
-        AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/local/bin)
-        if test "${PTLIB_CONFIG:-unset}" = "unset" ; then
-          AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/local/share/pwlib/make)
+        AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/local/bin$PATH_SEPARATOR/usr/local/share/pwlib/make)
+        PWLIB_INCDIR="/usr/local/include"
+        PWLIB_LIBDIR=`${PTLIB_CONFIG} --pwlibdir 2>/dev/null`
+        if test "${PWLIB_LIBDIR:-unset}" = "unset"; then
+          PWLIB_LIBDIR=`${PTLIB_CONFIG} --ptlibdir 2>/dev/null`
         fi
-        PWLIB_INCDIR="/usr/local/include"
-        PWLIB_LIBDIR=`${PTLIB_CONFIG} --pwlibdir`
         if test "${PWLIB_LIBDIR:-unset}" = "unset"; then
           if test "x$LIB64" != "x"; then
             PWLIB_LIBDIR="/usr/local/lib64"
@@ -121,9 +121,12 @@
       else
         AC_CHECK_HEADER(/usr/include/ptlib.h, HAS_PWLIB=1, )
         if test "${HAS_PWLIB:-unset}" != "unset" ; then
-          AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/share/pwlib/make)
+          AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/bin$PATH_SEPARATOR/usr/share/pwlib/make)
           PWLIB_INCDIR="/usr/include"
-          PWLIB_LIBDIR=`${PTLIB_CONFIG} --pwlibdir`
+          PWLIB_LIBDIR=`${PTLIB_CONFIG} --pwlibdir 2>/dev/null`
+          if test "${PWLIB_LIBDIR:-unset}" = "unset"; then
+            PWLIB_LIBDIR=`${PTLIB_CONFIG} --ptlibdir 2>/dev/null`
+          fi
           if test "${PWLIB_LIBDIR:-unset}" = "unset"; then
             if test "x$LIB64" != "x"; then
               PWLIB_LIBDIR="/usr/lib64"
@@ -188,8 +191,14 @@
 ])
 
 AC_DEFUN([AST_CHECK_PWLIB_VERSION], [
+	if test "x$7" != "x"; then
+	   	VNAME="$7"
+       	else
+	   	VNAME="$2_VERSION"
+	fi
+
 	if test "${HAS_$2:-unset}" != "unset"; then
-		$2_VERSION=`grep "$2_VERSION" ${$2_INCDIR}/$3 | sed -e 's/[[[:space:]]]\{1,\}/ /g' | cut -f3 -d ' ' | sed -e 's/"//g'`
+		$2_VERSION=`grep "$VNAME" ${$2_INCDIR}/$3 | sed -e 's/[[[:space:]]]\{1,\}/ /g' | cut -f3 -d ' ' | sed -e 's/"//g'`
 		$2_MAJOR_VERSION=`echo ${$2_VERSION} | cut -f1 -d.`
 		$2_MINOR_VERSION=`echo ${$2_VERSION} | cut -f2 -d.`
 		$2_BUILD_NUMBER=`echo ${$2_VERSION} | cut -f3 -d.`

Modified: team/oej/moremanager/autoconf/ast_prog_sed.m4
URL: http://svn.digium.com/svn-view/asterisk/team/oej/moremanager/autoconf/ast_prog_sed.m4?view=diff&rev=181649&r1=181648&r2=181649
==============================================================================
--- team/oej/moremanager/autoconf/ast_prog_sed.m4 (original)
+++ team/oej/moremanager/autoconf/ast_prog_sed.m4 Thu Mar 12 09:32:23 2009
@@ -12,7 +12,7 @@
      done
      echo "$ac_script" | sed 99q >conftest.sed
      $as_unset ac_script || ac_script=
-     _AC_PATH_PROG_FEATURE_CHECK(SED, [sed gsed],
+     ifdef([_AC_PATH_PROGS_FEATURE_CHECK], [_AC_PATH_PROGS_FEATURE_CHECK], [_AC_PATH_PROG_FEATURE_CHECK])(SED, [sed gsed],
 	[_AC_FEATURE_CHECK_LENGTH([ac_path_SED], [ac_cv_path_SED],
 		["$ac_path_SED" -f conftest.sed])])])
  SED="$ac_cv_path_SED"

Modified: team/oej/moremanager/channels/chan_dahdi.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/moremanager/channels/chan_dahdi.c?view=diff&rev=181649&r1=181648&r2=181649
==============================================================================
--- team/oej/moremanager/channels/chan_dahdi.c (original)
+++ team/oej/moremanager/channels/chan_dahdi.c Thu Mar 12 09:32:23 2009
@@ -12087,13 +12087,11 @@
 	cfg = ast_config_load("users.conf");
 	if (cfg) {
 		char *cat;
-		const char *chans;
 		process_dahdi(&conf, "", ast_variable_browse(cfg, "general"), 1, 1);
 		for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
 			if (!strcasecmp(cat, "general"))
 				continue;
-			chans = ast_variable_retrieve(cfg, cat, "dahdichan");
-			if (!ast_strlen_zero(chans)) {
+			if (!ast_strlen_zero(ast_variable_retrieve(cfg, cat, "dahdichan")) || !ast_strlen_zero(ast_variable_retrieve(cfg, cat, "zapchan"))) {
 				struct dahdi_chan_conf sect_conf;
 				memcpy(&sect_conf, &conf, sizeof(sect_conf));
 

Modified: team/oej/moremanager/channels/chan_iax2.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/moremanager/channels/chan_iax2.c?view=diff&rev=181649&r1=181648&r2=181649
==============================================================================
--- team/oej/moremanager/channels/chan_iax2.c (original)
+++ team/oej/moremanager/channels/chan_iax2.c Thu Mar 12 09:32:23 2009
@@ -175,7 +175,7 @@
 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
 
 /* Ethernet, etc */
-#define IAX_CAPABILITY_FULLBANDWIDTH 	0xFFFF
+#define IAX_CAPABILITY_FULLBANDWIDTH 	(0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED)
 /* T1, maybe ISDN */
 #define IAX_CAPABILITY_MEDBANDWIDTH 	(IAX_CAPABILITY_FULLBANDWIDTH & 	\
 					 ~AST_FORMAT_SLINEAR &			\
@@ -576,7 +576,9 @@
 	int encmethods;
 	/*! Encryption AES-128 Key */
 	aes_encrypt_ctx ecx;
-	/*! Decryption AES-128 Key */
+	/*! Decryption AES-128 Key corresponding to ecx */
+	aes_decrypt_ctx mydcx;
+	/*! Decryption AES-128 Key used to decrypt peer frames */
 	aes_decrypt_ctx dcx;
 	/*! 32 bytes of semi-random data */
 	unsigned char semirand[32];
@@ -868,6 +870,11 @@
 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
 static void prune_peers(void);
+static void prune_users(void);
+static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
+static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
+static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
+ 
 
 static const struct ast_channel_tech iax2_tech = {
 	.type = "IAX2",
@@ -1194,6 +1201,15 @@
 {
 	ao2_ref(peer, -1);
 	return NULL;
+}
+
+static struct iax2_user *find_user(const char *name)
+{
+	struct iax2_user tmp_user = {
+		.name = name,
+	};
+
+	return ao2_find(users, &tmp_user, OBJ_POINTER);
 }
 
 static inline struct iax2_user *user_ref(struct iax2_user *user)
@@ -2255,11 +2271,22 @@
 {
 	/* Called with iaxsl lock held, and iaxs[callno] non-NULL */
 	struct ast_iax2_full_hdr *fh = f->data;
+	struct ast_frame af;
+
+	/* if frame is encrypted. decrypt before updating it. */
+	if (f->encmethods) {
+		decode_frame(&f->mydcx, fh, &af, &f->datalen);
+	}
 	/* Mark this as a retransmission */
 	fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
 	/* Update iseqno */
 	f->iseqno = iaxs[f->callno]->iseqno;
 	fh->iseqno = f->iseqno;
+
+	/* Now re-encrypt the frame */
+	if (f->encmethods) {
+		encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
+	}
 	return 0;
 }
 
@@ -2356,26 +2383,44 @@
 
 static int iax2_prune_realtime(int fd, int argc, char *argv[])
 {
-	struct iax2_peer *peer;
+	struct iax2_peer *peer = NULL;
+	struct iax2_user *user = NULL;
 
 	if (argc != 4)
         return RESULT_SHOWUSAGE;
 	if (!strcmp(argv[3],"all")) {
-		reload_config();
+		prune_users();
+		prune_peers();
 		ast_cli(fd, "OK cache is flushed.\n");
-	} else if ((peer = find_peer(argv[3], 0))) {
-		if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
-			ast_set_flag(peer, IAX_RTAUTOCLEAR);
-			expire_registry(peer_ref(peer));
-			ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
-		} else {
-			ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
-		}
-		peer_unref(peer);
+		return RESULT_SUCCESS;
+	}
+	peer = find_peer(argv[3], 0);
+	user = find_user(argv[3]);
+	if (peer || user) {
+		if (peer) {
+			if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
+				ast_set_flag(peer, IAX_RTAUTOCLEAR);
+				expire_registry(peer_ref(peer));
+				ast_cli(fd, "Peer %s was removed from the cache.\n", argv[3]);
+			} else {
+				ast_cli(fd, "Peer %s is not eligible for this operation.\n", argv[3]);
+			}
+			peer_unref(peer);
+		}
+		if (user) {
+			if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
+				ast_set_flag(user, IAX_RTAUTOCLEAR);
+				ast_cli(fd, "User %s was removed from the cache.\n", argv[3]);
+			} else {
+				ast_cli(fd, "User %s is not eligible for this operation.\n", argv[3]);
+			}
+			ao2_unlink(users,user);
+			user_unref(user);
+		}
 	} else {
-		ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
-	}
-	
+		ast_cli(fd, "%s was not found in the cache.\n", argv[3]);
+	}
+
 	return RESULT_SUCCESS;
 }
 
@@ -4274,10 +4319,19 @@
 	return 0;
 }
 
-static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
-{
-	aes_encrypt_key128(digest, ecx);
-	aes_decrypt_key128(digest, dcx);
+static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
+{
+	build_ecx_key(digest, pvt);
+	aes_decrypt_key128(digest, &pvt->dcx);
+}
+  
+static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
+{
+	/* it is required to hold the corresponding decrypt key to our encrypt key
+	 * in the pvt struct because queued frames occasionally need to be decrypted and
+	 * re-encrypted when updated for a retransmission */
+	aes_encrypt_key128(digest, &pvt->ecx);
+	aes_decrypt_key128(digest, &pvt->mydcx);
 }
 
 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
@@ -4430,7 +4484,7 @@
 			MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
 			MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
 			MD5Final(digest, &md5);
-			build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
+			build_encryption_keys(digest, iaxs[callno]);
 			res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
 			if (!res) {
 				ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
@@ -4525,6 +4579,7 @@
 	fr->callno = pvt->callno;
 	fr->transfer = transfer;
 	fr->final = final;
+	fr->encmethods = 0;
 	if (!sendmini) {
 		/* We need a full frame */
 		if (seqno > -1)
@@ -4578,6 +4633,10 @@
 						iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
 				}
 				encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
+				fr->encmethods = pvt->encmethods;
+				fr->ecx = pvt->ecx;
+				fr->mydcx = pvt->mydcx;
+				memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
 			} else
 				ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
 		}
@@ -5815,7 +5874,7 @@
 	return res;
 }
 
-static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
+static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt)
 {
 	int res = -1;
 	int x;
@@ -5855,8 +5914,9 @@
 			/* If they support md5, authenticate with it.  */
 			for (x=0;x<16;x++)
 				sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
-			if (ecx && dcx)
-				build_enc_keys(digest, ecx, dcx);
+			if (pvt) {
+				build_encryption_keys(digest, pvt);
+			}
 			iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
 			res = 0;
 		} else if (authmethods & IAX_AUTH_PLAINTEXT) {
@@ -5897,7 +5957,7 @@
 	/* Check for override RSA authentication first */
 	if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
 		/* Normal password authentication */
-		res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
+		res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
 	} else {
 		struct ao2_iterator i = ao2_iterator_init(peers, 0);
 		while ((peer = ao2_iterator_next(&i))) {
@@ -5908,7 +5968,7 @@
 			    && (!peer->addr.sin_addr.s_addr || ((sin->sin_addr.s_addr & peer->mask.s_addr) == (peer->addr.sin_addr.s_addr & peer->mask.s_addr)))
 			    /* No specified host, or this is our host */
 				) {
-				res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
+				res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
 				if (!res) {
 					peer_unref(peer);
 					break;
@@ -5927,7 +5987,7 @@
 					peer_unref(peer);
 					return -1;
 				}
-				res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
+				res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
 				peer_unref(peer);
 			}
 			if (!peer) {
@@ -6232,7 +6292,7 @@
 			if (onoff) {
 				if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
 					ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
-							  "Noop", ast_strdup(peer->name), ast_free, "IAX2");
+							  "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
 			} else
 				ast_context_remove_extension(regcontext, ext, 1, NULL);
 		}
@@ -6558,9 +6618,9 @@
 				char tmpkey[256];
 				ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
 				tmpkey[strlen(tmpkey) - 1] = '\0';
-				res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
+				res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
 			} else
-				res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
+				res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
 			if (!res) {
 				reg->regstate = REG_STATE_AUTHSENT;
 				return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
@@ -10044,8 +10104,9 @@
 
 	i = ao2_iterator_init(users, 0);
 	while ((user = ao2_iterator_next(&i))) {
-		if (ast_test_flag(user, IAX_DELME))
+		if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
 			ao2_unlink(users, user);
+		}
 		user_unref(user);
 	}
 }
@@ -10058,8 +10119,9 @@
 
 	i = ao2_iterator_init(peers, 0);
 	while ((peer = ao2_iterator_next(&i))) {
-		if (ast_test_flag(peer, IAX_DELME))
+		if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
 			unlink_peer(peer);
+		}
 		peer_unref(peer);
 	}
 }

Modified: team/oej/moremanager/channels/chan_local.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/moremanager/channels/chan_local.c?view=diff&rev=181649&r1=181648&r2=181649
==============================================================================
--- team/oej/moremanager/channels/chan_local.c (original)
+++ team/oej/moremanager/channels/chan_local.c Thu Mar 12 09:32:23 2009
@@ -270,6 +270,7 @@
 							p->chan->audiohooks = p->owner->audiohooks;
 							p->owner->audiohooks = audiohooks_swapper;
 						}
+						ast_app_group_update(p->chan, p->owner);
 						ast_channel_masquerade(p->owner, p->chan->_bridge);
 						ast_set_flag(p, LOCAL_ALREADY_MASQED);
 					}

Modified: team/oej/moremanager/channels/chan_sip.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/moremanager/channels/chan_sip.c?view=diff&rev=181649&r1=181648&r2=181649
==============================================================================
--- team/oej/moremanager/channels/chan_sip.c (original)
+++ team/oej/moremanager/channels/chan_sip.c Thu Mar 12 09:32:23 2009
@@ -1283,7 +1283,7 @@
 static void copy_request(struct sip_request *dst, const struct sip_request *src);
 static void receive_message(struct sip_pvt *p, struct sip_request *req);
 static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req);
-static int sip_send_mwi_to_peer(struct sip_peer *peer);
+static int sip_send_mwi_to_peer(struct sip_peer *peer, int force);
 static int does_peer_need_mwi(struct sip_peer *peer);
 
 /*--- Dialog management */
@@ -1355,7 +1355,6 @@
 static int expire_register(const void *data);
 static void *do_monitor(void *data);
 static int restart_monitor(void);
-static int sip_send_mwi_to_peer(struct sip_peer *peer);
 static int sip_addrcmp(char *name, struct sockaddr_in *sin);	/* Support for peer matching */
 static int sip_refer_allocate(struct sip_pvt *p);
 static void ast_quiet_chan(struct ast_channel *chan);
@@ -1456,7 +1455,7 @@
 static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v);
 
 /* Realtime device support */
-static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey);
+static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey, int lastms);
 static struct sip_user *realtime_user(const char *username);
 static void update_peer(struct sip_peer *p, int expiry);
 static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *sin, int devstate_only);
@@ -2425,18 +2424,20 @@
 	that name and store that in the "regserver" field in the sippeers
 	table to facilitate multi-server setups.
 */
-static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey)
+static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey, int lastms)
 {
 	char port[10];
 	char ipaddr[INET_ADDRSTRLEN];
 	char regseconds[20];
+	char str_lastms[20];
 
 	char *sysname = ast_config_AST_SYSTEM_NAME;
 	char *syslabel = NULL;
 
 	time_t nowtime = time(NULL) + expirey;
 	const char *fc = fullcontact ? "fullcontact" : NULL;
-	
+
+	snprintf(str_lastms, sizeof(str_lastms), "%d", lastms);
 	snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);	/* Expiration time */
 	ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
 	snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
@@ -2454,6 +2455,9 @@
 		ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
 			"port", port, "regseconds", regseconds,
 			"username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */
+	/* We cannot do this in the same statement as above, because the lack of
+	 * this field could cause the whole statement to fail. */
+	ast_update_realtime("sippeers", "name", peername, "lastms", str_lastms, NULL);
 }
 
 /*! \brief Automatically add peer extension to dial plan */
@@ -2484,7 +2488,7 @@
 		if (onoff) {
 			if (!ast_exists_extension(NULL, context, ext, 1, NULL)) {
 				ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
-					 ast_strdup(peer->name), ast_free, "SIP");
+					 ast_strdup(peer->name), ast_free_ptr, "SIP");
 			}
 		} else {
 			ast_context_remove_extension(context, ext, 1, NULL);
@@ -2529,7 +2533,7 @@
 	int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
 	if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) &&
 	    (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) {
-		realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry);
+		realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry, p->lastms);
 	}
 }
 
@@ -4150,7 +4154,7 @@
 
 
 
-	if (ast_test_flag(&i->flags[0], SIP_DTMF) ==  SIP_DTMF_INBAND) {
+	if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
 		i->vad = ast_dsp_new();
 		ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT);
 		if (global_relaxdtmf)
@@ -8117,9 +8121,10 @@
 static void destroy_association(struct sip_peer *peer)
 {
 	if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) {
-		if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT))
+		if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) {
 			ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL);
-		else 
+			ast_update_realtime("sippeers", "name", peer->name, "lastms", "", NULL);
+		} else 
 			ast_db_del("SIP/Registry", peer->name);
 	}
 }
@@ -9214,34 +9219,41 @@
 
 	ast_mutex_lock(&iflock);
 
-	if (option_debug > 3 && totag)
+	if (option_debug > 3 && totag) {
 		ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
+	}
 
 	/* Search interfaces and find the match */
 	for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) {
 		if (!strcmp(sip_pvt_ptr->callid, callid)) {
 			int match = 1;
 
+			if (option_debug > 3)
+				ast_log(LOG_DEBUG, "Found call with callid %s (ourtag=%s, theirtag=%s)\n", callid, sip_pvt_ptr->tag, sip_pvt_ptr->theirtag);
+
 			/* Go ahead and lock it (and its owner) before returning */
 			ast_mutex_lock(&sip_pvt_ptr->lock);
 
 			/* Check if tags match. If not, this is not the call we want
-			   (With a forking SIP proxy, several call legs share the
-			   call id, but have different tags)
-			*/
+			 * (With a forking SIP proxy, several call legs share the
+			 * call id, but have different tags)
+			 */
 			if (pedanticsipchecking) {
-				const char *pvt_fromtag, *pvt_totag;
-
-				if (ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL)) {
-					/* Outgoing call tags : from is "our", to is "their" */
-					pvt_fromtag = sip_pvt_ptr->tag ;
-					pvt_totag = sip_pvt_ptr->theirtag ;
-				} else {
-					/* Incoming call tags : from is "their", to is "our" */
-					pvt_fromtag = sip_pvt_ptr->theirtag ;
-					pvt_totag = sip_pvt_ptr->tag ;
-				}
-				if (ast_strlen_zero(fromtag) || strcmp(fromtag, pvt_fromtag) || (!ast_strlen_zero(totag) && strcmp(totag, pvt_totag)))
+				/* RFC 3891
+				 * > 3.  User Agent Server Behavior: Receiving a Replaces Header
+				 * > The Replaces header contains information used to match an existing
+				 * > SIP dialog (call-id, to-tag, and from-tag).  Upon receiving an INVITE
+				 * > with a Replaces header, the User Agent (UA) attempts to match this
+				 * > information with a confirmed or early dialog.  The User Agent Server
+				 * > (UAS) matches the to-tag and from-tag parameters as if they were tags
+				 * > present in an incoming request.  In other words, the to-tag parameter
+				 * > is compared to the local tag, and the from-tag parameter is compared
+				 * > to the remote tag.
+				 *
+				 * Thus, the totag is always compared to the local tag, regardless if
+				 * this our call is an incoming or outgoing call.
+				 */
+				if (ast_strlen_zero(fromtag) || strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, sip_pvt_ptr->tag)))
 					match = 0;
 			}
 
@@ -9417,7 +9429,7 @@
 	ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context));
 	
 	/* Either an existing extension or the parking extension */
-	if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
+	if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
 		if (sip_debug_test_pvt(transferer)) {
 			ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri);
 		}
@@ -12921,10 +12933,13 @@
 	peer->call = NULL;
 	if (statechanged) {
 		const char *s = is_reachable ? "Reachable" : "Lagged";
+		char str_lastms[20];

[... 6079 lines stripped ...]



More information about the svn-commits mailing list