[asterisk-commits] oej: branch oej/pinefrog-1.4 r238015 - in /team/oej/pinefrog-1.4: channels/ i...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jan 6 09:57:46 CST 2010


Author: oej
Date: Wed Jan  6 09:57:42 2010
New Revision: 238015

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=238015
Log:
Asterisk now sends proper SDES CNAME packets. We need to have a bit more fantasy when
it comes to the content, but anyhow. Good start I think. 
Next, a polite RTCP Goodbye.

Modified:
    team/oej/pinefrog-1.4/channels/chan_sip.c
    team/oej/pinefrog-1.4/include/asterisk/rtp.h
    team/oej/pinefrog-1.4/main/rtp.c

Modified: team/oej/pinefrog-1.4/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinefrog-1.4/channels/chan_sip.c?view=diff&rev=238015&r1=238014&r2=238015
==============================================================================
--- team/oej/pinefrog-1.4/channels/chan_sip.c (original)
+++ team/oej/pinefrog-1.4/channels/chan_sip.c Wed Jan  6 09:57:42 2010
@@ -4709,8 +4709,9 @@
 	if (sip_methods[intended_method].need_rtp) {
 		p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
 		/* If the global videosupport flag is on, we always create a RTP interface for video */
-		if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT))
+		if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) {
 			p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
+		}
 		if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT))
 			p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr);
 		if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) {
@@ -4768,6 +4769,12 @@
 	else
 		ast_string_field_set(p, callid, callid);
 	/* Assign default music on hold class */
+	if (p->rtp) {
+		ast_rtcp_setcname(p->rtp, p->callid, strlen(p->callid));
+	}
+	if (p->vrtp) {
+		ast_rtcp_setcname(p->rtp, p->callid, strlen(p->callid));
+	}
 	ast_string_field_set(p, mohinterpret, default_mohinterpret);
 	ast_string_field_set(p, mohsuggest, default_mohsuggest);
 	p->capability = global_capability;
@@ -13472,8 +13479,10 @@
 		ast_rtp_stop(p->rtp);
 		sip_rtcp_report(p, p->rtp, "audio");
 	}
-	if (p->vrtp)
+	if (p->vrtp) {
 		ast_rtp_stop(p->vrtp);
+		sip_rtcp_report(p, p->rtp, "video");
+	}
 	if (p->udptl)
 		ast_udptl_stop(p->udptl);
 }

Modified: team/oej/pinefrog-1.4/include/asterisk/rtp.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinefrog-1.4/include/asterisk/rtp.h?view=diff&rev=238015&r1=238014&r2=238015
==============================================================================
--- team/oej/pinefrog-1.4/include/asterisk/rtp.h (original)
+++ team/oej/pinefrog-1.4/include/asterisk/rtp.h Wed Jan  6 09:57:42 2010
@@ -180,6 +180,10 @@
 int ast_rtp_sendcng(struct ast_rtp *rtp, int level);
 
 int ast_rtp_settos(struct ast_rtp *rtp, int tos);
+
+void ast_rtcp_setcname(struct ast_rtp *rtp, const char *cname, size_t length);
+
+
 
 /*! \brief When changing sources, don't generate a new SSRC */
 void ast_rtp_set_constantssrc(struct ast_rtp *rtp);

Modified: team/oej/pinefrog-1.4/main/rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinefrog-1.4/main/rtp.c?view=diff&rev=238015&r1=238014&r2=238015
==============================================================================
--- team/oej/pinefrog-1.4/main/rtp.c (original)
+++ team/oej/pinefrog-1.4/main/rtp.c Wed Jan  6 09:57:42 2010
@@ -64,8 +64,8 @@
 #define RTCP_MIN_INTERVALMS       500	/*!< Min milli-seconds between RTCP reports we send */
 #define RTCP_MAX_INTERVALMS       60000	/*!< Max milli-seconds between RTCP reports we send */
 
-#define RTCP_PT_FUR     192		/*!< FIR  - Full Intra-frame request */
-#define RTCP_PT_NACK    193		/*!< NACK - Negative acknowledgement */
+#define RTCP_PT_FUR     192		/*!< FIR  - Full Intra-frame request (h.261) */
+#define RTCP_PT_NACK    193		/*!< NACK - Negative acknowledgement (h.261) */
 #define RTCP_PT_IJ      195		/*!< IJ   - RFC 5450 Extended Inter-arrival jitter report */
 #define RTCP_PT_SR      200		/*!< SR   - RFC 3550 Sender report */
 #define RTCP_PT_RR      201		/*!< RR   - RFC 3550 Receiver report */
@@ -87,6 +87,7 @@
 	SDES_TOOL	= 6,		/*!< Name of application or tool */
 	SDES_NOTE	= 7,		/*!< Notice about the source */
 	SDES_PRIV	= 8,		/*!< SDES Private extensions */
+	SDES_H323_CADDR	= 9,		/*!< H.323 Callable address */
 };
 
 #define RTP_MTU		1200
@@ -228,6 +229,8 @@
  */
 struct ast_rtcp {
 	int s;				/*!< Socket */
+	char ourcname[255];		/*!< Our SDES RTP session name (CNAME) */
+	char theircname[255];		/*!< Their SDES RTP session name (CNAME) */
 	struct sockaddr_in us;		/*!< Socket representation of the local endpoint. */
 	struct sockaddr_in them;	/*!< Socket representation of the remote endpoint. */
 	struct sockaddr_in altthem;	/*!< Alternate source for RTCP */
@@ -888,11 +891,11 @@
 struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
 {
 	socklen_t len;
-	int position, i, packetwords;
+	int position, i, j, packetwords;
 	int res;
 	struct sockaddr_in sin;
-	char sdestext[255];
-	unsigned int sdesheader, sdeslength, sdestype;
+	char *sdes;
+	unsigned int sdeslength, sdestype;
 	unsigned int rtcpdata[8192 + AST_FRIENDLY_OFFSET];
 	unsigned int *rtcpheader;
 	int pt;
@@ -946,7 +949,11 @@
 		ast_log(LOG_DEBUG, "Got RTCP report of %d bytes - %d messages\n", res, packetwords);
 	}
 
-	/* Process a compound packet */
+	/* Process a compound packet 
+	   - A compound packet should start with a sender or receiver report. BYE can start as well
+		(seen in implementations) 
+	   -  Packet length should be a multiple of four bytes
+	*/
 	position = 0;
 	while (position < packetwords) {
 		i = position;
@@ -967,6 +974,7 @@
 		if (rtcp_debug_test_addr(&sin)) {
 		  	ast_verbose("\n-- Got RTCP from %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
 		  	ast_verbose("   PT: %d(%s)", pt, (pt == 200) ? "Sender Report" : (pt == 201) ? "Receiver Report" : (pt == 192) ? "H.261 FUR" : "Other");
+		  	ast_verbose("   Length : %d\n", length);
 		  	ast_verbose("   Reception reports: %d\n", rc);
 		  	ast_verbose("   SSRC of packet sender: %u", rtcpheader[i + 1]);
 		  	ast_verbose("   (Position %d of %d)\n", i, packetwords);
@@ -1057,11 +1065,58 @@
 			f = &rtp->f;
 			break;
 		case RTCP_PT_SDES:
-			sdesheader = ntohl(rtcpheader[i]);
-			sdeslength = (sdesheader & 0xff0000) >> 16;
-			sdestype = (sdesheader & 0x800000) >> 16;
-			if (rtcp_debug_test_addr(&sin)) {
-				ast_verbose("Received an SDES from %s:%d (Type %u, Length %u)\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port), sdestype, sdeslength);
+			/* SDES messages are divided into chunks, each one containing one or
+			   several items. Each chunk is for a different CSRC, so it's not really
+			   relevant in most cases of voip calls - unless you have an advanced
+			   mixer in the network that separates the different streams with CSRC 
+
+			   A chunk starts with SSRC/CSRC (four bytes), then SDES items 
+			   In the SDES message, there can be several items, ending with SDES_END
+			   The length of the all items is length - header 
+			   Chunk starts on a 32-bit boundary and needs padding by 0's
+
+		
+			   the "rc" variable contains the number of chunks 
+			   When we start, we're beyond the SSRC and starts with SDES items in the
+			   first chunk.
+			
+				an SDES item is one byte of type, one byte of length then data 
+				(no null termination). Text is UTF-8.
+				the last item is a zero (END) type with no length indication.
+			*/
+			
+			j = i * 4;
+			sdes = (char *) &rtcpheader[i];
+			ast_verbose("Received an SDES from %s:%d - Total length %d (%d bytes)\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port), length-i, ((length-i)*4) - 6);
+			while (j < length * 4) {
+				sdestype = (int) *sdes;
+				sdes++;
+				sdeslength = (int) *sdes;
+				sdes++;
+				if (rtcp_debug_test_addr(&sin)) {
+					ast_verbose(" --- SDES Type %u, Length %u Curj %d)\n", sdestype, sdeslength, j);
+				}
+				switch (sdestype) {
+				case SDES_CNAME:
+					strncpy(rtp->rtcp->theircname, sdes, sdeslength);
+					rtp->rtcp->theircname[sdeslength] = '\0';
+					if (rtcp_debug_test_addr(&sin)) {
+						ast_verbose(" --- SDES CNAME (utf8) %s\n", rtp->rtcp->theircname);
+					}
+					break;
+				case SDES_EMAIL:
+					break;
+				case SDES_PHONE:
+					break;
+				case SDES_LOC:
+					break;
+				case SDES_NOTE:
+					break;
+				case SDES_PRIV:
+					break;
+				}
+				j += sdeslength;	/* Header (1 byte) + length */
+				sdes += sdeslength;
 			}
 
 //	/*! \brief RFC 3550 RTCP SDES Item types */
@@ -2118,6 +2173,16 @@
 	return ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, ia);
 }
 
+/*! \brief set RTP cname used to describe session in RTCP sdes messages */
+void ast_rtcp_setcname(struct ast_rtp *rtp, const char *cname, size_t length)
+{
+	if (!rtp || !rtp->rtcp) {
+		return;
+	}
+	ast_copy_string(rtp->rtcp->ourcname, cname, length > 255 ? 255 : length);
+	ast_log(LOG_DEBUG, "--- Copied CNAME %s to RTCP structure (length %d)\n", cname, (int) length);
+}
+
 int ast_rtp_settos(struct ast_rtp *rtp, int tos)
 {
 	int res;
@@ -2507,12 +2572,49 @@
 	return res;
 }
 
+static int add_sdes_bodypart(struct ast_rtp *rtp, unsigned int *rtcp_packet, int len)
+{
+	unsigned int *start = rtcp_packet;
+	char *sdes;
+	int cnamelen;
+
+	rtcp_packet++;	/* Move 32 bits ahead */
+	*rtcp_packet = htonl(rtp->ssrc);               /* Our SSRC */
+	rtcp_packet ++;
+
+	len += 8;	/* Header + SSRC */
+
+	ast_log(LOG_DEBUG, "----About to copy CNAME to SDES packet --- (len %d)\n", len);
+
+	sdes = (char *) rtcp_packet;
+	cnamelen = (int) strlen(rtp->rtcp->ourcname);
+
+	*sdes = SDES_CNAME;
+	sdes++;
+	*sdes = (char) cnamelen;
+	sdes++;
+	strncpy(sdes, rtp->rtcp->ourcname, cnamelen);	/* NO terminating 0 */
+	sdes+=cnamelen;
+	*sdes = SDES_END;	/* Terminating SDES packet */
+
+	/* THere must be a multiple of four bytes in the packet */
+	len += 2 + cnamelen + ((cnamelen +2) % 4 == 0 ? 0 : 4 - ((cnamelen + 2) % 4)) ;
+	ast_log(LOG_DEBUG, "----our CNAME %s--- (cnamelen %d len %d)\n", rtp->rtcp->ourcname, cnamelen, len);
+
+	/* 2 is version, 1 is number of chunks, then RTCP packet type (SDES) and length */
+	*start = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | ((len/4)-1));
+
+	ast_log(LOG_DEBUG, "----Copied our CNAME to SDES packet --- (len %d)\n", len);
+
+	return len;
+}
+
 /*! \brief Send RTCP sender's report */
 static int ast_rtcp_write_sr(const void *data)
 {
 	struct ast_rtp *rtp = (struct ast_rtp *)data;
 	int res;
-	int len = 0;
+	int len = 0;	/* Measured in chunks of four bytes */
 	struct timeval now;
 	unsigned int now_lsw;
 	unsigned int now_msw;
@@ -2538,7 +2640,7 @@
 	}
 
 	gettimeofday(&now, NULL);
-	timeval2ntp(now, &now_msw, &now_lsw); /* fill thses ones in from utils.c*/
+	timeval2ntp(now, &now_msw, &now_lsw); /* fill theses ones in from utils.c*/
 	rtcpheader = (unsigned int *)bdata;
 	rtcpheader[1] = htonl(rtp->ssrc);               /* Our SSRC */
 	rtcpheader[2] = htonl(now_msw);                 /* now, MSW. gettimeofday() + SEC_BETWEEN_1900_AND_1970*/
@@ -2579,13 +2681,10 @@
 		len += 8;
 		rtp->rtcp->sendfur = 0;
 	}
-	
-	/* Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos */ 
-	/* it can change mid call, and SDES can't) */
-	rtcpheader[len/4]     = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | 2);
-	rtcpheader[(len/4)+1] = htonl(rtp->ssrc);               /* Our SSRC */
-	rtcpheader[(len/4)+2] = htonl(0x01 << 24);                    /* Empty for the moment */
-	len += 12;
+
+	len = add_sdes_bodypart(rtp, &rtcpheader[len/4], len);
+	
+	
 	
 	res = sendto(rtp->rtcp->s, (unsigned int *)rtcpheader, len, 0, (struct sockaddr *)&rtp->rtcp->them, sizeof(rtp->rtcp->them));
 	if (res < 0) {
@@ -2608,11 +2707,11 @@
 		ast_verbose("  Sent packets: %u\n", rtp->txcount);
 		ast_verbose("  Sent octets: %u\n", rtp->txoctetcount);
 		ast_verbose("  Report block:\n");
-		ast_verbose("  Fraction lost: %u\n", fraction);
-		ast_verbose("  Cumulative loss: %u\n", lost);
-		ast_verbose("  IA jitter: %.4f\n", rtp->rxjitter);
-		ast_verbose("  Their last SR: %u\n", rtp->rtcp->themrxlsr);
-		ast_verbose("  DLSR: %4.4f (sec)\n\n", (double)(ntohl(rtcpheader[12])/65536.0));
+		ast_verbose("    Fraction lost (since last report): %u\n", fraction);
+		ast_verbose("    Cumulative loss: %u\n", lost);
+		ast_verbose("    IA jitter: %.4f\n", rtp->rxjitter);
+		ast_verbose("    Their last SR: %u\n", rtp->rtcp->themrxlsr);
+		ast_verbose("    Delay since last SR (DLSR): %4.4f (sec)\n\n", (double)(ntohl(rtcpheader[12])/65536.0));
 	}
 	return res;
 }




More information about the asterisk-commits mailing list