[Asterisk-cvs] asterisk/channels chan_sip.c,1.577,1.578

markster at lists.digium.com markster at lists.digium.com
Thu Dec 2 17:19:42 CST 2004


Update of /usr/cvsroot/asterisk/channels
In directory mongoose.digium.com:/tmp/cvs-serv17321/channels

Modified Files:
	chan_sip.c 
Log Message:
Merge SIP portion of new codec work from bug #2945


Index: chan_sip.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
retrieving revision 1.577
retrieving revision 1.578
diff -u -d -r1.577 -r1.578
--- chan_sip.c	28 Nov 2004 21:49:07 -0000	1.577
+++ chan_sip.c	2 Dec 2004 22:18:09 -0000	1.578
@@ -163,6 +163,7 @@
 static int usecnt =0;
 AST_MUTEX_DEFINE_STATIC(usecnt_lock);
 
+
 /* Protect the interface list (of sip_pvt's) */
 AST_MUTEX_DEFINE_STATIC(iflock);
 
@@ -220,10 +221,8 @@
 #define DEC_OUT_USE	2
 #define INC_OUT_USE	3
 
-static struct sip_codec_pref {
-	int codec;
-	struct sip_codec_pref *next;
-} *prefs;
+static struct ast_codec_pref prefs;
+
 
 /* sip_request: The data grabbed from the UDP socket */
 struct sip_request {
@@ -254,6 +253,7 @@
 	ast_mutex_t lock;			/* Channel private lock */
 	char callid[80];			/* Global CallID */
 	char randdata[80];			/* Random data */
+	struct ast_codec_pref prefs; /* codec prefs */
 	unsigned int ocseq;			/* Current outgoing seqno */
 	unsigned int icseq;			/* Current incoming seqno */
 	unsigned int callgroup;			/* Call group */
@@ -391,6 +391,7 @@
 	char language[MAX_LANGUAGE];	/* Default language for this user */
 	char musicclass[MAX_LANGUAGE];  /* Music on Hold class */
 	char useragent[256];		/* User agent in SIP request */
+	struct ast_codec_pref prefs; /* codec prefs */
 	unsigned int callgroup;		/* Call group */
 	unsigned int pickupgroup;	/* Pickup Group */
 	int nat;			/* NAT setting */
@@ -435,6 +436,7 @@
 	char language[MAX_LANGUAGE];	/* Default language for prompts */
 	char musicclass[MAX_LANGUAGE];  /* Music on Hold class */
 	char useragent[256];		/* User agent in SIP request (saved from registration) */
+	struct ast_codec_pref prefs; /* codec prefs */
 	int lastmsgssent;
 	time_t	lastmsgcheck;		/* Last time we checked for MWI */
 	int dynamic;			/* Dynamic? Yes or no. Dynamic hosts register with us  */
@@ -1364,71 +1366,8 @@
 	return 0;
 }
 
-/*--- sip_prefs_free: Free codec list in preference structure ---*/
-static void sip_prefs_free(void)
-{
-	struct sip_codec_pref *cur, *next;
-	cur = prefs;
-	while(cur) {
-		next = cur->next;
-		free(cur);
-		cur = next;
-	}
-	prefs = NULL;
-}
 
-/*--- sip_pref_remove: Remove codec from pref list ---*/
-static void sip_pref_remove(int format)
-{
-	struct sip_codec_pref *cur, *prev=NULL;
-	cur = prefs;
-	while(cur) {
-		if (cur->codec == format) {
-			if (prev)
-				prev->next = cur->next;
-			else
-				prefs = cur->next;
-			free(cur);
-			return;
-		}
-		prev = cur;
-		cur = cur->next;
-	}
-}
-
-/*--- sip_pref_append: Append codec to list ---*/
-static int sip_pref_append(int format)
-{
-	struct sip_codec_pref *cur, *tmp;
-	sip_pref_remove(format);
-	tmp = (struct sip_codec_pref *)malloc(sizeof(struct sip_codec_pref));
-	if (!tmp)
-		return -1;
-	memset(tmp, 0, sizeof(struct sip_codec_pref));
-	tmp->codec = format;
-	if (prefs) {
-		cur = prefs;
-		while(cur->next)
-			cur = cur->next;
-		cur->next = tmp;
-	} else
-		prefs = tmp;
-	return 0;
-}
 
-/*--- sip_codec_choose: Pick a codec ---*/
-static int sip_codec_choose(int formats)
-{
-	struct sip_codec_pref *cur;
-	formats &= ((AST_FORMAT_MAX_AUDIO << 1) - 1);
-	cur = prefs;
-	while(cur) {
-		if (formats & cur->codec)
-			return cur->codec;
-		cur = cur->next;
-	}
-	return ast_best_codec(formats);
-}
 
 /*--- sip_call: Initiate SIP call from PBX ---*/
 /*      used from the dial() application      */
@@ -1985,12 +1924,14 @@
 	if (tmp) {
 		/* Select our native format based on codec preference until we receive
 		   something from another device to the contrary. */
+		ast_mutex_lock(&i->lock);
 		if (i->jointcapability)
-			tmp->nativeformats = sip_codec_choose(i->jointcapability);
+			tmp->nativeformats = ast_codec_choose(&i->prefs, i->jointcapability, 1);
 		else if (i->capability)
-			tmp->nativeformats = sip_codec_choose(i->capability);
+			tmp->nativeformats = ast_codec_choose(&i->prefs, i->capability, 1);
 		else
-			tmp->nativeformats = sip_codec_choose(global_capability);
+			tmp->nativeformats = ast_codec_choose(&i->prefs, global_capability, 1);
+		ast_mutex_unlock(&i->lock);
 		fmt = ast_best_codec(tmp->nativeformats);
 		if (title)
 			snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%04x", title, rand() & 0xffff);
@@ -2083,6 +2024,7 @@
 		}
 		for (v = i->vars ; v ; v = v->next)
 			pbx_builtin_setvar_helper(tmp,v->name,v->value);
+				
 	} else
 		ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
 	return tmp;
@@ -2291,9 +2233,11 @@
 	/* Keep track of stuff */
 	memset(p, 0, sizeof(struct sip_pvt));
         ast_mutex_init(&p->lock);
+
 	p->initid = -1;
 	p->autokillid = -1;
 	p->stateid = -1;
+	p->prefs = prefs;
 #ifdef OSP_SUPPORT
 	p->osphandle = -1;
 #endif	
@@ -2770,7 +2714,8 @@
 	p->noncodeccapability = noncodeccapability & peernoncodeccapability;
 	
 	if (debug) {
-		const unsigned slen=80;
+		/* shame on whoever coded this.... */
+		const unsigned slen=512;
 		char s1[slen], s2[slen], s3[slen], s4[slen];
 
 		ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n",
@@ -2790,12 +2735,12 @@
 	}
 	if (p->owner) {
 		if (!(p->owner->nativeformats & p->jointcapability)) {
-			const unsigned slen=80;
+			const unsigned slen=512;
 			char s1[slen], s2[slen];
 			ast_log(LOG_DEBUG, "Oooh, we need to change our formats since our peer supports only %s and not %s\n", 
 					ast_getformatname_multiple(s1, slen, p->jointcapability),
 					ast_getformatname_multiple(s2, slen, p->owner->nativeformats));
-			p->owner->nativeformats = sip_codec_choose(p->jointcapability);
+			p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1);
 			ast_set_read_format(p->owner, p->owner->readformat);
 			ast_set_write_format(p->owner, p->owner->writeformat);
 		}
@@ -3336,13 +3281,13 @@
 /*--- add_sdp: Add Session Description Protocol message ---*/
 static int add_sdp(struct sip_request *resp, struct sip_pvt *p)
 {
-	int len;
-	int codec;
+	int len = 0;
+	int codec = 0;
+	int pref_codec = 0;
 	int alreadysent = 0;
 	char costr[80];
 	struct sockaddr_in sin;
 	struct sockaddr_in vsin;
-	struct sip_codec_pref *cur;
 	char v[256] = "";
 	char s[256] = "";
 	char o[256] = "";
@@ -3353,11 +3298,13 @@
 	char a[1024] = "";
 	char a2[1024] = "";
 	char iabuf[INET_ADDRSTRLEN];
-	int x;
-	int capability;
+	int x = 0;
+	int capability = 0 ;
 	struct sockaddr_in dest;
 	struct sockaddr_in vdest = { 0, };
-	int debug=sip_debug_test_pvt(p);
+	int debug=0;
+	
+	debug = sip_debug_test_pvt(p);
 
 	/* XXX We break with the "recommendation" and send our IP, in order that our
 	       peer doesn't have to ast_gethostbyname() us XXX */
@@ -3409,6 +3356,7 @@
 	snprintf(t, sizeof(t), "t=0 0\r\n");
 	snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port));
 	snprintf(m2, sizeof(m2), "m=video %d RTP/AVP", ntohs(vdest.sin_port));
+	/* Prefer the codec we were requested to use, first, no matter what */
 	if (capability & p->prefcodec) {
 		if (debug)
 			ast_verbose("Answering/Requesting with root capability %d\n", p->prefcodec);
@@ -3428,33 +3376,34 @@
 		alreadysent |= p->prefcodec;
 	}
 	/* Start by sending our preferred codecs */
-	cur = prefs;
-	while(cur) {
-		if ((capability & cur->codec) && !(alreadysent & cur->codec)) {
+	for (x = 0 ; x < 32 ; x++) {
+		if(!(pref_codec = ast_codec_pref_index(&p->prefs,x)))
+			break; 
+		if ((capability & pref_codec) && !(alreadysent & pref_codec)) {
 			if (debug)
-				ast_verbose("Answering with preferred capability 0x%x(%s)\n", cur->codec, ast_getformatname(cur->codec));
-			codec = ast_rtp_lookup_code(p->rtp, 1, cur->codec);
+				ast_verbose("Answering with preferred capability 0x%x (%s)\n", pref_codec, ast_getformatname(pref_codec));
+			codec = ast_rtp_lookup_code(p->rtp, 1, pref_codec);
 			if (codec > -1) {
 				snprintf(costr, sizeof(costr), " %d", codec);
-				if (cur->codec <= AST_FORMAT_MAX_AUDIO) {
+				if (pref_codec <= AST_FORMAT_MAX_AUDIO) {
 					strncat(m, costr, sizeof(m) - strlen(m) - 1);
-					snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, cur->codec));
+					snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, pref_codec));
 					strncat(a, costr, sizeof(a) - strlen(a) - 1);
 				} else {
 					strncat(m2, costr, sizeof(m2) - strlen(m2) - 1);
-					snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/90000\r\n", codec, ast_rtp_lookup_mime_subtype(1, cur->codec));
+					snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/90000\r\n", codec, ast_rtp_lookup_mime_subtype(1, pref_codec));
 					strncat(a2, costr, sizeof(a2) - strlen(a) - 1);
 				}
 			}
 		}
-		alreadysent |= cur->codec;
-		cur = cur->next;
+		alreadysent |= pref_codec;
 	}
+
 	/* Now send any other common codecs, and non-codec formats: */
 	for (x = 1; x <= ((videosupport && p->vrtp) ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
 		if ((capability & x) && !(alreadysent & x)) {
 			if (debug)
-				ast_verbose("Answering with capability 0x%x(%s)\n", x, ast_getformatname(x));
+				ast_verbose("Answering with capability 0x%x (%s)\n", x, ast_getformatname(x));
 			codec = ast_rtp_lookup_code(p->rtp, 1, x);
 			if (codec > -1) {
 				snprintf(costr, sizeof(costr), " %d", codec);
@@ -3473,7 +3422,7 @@
 	for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
 		if (p->noncodeccapability & x) {
 			if (debug)
-				ast_verbose("Answering with non-codec capability 0x%x(%s)\n", x, ast_getformatname(x));
+				ast_verbose("Answering with non-codec capability 0x%x (%s)\n", x, ast_rtp_lookup_mime_subtype(0, x));
 			codec = ast_rtp_lookup_code(p->rtp, 0, x);
 			if (codec > -1) {
 				snprintf(costr, sizeof(costr), " %d", codec);
@@ -5349,6 +5298,7 @@
 				p->vars = tmpvar;
 			}
 		}
+		p->prefs = user->prefs;
 		p->nat = user->nat;
 #ifdef OSP_SUPPORT
 		p->ospauth = user->ospauth;
@@ -5700,7 +5650,7 @@
 		snprintf(srch, sizeof(srch), FORMAT, name,
 			peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)",
 			peer->dynamic ? " D " : "   ", 	/* Dynamic or not? */
-			(peer->nat & SIP_NAT_ROUTE) ? " N " : "   ",	/* NAT=yes? */
+			(peer->nat & SIP_NAT_ROUTE) ? " Y " : "   ",	/* NAT=yes? */
 			peer->ha ? " A " : "   ", 	/* permit/deny */
 			nm, ntohs(peer->addr.sin_port), status);
 
@@ -5760,6 +5710,9 @@
 	char cbuf[256];
 	char iabuf[INET_ADDRSTRLEN];
 	struct sip_peer *peer;
+	char codec_buf[512];
+	struct ast_codec_pref *pref;
+	int x = 0, codec = 0;
 
 	if (argc != 4)
 		return RESULT_SHOWUSAGE;
@@ -5805,38 +5758,23 @@
 		ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
 		ast_cli(fd, "  Username     : %s\n", peer->username);
 		ast_cli(fd, "  Codecs       : ");
-		/* This should really be a function in frame.c */
-		if (peer->capability & AST_FORMAT_G723_1)
-               		ast_cli(fd, "G723 ");
-		if (peer->capability & AST_FORMAT_GSM)
-			ast_cli(fd, "GSM ");
-		if (peer->capability & AST_FORMAT_ULAW)
-			ast_cli(fd, "ULAW ");
-		if (peer->capability & AST_FORMAT_ALAW)
-			ast_cli(fd, "ALAW ");
-		if (peer->capability & AST_FORMAT_G726)
-			ast_cli(fd, "G.726 ");
-		if (peer->capability & AST_FORMAT_SLINEAR)
-			ast_cli(fd, "SLINR ");
-		if (peer->capability & AST_FORMAT_LPC10)
-			ast_cli(fd, "LPC10 ");
-		if (peer->capability & AST_FORMAT_ADPCM)
-			ast_cli(fd, "ADPCM ");
-		if (peer->capability & AST_FORMAT_G729A)
-			ast_cli(fd, "G.729A ");
-		if (peer->capability & AST_FORMAT_SPEEX)
-			ast_cli(fd, "SPEEX ");
-		if (peer->capability & AST_FORMAT_ILBC)
-			ast_cli(fd, "ILBC ");
-		if (peer->capability & AST_FORMAT_JPEG)
-			ast_cli(fd, "JPEG ");
-		if (peer->capability & AST_FORMAT_PNG)
-			ast_cli(fd, "PNG ");
-		if (peer->capability & AST_FORMAT_H261)
-			ast_cli(fd, "H.261 ");
-		if (peer->capability & AST_FORMAT_H263)   
-			ast_cli(fd, "H.263 ");
-		ast_cli(fd, "\n");
+		ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
+		ast_cli(fd, "%s\n", codec_buf);
+		ast_cli(fd, "  Codec Order  : (");
+		pref = &peer->prefs;
+		for(x = 0; x < 32 ; x++) {
+			codec = ast_codec_pref_index(pref,x);
+			if(!codec)
+				break;
+			ast_cli(fd, "%s", ast_getformatname(codec));
+			if(x < 31 && ast_codec_pref_index(pref,x+1))
+				ast_cli(fd, "|");
+		}
+
+		if (!x)
+			ast_cli(fd, "none");
+		ast_cli(fd, ")\n");
+
 		ast_cli(fd, "  Status       : ");
 		if (peer->lastms < 0)
 			strncpy(status, "UNREACHABLE", sizeof(status) - 1);
@@ -8188,6 +8126,7 @@
 		user->trustrpid = global_trustrpid;
 		user->dtmfmode = global_dtmfmode;
 		user->progressinband = global_progressinband;
+		user->prefs = prefs;
 #ifdef OSP_SUPPORT
 		user->ospauth = global_ospauth;
 #endif
@@ -8271,17 +8210,9 @@
 					user->amaflags = format;
 				}
 			} else if (!strcasecmp(v->name, "allow")) {
-				format = ast_getformatbyname(v->value);
-				if (format < 1) 
-					ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
-				else
-					user->capability |= format;
+				ast_parse_allow_deny(&user->prefs, &user->capability, v->value, 1);
 			} else if (!strcasecmp(v->name, "disallow")) {
-				format = ast_getformatbyname(v->value);
-				if (format < 1) 
-					ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value);
-				else
-					user->capability &= ~format;
+				ast_parse_allow_deny(&user->prefs, &user->capability, v->value, 0);
 			} else if (!strcasecmp(v->name, "insecure")) {
 				user->insecure = ast_true(v->value);
 			} else if (!strcasecmp(v->name, "callingpres")) {
@@ -8324,6 +8255,7 @@
 	peer = malloc(sizeof(struct sip_peer));
 	if (!peer)
 		return NULL;
+
 	memset(peer, 0, sizeof(struct sip_peer));
 	peer->expire = -1;
 	peer->pokeexpire = -1;
@@ -8346,6 +8278,7 @@
 	peer->dynamic = 1;
 	peer->trustrpid = global_trustrpid;
 	peer->progressinband = global_progressinband;
+	peer->prefs = prefs;
 #ifdef OSP_SUPPORT
 	peer->ospauth = global_ospauth;
 #endif
@@ -8360,7 +8293,6 @@
 	struct sip_peer *prev;
 	struct ast_ha *oldha = NULL;
 	int maskfound=0;
-	int format;
 	int found=0;
 
 	prev = NULL;
@@ -8407,6 +8339,7 @@
 			peer->defaddr.sin_family = AF_INET;
 			peer->expiry = expiry;
 		}
+		peer->prefs = prefs;
 		oldha = peer->ha;
 		peer->ha = NULL;
 		peer->addr.sin_family = AF_INET;
@@ -8521,17 +8454,9 @@
 			} else if (!strcasecmp(v->name, "pickupgroup")) {
 				peer->pickupgroup = ast_get_group(v->value);
 			} else if (!strcasecmp(v->name, "allow")) {
-				format = ast_getformatbyname(v->value);
-				if (format < 1) 
-					ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
-				else
-					peer->capability |= format;
+				ast_parse_allow_deny(&peer->prefs, &peer->capability, v->value, 1);
 			} else if (!strcasecmp(v->name, "disallow")) {
-				format = ast_getformatbyname(v->value);
-				if (format < 1) 
-					ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value);
-				else
-					peer->capability &= ~format;
+				ast_parse_allow_deny(&peer->prefs, &peer->capability, v->value, 0);
 			} else if (!strcasecmp(v->name, "insecure")) {
 				if (!strcasecmp(v->value, "very")) {
 					peer->insecure = 2;
@@ -8626,12 +8551,11 @@
 	}
 	
 	
-	sip_prefs_free();
-	
 	/* Reset IP addresses  */
 	memset(&bindaddr, 0, sizeof(bindaddr));
 	memset(&localaddr, 0, sizeof(localaddr));
 	memset(&externip, 0, sizeof(externip));
+	memset(&prefs, 0 , sizeof(struct ast_codec_pref));
 
 	/* Initialize some reasonable defaults at SIP reload */
 	global_nat = SIP_NAT_RFC3581;
@@ -8794,21 +8718,9 @@
 			else
 				memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
 		} else if (!strcasecmp(v->name, "allow")) {
-			format = ast_getformatbyname(v->value);
-			if (format < 1) 
-				ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
-			else {
-				global_capability |= format;
-				sip_pref_append(format);
-			}
+			ast_parse_allow_deny(&prefs, &global_capability, v->value, 1);
 		} else if (!strcasecmp(v->name, "disallow")) {
-			format = ast_getformatbyname(v->value);
-			if (format < 1) 
-				ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value);
-			else {
-				global_capability &= ~format;
-				sip_pref_remove(format);
-			}
+			ast_parse_allow_deny(&prefs, &global_capability, v->value, 0);
 		} else if (!strcasecmp(v->name, "register")) {
 			sip_register(v->value, v->lineno);
 		} else if (!strcasecmp(v->name, "recordhistory")) {
@@ -9127,7 +9039,6 @@
 	struct sip_peer *peer;
 	delete_users();
 	reload_config();
-
 	prune_peers();
 	/* And start the monitor for the first time */
 	ast_mutex_lock(&regl.lock);
@@ -9171,9 +9082,9 @@
 	struct sip_peer *peer;
 	struct sip_registry *reg;
 
-        ast_mutex_init(&userl.lock);
-        ast_mutex_init(&peerl.lock);
-        ast_mutex_init(&regl.lock);
+	ast_mutex_init(&userl.lock);
+	ast_mutex_init(&peerl.lock);
+	ast_mutex_init(&regl.lock);
 	sched = sched_context_create();
 	if (!sched) {
 		ast_log(LOG_WARNING, "Unable to create schedule context\n");
@@ -9182,7 +9093,8 @@
 	if (!io) {
 		ast_log(LOG_WARNING, "Unable to create I/O context\n");
 	}
-	
+
+
 	res = reload_config();
 	if (!res) {
 		/* Make sure we can register our sip channel type */




More information about the svn-commits mailing list