[asterisk-commits] branch oej/siptransfer r28556 - in /team/oej/siptransfer: ./ apps/ channels/ ...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Fri May 19 02:57:16 MST 2006


Author: oej
Date: Fri May 19 04:57:15 2006
New Revision: 28556

URL: http://svn.digium.com/view/asterisk?rev=28556&view=rev
Log:
Reset automerge

Added:
    team/oej/siptransfer/doc/video.txt
      - copied unchanged from r28555, trunk/doc/video.txt
Modified:
    team/oej/siptransfer/   (props changed)
    team/oej/siptransfer/.cleancount
    team/oej/siptransfer/Makefile
    team/oej/siptransfer/app.c
    team/oej/siptransfer/apps/app_hasnewvoicemail.c
    team/oej/siptransfer/apps/app_meetme.c
    team/oej/siptransfer/apps/app_queue.c
    team/oej/siptransfer/apps/app_voicemail.c
    team/oej/siptransfer/channels/chan_iax2.c
    team/oej/siptransfer/channels/chan_local.c
    team/oej/siptransfer/channels/chan_misdn.c
    team/oej/siptransfer/channels/chan_sip.c
    team/oej/siptransfer/channels/chan_zap.c
    team/oej/siptransfer/channels/misdn/isdn_lib.c
    team/oej/siptransfer/configs/sip.conf.sample
    team/oej/siptransfer/configs/zapata.conf.sample
    team/oej/siptransfer/enum.c
    team/oej/siptransfer/funcs/func_strings.c
    team/oej/siptransfer/include/asterisk/app.h
    team/oej/siptransfer/res/res_musiconhold.c

Propchange: team/oej/siptransfer/
------------------------------------------------------------------------------
    automerge = http://edvina.net/training/

Propchange: team/oej/siptransfer/
------------------------------------------------------------------------------
Binary property 'branch-1.2-blocked' - no diff available.

Propchange: team/oej/siptransfer/
------------------------------------------------------------------------------
Binary property 'branch-1.2-merged' - no diff available.

Propchange: team/oej/siptransfer/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri May 19 04:57:15 2006
@@ -1,1 +1,1 @@
-/trunk:1-27720
+/trunk:1-28555

Modified: team/oej/siptransfer/.cleancount
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/.cleancount?rev=28556&r1=28555&r2=28556&view=diff
==============================================================================
--- team/oej/siptransfer/.cleancount (original)
+++ team/oej/siptransfer/.cleancount Fri May 19 04:57:15 2006
@@ -1,1 +1,1 @@
-16
+17

Modified: team/oej/siptransfer/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/Makefile?rev=28556&r1=28555&r2=28556&view=diff
==============================================================================
--- team/oej/siptransfer/Makefile (original)
+++ team/oej/siptransfer/Makefile Fri May 19 04:57:15 2006
@@ -284,7 +284,8 @@
 endif
 
 MOD_SUBDIRS=res channels pbx apps codecs formats cdr funcs
-SUBDIRS:=$(MOD_SUBDIRS) utils stdtime agi
+OTHER_SUBDIRS=utils stdtime agi
+SUBDIRS:=$(MOD_SUBDIRS) $(OTHER_SUBDIRS)
 
 OBJS=io.o sched.o logger.o frame.o loader.o config.o channel.o \
 	translate.o file.o pbx.o cli.o md5.o term.o \
@@ -871,7 +872,8 @@
 valgrind: dont-optimize
 
 depend: include/asterisk/version.h include/asterisk/buildopts.h .depend defaults.h 
-	@for x in $(SUBDIRS); do $(MAKE) -C $$x depend || exit 1 ; done
+	@for x in $(MOD_SUBDIRS); do CFLAGS="$(MOD_SUBDIR_CFLAGS)$(ASTCFLAGS)" $(MAKE) -C $$x depend || exit 1 ; done
+	@for x in $(OTHER_SUBDIRS); do CFLAGS="$(OTHER_SUBDIR_CFLAGS)$(ASTCFLAGS)" $(MAKE) -C $$x depend || exit 1 ; done
 
 .depend: include/asterisk/version.h include/asterisk/buildopts.h defaults.h
 	build_tools/mkdep $(CFLAGS) $(wildcard *.c)

Modified: team/oej/siptransfer/app.c
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/app.c?rev=28556&r1=28555&r2=28556&view=diff
==============================================================================
--- team/oej/siptransfer/app.c (original)
+++ team/oej/siptransfer/app.c Fri May 19 04:57:15 2006
@@ -146,18 +146,22 @@
 
 static int (*ast_has_voicemail_func)(const char *mailbox, const char *folder) = NULL;
 static int (*ast_messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs) = NULL;
+static int (*ast_messagecount2_func)(const char *context, const char *mailbox, const char *folder) = NULL;
 
 void ast_install_vm_functions(int (*has_voicemail_func)(const char *mailbox, const char *folder),
-			      int (*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs))
+			      int (*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs),
+			      int (*messagecount2_func)(const char *context, const char *mailbox, const char *folder))
 {
 	ast_has_voicemail_func = has_voicemail_func;
 	ast_messagecount_func = messagecount_func;
+	ast_messagecount2_func = messagecount2_func;
 }
 
 void ast_uninstall_vm_functions(void)
 {
 	ast_has_voicemail_func = NULL;
 	ast_messagecount_func = NULL;
+	ast_messagecount2_func = NULL;
 }
 
 int ast_app_has_voicemail(const char *mailbox, const char *folder)

Modified: team/oej/siptransfer/apps/app_hasnewvoicemail.c
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/apps/app_hasnewvoicemail.c?rev=28556&r1=28555&r2=28556&view=diff
==============================================================================
--- team/oej/siptransfer/apps/app_hasnewvoicemail.c (original)
+++ team/oej/siptransfer/apps/app_hasnewvoicemail.c Fri May 19 04:57:15 2006
@@ -78,26 +78,6 @@
 "		<# of messages in the folder, 0 for NONE>\n";
 
 LOCAL_USER_DECL;
-
-static int hasvoicemail_internal(char *context, char *box, char *folder)
-{
-	char vmpath[256];
-	DIR *vmdir;
-	struct dirent *vment;
-	int count=0;
-
-	snprintf(vmpath,sizeof(vmpath), "%s/voicemail/%s/%s/%s", (char *)ast_config_AST_SPOOL_DIR, context, box, folder);
-	if ((vmdir = opendir(vmpath))) {
-		/* No matter what the format of VM, there will always be a .txt file for each message. */
-		while ((vment = readdir(vmdir))) {
-			if (!strncmp(vment->d_name + 7, ".txt", 4)) {
-				count++;
-			}
-		}
-		closedir(vmdir);
-	}
-	return count;
-}
 
 static int hasvoicemail_exec(struct ast_channel *chan, void *data)
 {
@@ -130,11 +110,10 @@
 
 	AST_STANDARD_APP_ARGS(args, input);
 
-	if ((vmbox = strsep(&args.vmbox, "@")))
-		if (!ast_strlen_zero(args.vmbox))
-			context = args.vmbox;
-	if (!vmbox)
-		vmbox = args.vmbox;
+	vmbox = strsep(&args.vmbox, "@");
+
+	if (!ast_strlen_zero(args.vmbox))
+		context = args.vmbox;
 
 	vmfolder = strchr(vmbox, '/');
 	if (vmfolder) {
@@ -149,7 +128,7 @@
 			priority_jump = 1;
 	}
 
-	vmcount = hasvoicemail_internal(context, vmbox, vmfolder);
+	vmcount = ast_app_messagecount2(context, vmbox, vmfolder);
 	/* Set the count in the channel variable */
 	if (varname) {
 		snprintf(tmp, sizeof(tmp), "%d", vmcount);
@@ -198,7 +177,7 @@
 		args.folder = "INBOX";
 	}
 
-	snprintf(buf, len, "%d", hasvoicemail_internal(context, args.vmbox, args.folder));
+	snprintf(buf, len, "%d", ast_app_messagecount2(context, args.vmbox, args.folder));
 
 	LOCAL_USER_REMOVE(u);
 	

Modified: team/oej/siptransfer/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/apps/app_meetme.c?rev=28556&r1=28555&r2=28556&view=diff
==============================================================================
--- team/oej/siptransfer/apps/app_meetme.c (original)
+++ team/oej/siptransfer/apps/app_meetme.c Fri May 19 04:57:15 2006
@@ -109,7 +109,6 @@
 "      's' -- Present menu (user or admin) when '*' is received ('send' to menu)\n"
 "      't' -- set talk only mode. (Talk only, no listening)\n"
 "      'T' -- set talker detection (sent to manager interface and meetme list)\n"
-"      'v' -- video mode\n"
 "      'w' -- wait until the marked user enters the conference\n"
 "      'x' -- close the conference when last marked user exits\n"
 "      'X' -- allow user to exit the conference by entering a valid single\n"
@@ -233,7 +232,7 @@
 #define CONFFLAG_STARMENU (1 << 4)		/* If set asterisk will provide a menu to the user when '*' is pressed */
 #define CONFFLAG_TALKER (1 << 5)		/* If set the use can only send audio to the conference */
 #define CONFFLAG_QUIET (1 << 6)			/* If set there will be no enter or leave sounds */
-#define CONFFLAG_VIDEO (1 << 7)			/* Set to enable video mode */
+#define CONFFLAG_ANNOUNCEUSERCOUNT (1 << 7)	/* If set, when user joins the conference, they will be told the number of users that are already in */
 #define CONFFLAG_AGI (1 << 8)			/* Set to run AGI Script in Background */
 #define CONFFLAG_MOH (1 << 9)			/* Set to have music on hold when user is alone in conference */
 #define CONFFLAG_MARKEDEXIT (1 << 10)		/* If set the MeetMe will return if all marked with this flag left */
@@ -248,10 +247,9 @@
 #define CONFFLAG_EMPTY (1 << 19)
 #define CONFFLAG_EMPTYNOPIN (1 << 20)
 #define CONFFLAG_ALWAYSPROMPT (1 << 21)
-#define CONFFLAG_ANNOUNCEUSERCOUNT (1 << 22)	/* If set, when user joins the conference, they will be told the number of users that are already in */
-#define CONFFLAG_OPTIMIZETALKER (1 << 23)	/* If set, treats talking users as muted users */
-#define CONFFLAG_NOONLYPERSON (1 << 24)		/* If set, won't speak the extra prompt when the first person enters the conference */
-#define CONFFLAG_INTROUSERNOREVIEW (1 << 25) /* If set, user will be asked to record name on entry of conference without review */
+#define CONFFLAG_OPTIMIZETALKER (1 << 22)	/* If set, treats talking users as muted users */
+#define CONFFLAG_NOONLYPERSON (1 << 23)		/* If set, won't speak the extra prompt when the first person enters the conference */
+#define CONFFLAG_INTROUSERNOREVIEW (1 << 24)	/* If set, user will be asked to record name on entry of conference without review */
 
 AST_APP_OPTIONS(meetme_opts, {
 	AST_APP_OPTION('A', CONFFLAG_MARKEDUSER ),

Modified: team/oej/siptransfer/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/apps/app_queue.c?rev=28556&r1=28555&r2=28556&view=diff
==============================================================================
--- team/oej/siptransfer/apps/app_queue.c (original)
+++ team/oej/siptransfer/apps/app_queue.c Fri May 19 04:57:15 2006
@@ -1895,11 +1895,10 @@
 	int res;
 
 	if (!qe->parent->autofill) {
-
 		/* Atomically read the parent head -- does not need a lock */
 		ch = qe->parent->head;
 		/* If we are now at the top of the head, break out */
-		if ((ch == qe) || (qe->parent->autofill)) {
+		if (ch == qe) {
 			if (option_debug)
 				ast_log(LOG_DEBUG, "It's our turn (%s).\n", qe->chan->name);
 			res = 1;

Modified: team/oej/siptransfer/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/apps/app_voicemail.c?rev=28556&r1=28555&r2=28556&view=diff
==============================================================================
--- team/oej/siptransfer/apps/app_voicemail.c (original)
+++ team/oej/siptransfer/apps/app_voicemail.c Fri May 19 04:57:15 2006
@@ -2014,7 +2014,7 @@
 #ifdef USE_ODBC_STORAGE
 static int messagecount(const char *mailbox, int *newmsgs, int *oldmsgs)
 {
-	int x = 0;
+	int x = -1;
 	int res;
 	SQLHSTMT stmt;
 	char sql[256];
@@ -2027,6 +2027,7 @@
                 *newmsgs = 0;
         if (oldmsgs)
                 *oldmsgs = 0;
+
         /* If no mailbox, return immediately */
         if (ast_strlen_zero(mailbox))
                 return 0;
@@ -2118,7 +2119,7 @@
 		SQLFreeHandle (SQL_HANDLE_STMT, stmt);
 		odbc_release_obj(obj);
 		*oldmsgs = atoi(rowdata);
-		x = 1;
+		x = 0;
 	} else
 		ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
 		
@@ -2126,76 +2127,73 @@
 	return x;
 }
 
+static int messagecount2(const char *context, const char *mailbox, const char *folder)
+{
+	struct odbc_obj *obj = NULL;
+	int nummsgs = 0;
+	int res;
+	SQLHSTMT stmt = NULL;
+	char sql[256];
+	char rowdata[20];
+	if (!folder)
+		folder = "INBOX";
+	/* If no mailbox, return immediately */
+	if (ast_strlen_zero(mailbox))
+		return 0;
+
+	obj = odbc_request_obj(odbc_database, 0);
+	if (obj) {
+		res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);
+		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
+			ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
+			goto yuck;
+		}
+		snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, mailbox, folder);
+		res = SQLPrepare(stmt, sql, SQL_NTS);
+		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {  
+			ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
+			SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+			goto yuck;
+		}
+		res = odbc_smart_execute(obj, stmt);
+		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
+			ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
+			SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+			goto yuck;
+		}
+		res = SQLFetch(stmt);
+		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
+			ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
+			SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+			goto yuck;
+		}
+		res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
+		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
+			ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
+			SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+			goto yuck;
+		}
+		nummsgs = atoi(rowdata);
+		SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+	} else
+		ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
+
+yuck:
+	if (obj)
+		odbc_release_obj(obj);
+	return nummsgs;
+}
+
 static int has_voicemail(const char *mailbox, const char *folder)
 {
-	struct odbc_obj *obj;
-	int nummsgs = 0;
-        int res;
-        SQLHSTMT stmt;
-        char sql[256];
-        char rowdata[20];
-        char tmp[256]="";
-        char *context;
-	if (!folder)
-                folder = "INBOX";
-	/* If no mailbox, return immediately */
-        if (ast_strlen_zero(mailbox))
-                return 0;
-
+	char *context, tmp[256];
 	ast_copy_string(tmp, mailbox, sizeof(tmp));
-                        
-        context = strchr(tmp, '@');
-        if (context) {
-                *context = '\0';
-                context++;
-        } else
-                context = "default";
-
-	obj = odbc_request_obj(odbc_database, 0);
-        if (obj) {
-                res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);
-                if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
-                        ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
-			odbc_release_obj(obj);
-                        goto yuck;
-                }
-		snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, tmp, "INBOX");
-                res = SQLPrepare(stmt, sql, SQL_NTS);
-                if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {  
-                        ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
-                        SQLFreeHandle (SQL_HANDLE_STMT, stmt);
-			odbc_release_obj(obj);
-                        goto yuck;
-                }
-                res = odbc_smart_execute(obj, stmt);
-                if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
-                        ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
-                        SQLFreeHandle (SQL_HANDLE_STMT, stmt);
-			odbc_release_obj(obj);
-                        goto yuck;
-                }
-                res = SQLFetch(stmt);
-                if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
-                        ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
-                        SQLFreeHandle (SQL_HANDLE_STMT, stmt);
-			odbc_release_obj(obj);
-                        goto yuck;
-                }
-                res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
-                if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
-                        ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
-                        SQLFreeHandle (SQL_HANDLE_STMT, stmt);
-			odbc_release_obj(obj);
-                        goto yuck;
-                }
-                nummsgs = atoi(rowdata);
-                SQLFreeHandle (SQL_HANDLE_STMT, stmt);
-		odbc_release_obj(obj);
-       } else
-                ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
-
-yuck:
-	if (nummsgs>=1)
+	if ((context = strchr(tmp, '@')))
+		*context++ = '\0';
+	else
+		context = "default";
+
+	if (messagecount2(context, tmp, folder))
 		return 1;
 	else
 		return 0;
@@ -2203,7 +2201,7 @@
 
 #else
 
-static int has_voicemail(const char *mailbox, const char *folder)
+static int __has_voicemail(const char *mailbox, const char *folder, int shortcircuit)
 {
 	DIR *dir;
 	struct dirent *de;
@@ -2211,7 +2209,7 @@
 	char tmp[256]="";
 	char *mb, *cur;
 	char *context;
-	int ret;
+	int ret = 0;
 	if (!folder)
 		folder = "INBOX";
 	/* If no mailbox, return immediately */
@@ -2223,11 +2221,13 @@
 		ret = 0;
 		while((cur = strsep(&mb, ","))) {
 			if (!ast_strlen_zero(cur)) {
-				if (has_voicemail(cur, folder))
-					return 1; 
-			}
-		}
-		return 0;
+				if ((ret += __has_voicemail(cur, folder, shortcircuit))) {
+					if (shortcircuit)
+						return 1; 
+				}
+			}
+		}
+		return ret;
 	}
 	ast_copy_string(tmp, mailbox, sizeof(tmp));
 	context = strchr(tmp, '@');
@@ -2241,15 +2241,29 @@
 	if (!dir)
 		return 0;
 	while ((de = readdir(dir))) {
-		if (!strncasecmp(de->d_name, "msg", 3))
-			break;
+		if (!strncasecmp(de->d_name, "msg", 3)) {
+			if (shortcircuit) {
+				ret = 1;
+				break;
+			} else if (!strncasecmp(de->d_name + 8, "txt", 3))
+				ret++;
+		}
 	}
 	closedir(dir);
-	if (de)
-		return 1;
-	return 0;
-}
-
+	return ret;
+}
+
+static int has_voicemail(const char *mailbox, const char *folder)
+{
+	return __has_voicemail(mailbox, folder, 1);
+}
+
+static int messagecount2(const char *context, const char *mailbox, const char *folder)
+{
+	char tmp[256];
+	snprintf(tmp, sizeof(tmp), "%s@%s", mailbox, context);
+	return __has_voicemail(tmp, folder, 0);
+}
 
 static int messagecount(const char *mailbox, int *newmsgs, int *oldmsgs)
 {
@@ -5838,7 +5852,7 @@
 				LOCAL_USER_REMOVE(u);
 				return -1;
 			}
-			ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING);
+			ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
 			if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
 				int gain;
 
@@ -6640,7 +6654,7 @@
 	/* compute the location of the voicemail spool directory */
 	snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
 
-	ast_install_vm_functions(has_voicemail, messagecount);
+	ast_install_vm_functions(has_voicemail, messagecount, messagecount2);
 
 #if defined(USE_ODBC_STORAGE) && !defined(EXTENDED_ODBC_STORAGE)
 	ast_log(LOG_WARNING, "The current ODBC storage table format will be changed soon."
@@ -6826,12 +6840,13 @@
 					res = ast_play_and_wait(chan, "vm-star-cancel");
 				if (!res)
 					res = ast_waitfordigit(chan, 6000);
-				if (!res)
+				if (!res) {
 					retries++;
-				if (retries > 3)
-					res = 't';
+					if (retries > 3)
+						res = 't';
+				}
 				break; 
-
+				
 			}
 			if (res == 't')
 				res = 0;
@@ -6839,7 +6854,7 @@
 				res = -1;
 		}
 		break;
-
+		
 	case 1:	/* Reply */
 		/* Send reply directly to sender */
 		if (ast_strlen_zero(cid))

Modified: team/oej/siptransfer/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/channels/chan_iax2.c?rev=28556&r1=28555&r2=28556&view=diff
==============================================================================
--- team/oej/siptransfer/channels/chan_iax2.c (original)
+++ team/oej/siptransfer/channels/chan_iax2.c Fri May 19 04:57:15 2006
@@ -412,7 +412,7 @@
 	int expire;				/*!< Sched ID of expiration */
 	int refresh;				/*!< How often to refresh */
 	enum iax_reg_state regstate;
-	int messages;				/*!< Message count */
+	int messages;				/*!< Message count, low 8 bits = new, high 8 bits = old */
 	int callno;				/*!< Associated call number if applicable */
 	struct sockaddr_in us;			/*!< Who the server thinks we are */
 	struct iax2_registry *next;
@@ -476,7 +476,10 @@
 	int maxtime;
 	/*! Peer Address */
 	struct sockaddr_in addr;
+	/*! Actual used codec preferences */
 	struct ast_codec_pref prefs;
+	/*! Requested codec preferences */
+	struct ast_codec_pref rprefs;
 	/*! Our call number */
 	unsigned short callno;
 	/*! Peer callno */
@@ -4693,9 +4696,12 @@
 	if (ies->version)
 		version = ies->version;
 
-	if(ies->codec_prefs)
+	/* Use provided preferences until told otherwise for actual preferences */
+	if(ies->codec_prefs) {
+		ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
 		ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
-	
+	}
+
 	if (!gotcapability) 
 		iaxs[callno]->peercapability = iaxs[callno]->peerformat;
 	if (version > IAX_PROTO_VERSION) {
@@ -5404,7 +5410,7 @@
 		return -1;
 	}
 	memcpy(&reg->us, &us, sizeof(reg->us));
-	reg->messages = ies->msgcount;
+	reg->messages = ies->msgcount & 0xffff;		/* only low 16 bits are used in the transmission of the IE */
 	/* always refresh the registration at the interval requested by the server
 	   we are registering to
 	*/
@@ -5414,12 +5420,12 @@
 	reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
 	if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
 		if (option_verbose > 2) {
-			if (reg->messages > 65534)
-				snprintf(msgstatus, sizeof(msgstatus), " with message(s) waiting\n");
+			if (reg->messages > 255)
+				snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
 			else if (reg->messages > 1)
-				snprintf(msgstatus, sizeof(msgstatus), " with %d messages waiting\n", reg->messages);
+				snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
 			else if (reg->messages > 0)
-				snprintf(msgstatus, sizeof(msgstatus), " with 1 message waiting\n");
+				snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
 			else
 				snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
 			snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port));
@@ -6297,7 +6303,7 @@
 	struct iax_frame *duped_fr;
 	char host_pref_buf[128];
 	char caller_pref_buf[128];
-	struct ast_codec_pref pref,rpref;
+	struct ast_codec_pref pref;
 	char *using_prefs = "mine";
 
 	dblbuf[0] = 0;	/* Keep GCC from whining */
@@ -6817,20 +6823,22 @@
 							strcpy(host_pref_buf, "disabled");
 						} else {
 							using_prefs = "mine";
-							if(ies.codec_prefs) {
-								ast_codec_pref_convert(&rpref, ies.codec_prefs, 32, 0);
+							/* If the information elements are in here... use them */
+							if (ies.codec_prefs)
+								ast_codec_pref_convert(&iaxs[fr.callno]->rprefs, ies.codec_prefs, 32, 0);
+							if (ast_codec_pref_index(&iaxs[fr.callno]->rprefs, 0)) {
 								/* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
 								if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) {
-									pref = rpref;
+									pref = iaxs[fr.callno]->rprefs;
 									using_prefs = "caller";
 								} else {
 									pref = iaxs[fr.callno]->prefs;
 								}
 							} else
 								pref = iaxs[fr.callno]->prefs;
-						
+							
 							format = ast_codec_choose(&pref, iaxs[fr.callno]->capability & iaxs[fr.callno]->peercapability, 0);
-							ast_codec_pref_string(&rpref, caller_pref_buf, sizeof(caller_pref_buf) - 1);
+							ast_codec_pref_string(&iaxs[fr.callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
 							ast_codec_pref_string(&iaxs[fr.callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
 						}
 						if (!format) {
@@ -6861,12 +6869,12 @@
 										strcpy(host_pref_buf,"disabled");
 									} else {
 										using_prefs = "mine";
-										if(ies.codec_prefs) {
+										if (ast_codec_pref_index(&iaxs[fr.callno]->rprefs, 0)) {
 											/* Do the opposite of what we tried above. */
 											if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) {
 												pref = iaxs[fr.callno]->prefs;								
 											} else {
-												pref = rpref;
+												pref = iaxs[fr.callno]->rprefs;
 												using_prefs = "caller";
 											}
 											format = ast_codec_choose(&pref, iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability, 1);
@@ -7219,11 +7227,11 @@
 						strcpy(host_pref_buf, "disabled");
 					} else {
 						using_prefs = "mine";
-						if(ies.codec_prefs) {
-							/* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
-							ast_codec_pref_convert(&rpref, ies.codec_prefs, 32, 0);
+						if (ies.codec_prefs)
+							ast_codec_pref_convert(&iaxs[fr.callno]->rprefs, ies.codec_prefs, 32, 0);
+						if (ast_codec_pref_index(&iaxs[fr.callno]->rprefs, 0)) {
 							if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) {
-								ast_codec_pref_convert(&pref, ies.codec_prefs, 32, 0);
+								pref = iaxs[fr.callno]->rprefs;
 								using_prefs = "caller";
 							} else {
 								pref = iaxs[fr.callno]->prefs;
@@ -7232,7 +7240,7 @@
 							pref = iaxs[fr.callno]->prefs;
 					
 						format = ast_codec_choose(&pref, iaxs[fr.callno]->capability & iaxs[fr.callno]->peercapability, 0);
-						ast_codec_pref_string(&rpref, caller_pref_buf, sizeof(caller_pref_buf) - 1);
+						ast_codec_pref_string(&iaxs[fr.callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
 						ast_codec_pref_string(&iaxs[fr.callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
 					}
 					if (!format) {
@@ -7266,12 +7274,12 @@
 									strcpy(host_pref_buf,"disabled");
 								} else {
 									using_prefs = "mine";
-									if(ies.codec_prefs) {
+									if (ast_codec_pref_index(&iaxs[fr.callno]->rprefs, 0)) {
 										/* Do the opposite of what we tried above. */
 										if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) {
 											pref = iaxs[fr.callno]->prefs;						
 										} else {
-											pref = rpref;
+											pref = iaxs[fr.callno]->rprefs;
 											using_prefs = "caller";
 										}
 										format = ast_codec_choose(&pref, iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability, 1);

Modified: team/oej/siptransfer/channels/chan_local.c
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/channels/chan_local.c?rev=28556&r1=28555&r2=28556&view=diff
==============================================================================
--- team/oej/siptransfer/channels/chan_local.c (original)
+++ team/oej/siptransfer/channels/chan_local.c Fri May 19 04:57:15 2006
@@ -60,6 +60,7 @@
 #include "asterisk/musiconhold.h"
 #include "asterisk/manager.h"
 #include "asterisk/stringfields.h"
+#include "asterisk/devicestate.h"
 
 static const char tdesc[] = "Local Proxy Channel Driver";
 
@@ -75,6 +76,8 @@
 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
+static int local_sendtext(struct ast_channel *ast, const char *text);
+static int local_devicestate(void *data);
 
 /* PBX interface structure for channel registration */
 static const struct ast_channel_tech local_tech = {
@@ -88,10 +91,13 @@
 	.answer = local_answer,
 	.read = local_read,
 	.write = local_write,
+	.write_video = local_write,
 	.exception = local_read,
 	.indicate = local_indicate,
 	.fixup = local_fixup,
 	.send_html = local_sendhtml,
+	.send_text = local_sendtext,
+	.devicestate = local_devicestate,
 };
 
 struct local_pvt {
@@ -110,6 +116,28 @@
 };
 
 static AST_LIST_HEAD_STATIC(locals, local_pvt);
+
+/*! \brief Adds devicestate to local channels */
+static int local_devicestate(void *data)
+{
+	char *exten;
+	char *context;
+
+	int res;
+		
+	exten = ast_strdupa(data);
+	if ((context  = strchr(exten, '@'))) {
+		*context = '\0';
+		context = context + 1;
+	}
+	if (option_debug > 2)
+		ast_log(LOG_DEBUG, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
+	res = ast_exists_extension(NULL, context, exten, 1, NULL);
+	if (!res)
+		return AST_DEVICE_NOT_INUSE;
+	else
+		return AST_DEVICE_INUSE;
+}
 
 static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us)
 {
@@ -231,12 +259,13 @@
 	/* Just queue for delivery to the other side */
 	ast_mutex_lock(&p->lock);
 	isoutbound = IS_OUTBOUND(ast, p);
-	if (f && (f->frametype == AST_FRAME_VOICE)) 
+	if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO))
 		check_bridge(p, isoutbound);
 	if (!p->alreadymasqed)
 		res = local_queue_frame(p, isoutbound, f, ast);
 	else {
-		ast_log(LOG_DEBUG, "Not posting to queue since already masked on '%s'\n", ast->name);
+		if (option_debug)
+			ast_log(LOG_DEBUG, "Not posting to queue since already masked on '%s'\n", ast->name);
 		res = 0;
 	}
 	ast_mutex_unlock(&p->lock);
@@ -287,6 +316,22 @@
 	ast_mutex_lock(&p->lock);
 	isoutbound = IS_OUTBOUND(ast, p);
 	f.subclass = digit;
+	res = local_queue_frame(p, isoutbound, &f, ast);
+	ast_mutex_unlock(&p->lock);
+	return res;
+}
+
+static int local_sendtext(struct ast_channel *ast, const char *text)
+{
+	struct local_pvt *p = ast->tech_pvt;
+	int res = -1;
+	struct ast_frame f = { AST_FRAME_TEXT, };
+	int isoutbound;
+
+	ast_mutex_lock(&p->lock);
+	isoutbound = IS_OUTBOUND(ast, p);
+	f.data = (char *) text;
+	f.datalen = strlen(text) + 1;
 	res = local_queue_frame(p, isoutbound, &f, ast);
 	ast_mutex_unlock(&p->lock);
 	return res;

Modified: team/oej/siptransfer/channels/chan_misdn.c
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/channels/chan_misdn.c?rev=28556&r1=28555&r2=28556&view=diff
==============================================================================
--- team/oej/siptransfer/channels/chan_misdn.c (original)
+++ team/oej/siptransfer/channels/chan_misdn.c Fri May 19 04:57:15 2006
@@ -2316,7 +2316,7 @@
 }
 
 
-static struct chan_list *init_chan_list(void)
+static struct chan_list *init_chan_list(int orig)
 {
 	struct chan_list *cl=malloc(sizeof(struct chan_list));
 	
@@ -2326,6 +2326,8 @@
 	}
 	
 	memset(cl,0,sizeof(struct chan_list));
+
+	cl->orginator=orig;
 	
 	return cl;
 	
@@ -2342,7 +2344,7 @@
 	int channel=0, port=0;
 	struct misdn_bchannel *newbc = NULL;
 	
-	struct chan_list *cl=init_chan_list();
+	struct chan_list *cl=init_chan_list(ORG_AST);
 	
 	sprintf(buf,"%s/%s",misdn_type,(char*)data);
 	ast_copy_string(buf2,data, 128);
@@ -3171,7 +3173,7 @@
 	print_bearer(bc);
     
 	{
-		struct chan_list *ch=init_chan_list();
+		struct chan_list *ch=init_chan_list(ORG_MISDN);
 		struct ast_channel *chan;
 
 		if (!ch) { chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); return 0;}
@@ -3429,6 +3431,8 @@
 		
 		send_cause2ast(ch->ast,bc);
 
+
+		chan_misdn_log(0,bc->port," org:%d nt:%d, inbandavail:%d state:%d\n", ch->orginator, bc->nt, misdn_inband_avail(bc), ch->state);
 		if ( ch->orginator==ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
 			/* If there's inband information available (e.g. a
 			   recorded message saying what was wrong with the

Modified: team/oej/siptransfer/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/channels/chan_sip.c?rev=28556&r1=28555&r2=28556&view=diff
==============================================================================
--- team/oej/siptransfer/channels/chan_sip.c (original)
+++ team/oej/siptransfer/channels/chan_sip.c Fri May 19 04:57:15 2006
@@ -519,11 +519,13 @@
 	int len;		/*!< Length */
 	int headers;		/*!< # of SIP Headers */
 	int method;		/*!< Method of this request */
-	int lines;		/*!< SDP Content */
+	int lines;		/*!< Body Content */
 	unsigned int flags;	/*!< SIP_PKT Flags for this packet */
 	char *header[SIP_MAX_HEADERS];
 	char *line[SIP_MAX_LINES];
 	char data[SIP_MAX_PACKET];
+	unsigned int sdp_start; /*!< the line number where the SDP begins */
+	unsigned int sdp_end;	/*!< the line number where the SDP ends */
 };
 
 /*
@@ -636,21 +638,22 @@
 #define SIP_NAT_ROUTE		(2 << 18)	/*!< NAT Only ROUTE */
 #define SIP_NAT_ALWAYS		(3 << 18)	/*!< NAT Both ROUTE and RFC3581 */
 /* re-INVITE related settings */
-#define SIP_REINVITE		(3 << 20)	/*!< two bits used */
+#define SIP_REINVITE		(7 << 20)	/*!< three bits used */
 #define SIP_CAN_REINVITE	(1 << 20)	/*!< allow peers to be reinvited to send media directly p2p */
-#define SIP_REINVITE_UPDATE	(2 << 20)	/*!< use UPDATE (RFC3311) when reinviting this peer */
+#define SIP_CAN_REINVITE_NAT	(2 << 20)	/*!< allow media reinvite when new peer is behind NAT */
+#define SIP_REINVITE_UPDATE	(4 << 20)	/*!< use UPDATE (RFC3311) when reinviting this peer */
 /* "insecure" settings */
-#define SIP_INSECURE_PORT	(1 << 22)	/*!< don't require matching port for incoming requests */
-#define SIP_INSECURE_INVITE	(1 << 23)	/*!< don't require authentication for incoming INVITEs */
+#define SIP_INSECURE_PORT	(1 << 23)	/*!< don't require matching port for incoming requests */
+#define SIP_INSECURE_INVITE	(1 << 24)	/*!< don't require authentication for incoming INVITEs */
 /* Sending PROGRESS in-band settings */
-#define SIP_PROG_INBAND		(3 << 24)	/*!< three settings, uses two bits */
-#define SIP_PROG_INBAND_NEVER	(0 << 24)
-#define SIP_PROG_INBAND_NO	(1 << 24)
-#define SIP_PROG_INBAND_YES	(2 << 24)
-#define SIP_CALL_ONHOLD		(1 << 26)	/*!< Call states */
-#define SIP_CALL_LIMIT		(1 << 27)	/*!< Call limit enforced for this call */
-#define SIP_SENDRPID		(1 << 28)	/*!< Remote Party-ID Support */
-#define SIP_INC_COUNT		(1 << 29)	/*!< Did this connection increment the counter of in-use calls? */
+#define SIP_PROG_INBAND		(3 << 25)	/*!< three settings, uses two bits */
+#define SIP_PROG_INBAND_NEVER	(0 << 25)
+#define SIP_PROG_INBAND_NO	(1 << 25)
+#define SIP_PROG_INBAND_YES	(2 << 25)
+#define SIP_CALL_ONHOLD		(1 << 27)	/*!< Call states */
+#define SIP_CALL_LIMIT		(1 << 28)	/*!< Call limit enforced for this call */
+#define SIP_SENDRPID		(1 << 29)	/*!< Remote Party-ID Support */
+#define SIP_INC_COUNT		(1 << 30)	/*!< Did this connection increment the counter of in-use calls? */
 
 #define SIP_FLAGS_TO_COPY \
 	(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \
@@ -1089,9 +1092,9 @@
 
 /*--- Codec handling / SDP */
 static void try_suggested_sip_codec(struct sip_pvt *p);
-static const char *get_sdp_by_line(const char* line, const char *name, int nameLen);
 static const char* get_sdp_iterate(int* start, struct sip_request *req, const char *name);
 static const char *get_sdp(struct sip_request *req, const char *name);
+static int find_sdp(struct sip_request *req);
 static int process_sdp(struct sip_pvt *p, struct sip_request *req);
 static void add_codec_to_sdp(const struct sip_pvt *p, int codec, int sample_rate,
 			     char **m_buf, size_t *m_size, char **a_buf, size_t *a_size,
@@ -1942,17 +1945,31 @@
 static void register_peer_exten(struct sip_peer *peer, int onoff)
 {
 	char multi[256];
-	char *stringp, *ext;
+	char *stringp, *ext, *context;
 	if (!ast_strlen_zero(global_regcontext)) {
 
 		ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
 		stringp = multi;
 		while((ext = strsep(&stringp, "&"))) {
+ 			if((context = strchr(ext, '@'))) {
+				context++;
+				if (!ast_context_find(context)) {
+					ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
+					continue;
+				}
+				ext = strsep(&ext, "@");
+				if (onoff)
+					ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
+						 ast_strdup(peer->name), free, "SIP");
+				else
+					ast_context_remove_extension(context, ext, 1, NULL);
+			} else {
 			if (onoff)
 				ast_add_extension(global_regcontext, 1, ext, 1, NULL, NULL, "Noop",
 						  ast_strdup(peer->name), free, "SIP");
 			else
 				ast_context_remove_extension(global_regcontext, ext, 1, NULL);
+			}
 		}
 	}
 }
@@ -2194,18 +2211,19 @@
 		ast_rtp_destroy(r->vrtp);
 		r->vrtp = NULL;
 	}
-	ast_rtp_setdtmf(r->rtp, ast_test_flag(&r->flags[0], SIP_DTMF) != SIP_DTMF_INFO);
 	r->prefs = peer->prefs;
 	natflags = ast_test_flag(&r->flags[0], SIP_NAT) & SIP_NAT_ROUTE;
 	if (r->rtp) {
 		if (option_debug)
 			ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", natflags);
 		ast_rtp_setnat(r->rtp, natflags);
+		ast_rtp_setdtmf(r->rtp, ast_test_flag(&r->flags[0], SIP_DTMF) != SIP_DTMF_INFO);
 	}
 	if (r->vrtp) {
 		if (option_debug)
 			ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", natflags);
 		ast_rtp_setnat(r->vrtp, natflags);
+		ast_rtp_setdtmf(r->vrtp, 0);
 	}
 	ast_string_field_set(r, peername, peer->username);
 	ast_string_field_set(r, authname, peer->username);
@@ -3301,35 +3319,53 @@
 }
 
 /*! \brief Reads one line of SIP message body */
-static const char *get_sdp_by_line(const char* line, const char *name, int nameLen)
+static char *get_body_by_line(const char *line, const char *name, int nameLen)
 {
 	if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=')
 		return ast_skip_blanks(line + nameLen + 1);
+
 	return "";
 }
 
-/*! \brief get_sdp_iterate: lookup 'name' in the request starting
+/*! \brief Lookup 'name' in the SDP starting
  * at the 'start' line. Returns the matching line, and 'start'
  * is updated with the next line number.
  */
-static const char* get_sdp_iterate(int* start, struct sip_request *req, const char *name)
+static const char *get_sdp_iterate(int *start, struct sip_request *req, const char *name)
 {
 	int len = strlen(name);
 
-	while (*start < req->lines) {
-		const char *r = get_sdp_by_line(req->line[(*start)++], name, len);
+	while (*start < req->sdp_end) {
+		const char *r = get_body_by_line(req->line[(*start)++], name, len);
 		if (r[0] != '\0')
 			return r;
 	}
+
 	return "";
 }
 
-/*! \brief  get_sdp: Gets all kind of SIP message bodies, including SDP,
-   but the name wrongly applies _only_ sdp */
+/*! \brief Get a line from an SDP message body */
 static const char *get_sdp(struct sip_request *req, const char *name) 
 {
 	int dummy = 0;
+
 	return get_sdp_iterate(&dummy, req, name);
+}
+
+/*! \brief Get a specific line from the message body */
+static char *get_body(struct sip_request *req, char *name) 
+{
+	int x;
+	int len = strlen(name);
+	char *r;
+
+	for (x = 0; x < req->lines; x++) {
+		r = get_body_by_line(req->line[x], name, len);
+		if (r[0] != '\0')
+			return r;
+	}
+
+	return "";
 }
 
 /*! \brief Find compressed SIP alias */
@@ -3360,9 +3396,11 @@
 		{ "Session-Expires",     "x" },
 	};
 	int x;
+
 	for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 
 		if (!strcasecmp(aliases[x].fullname, name))
 			return aliases[x].shortname;
+
 	return _default;
 }
 
@@ -3891,7 +3929,69 @@
 	determine_firstline_parts(req);
 }
 
-/*! \brief Process SIP SDP and activate RTP channels*/
+/*!
+  \brief Determine whether a SIP message contains an SDP in its body
+  \param req the SIP request to process
+  \return 1 if SDP found, 0 if not found
+
+  Also updates req->sdp_start and req->sdp_end to indicate where the SDP
+  lives in the message body.
+*/
+static int find_sdp(struct sip_request *req)
+{
+	const char *content_type;
+	const char *search;
+	char *boundary;
+	unsigned int x;
+
+	content_type = get_header(req, "Content-Type");
+
+	/* if the body contains only SDP, this is easy */
+	if (!strcasecmp(content_type, "application/sdp")) {
+		req->sdp_start = 0;
+		req->sdp_end = req->lines;
+		return 1;
+	}
+
+	/* if it's not multipart/mixed, there cannot be an SDP */
+	if (strncasecmp(content_type, "multipart/mixed", 15))
+		return 0;
+
+	/* if there is no boundary marker, it's invalid */
+	if (!(search = strcasestr(content_type, ";boundary=")))
+		return 0;
+
+	search += 10;
+

[... 758 lines stripped ...]


More information about the asterisk-commits mailing list