[asterisk-commits] branch oej/test-this-branch r19732 - in /team/oej/test-this-branch: ./ apps/ ...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Apr 13 04:45:02 MST 2006


Author: oej
Date: Thu Apr 13 06:44:38 2006
New Revision: 19732

URL: http://svn.digium.com/view/asterisk?rev=19732&view=rev
Log:
Reset, resolve go

Added:
    team/oej/test-this-branch/apps/app_speech_utils.c
      - copied unchanged from r19128, trunk/apps/app_speech_utils.c
    team/oej/test-this-branch/doc/datastores.txt
      - copied unchanged from r19128, trunk/doc/datastores.txt
    team/oej/test-this-branch/doc/speechrec.txt
      - copied unchanged from r19128, trunk/doc/speechrec.txt
    team/oej/test-this-branch/include/asterisk/speech.h
      - copied unchanged from r19128, trunk/include/asterisk/speech.h
    team/oej/test-this-branch/res/res_speech.c
      - copied unchanged from r19128, trunk/res/res_speech.c
Modified:
    team/oej/test-this-branch/   (props changed)
    team/oej/test-this-branch/.cleancount
    team/oej/test-this-branch/UPGRADE.txt
    team/oej/test-this-branch/app.c
    team/oej/test-this-branch/apps/app_dial.c
    team/oej/test-this-branch/apps/app_parkandannounce.c
    team/oej/test-this-branch/apps/app_queue.c
    team/oej/test-this-branch/apps/app_rpt.c
    team/oej/test-this-branch/apps/app_voicemail.c
    team/oej/test-this-branch/channel.c
    team/oej/test-this-branch/channels/chan_misdn.c
    team/oej/test-this-branch/channels/chan_sip.c
    team/oej/test-this-branch/channels/misdn/isdn_lib.c
    team/oej/test-this-branch/doc/00README.1st
    team/oej/test-this-branch/doc/CODING-GUIDELINES
    team/oej/test-this-branch/formats/format_g723.c
    team/oej/test-this-branch/formats/format_g726.c
    team/oej/test-this-branch/formats/format_g729.c
    team/oej/test-this-branch/formats/format_gsm.c
    team/oej/test-this-branch/formats/format_h263.c
    team/oej/test-this-branch/formats/format_h264.c
    team/oej/test-this-branch/formats/format_ilbc.c
    team/oej/test-this-branch/formats/format_ogg_vorbis.c
    team/oej/test-this-branch/formats/format_pcm.c
    team/oej/test-this-branch/formats/format_sln.c
    team/oej/test-this-branch/formats/format_vox.c
    team/oej/test-this-branch/formats/format_wav.c
    team/oej/test-this-branch/formats/format_wav_gsm.c
    team/oej/test-this-branch/funcs/func_odbc.c
    team/oej/test-this-branch/include/asterisk/channel.h
    team/oej/test-this-branch/include/asterisk/compat.h
    team/oej/test-this-branch/include/asterisk/doxyref.h
    team/oej/test-this-branch/include/asterisk/frame.h
    team/oej/test-this-branch/pbx.c
    team/oej/test-this-branch/res/res_config_pgsql.c
    team/oej/test-this-branch/utils.c

Propchange: team/oej/test-this-branch/
------------------------------------------------------------------------------
    automerge = http://edvina.net/training/

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

Propchange: team/oej/test-this-branch/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Apr 13 06:44:38 2006
@@ -1,1 +1,1 @@
-/trunk:1-18604
+/trunk:1-19128

Modified: team/oej/test-this-branch/.cleancount
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/.cleancount?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/.cleancount (original)
+++ team/oej/test-this-branch/.cleancount Thu Apr 13 06:44:38 2006
@@ -1,1 +1,1 @@
-13
+15

Modified: team/oej/test-this-branch/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/UPGRADE.txt?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/UPGRADE.txt (original)
+++ team/oej/test-this-branch/UPGRADE.txt Thu Apr 13 06:44:38 2006
@@ -1,5 +1,10 @@
 Information for Upgrading From Previous Asterisk Releases
 =========================================================
+
+PBX Core:
+
+* The (very old and undocumented) ability to use BYEXTENSION for dialing
+  instead of ${EXTEN} has been removed.
 
 Command Line Interface:
 

Modified: team/oej/test-this-branch/app.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/app.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/app.c (original)
+++ team/oej/test-this-branch/app.c Thu Apr 13 06:44:38 2006
@@ -552,7 +552,6 @@
 	struct ast_dsp *sildet=NULL;   	/* silence detector dsp */
 	int totalsilence = 0;
 	int dspsilence = 0;
-	int gotsilence = 0;		/* did we timeout for silence? */
 	int rfmt=0;
 	struct ast_silence_generator *silgen = NULL;
 
@@ -675,7 +674,7 @@
 						if (option_verbose > 2)
 							ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000);
 						ast_frfree(f);
-						gotsilence = 1;
+						res = 'S';
 						outmsg=2;
 						break;
 					}
@@ -779,7 +778,6 @@
 	struct ast_dsp *sildet;   	/* silence detector dsp */
 	int totalsilence = 0;
 	int dspsilence = 0;
-	int gotsilence = 0;		/* did we timeout for silence? */
 	int rfmt=0;	
 	char prependfile[80];
 	
@@ -898,7 +896,7 @@
 					if (option_verbose > 2) 
 						ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000);
 					ast_frfree(f);
-					gotsilence = 1;
+					res = 'S';
 					outmsg=2;
 					break;
 					}

Modified: team/oej/test-this-branch/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_dial.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_dial.c (original)
+++ team/oej/test-this-branch/apps/app_dial.c Thu Apr 13 06:44:38 2006
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * Mark Spencer <markster at digium.com>
  *
@@ -747,10 +747,8 @@
 	int numnochan = 0;
 	int cause;
 	char numsubst[AST_MAX_EXTENSION];
-	char restofit[AST_MAX_EXTENSION];
 	char cidname[AST_MAX_EXTENSION];
 	char toast[80];
-	char *newnum;
 	char *l;
 	int privdb_val=0;
 	unsigned int calldurationlimit=0;
@@ -1007,14 +1005,6 @@
 			ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);	
 		}
 		ast_copy_string(numsubst, number, sizeof(numsubst));
-		/* If we're dialing by extension, look at the extension to know what to dial */
-		if ((newnum = strstr(numsubst, "BYEXTENSION"))) {
-			/* strlen("BYEXTENSION") == 11 */
-			ast_copy_string(restofit, newnum + 11, sizeof(restofit));
-			snprintf(newnum, sizeof(numsubst) - (newnum - numsubst), "%s%s", chan->exten,restofit);
-			if (option_debug)
-				ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
-		}
 		/* Request the peer */
 		tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
 		if (!tmp->chan) {

Modified: team/oej/test-this-branch/apps/app_parkandannounce.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_parkandannounce.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_parkandannounce.c (original)
+++ team/oej/test-this-branch/apps/app_parkandannounce.c Thu Apr 13 06:44:38 2006
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * Mark Spencer <markster at digium.com>
  *
@@ -164,9 +164,9 @@
 	}
 	/* At this point we have a priority and maybe an extension and a context */
 	chan->priority = atoi(priority);
-	if(exten && strcasecmp(exten, "BYEXTENSION"))
+	if (exten)
 		strncpy(chan->exten, exten, sizeof(chan->exten)-1);
-	if(context)
+	if (context)
 		strncpy(chan->context, context, sizeof(chan->context)-1);
 	} else {  /* increment the priority by default*/
 		chan->priority++;

Modified: team/oej/test-this-branch/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_queue.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_queue.c (original)
+++ team/oej/test-this-branch/apps/app_queue.c Thu Apr 13 06:44:38 2006
@@ -2018,11 +2018,9 @@
 	struct member *cur;
 	struct callattempt *outgoing=NULL; /* the queue we are building */
 	int to;
-	char restofit[AST_MAX_EXTENSION];
 	char oldexten[AST_MAX_EXTENSION]="";
 	char oldcontext[AST_MAX_CONTEXT]="";
 	char queuename[256]="";
-	char *newnum;
 	struct ast_channel *peer;
 	struct ast_channel *which;
 	struct callattempt *lpeer;
@@ -2103,14 +2101,6 @@
 		tmp->oldstatus = cur->status;
 		tmp->lastcall = cur->lastcall;
 		ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
-		/* If we're dialing by extension, look at the extension to know what to dial */
-		if ((newnum = strstr(tmp->interface, "/BYEXTENSION"))) {
-			newnum++;
-			strncpy(restofit, newnum + strlen("BYEXTENSION"), sizeof(restofit) - 1);
-			snprintf(newnum, sizeof(tmp->interface) - (newnum - tmp->interface), "%s%s", qe->chan->exten, restofit);
-			if (option_debug)
-				ast_log(LOG_DEBUG, "Dialing by extension %s\n", tmp->interface);
-		}
 		/* Special case: If we ring everyone, go ahead and ring them, otherwise
 		   just calculate their metric for the appropriate strategy */
 		if (!calc_metric(qe->parent, cur, x++, qe, tmp)) {

Modified: team/oej/test-this-branch/apps/app_rpt.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_rpt.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_rpt.c (original)
+++ team/oej/test-this-branch/apps/app_rpt.c Thu Apr 13 06:44:38 2006
@@ -6452,9 +6452,9 @@
 		}
 		/* At this point we have a priority and maybe an extension and a context */
 		chan->priority = atoi(priority);
-		if(exten && strcasecmp(exten, "BYEXTENSION"))
+		if (exten)
 			strncpy(chan->exten, exten, sizeof(chan->exten)-1);
-		if(context)
+		if (context)
 			strncpy(chan->context, context, sizeof(chan->context)-1);
 		} else {  /* increment the priority by default*/
 			chan->priority++;

Modified: team/oej/test-this-branch/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_voicemail.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_voicemail.c (original)
+++ team/oej/test-this-branch/apps/app_voicemail.c Thu Apr 13 06:44:38 2006
@@ -3311,7 +3311,7 @@
 				cmd = 't';
 		 }
 	}
-	if (cmd == 't')
+	if (cmd == 't' || cmd == 'S')
 		cmd = 0;
 	return cmd;
 }

Modified: team/oej/test-this-branch/channel.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/channel.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/channel.c (original)
+++ team/oej/test-this-branch/channel.c Thu Apr 13 06:44:38 2006
@@ -655,6 +655,7 @@
 	headp = &tmp->varshead;
 	ast_mutex_init(&tmp->lock);
 	AST_LIST_HEAD_INIT_NOLOCK(headp);
+	AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
 	strcpy(tmp->context, "default");
 	ast_string_field_set(tmp, language, defaultlanguage);
 	strcpy(tmp->exten, "s");
@@ -930,6 +931,7 @@
 	struct ast_var_t *vardata;
 	struct ast_frame *f, *fp;
 	struct varshead *headp;
+	struct ast_datastore *datastore = NULL;
 	char name[AST_CHANNEL_NAME];
 	
 	headp=&chan->varshead;
@@ -983,6 +985,12 @@
 		ast_frfree(fp);
 	}
 	
+	/* Get rid of each of the data stores on the channel */
+	while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
+		/* Free the data store */
+		ast_channel_datastore_free(datastore);
+	AST_LIST_HEAD_INIT_NOLOCK(&chan->datastores);
+
 	/* loop over the variables list, freeing all data and deleting list items */
 	/* no need to lock the list, as the channel is already locked */
 	
@@ -999,6 +1007,105 @@
 	AST_LIST_UNLOCK(&channels);
 
 	ast_device_state_changed_literal(name);
+}
+
+struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, char *uid)
+{
+	struct ast_datastore *datastore = NULL;
+
+	/* Make sure we at least have type so we can identify this */
+	if (info == NULL) {
+		return NULL;
+	}
+
+	/* Allocate memory for datastore and clear it */
+	datastore = ast_calloc(1, sizeof(*datastore));
+	if (datastore == NULL) {
+		return NULL;
+	}
+
+	datastore->info = info;
+
+	if (uid != NULL) {
+		datastore->uid = ast_strdup(uid);
+	}
+
+	return datastore;
+}
+
+int ast_channel_datastore_free(struct ast_datastore *datastore)
+{
+	int res = 0;
+
+	/* Using the destroy function (if present) destroy the data */
+	if (datastore->info->destroy != NULL && datastore->data != NULL) {
+		datastore->info->destroy(datastore->data);
+		datastore->data = NULL;
+	}
+
+	/* Free allocated UID memory */
+	if (datastore->uid != NULL) {
+		free(datastore->uid);
+		datastore->uid = NULL;
+	}
+
+	/* Finally free memory used by ourselves */
+	free(datastore);
+	datastore = NULL;
+
+	return res;
+}
+
+int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
+{
+	int res = 0;
+
+	AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
+
+	return res;
+}
+
+int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
+{
+	struct ast_datastore *datastore2 = NULL;
+	int res = -1;
+
+	/* Find our position and remove ourselves */
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore2, entry) {
+		if (datastore2 == datastore) {
+			AST_LIST_REMOVE_CURRENT(&chan->datastores, entry);
+			res = 0;
+			break;
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END
+
+	return res;
+}
+
+struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, char *uid)
+{
+	struct ast_datastore *datastore = NULL;
+	
+	if (info == NULL)
+		return NULL;
+
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) {
+		if (datastore->info == info) {
+			if (uid != NULL && datastore->uid != NULL) {
+				if (!strcasecmp(uid, datastore->uid)) {
+					/* Matched by type AND uid */
+					break;
+				}
+			} else {
+				/* Matched by type at least */
+				break;
+			}
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END
+
+	return datastore;
 }
 
 int ast_channel_spy_add(struct ast_channel *chan, struct ast_channel_spy *spy)
@@ -3061,6 +3168,11 @@
 		if (x != AST_GENERATOR_FD)
 			original->fds[x] = clone->fds[x];
 	}
+	/* Move data stores over */
+	if (AST_LIST_FIRST(&clone->datastores))
+                AST_LIST_INSERT_TAIL(&original->datastores, AST_LIST_FIRST(&clone->datastores), entry);
+	AST_LIST_HEAD_INIT_NOLOCK(&clone->datastores);
+
 	clone_variables(original, clone);
 	AST_LIST_HEAD_INIT_NOLOCK(&clone->varshead);
 	/* Presense of ADSI capable CPE follows clone */

Modified: team/oej/test-this-branch/channels/chan_misdn.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/channels/chan_misdn.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/channels/chan_misdn.c (original)
+++ team/oej/test-this-branch/channels/chan_misdn.c Thu Apr 13 06:44:38 2006
@@ -2067,7 +2067,6 @@
 
 	if (!len) {
 		chan_misdn_log(4,tmp->bc->port,"misdn_read: ZERO READ\n");
-
 		tmp->frame.frametype = AST_FRAME_NULL;
 		tmp->frame.subclass = 0;
 		return &tmp->frame;
@@ -2885,7 +2884,7 @@
 			close(ch->pipe[0]);
 			close(ch->pipe[1]);
 			
-			if (ast && MISDN_ASTERISK_PVT(ast)) {
+			if (ast && MISDN_ASTERISK_TECH_PVT(ast)) {
 				chan_misdn_log(1, bc->port, "* RELEASING CHANNEL pid:%d ctx:%s dad:%s oad:%s state: %s\n",bc?bc->pid:-1, ast->context, ast->exten,AST_CID_P(ast),misdn_get_ch_state(ch));
 				chan_misdn_log(3, bc->port, " --> * State Down\n");
 				/* copy cause */
@@ -3556,7 +3555,7 @@
 		
 		send_cause2ast(ch->ast,bc);
 
-		if (misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
+		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
 			   dialled number, or perhaps even giving an
@@ -3588,7 +3587,6 @@
 		*/
 		
 		misdn_lib_send_event(bc,EVENT_RELEASE);
-		
 	}
 	break;
 	

Modified: team/oej/test-this-branch/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/channels/chan_sip.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/channels/chan_sip.c (original)
+++ team/oej/test-this-branch/channels/chan_sip.c Thu Apr 13 06:44:38 2006
@@ -107,7 +107,6 @@
 #define TRUE 1
 #endif
 
- 
 #define VIDEO_CODEC_MASK	0x1fc0000 /*!< Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO */
 #ifndef IPTOS_MINCOST
 #define IPTOS_MINCOST		0x02
@@ -159,6 +158,7 @@
 #define SIP_MAX_LINES 		64			/*!< Max amount of lines in SIP attachment (like SDP) */
 #define SIP_MAX_PACKET		4096	/*!< Also from RFC 3261 (2543), should sub headers tho */
 
+#define	INITIAL_CSEQ		101	/*!< our initial sip sequence number */
 
 #ifdef AST_JB
 #include "asterisk/abstract_jb.h"
@@ -288,31 +288,6 @@
 	{ SIP_PUBLISH,	 NO_RTP, "PUBLISH" }
 };
 
-/*! \brief Structure for conversion between compressed SIP and "normal" SIP */
-static const struct cfalias {
-	char * const fullname;
-	char * const shortname;
-} aliases[] = {
-	{ "Content-Type", "c" },
-	{ "Content-Encoding", "e" },
-	{ "From", "f" },
-	{ "Call-ID", "i" },
-	{ "Contact", "m" },
-	{ "Content-Length", "l" },
-	{ "Subject", "s" },
-	{ "To", "t" },
-	{ "Supported", "k" },
-	{ "Refer-To", "r" },
-	{ "Referred-By", "b" },
-	{ "Allow-Events", "u" },
-	{ "Event", "o" },
-	{ "Via", "v" },
-	{ "Accept-Contact", "a" },
-	{ "Reject-Contact", "j" },
-	{ "Request-Disposition", "d" },
-	{ "Session-Expires", "x" },
-};
-
 /*!  Define SIP option tags, used in Require: and Supported: headers 
  	We need to be aware of these properties in the phones to use 
 	the replace: header. We should not do that without knowing
@@ -347,7 +322,7 @@
 	int id;			/*!< Bitmap ID */
 	int supported;		/*!< Supported by Asterisk ? */
 	char * const text;	/*!< Text id, as in standard */
-} sip_options[] = {
+} sip_options[] = {	/* XXX used in 3 places */
 	/* Replaces: header for transfer */
 	{ SIP_OPT_REPLACES,	SUPPORTED,	"replaces" },	
 	/* RFC3262: PRACK 100% reliability */
@@ -535,13 +510,31 @@
 	int len;		/*!< Length */
 	int headers;		/*!< # of SIP Headers */
 	int method;		/*!< Method of this request */
+	int lines;		/*!< SDP Content */
+	unsigned int flags;	/*!< SIP_PKT Flags for this packet */
 	char *header[SIP_MAX_HEADERS];
-	int lines;		/*!< SDP Content */
 	char *line[SIP_MAX_LINES];
 	char data[SIP_MAX_PACKET];
-	int debug;		/*!< Debug flag for this packet */
-	unsigned int flags;	/*!< SIP_PKT Flags for this packet */
 };
+
+/*
+ * A sip packet is stored into the data[] buffer, with the header followed
+ * by an empty line and the body of the message.
+ * On outgoing packets, data is accumulated in data[] with len reflecting
+ * the next available byte, headers and lines count the number of lines
+ * in both parts. There are no '\0' in data[0..len-1].
+ *
+ * On received packet, the input read from the socket is copied into data[],
+ * len is set and the string is NUL-terminated. Then a parser fills up
+ * the other fields -header[] and line[] to point to the lines of the
+ * message, rlPart1 and rlPart2 parse the first lnie as below:
+ *
+ * Requests have in the first line	METHOD URI SIP/2.0
+ *	rlPart1 = method; rlPart2 = uri;
+ * Responses have in the first line	SIP/2.0 code description
+ *	rlPart1 = SIP/2.0; rlPart2 = code + description;
+ *
+ */
 
 /*! \brief structure used in transfers */
 struct sip_dual {
@@ -702,6 +695,9 @@
 /* SIP packet flags */
 #define SIP_PKT_DEBUG		(1 << 0)	/*!< Debug this packet */
 #define SIP_PKT_WITH_TOTAG	(1 << 1)	/*!< This packet has a to-tag */
+#define SIP_PKT_IGNORE 		(1 << 2)	/*!< This is a re-transmit, ignore it */
+#define SIP_PKT_IGNORE_RESP	(1 << 3)	/*!< Resp ignore - ??? */
+#define SIP_PKT_IGNORE_REQ	(1 << 4)	/*!< Req ignore - ??? */
 
 #define sipdebug		ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG)
 #define sipdebug_config		ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG)
@@ -845,6 +841,7 @@
 };	
 
 /*! \brief Structure for SIP peer data, we place calls to peers if registered  or fixed IP address (host) */
+/* XXX field 'name' must be first otherwise sip_addrcmp() will fail */
 struct sip_peer {
 	ASTOBJ_COMPONENTS(struct sip_peer);	/*!< name, refcount, objflags,  object pointers */
 	enum objecttype type;		/*!< SIP_PEER and/or SIP_USER */
@@ -982,7 +979,7 @@
 /*---------------------------- Forward declarations of functions in chan_sip.c */
 static int transmit_response(struct sip_pvt *p, char *msg, struct sip_request *req);
 static int transmit_response_with_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, enum xmittype reliable);
-static int transmit_response_with_unsupported(struct sip_pvt *p, char *msg, struct sip_request *req, char *unsupported);
+static int transmit_response_with_unsupported(struct sip_pvt *p, const char *msg, struct sip_request *req, const char *unsupported);
 static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, struct sip_request *req, const char *rand, enum xmittype reliable, const char *header, int stale);
 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 inc, enum xmittype reliable, int newbranch);
@@ -1027,15 +1024,15 @@
 static void sip_dump_history(struct sip_pvt *dialog);	/* Dump history to LOG_DEBUG at end of dialog, before destroying data */
 static const struct cfsubscription_types *find_subscription_type(enum subscriptiontype subtype);
 static int transmit_state_notify(struct sip_pvt *p, int state, int full);
-static char *gettag(struct sip_request *req, char *header, char *tagbuf, int tagbufsize);
-static int find_sip_method(char *msg);
-static unsigned int parse_sip_options(struct sip_pvt *pvt, char *supported);
+static const char *gettag(const struct sip_request *req, char *header, char *tagbuf, int tagbufsize);
+static int find_sip_method(const char *msg);
+static unsigned int parse_sip_options(struct sip_pvt *pvt, const char *supported);
 static void sip_destroy(struct sip_pvt *p);
 static void sip_destroy_device(struct sip_peer *device);
 static void parse_request(struct sip_request *req);
-static char *get_header(struct sip_request *req, const char *name);
+static const char *get_header(const struct sip_request *req, const char *name);
 static void copy_request(struct sip_request *dst,struct sip_request *src);
-static int transmit_response_reliable(struct sip_pvt *p, char *msg, struct sip_request *req);
+static int transmit_response_reliable(struct sip_pvt *p, const char *msg, struct sip_request *req);
 static int transmit_register(struct sip_registry *r, int sipmethod, char *auth, char *authheader);
 static int sip_poke_peer(struct sip_peer *peer);
 static int __sip_do_register(struct sip_registry *r);
@@ -1057,6 +1054,17 @@
 static int transmit_reinvite_with_t38_sdp(struct sip_pvt *p);
 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);
+
+/*------Request handling functions */
+static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e);
+static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock);
+static int handle_request_bye(struct sip_pvt *p, struct sip_request *req);
+static int handle_request_register(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e);
+static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req);
+static int handle_request_message(struct sip_pvt *p, struct sip_request *req);
+static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e);
+static void handle_request_info(struct sip_pvt *p, struct sip_request *req);
+static int handle_request_options(struct sip_pvt *p, struct sip_request *req);
 
 /*----- RTP interface functions */
 static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active);
@@ -1110,25 +1118,37 @@
 	set_udptl_peer: sip_set_udptl_peer,
 };
 
-/*! \brief Find SIP method from header
- * Strictly speaking, SIP methods are case SENSITIVE, but we don't check 
- * following Jon Postel's rule: Be gentle in what you accept, strict with what you send */
-static int find_sip_method(char *msg)
+/*! \brief returns true if 'name' (with optional trailing whitespace)
+ * matches the sip method 'id'.
+ * Strictly speaking, SIP methods are case SENSITIVE, but we do
+ * a case-insensitive comparison to be more tolerant.
+ * following Jon Postel's rule: Be gentle in what you accept, strict with what you send 
+ */
+static int method_match(enum sipmethod id, const char *name)
+{
+	int len = strlen(sip_methods[id].text);
+	int l_name = name ? strlen(name) : 0;
+	/* true if the string is long enough, and ends with whitespace, and matches */
+	return (l_name >= len && name[len] < 33 &&
+		!strncasecmp(sip_methods[id].text, name, len));
+}
+
+/*! \brief  find_sip_method: Find SIP method from header */
+static int find_sip_method(const char *msg)
 {
 	int i, res = 0;
 	
 	if (ast_strlen_zero(msg))
 		return 0;
-
 	for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) {
-		if (!strcasecmp(sip_methods[i].text, msg)) 
+		if (method_match(i, msg))
 			res = sip_methods[i].id;
 	}
 	return res;
 }
 
 /*! \brief Parse supported header in incoming packet */
-static unsigned int parse_sip_options(struct sip_pvt *pvt, char *supported)
+static unsigned int parse_sip_options(struct sip_pvt *pvt, const char *supported)
 {
 	char *next, *sep;
 	char *temp = ast_strdupa(supported);
@@ -1179,29 +1199,35 @@
 	return 1;
 }
 
+/* The real destination address for a write */
+static const struct sockaddr_in *sip_real_dst(const struct sip_pvt *p)
+{
+	return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
+}
+
+static const char *sip_nat_mode(const struct sip_pvt *p)
+{
+	return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT";
+}
+
 /*! \brief Test PVT for debugging output */
 static inline int sip_debug_test_pvt(struct sip_pvt *p) 
 {
 	if (!sipdebug)
 		return 0;
-	return sip_debug_test_addr(ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ? &p->recv : &p->sa);
-}
-
+	return sip_debug_test_addr(sip_real_dst(p));
+}
 
 /*! \brief Transmit SIP message */
 static int __sip_xmit(struct sip_pvt *p, char *data, int len)
 {
 	int res;
 	char iabuf[INET_ADDRSTRLEN];
-
-	if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
-		res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in));
-	else
-		res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in));
-
-	if (res != len) {
-		ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), res, strerror(errno));
-	}
+	const struct sockaddr_in *dst = sip_real_dst(p);
+	res=sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
+
+	if (res != len)
+		ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(iabuf, sizeof(iabuf), dst->sin_addr), ntohs(dst->sin_port), res, strerror(errno));
 	return res;
 }
 
@@ -1232,7 +1258,7 @@
 
 	if (localaddr && externip.sin_addr.s_addr &&
 	   ast_apply_ha(localaddr, &theirs)) {
-		if (externexpire && (time(NULL) >= externexpire)) {
+		if (externexpire && time(NULL) >= externexpire) {
 			struct ast_hostent ahp;
 			struct hostent *hp;
 
@@ -1415,7 +1441,6 @@
 	pkt->timer_t1 = p->timer_t1;	/* Set SIP timer T1 */
 	if (fatal)
 		ast_set_flag(pkt, FLAG_FATAL);
-
 	if (pkt->timer_t1)
 		siptimer_a = pkt->timer_t1 * 2;
 
@@ -1482,10 +1507,11 @@
 /*! \brief Cancel destruction of SIP dialog */
 static int sip_cancel_destroy(struct sip_pvt *p)
 {
-	if (p->autokillid > -1)
+	if (p->autokillid > -1) {
 		ast_sched_del(sched, p->autokillid);
-	append_history(p, "CancelDestroy", "");
-	p->autokillid = -1;
+		append_history(p, "CancelDestroy", "");
+		p->autokillid = -1;
+	}
 	return 0;
 }
 
@@ -1534,9 +1560,9 @@
 /*! \brief Pretend to ack all packets */
 static int __sip_pretend_ack(struct sip_pvt *p)
 {
-	struct sip_pkt *cur=NULL;
-
-	while(p->packets) {
+	struct sip_pkt *cur = NULL;
+
+	while (p->packets) {
 		if (cur == p->packets) {
 			ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
 			return -1;
@@ -1562,16 +1588,14 @@
 {
 	struct sip_pkt *cur;
 	int res = -1;
-	char *msg = sip_methods[sipmethod].text;
-
-	for (cur = p->packets; cur ; cur = cur->next) {
-		if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
-			((ast_test_flag(cur, FLAG_RESPONSE)) || 
-			 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
+
+	for (cur = p->packets; cur; cur = cur->next) {
+		if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp &&
+			(ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) {
 			/* this is our baby */
 			if (cur->retransid > -1) {
 				if (option_debug > 3 && sipdebug)
-					ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, msg);
+					ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
 				ast_sched_del(sched, cur->retransid);
 			}
 			cur->retransid = -1;
@@ -1712,6 +1736,7 @@
 	char ipaddr[20];
 	char regseconds[20];
 	time_t nowtime;
+	const char *fc = fullcontact ? "fullcontact" : NULL;
 	
 	time(&nowtime);
 	nowtime += expirey;
@@ -1719,10 +1744,9 @@
 	ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr);
 	snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
 	
-	if (fullcontact)
-		ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, "fullcontact", fullcontact, NULL);
-	else
-		ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, NULL);
+	ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
+		"port", port, "regseconds", regseconds,
+		"username", username, fc, fullcontact, NULL); /* note fc _can_ be NULL */
 }
 
 /*! \brief Automatically add peer extension to dial plan */
@@ -1843,14 +1867,14 @@
 	if (!newpeername) {	/* Did not find peer in realtime */
 		ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf);
 		ast_variables_destroy(var);
-		return (struct sip_peer *) NULL;
+		return NULL;
 	}
 
 	/* Peer found in realtime, now build it in memory */
 	peer = build_peer(newpeername, var, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
 	if (!peer) {
 		ast_variables_destroy(var);
-		return (struct sip_peer *) NULL;
+		return NULL;
 	}
 
 	if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
@@ -1947,18 +1971,16 @@
  * realtime storage (defined in extconfig.conf) */
 static struct sip_peer *find_user(const char *name, int realtime)
 {
-	struct sip_peer *u = NULL;
-	u = ASTOBJ_CONTAINER_FIND(&userl,name);
-	if (!u && realtime) {
+	struct sip_peer *u = ASTOBJ_CONTAINER_FIND(&userl,name);
+	if (!u && realtime)
 		u = realtime_user(name);
-	}
 	return u;
 }
 
 /*! \brief Create address structure from peer reference */
 static int create_addr_from_peer(struct sip_pvt *r, struct sip_peer *peer)
 {
-	int usenatroute;
+	int natflags;
 
 	if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
 	    (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
@@ -1976,6 +1998,7 @@
 		r->vrtp = NULL;
 	}
 	r->prefs = peer->prefs;
+
 	if (ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)) {
 		ast_copy_flags(&r->t38.t38support, &peer->flags[1], SIP_PAGE2_T38SUPPORT);
 		r->t38.capability = global_t38_capability;
@@ -1996,21 +2019,21 @@
 		if (r->udptl)
 			ast_udptl_destroy(r->udptl);
 	}
-	usenatroute = ast_test_flag(&r->flags[0], SIP_NAT) & SIP_NAT_ROUTE;
+	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", usenatroute);
-		ast_rtp_setnat(r->rtp, usenatroute);
+			ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", natflags);
+		ast_rtp_setnat(r->rtp, natflags);
 	}
 	if (r->vrtp) {
 		if (option_debug)
-			ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", usenatroute);
-		ast_rtp_setnat(r->vrtp, usenatroute);
+			ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", natflags);
+		ast_rtp_setnat(r->vrtp, natflags);
 	}
 	if (r->udptl) {
 		if (option_debug)
-			ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %d\n", usenatroute);
-		ast_udptl_setnat(r->udptl, usenatroute);
+			ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %d\n", natflags);
+		ast_udptl_setnat(r->udptl, natflags);
 	}
 	ast_string_field_set(r, peername, peer->username);
 	ast_string_field_set(r, authname, peer->username);
@@ -2034,8 +2057,7 @@
 	if (ast_strlen_zero(r->tohost)) {
 		char iabuf[INET_ADDRSTRLEN];
 
-		ast_inet_ntoa(iabuf, sizeof(iabuf),  peer->addr.sin_addr.s_addr ? peer->addr.sin_addr : peer->defaddr.sin_addr);
-
+		ast_inet_ntoa(iabuf, sizeof(iabuf),  r->sa.sin_addr);
 		ast_string_field_set(r, tohost, iabuf);
 	}
 	if (!ast_strlen_zero(peer->fromdomain))
@@ -2083,10 +2105,8 @@
 
 	ast_copy_string(peer, opeer, sizeof(peer));
 	port = strchr(peer, ':');
-	if (port) {
-		*port = '\0';
-		port++;
-	}
+	if (port)
+		*port++ = '\0';
 	dialog->sa.sin_family = AF_INET;
 	dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */
 	p = find_peer(peer, NULL, 1);
@@ -2101,10 +2121,7 @@
 			return -1;
 
 		hostn = peer;
-		if (port)
-			portno = atoi(port);
-		else
-			portno = DEFAULT_SIP_PORT;
+		portno = port ? atoi(port) : DEFAULT_SIP_PORT;
 		if (srvlookup) {
 			char service[MAXHOSTNAMELEN];
 			int tportno;
@@ -2141,6 +2158,7 @@
 	ast_mutex_lock(&p->lock);
 	p->initid = -1;
 	if (p->owner) {
+		/* XXX fails on possible deadlock */
 		if (!ast_mutex_trylock(&p->owner->lock)) {
 			ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
 			ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
@@ -2250,7 +2268,7 @@
 
 	/* Remove link from peer to subscription of MWI */
 	if (p->relatedpeer && p->relatedpeer->mwipvt)
-		p->relatedpeer->mwipvt = (struct sip_pvt *) NULL;
+		p->relatedpeer->mwipvt = NULL;
 
 	if (dumphistory)
 		sip_dump_history(p);
@@ -2320,9 +2338,8 @@
 	/* remove all current packets in this dialog */
 	while((cp = p->packets)) {
 		p->packets = p->packets->next;
-		if (cp->retransid > -1) {
+		if (cp->retransid > -1)
 			ast_sched_del(sched, cp->retransid);
-		}
 		free(cp);
 	}
 	if (p->chanvars) {
@@ -2536,10 +2553,9 @@
    31 normal unspecified                   480 Temporarily unavailable
 \endverbatim
 */
-static char *hangup_cause2sip(int cause)
-{
-	switch(cause)
-	{
+static const char *hangup_cause2sip(int cause)
+{
+	switch (cause) {
 		case AST_CAUSE_UNALLOCATED:		/* 1 */
 		case AST_CAUSE_NO_ROUTE_DESTINATION:	/* 3 IAX2: Can't find extension in context */
 		case AST_CAUSE_NO_ROUTE_TRANSIT_NET:	/* 2 */
@@ -2648,10 +2664,10 @@
 					update_call_counter(p, INC_CALL_LIMIT);
 				}
 			} else {	/* Incoming call, not up */
-				char *res;
-				if (ast->hangupcause && ((res = hangup_cause2sip(ast->hangupcause)))) {
+				const char *res;
+				if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause)))
 					transmit_response_reliable(p, res, &p->initreq);
-				} else 
+				else 
 					transmit_response_reliable(p, "603 Declined", &p->initreq);
 			}
 		} else {	/* Call is in UP state, send BYE */
@@ -2795,16 +2811,25 @@
         Basically update any ->owner links */
 static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
 {
-	struct sip_pvt *p = newchan->tech_pvt;
+	int ret = -1;
+	struct sip_pvt *p;
+
+	if (!newchan || !newchan->tech_pvt) {
+		ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name);
+		return -1;
+	}
+	p = newchan->tech_pvt;
+
 	ast_mutex_lock(&p->lock);
-	if (p->owner != oldchan) {
+	if (p->owner != oldchan)
 		ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
-		ast_mutex_unlock(&p->lock);
-		return -1;
-	}
-	p->owner = newchan;
+	else {
+		p->owner = newchan;
+		append_history(p, "Masq", "Old channel: %s\n", oldchan->name);
+		ret = 0;
+	}
 	ast_mutex_unlock(&p->lock);
-	return 0;
+	return ret;
 }
 
 /*! \brief Send DTMF character on SIP channel
@@ -3059,26 +3084,20 @@
 	if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
 		tmp->cid.cid_dnid = ast_strdup(i->exten);
 	tmp->priority = 1;
-	if (!ast_strlen_zero(i->uri)) {
+	if (!ast_strlen_zero(i->uri))
 		pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
-	}
-	if (!ast_strlen_zero(i->domain)) {
+	if (!ast_strlen_zero(i->domain))
 		pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
-	}
-	if (!ast_strlen_zero(i->useragent)) {
+	if (!ast_strlen_zero(i->useragent))
 		pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent);
-	}
-	if (!ast_strlen_zero(i->callid)) {
+	if (!ast_strlen_zero(i->callid))
 		pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
-	}
 	ast_setstate(tmp, state);
-	if (state != AST_STATE_DOWN) {
-		if (ast_pbx_start(tmp)) {
-			ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
-			tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
-			ast_hangup(tmp);
-			tmp = NULL;
-		}
+	if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
+		ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
+		tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
+		ast_hangup(tmp);
+		tmp = NULL;
 	}
 	/* Set channel variables for this call from configuration */
 	for (v = i->chanvars ; v ; v = v->next)
@@ -3098,52 +3117,64 @@
 }
 
 /*! \brief Reads one line of SIP message body */
-static char* get_sdp_by_line(char* line, char *name, int nameLen)
-{
-	if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') {
+static const char* get_sdp_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 Gets all kind of SIP message bodies, including SDP,
-   but the name wrongly applies _only_ sdp */
-static char *get_sdp(struct sip_request *req, char *name) 
-{
-	int x;
+/*! \brief get_sdp_iterate: lookup 'name' in the request 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)
+{
 	int len = strlen(name);
-	char *r;
-
-	for (x = 0; x < req->lines; x++) {
-		r = get_sdp_by_line(req->line[x], name, len);
+
+	while (*start < req->lines) {
+		const char *r = get_sdp_by_line(req->line[(*start)++], name, len);

[... 3567 lines stripped ...]


More information about the asterisk-commits mailing list