[Sumover-dev] [svn commit] r4468 - in vic/branches/cc: rtp

sumover-dev at cs.ucl.ac.uk sumover-dev at cs.ucl.ac.uk
Mon Jun 22 23:48:11 BST 2009


Author: piers
Date: Mon Jun 22 23:48:09 2009
New Revision: 4468

Modified:
   vic/branches/cc/net/net-ip.cpp
   vic/branches/cc/rtp/rtp.h
   vic/branches/cc/rtp/session.cpp
   vic/branches/cc/rtp/session.h
   vic/branches/cc/rtp/transmitter.cpp

Log:
More fixes for TFWC code. Created a new generic function for sending RTCP-XR reports. Added code for ECN monitoring of incoming packets (only works on Linux)


Modified: vic/branches/cc/net/net-ip.cpp
==============================================================================
--- vic/branches/cc/net/net-ip.cpp	(original)
+++ vic/branches/cc/net/net-ip.cpp	Mon Jun 22 23:48:09 2009
@@ -111,6 +111,7 @@
     		}
     		return (result);
   	}
+	uint8_t recv_tos() { return recv_tos_;}
     protected:
 	struct sockaddr_in sin;
 	virtual int dorecv(u_char* buf, int len, Address &from, int fd);
@@ -121,6 +122,7 @@
 	int openrsock(Address & g_addr, Address & s_addr_ssm, u_short port, Address & local);
 	void dosend(u_char* buf, int len, int fd);
 	time_t last_reset_;
+	uint8_t recv_tos_;
 };
 
 static class IPNetworkMatcher : public Matcher {
@@ -350,6 +352,18 @@
 		exit(1);
 	}
 #endif
+	
+	/*
+      * Enable the TOS value from received packets to be
+      * returned along with the payload.
+      */
+#ifdef IP_RECVTOS
+     int optval = 1;
+     if (setsockopt(fd, IPPROTO_IP, IP_RECVTOS, &optval, sizeof(optval)) == -1)
+             debug_msg("ERROR setsockopt IP_RECVTOS\n");
+#endif
+
+
 	memset((char *)&sin, 0, sizeof(sin));
 	sin.sin_family = AF_INET;
 	sin.sin_port = port;
@@ -502,6 +516,9 @@
         }
 	}
 
+    int c=1;
+    printf("set TOS:%d\n",setsockopt(fd, IPPROTO_IP, IP_TOS, (char*)&c,         sizeof(c)));
+
 	memset((char *)&sin, 0, sizeof(sin));
 	sin.sin_family = AF_INET;
 	sin.sin_port = port;
@@ -585,8 +602,52 @@
 #else
 	int fromlen = sizeof(sfrom);
 #endif
-	int cc = ::recvfrom(fd, (char*)buf, len, 0,
-			    (sockaddr*)&sfrom, &fromlen);
+    int c=255;
+	int cc;
+
+     struct iovec iov[2];
+     unsigned char cbuf[128];
+     struct cmsghdr *cm;
+     struct msghdr m;
+     int found;
+     u_char data[2048];
+
+     (void)memset(&m, 0, sizeof(m));
+     (void)memset(&iov, 0, sizeof(iov));
+
+     iov[0].iov_base = buf;         /* buffer for packet payload */
+     iov[0].iov_len = len;  /* expected packet length */
+
+     m.msg_name = (sockaddr*)&sfrom;             /* sockaddr_in of peer */
+     m.msg_namelen = sizeof(sfrom);
+     m.msg_iov = iov;
+     m.msg_iovlen = 1;
+     m.msg_control = (caddr_t)cbuf;   /* buffer for control messages */
+     m.msg_controllen = sizeof(cbuf);
+
+     found = 0;
+	 if (cc = recvmsg(fd, &m, 0) == -1)
+			 debug_msg("recvmsg problem\n");
+	 for (cm = CMSG_FIRSTHDR(&m); cm != NULL;
+		  cm = CMSG_NXTHDR(&m, cm)) {
+			 if (cm->cmsg_level == IPPROTO_IP &&
+				 cm->cmsg_type == IP_TOS &&
+				 //cm->cmsg_len == CMSG_LEN(sizeof(struct in_addr))) {
+				 cm->cmsg_len ) {
+					 found = 1;
+					 (void)printf("recvopts limit: %d\n",
+						 *(uint8_t *)CMSG_DATA(cm));
+					 recv_tos_ = *(uint8_t *)CMSG_DATA(cm);
+					 break;
+			 } else 
+				debug_msg("recvmsg problem: no IP_TOS (type:%d,len:%d)\n", cm->cmsg_type, cm->cmsg_len);
+
+	 }
+	 if (cm == NULL && !found);
+			 //debug_msg("recvmsg problem: no cm\n");
+
+	//int cc = ::recvfrom(fd, (char*)buf, len, 0,
+	//		    (sockaddr*)&sfrom, &fromlen);
 	if (cc < 0) {
 		if (errno != EWOULDBLOCK)
 			perror("recvfrom");

Modified: vic/branches/cc/rtp/rtp.h
==============================================================================
--- vic/branches/cc/rtp/rtp.h	(original)
+++ vic/branches/cc/rtp/rtp.h	Mon Jun 22 23:48:09 2009
@@ -147,6 +147,8 @@
 #define XR_BT_2	0x02	// Duplicate RLE Report Block
 #define XR_BT_3	0x03	// Packet Receipt Times Report Block
 #define XR_BT_4	0x04	// Receiver Reference Time Report Block
+
+#define XR_BT_ECN	0x44	// ECN Report block - TEST
 struct rtcp_xr {
 	// extended report block header
 	u_int8_t BT;	  /* Block Type */

Modified: vic/branches/cc/rtp/session.cpp
==============================================================================
--- vic/branches/cc/rtp/session.cpp	(original)
+++ vic/branches/cc/rtp/session.cpp	Mon Jun 22 23:48:09 2009
@@ -649,7 +649,6 @@
 	// set RTCP flag to XR packet
 	flags |= RTCP_PT_XR;
 
-	debug_msg("about to send RTCP XR\n");
 
 	// declare XR packet
 	rtcp_xr_BT_1_hdr* xr = (rtcp_xr_BT_1_hdr*)(rh + 1);
@@ -670,7 +669,7 @@
 	if (am_i_sender()) {
 		// this block is used for giving seqno and ackofack
 		if(bt == XR_BT_1) {
-	debug_msg("about to send RTCP XR 1\n");
+			debug_msg("About to send RTCP XR: AofA\n");
 			// number of block entries
 			//num_ssrc = 1;
 			//num_begins = 1;
@@ -729,7 +728,8 @@
 
 			// number of AckVec array
 			num_chunks = tfwc_rcvr_numvec();
-			if (num_chunks<1) num_chunks=1;
+			// Added second check as it seems that sometimes num_chunks >> 1 ???
+			if (num_chunks<1 || num_chunks> 128 ) num_chunks=1;
 
 			// allocate report block in memory
 			//rb = (u_char *) malloc(sizeof(xr) + num_ssrc 
@@ -752,9 +752,11 @@
 			// clone AckVec from TfwcRcvr
 			u_int16_t *chunks = (u_int16_t *) (xr + 1);
 
+			debug_msg("About to send RTCP XR AckVec(%d chunks):",num_chunks);
 			for (int i = 0; i <= num_chunks; i++) {
 				chunks[i] = htons(tfwc_rcvr_getvec(i));
-			}
+				printf("%d:%x,",i,chunks[i]);
+			}printf("\n");
 		}
 		else if (bt == XR_BT_3) {
 			/*XXX*/
@@ -781,6 +783,78 @@
 	ch->send(pktbuf_, len);
 }
 
+// New version
+void SessionManager::send_Xreport(CtrlHandler* ch, uint8_t bt, uint8_t rsvd, uint8_t thin, uint16_t begin_seq, uint16_t end_seq, uint16_t *chunks, uint16_t num_chunks, uint32_t xrssrc)
+{
+	SourceManager& sm = SourceManager::instance();
+	Source& s = *sm.localsrc();
+	rtcphdr* rh = (rtcphdr*)pktbuf_;
+	rh->rh_ssrc = s.srcid();
+	int flags = RTP_VERSION << 14;	// RTCP flags
+	int layer = ch - ch_; //LLL
+	Source::Layer& sl = s.layer(layer);
+	timeval now = unixtime();
+	sl.lts_ctrl(now);
+
+	// set RTCP flag to XR packet
+	flags |= RTCP_PT_XR;
+
+	switch (bt) {
+	  case XR_BT_1:
+	  case XR_BT_3:
+	  case XR_BT_ECN:
+		break;
+	  default:
+	    debug_msg("ERROR: Unknown XR packet type: %d\n",bt);
+		return;
+	}
+
+	// set xr pointer to XR packet
+	rtcp_xr_BT_1_hdr* xr = (rtcp_xr_BT_1_hdr*)(rh + 1);
+
+	// set XR block type and flags (block type and length)
+	xr->BT = bt;
+	xr->xr_flags.rsvd = rsvd;
+	xr->xr_flags.T = thin;
+	xr->ssrc = htonl(xrssrc);
+
+	// get current RTP data packet seqno from TfwcSndr
+	xr->begin_seq = htons(begin_seq);
+	xr->end_seq = htons(end_seq);
+
+	debug_msg("About to send RTCP XR: %d, beg_seq: %d, end: %d\n",bt,ntohs(xr->begin_seq),ntohs(xr->end_seq));
+
+	if (num_chunks > 512) {
+	  debug_msg("ERROR num_chunks too large:%d\n",num_chunks);
+	  return;
+	}
+	
+	debug_msg("About to send RTCP XR AckVec(%d chunks):",num_chunks);
+	u_int16_t *xrchunks = (u_int16_t *) (xr + 1);
+	for (int i=0; i<num_chunks; i++) {
+		printf("%d:%x,",i,chunks[i]);
+	    xrchunks[i] = htons(chunks[i]);
+	}
+
+	// XR report block length in bytes
+	int xrlen = sizeof(rtcp_xr_BT_1_hdr) + num_chunks*2;
+	 
+	// Convert XR report block length to multiples of 32 bit-words minus 1
+	xr->xr_len = htons((xrlen >> 2) - 1);
+
+	// RTCP header flags (this is not the XR header flags)
+	rh->rh_flags = htons(flags);
+
+	// RTCP packet length
+	int len = (u_char *) ++xr + num_chunks*2 - pktbuf_;	
+	debug_msg("RTCP XR: len: %d, xrlen=%d\n", len, xrlen);
+	len = sizeof(rtcphdr) + sizeof(rtcp_xr_BT_1_hdr) + num_chunks*2;
+	rh->rh_len = htons((len >> 2) - 1);
+
+	// send XR report block
+	ch->send(pktbuf_, len);
+}
+
 /*XXX check for buffer overflow*/
 /*
 * Send an RTPv2 report packet.
@@ -1240,7 +1314,6 @@
 void SessionManager::parse_xr_records(u_int32_t ssrc, rtcp_xr* xr, int cnt,
 				const u_char* ep, Address & addr)
 {
-	printf("\tentering parse_xr_records()\n");
 	rtcp_xr_BT_1_hdr *xr1;
 	UNUSED(ssrc);
 	UNUSED(cnt);
@@ -1277,12 +1350,15 @@
 	  if (am_i_sender()) {
 		  // parse XR chunks
 		  printf("\tparse_xr - i_am_sender \n");
+		  printf("num_chunks:%d, beg:%d, end:%d\n",num_chunks, begin, end);
 		  tfwc_sndr_recv(xr->BT, begin, end, chunk, num_chunks);
 		  // we need to call Transmitter::output(pb) to make Ack driven
 		  cc_output();
 	  }
 	  // i am an RTP data receiver, so do the receiver stuffs
 	  else {
+		  printf("\tparse_xr - i_am_recvr \n");
+		  printf("num_chunks:%d, beg:%d, end:%d\n",num_chunks, begin, end);
 		  // parse XR chunks
 		  tfwc_rcvr_recv(xr->BT, begin, chunk, num_chunks);
 		  // send receiver side XR report

Modified: vic/branches/cc/rtp/session.h
==============================================================================
--- vic/branches/cc/rtp/session.h	(original)
+++ vic/branches/cc/rtp/session.h	Mon Jun 22 23:48:09 2009
@@ -139,6 +139,8 @@
 //	virtual void send_report();
 	virtual void send_report(CtrlHandler*, int bye, int app = 0);
 	virtual void send_xreport(CtrlHandler*, int bt, int bye);
+	virtual void send_Xreport(CtrlHandler* ch, uint8_t bt, uint8_t rsvd, uint8_t thin, uint16_t begin_seq, uint16_t end_seq, uint16_t *chunks, uint16_t num_chunks, uint32_t xrssrc);
+
 	void build_aoa_pkt(CtrlHandler* ch);
 	void build_ts_pkt(CtrlHandler* ch);
 	void build_ackv_pkt(CtrlHandler* ch);

Modified: vic/branches/cc/rtp/transmitter.cpp
==============================================================================
--- vic/branches/cc/rtp/transmitter.cpp	(original)
+++ vic/branches/cc/rtp/transmitter.cpp	Mon Jun 22 23:48:09 2009
@@ -295,18 +295,20 @@
         tfwc_sndr_send(pb);
 
         // declare the next packet
-        pktbuf* nx = pb->next;
+        //pktbuf* nx = pb->next;
+        head_ = pb->next;
 
         // call Transmitter::output(pb)
         output(pb);
 
         // move packet pointer
-        pb = nx;
+        //pb = nx;
 
         // if pb is not 0, 
         // then move head pointer and parse rtp header
-        if (pb != 0) {
-            head_ = pb;
+        if (head_ != 0) {
+            pb = head_;
+            //head_ = pb;
             rh = (rtphdr *) pb->data;
         } else {
             break;



More information about the Sumover-dev mailing list