[svn-commits] branch kpfleming/vldtmf r8959 - /team/kpfleming/vldtmf/rtp.c

svn-commits at lists.digium.com svn-commits at lists.digium.com
Tue Jan 31 14:21:08 MST 2006


Author: kpfleming
Date: Mon Jan 30 21:31:48 2006
New Revision: 8959

URL: http://svn.digium.com/view/asterisk?rev=8959&view=rev
Log:
use structures for RTP headers/events

Modified:
    team/kpfleming/vldtmf/rtp.c

Modified: team/kpfleming/vldtmf/rtp.c
URL: http://svn.digium.com/view/asterisk/team/kpfleming/vldtmf/rtp.c?rev=8959&r1=8958&r2=8959&view=diff
==============================================================================
--- team/kpfleming/vldtmf/rtp.c (original)
+++ team/kpfleming/vldtmf/rtp.c Mon Jan 30 21:31:48 2006
@@ -114,7 +114,6 @@
 	struct ast_smoother *smoother;
 	int *ioid;
 	unsigned short seqno;		/*!< Sequence number, RFC 3550, page 13. */
-	unsigned short rxseqno;
 	struct sched_context *sched;
 	struct io_context *io;
 	void *data;
@@ -145,6 +144,62 @@
 /*! \brief List of current sessions */
 static AST_LIST_HEAD_STATIC(protos, ast_rtp_protocol);
 
+struct rtp_header {
+	/* Always keep in network byte order */
+#if __BYTE_ORDER == __BIG_ENDIAN
+	uint32_t version:2;
+	uint32_t padding:1;
+	uint32_t extension:1;
+	uint32_t csrc_count:4;
+	uint32_t marker:1;
+	uint32_t payload:7;
+	uint32_t sequence:16;
+	uint32_t timestamp;
+	uint32_t ssrc;
+#else
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	uint32_t sequence:16;
+	uint32_t payload:7;
+	uint32_t marker:1;
+	uint32_t csrc_count:4;
+	uint32_t extension:1;
+	uint32_t padding:1;
+	uint32_t version:2;
+	uint32_t timestamp;
+	uint32_t ssrc;
+#else
+#error Byte order not defined
+#endif
+#endif
+};
+
+struct rfc2833_event {
+	struct rtp_header header;
+	/* Always keep in network byte order */
+#if __BYTE_ORDER == __BIG_ENDIAN
+	uint32_t event:8;
+	uint32_t end:1;
+	uint32_t reserved:1;
+	uint32_t volume:6;
+	uint32_t duration:16;
+#else
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	uint32_t duration:16;
+	uint32_t volume:6;
+	uint32_t reserved:1;
+	uint32_t end:1;
+	uint32_t event:8;
+#else
+#error Byte order not defined
+#endif
+#endif
+};
+
+struct rfc3389_event {
+	struct rtp_header header;
+	char level;
+};
+
 int ast_rtp_fd(struct ast_rtp *rtp)
 {
 	return rtp->s;
@@ -221,6 +276,7 @@
 	unsigned int event;
 	char resp = 0;
 	struct ast_frame *f = NULL;
+
 	event = ntohl(*((unsigned int *)(data)));
 	event &= 0x001F;
 	if (option_debug > 2 || rtpdebug)
@@ -314,9 +370,11 @@
 static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *data, int len)
 {
 	struct ast_frame *f = NULL;
+
 	/* Convert comfort noise into audio with various codecs.  Unfortunately this doesn't
 	   totally help us out becuase we don't have an engine to keep it going and we are not
 	   guaranteed to have it every 20ms or anything */
+
 	if (rtpdebug)
 		ast_log(LOG_DEBUG, "- RTP 3389 Comfort noise event: Level %d (len = %d)\n", rtp->lastrxformat, len);
 
@@ -331,6 +389,7 @@
 	/* Must have at least one byte */
 	if (!len)
 		return NULL;
+
 	if (len < 24) {
 		rtp->f.data = rtp->rawdata + AST_FRIENDLY_OFFSET;
 		rtp->f.datalen = len - 1;
@@ -341,12 +400,14 @@
 		rtp->f.offset = 0;
 		rtp->f.datalen = 0;
 	}
+
 	rtp->f.frametype = AST_FRAME_CNG;
 	rtp->f.subclass = data[0] & 0x7f;
 	rtp->f.datalen = len - 1;
 	rtp->f.samples = 0;
 	rtp->f.delivery.tv_usec = rtp->f.delivery.tv_sec = 0;
 	f = &rtp->f;
+
 	return f;
 }
 
@@ -354,11 +415,10 @@
 {
 	struct ast_rtp *rtp = cbdata;
 	struct ast_frame *f;
-	f = ast_rtp_read(rtp);
-	if (f) {
-		if (rtp->callback)
-			rtp->callback(rtp, f, rtp->data);
-	}
+
+	if ((f = ast_rtp_read(rtp)) && rtp->callback)
+		rtp->callback(rtp, f, rtp->data);
+
 	return 1;
 }
 
@@ -420,31 +480,23 @@
 
 struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
 {
+	unsigned char *buffer = rtp->rawdata + AST_FRIENDLY_OFFSET;
 	int res;
 	struct sockaddr_in sin;
 	socklen_t len;
 	unsigned int seqno;
-	int version;
-	int payloadtype;
-	int hdrlen = 12;
-	int padding;
-	int mark;
-	int ext;
-	int x;
+	unsigned int timestamp;
 	char iabuf[INET_ADDRSTRLEN];
-	unsigned int timestamp;
-	unsigned int *rtpheader;
+	struct rtp_header *header;
 	static struct ast_frame *f, null_frame = { AST_FRAME_NULL, };
 	struct rtpPayloadType rtpPT;
 	
 	len = sizeof(sin);
 	
-	/* Cache where the header will go */
-	res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
-					0, (struct sockaddr *)&sin, &len);
-
-
-	rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
+	res = recvfrom(rtp->s, buffer, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
+		       0, (struct sockaddr *) &sin, &len);
+
+
 	if (res < 0) {
 		if (errno != EAGAIN)
 			ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
@@ -452,7 +504,7 @@
 			CRASH;
 		return &null_frame;
 	}
-	if (res < hdrlen) {
+	if (res < sizeof(*header)) {
 		ast_log(LOG_WARNING, "RTP Read too short\n");
 		return &null_frame;
 	}
@@ -467,100 +519,92 @@
 		if ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
 		    (rtp->them.sin_port != sin.sin_port)) {
 			memcpy(&rtp->them, &sin, sizeof(rtp->them));
-			rtp->rxseqno = 0;
 			ast_set_flag(rtp, FLAG_NAT_ACTIVE);
 			if (option_debug || rtpdebug)
-				ast_log(LOG_DEBUG, "RTP NAT: Got audio from other end. Now sending to address %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port));
-		}
-	}
-
-	/* Get fields */
-	seqno = ntohl(rtpheader[0]);
+				ast_log(LOG_DEBUG, "RTP NAT: Got audio from other end. Now sending to address %s:%d\n",
+					ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr),
+					ntohs(rtp->them.sin_port));
+		}
+	}
+
+	header = (struct rtp_header *) buffer;
+	buffer += sizeof(*header);
+	res -= sizeof(*header);
 
 	/* Check RTP version */
-	version = (seqno & 0xC0000000) >> 30;
-	if (version != 2)
+	if (header->version != 2)
 		return &null_frame;
 	
-	payloadtype = (seqno & 0x7f0000) >> 16;
-	padding = seqno & (1 << 29);
-	mark = seqno & (1 << 23);
-	ext = seqno & (1 << 28);
-	seqno &= 0xffff;
-	timestamp = ntohl(rtpheader[1]);
+	/* Get fields */
+	seqno = ntohs(header->sequence);
+	timestamp = ntohl(header->timestamp);
+
+	/* Remove padding bytes, if any*/
+	if (header->padding)
+		res -= *(buffer + res - 1);
 	
-	if (padding) {
-		/* Remove padding bytes */
-		res -= rtp->rawdata[AST_FRIENDLY_OFFSET + res - 1];
-	}
-	
-	if (ext) {
-		/* RTP Extension present */
-		hdrlen += 4;
-		hdrlen += (ntohl(rtpheader[3]) & 0xffff) << 2;
-	}
-
-	if (res < hdrlen) {
-		ast_log(LOG_WARNING, "RTP Read too short (%d, expecting %d)\n", res, hdrlen);
-		return &null_frame;
-	}
-
-	if(rtp_debug_test_addr(&sin))
-		ast_verbose("Got RTP packet from %s:%d (type %d, seq %d, ts %d, len %d)\n"
-			, ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen);
-
-   	rtpPT = ast_rtp_lookup_pt(rtp, payloadtype);
+	/* Is an RTP Extension present? */
+	if (header->extension) {
+		int ext_len = 4;
+
+		ext_len += (ntohl(*((unsigned int *) buffer)) & 0xffff) << 2;
+
+		buffer += ext_len;
+		res -= ext_len;
+
+		if (res < 1) {
+			ast_log(LOG_WARNING, "RTP Read too short\n");
+			return &null_frame;
+		}
+	}
+
+	if (rtp_debug_test_addr(&sin))
+		ast_verbose("Got RTP packet from %s:%d (type %d, seq %d, ts %d, len %d)\n",
+			    ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr),
+			    ntohs(sin.sin_port), header->payload, seqno,
+			    timestamp, res);
+
+   	rtpPT = ast_rtp_lookup_pt(rtp, header->payload);
 	if (!rtpPT.isAstFormat) {
-		/* This is special in-band data that's not one of our codecs */
-		if (rtpPT.code == AST_RTP_DTMF) {
+		f = &null_frame;
+		switch (rtpPT.code) {
+		case AST_RTP_DTMF:
+			/* This is special in-band data that's not one of our codecs */
 			/* It's special -- rfc2833 process it */
-			if(rtp_debug_test_addr(&sin)) {
-				unsigned char *data;
-				unsigned int event;
-				unsigned int event_end;
-				unsigned int duration;
-				data = rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen;
-				event = ntohl(*((unsigned int *)(data)));
-				event >>= 24;
-				event_end = ntohl(*((unsigned int *)(data)));
-				event_end <<= 8;
-				event_end >>= 24;
-				duration = ntohl(*((unsigned int *)(data)));
-				duration &= 0xFFFF;
-				ast_verbose("Got rfc2833 RTP packet from %s:%d (type %d, seq %d, ts %d, len %d, mark %d, event %08x, end %d, duration %d) \n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp, res - hdrlen, (mark?1:0), event, ((event_end & 0x80)?1:0), duration);
+			if (rtp_debug_test_addr(&sin)) {
+				struct rfc2833_event *event = (struct rfc2833_event *) buffer;
+
+				ast_verbose("Got rfc2833 RTP packet from %s:%d (type %d, seq %d, ts %d, len %d, mark %d, event %08x, end %d, duration %d) \n",
+					    ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr),
+					    ntohs(sin.sin_port), header->payload, seqno,
+					    timestamp, res, header->marker,
+					    event->event, event->end, event->duration);
 			}
-			if (rtp->lasteventseqn <= seqno || rtp->resp == 0 || (rtp->lasteventseqn >= 65530 && seqno <= 6)) {
-				f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno);
+			if (rtp->lasteventseqn <= seqno || rtp->resp == 0 ||
+			    (rtp->lasteventseqn >= 65530 && seqno <= 6)) {
+				f = process_rfc2833(rtp, buffer, res, seqno);
 				rtp->lasteventseqn = seqno;
-			} else
-				f = NULL;
-			if (f)
-				return f;
-			else
-				return &null_frame;
-		} else if (rtpPT.code == AST_RTP_CISCO_DTMF) {
+			}
+			break;
+		case AST_RTP_CISCO_DTMF:
 			/* It's really special -- process it the Cisco way */
-			if (rtp->lasteventseqn <= seqno || rtp->resp == 0 || (rtp->lasteventseqn >= 65530 && seqno <= 6)) {
-				f = process_cisco_dtmf(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
+			if (rtp->lasteventseqn <= seqno || rtp->resp == 0 ||
+			    (rtp->lasteventseqn >= 65530 && seqno <= 6)) {
+				f = process_cisco_dtmf(rtp, buffer, res);
 				rtp->lasteventseqn = seqno;
-			} else 
-				f = NULL;
-				if (f) 
-				return f; 
-			else 
-				return &null_frame;
-		} else if (rtpPT.code == AST_RTP_CN) {
+			}
+			break;
+		case AST_RTP_CN:
 			/* Comfort Noise */
-			f = process_rfc3389(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
-			if (f) 
-				return f; 
-			else 
-				return &null_frame;
-		} else {
-			ast_log(LOG_NOTICE, "Unknown RTP codec %d received\n", payloadtype);
-			return &null_frame;
-		}
-	}
+			f = process_rfc3389(rtp, buffer, res);
+			break;
+		default:
+			ast_log(LOG_NOTICE, "Unknown RTP payload %d received\n", header->payload);
+			break;
+		}
+		return f ? f : &null_frame;
+	}
+
 	rtp->f.subclass = rtpPT.code;
 	if (rtp->f.subclass < AST_FORMAT_MAX_AUDIO)
 		rtp->f.frametype = AST_FRAME_VOICE;
@@ -571,31 +615,12 @@
 	if (!rtp->lastrxts)
 		rtp->lastrxts = timestamp;
 
-	if (rtp->rxseqno) {
-		for (x=rtp->rxseqno + 1; x < seqno; x++) {
-			/* Queue empty frames */
-			rtp->f.mallocd = 0;
-			rtp->f.datalen = 0;
-			rtp->f.data = NULL;
-			rtp->f.offset = 0;
-			rtp->f.samples = 0;
-			rtp->f.src = "RTPMissedFrame";
-		}
-	}
-	rtp->rxseqno = seqno;
-
 	if (rtp->dtmfcount) {
-#if 0
-		printf("dtmfcount was %d\n", rtp->dtmfcount);
-#endif		
 		rtp->dtmfcount -= (timestamp - rtp->lastrxts);
 		if (rtp->dtmfcount < 0)
 			rtp->dtmfcount = 0;
-#if 0
-		if (dtmftimeout != rtp->dtmfcount)
-			printf("dtmfcount is %d\n", rtp->dtmfcount);
-#endif
-	}
+	}
+
 	rtp->lastrxts = timestamp;
 
 	/* Send any pending DTMF */
@@ -604,15 +629,17 @@
 			ast_log(LOG_DEBUG, "Sending pending DTMF\n");
 		return send_dtmf(rtp);
 	}
+
 	rtp->f.mallocd = 0;
-	rtp->f.datalen = res - hdrlen;
-	rtp->f.data = rtp->rawdata + hdrlen + AST_FRIENDLY_OFFSET;
-	rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET;
+	rtp->f.datalen = res;
+	rtp->f.data = buffer;
+	rtp->f.offset = buffer - rtp->rawdata;
+
 	if (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) {
 		rtp->f.samples = ast_codec_get_samples(&rtp->f);
 		if (rtp->f.subclass == AST_FORMAT_SLINEAR) 
 			ast_frame_byteswap_be(&rtp->f);
-		calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark);
+		calc_rxstamp(&rtp->f.delivery, rtp, timestamp, header->marker);
 	} else {
 		/* Video -- samples is # of samples vs. 90000 */
 		if (!rtp->lastividtimestamp)
@@ -621,11 +648,12 @@
 		rtp->lastividtimestamp = timestamp;
 		rtp->f.delivery.tv_sec = 0;
 		rtp->f.delivery.tv_usec = 0;
-		if (mark)
+		if (header->marker)
 			rtp->f.subclass |= 0x1;
 		
 	}
 	rtp->f.src = "RTP";
+
 	return &rtp->f;
 }
 
@@ -1110,7 +1138,6 @@
 		rtp->rtcp->them.sin_port = htons(ntohs(them->sin_port) + 1);
 		rtp->rtcp->them.sin_addr = them->sin_addr;
 	}
-	rtp->rxseqno = 0;
 }
 
 void ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
@@ -1152,7 +1179,6 @@
 	rtp->dtmfcount = 0;
 	rtp->dtmfduration = 0;
 	rtp->seqno = 0;
-	rtp->rxseqno = 0;
 }
 
 void ast_rtp_destroy(struct ast_rtp *rtp)
@@ -1188,30 +1214,6 @@
 	rtp->txcore = t;
 	return (unsigned int) ms;
 }
-
-struct rtp_header {
-	/* Always keep in network byte order */
-#if __BYTE_ORDER == __BIG_ENDIAN
-	/* first byte */
-        u_int32_t version:2;
-        u_int32_t flow:6;
-	/* second byte */
-	u_int32_t option:1;
-	u_int32_t sync:1;
-	u_int32_t format:6;
-	/* third and fourth bytes */
-	u_int32_t sequence:16;
-	/* fifth through eighth bytes */
-	u_int32_t timestamp;
-	/* ninth through twelfth bytes */
-	u_int32_t ssrc;
-#else
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#else
-#error Byte order not defined
-#endif
-#endif
-};
 
 static char prep_digit(char digit)
 {
@@ -1231,6 +1233,15 @@
 	}
 }
 
+void static prep_header(struct rtp_header *header, struct ast_rtp *rtp, int payload)
+{
+	header->payload = ast_rtp_lookup_code(rtp, 0, payload);
+	header->sequence = htons(rtp->seqno);
+	header->version = 2;
+	header->timestamp = htonl(rtp->lastdigitts);
+	header->ssrc = htonl(rtp->ssrc);
+}
+
 int ast_rtp_send_digit_begin(struct ast_rtp *rtp, char digit)
 {
 	/* If we have no peer, return immediately */	
@@ -1250,12 +1261,9 @@
 
 int ast_rtp_senddigit(struct ast_rtp *rtp, char digit)
 {
-	unsigned int *rtpheader;
-	int hdrlen = 12;
+	struct rfc2833_event event;
 	int res;
 	int x;
-	int payload;
-	char data[256];
 	char iabuf[INET_ADDRSTRLEN];
 
 	/* If we have no peer, return immediately */	
@@ -1265,45 +1273,40 @@
 	if ((digit = prep_digit(digit)) == -1)
 		return -1;
 
-	payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_DTMF);
+	memset(&event, 0, sizeof(event));
+
+	prep_header(&event.header, rtp, AST_RTP_DTMF);
+	event.header.marker = 1;
 
 	rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
 	
-	/* Get a pointer to the header */
-	rtpheader = (unsigned int *)data;
-	rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno));
-	rtpheader[1] = htonl(rtp->lastdigitts);
-	rtpheader[2] = htonl(rtp->ssrc); 
-	rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
+	event.event = digit;
+	event.volume = 0xa;
+
 	for (x = 0; x < 6; x++) {
 		if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
-			res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them));
+			res = sendto(rtp->s, &event, sizeof(event), 0,
+				     (struct sockaddr *) &rtp->them, sizeof(rtp->them));
 			if (res < 0) 
 				ast_log(LOG_ERROR, "RTP Transmission error to %s:%d: %s\n",
 					ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr),
 					ntohs(rtp->them.sin_port), strerror(errno));
 			if (rtp_debug_test_addr(&rtp->them))
-				ast_verbose("Sent RTP packet to %s:%d (type %d, seq %u, ts %u, len %u)\n",
+				ast_verbose("Sent RTP packet to %s:%d (type %d, seq %u, ts %u, len %lu)\n",
 					    ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr),
-					    ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
+					    ntohs(rtp->them.sin_port), event.header.payload,
+					    rtp->seqno, rtp->lastdigitts, sizeof(event));
 		}
 		/* Sequence number of last two end packets does not get incremented */
 		if (x < 3)
 			rtp->seqno++;
 		/* Clear marker bit and set seqno */
-		rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno));
+		event.header.marker = 0;
+		event.header.sequence = htons(rtp->seqno);
 		/* For the last three packets, set the duration and the end bit */
 		if (x == 2) {
-#if 0
-			/* No, this is wrong...  Do not increment lastdigitts, that's not according
-			   to the RFC, as best we can determine */
-			rtp->lastdigitts++; /* or else the SPA3000 will click instead of beeping... */
-			rtpheader[1] = htonl(rtp->lastdigitts);
-#endif			
-			/* Make duration 800 (100ms) */
-			rtpheader[3] |= htonl((800));
-			/* Set the End bit */
-			rtpheader[3] |= htonl((1 << 23));
+			event.duration = htons(800);
+			event.end = 1;
 		}
 	}
 	/* Increment the digit timestamp by 120ms, to ensure that digits
@@ -1322,44 +1325,47 @@
 
 int ast_rtp_sendcng(struct ast_rtp *rtp, int level)
 {
-	unsigned int *rtpheader;
-	int hdrlen = 12;
+	struct rfc3389_event event;
 	int res;
-	int payload;
-	char data[256];
 	char iabuf[INET_ADDRSTRLEN];
-	level = 127 - (level & 0x7f);
-	payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_CN);
 
 	/* If we have no peer, return immediately */	
 	if (!rtp->them.sin_addr.s_addr)
 		return 0;
 
+	level = 127 - (level & 0x7f);
+
+	memset(&event, 0, sizeof(event));
+
+	prep_header(&event.header, rtp, AST_RTP_CN);
+
 	rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
 
-	/* Get a pointer to the header */
-	rtpheader = (unsigned int *)data;
-	rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno++));
-	rtpheader[1] = htonl(rtp->lastts);
-	rtpheader[2] = htonl(rtp->ssrc); 
-	data[12] = level;
+	event.level = level;
+
 	if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
-		res = sendto(rtp->s, (void *)rtpheader, hdrlen + 1, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
+		res = sendto(rtp->s, &event, sizeof(event), 0,
+			     (struct sockaddr *) &rtp->them, sizeof(rtp->them));
 		if (res <0) 
-			ast_log(LOG_ERROR, "RTP Comfort Noise Transmission error to %s:%d: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno));
-		if(rtp_debug_test_addr(&rtp->them))
-			ast_verbose("Sent Comfort Noise RTP packet to %s:%d (type %d, seq %d, ts %d, len %d)\n"
-					, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastts,res - hdrlen);		   
-		   
-	}
+			ast_log(LOG_ERROR, "RTP Comfort Noise Transmission error to %s:%d: %s\n",
+				ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr),
+				ntohs(rtp->them.sin_port), strerror(errno));
+		if (rtp_debug_test_addr(&rtp->them))
+			ast_verbose("Sent Comfort Noise RTP packet to %s:%d (type %d, seq %d, ts %d, len %lu)\n",
+				    ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr),
+				    ntohs(rtp->them.sin_port), event.header.payload,
+				    rtp->seqno, rtp->lastts, sizeof(event));
+	}
+
+	rtp->seqno++;
+
 	return 0;
 }
 
 static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec)
 {
-	unsigned char *rtpheader;
+	struct rtp_header *header;
 	char iabuf[INET_ADDRSTRLEN];
-	int hdrlen = 12;
 	int res;
 	unsigned int ms;
 	int pred;
@@ -1406,29 +1412,32 @@
 	if (rtp->lastts > rtp->lastdigitts)
 		rtp->lastdigitts = rtp->lastts;
 
-	/* Get a pointer to the header */
-	rtpheader = (unsigned char *)(f->data - hdrlen);
-
-	put_unaligned_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (rtp->seqno) | (mark << 23)));
-	put_unaligned_uint32(rtpheader + 4, htonl(rtp->lastts));
-	put_unaligned_uint32(rtpheader + 8, htonl(rtp->ssrc)); 
+	header = (struct rtp_header *)(f->data - sizeof(*header));
+	prep_header(header, rtp, codec);
+	header->marker = mark;
 
 	if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
-		res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
+		res = sendto(rtp->s, header, f->datalen + sizeof(*header), 0,
+			     (struct sockaddr *)&rtp->them, sizeof(rtp->them));
 		if (res <0) {
 			if (!rtp->nat || (rtp->nat && (ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_ACTIVE))) {
-				ast_log(LOG_DEBUG, "RTP Transmission error of packet %d to %s:%d: %s\n", rtp->seqno, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno));
+				ast_log(LOG_DEBUG, "RTP Transmission error of packet %d to %s:%d: %s\n",
+					rtp->seqno, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr),
+					ntohs(rtp->them.sin_port), strerror(errno));
 			} else if ((ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_INACTIVE) || rtpdebug) {
 				/* Only give this error message once if we are not RTP debugging */
 				if (option_debug || rtpdebug)
-					ast_log(LOG_DEBUG, "RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio...\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port));
+					ast_log(LOG_DEBUG, "RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio...\n",
+						ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr),
+						ntohs(rtp->them.sin_port));
 				ast_set_flag(rtp, FLAG_NAT_INACTIVE_NOWARN);
 			}
 		}
 				
-		if(rtp_debug_test_addr(&rtp->them))
-			ast_verbose("Sent RTP packet to %s:%d (type %d, seq %u, ts %u, len %u)\n"
-					, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), codec, rtp->seqno, rtp->lastts,res - hdrlen);
+		if (rtp_debug_test_addr(&rtp->them))
+			ast_verbose("Sent RTP packet to %s:%d (type %d, seq %u, ts %u, len %u)\n",
+				    ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr),
+				    ntohs(rtp->them.sin_port), codec, rtp->seqno, rtp->lastts, res);
 	}
 
 	rtp->seqno++;



More information about the svn-commits mailing list