[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