[Sumover-dev] [svn commit] r4804 - in vic/branches/cc: rtp
sumover-dev at cs.ucl.ac.uk
sumover-dev at cs.ucl.ac.uk
Sun May 9 02:16:39 BST 2010
Author: soohyunc
Date: Sun May 9 02:16:38 2010
New Revision: 4804
Modified:
vic/branches/cc/cc/tfrc_rcvr.h
vic/branches/cc/cc/tfrc_sndr.h
vic/branches/cc/cc/tfwc_rcvr.h
vic/branches/cc/cc/tfwc_sndr.h
vic/branches/cc/rtp/session.cpp
vic/branches/cc/rtp/session.h
vic/branches/cc/rtp/transmitter.cpp
vic/branches/cc/rtp/transmitter.h
Log:
added TFRC sending and receiving mechanisms
(currently, TFRC's send rate calculation is omitted)
Modified: vic/branches/cc/cc/tfrc_rcvr.h
==============================================================================
--- vic/branches/cc/cc/tfrc_rcvr.h (original)
+++ vic/branches/cc/cc/tfrc_rcvr.h Sun May 9 02:16:38 2010
@@ -42,8 +42,18 @@
public:
TfrcRcvr();
+ // receive AoA
void recv_aoa(u_int16_t type, u_int16_t *chunk);
+ // receive RTP data
void recv_seqno(u_int16_t seqno);
+ // AckVec clone
+ inline u_int16_t getvec(int i) { return tfrcAV[i]; }
+ // AckVec begin seqno
+ inline u_int16_t begins() { return begins_; }
+ // AckVec end seqno plus one
+ inline u_int16_t ends() { return ends_; }
+ // number of AckVec array
+ inline u_int16_t numvec() { return numVec_; }
// TfrcRcvr instance
static inline TfrcRcvr& instance() { return instance_; }
Modified: vic/branches/cc/cc/tfrc_sndr.h
==============================================================================
--- vic/branches/cc/cc/tfrc_sndr.h (original)
+++ vic/branches/cc/cc/tfrc_sndr.h Sun May 9 02:16:38 2010
@@ -40,7 +40,6 @@
#include "cc_timer.h"
class TfrcSndr;
-class Transmitter;
// TFRC sender class
class TfrcSndr {
@@ -62,6 +61,9 @@
void recv(u_int16_t, u_int16_t, u_int16_t,
u_int16_t*, double, bool, pktbuf*);
+ // return ackofack
+ inline u_int16_t get_aoa() { return aoa_; }
+
u_int16_t seqno_; // packet sequence number
double x_rate_; // send rate
Modified: vic/branches/cc/cc/tfwc_rcvr.h
==============================================================================
--- vic/branches/cc/cc/tfwc_rcvr.h (original)
+++ vic/branches/cc/cc/tfwc_rcvr.h Sun May 9 02:16:38 2010
@@ -41,8 +41,12 @@
class TfwcRcvr {
public:
TfwcRcvr();
+
+ // receive AoA
void recv_aoa(u_int16_t type, u_int16_t *chunk);
+ // receive RTP data
void recv_seqno(u_int16_t seqno);
+
// AckVec clone
inline u_int16_t getvec(int i) { return tfwcAV[i]; }
// ts echo
Modified: vic/branches/cc/cc/tfwc_sndr.h
==============================================================================
--- vic/branches/cc/cc/tfwc_sndr.h (original)
+++ vic/branches/cc/cc/tfwc_sndr.h Sun May 9 02:16:38 2010
@@ -44,7 +44,6 @@
#define TFWC_TIMER_RESET 1
class TfwcSndr;
-class Transmitter;
// re-transmission timer
class TfwcRtxTimer : public CcTimerHandler {
Modified: vic/branches/cc/rtp/session.cpp
==============================================================================
--- vic/branches/cc/rtp/session.cpp (original)
+++ vic/branches/cc/rtp/session.cpp Sun May 9 02:16:38 2010
@@ -450,9 +450,9 @@
void SessionManager::transmit(pktbuf* pb, bool recv_by_ch)
{
- //mh_.msg_iov = pb->iov;
- // dh_[.net()->send(mh_);
- //debug_msg("L %d,",pb->layer);
+ // mh_.msg_iov = pb->iov;
+ // dh_[.net()->send(mh_);
+ // debug_msg("L %d,",pb->layer);
// receive XR before sending
if(!recv_by_ch)
@@ -474,9 +474,10 @@
// upon every RTP data packet transmission.
switch (cc_type_) {
case WBCC:
- ch_[0].send_aoa(); // send ack of ack
+ ch_->send_aoa(); // send ack of ack
break;
case RBCC:
+ ch_->send_aoa(); // send ack of ack
break;
}
}
@@ -680,64 +681,85 @@
u_int16_t *chunks = NULL;
u_int16_t num_chunks = 0;
- // i am an RTP data sender
+ // -----------------------------------------------------------------*
+ // i am an RTP data sender *
+ // -----------------------------------------------------------------*
if (am_i_sender()) {
if(bt == XR_BT_1) {
- num_chunks = 1;
- chunks = (u_int16_t *) malloc(num_chunks * sizeof(u_int16_t));
+ num_chunks = 1;
+ chunks = (u_int16_t *) malloc(num_chunks * sizeof(u_int16_t));
- switch (cc_type_) {
- case WBCC:
- // this block is used for giving ackofack
- // set AckofAck
- chunks[num_chunks-1] = tfwc_sndr_.get_aoa();
-
- // send_xreport (sender's report)
- // - just sending ackofack information
- send_xreport(ch, XR_BT_1, 0, 0, 0, 0, chunks, num_chunks, 0);
- break;
+ switch (cc_type_) {
+ case WBCC:
+ // this block is used for giving ackofack
+ chunks[num_chunks-1] = tfwc_sndr_.get_aoa();
+ break;
+
+ case RBCC:
+ // this block is used for giving ackofack
+ chunks[num_chunks-1] = tfrc_sndr_.get_aoa();
+ break;
+ } // switch (cc_type_)
- case RBCC:
- // for TFRC, no action needed here.
- break;
- }
+ // send_xreport (sender's report)
+ // - just sending ackofack information
+ send_xreport(ch, XR_BT_1, 0, 0, 0, 0, chunks, num_chunks, 0);
}
else if (bt == XR_BT_3) {
/*XXX*/
}
- }
- // i am an RTP data receiver
+ }
+ // -----------------------------------------------------------------*
+ // i am an RTP data receiver *
+ // -----------------------------------------------------------------*
else {
// this block is used for giving ackvec
if (bt == XR_BT_1) {
- switch (cc_type_) {
- case WBCC:
- // get the number of required chunks for giving AckVec
- num_chunks = tfwc_rcvr_.numvec();
- chunks = (u_int16_t *)
- malloc(num_chunks * sizeof(u_int16_t));
+ switch (cc_type_) {
+ case WBCC:
+ // get the number of required chunks for giving AckVec
+ num_chunks = tfwc_rcvr_.numvec();
+ chunks = (u_int16_t *)malloc(num_chunks * sizeof(u_int16_t));
- // set/printing chunks
- //fprintf(stderr, "\t printing chunks: ");
- for (int i = 0; i < num_chunks; i++) {
- chunks[i] = tfwc_rcvr_.getvec(i);
- // fprintf(stderr, "[%d:%x] ", i, chunks[i]);
- }
- //fprintf(stderr, "...........%s +%d\n",__FILE__,__LINE__);
- break;
-
- case RBCC:
- break;
- }
- // send_xreport (receiver's report)
- // - sending AckVec
- send_xreport(ch, XR_BT_1, 0, 0, tfwc_rcvr_.begins(),
- tfwc_rcvr_.ends(), chunks, num_chunks, 0);
+ // set/printing chunks
+ //fprintf(stderr, "\t printing chunks: ");
+ for (int i = 0; i < num_chunks; i++) {
+ chunks[i] = tfwc_rcvr_.getvec(i);
+ // fprintf(stderr, "[%d:%x] ", i, chunks[i]);
+ }
+ //fprintf(stderr, "...........%s +%d\n",__FILE__,__LINE__);
+
+ // send_xreport (receiver's report)
+ // - sending AckVec
+ send_xreport(ch, XR_BT_1, 0, 0, tfwc_rcvr_.begins(),
+ tfwc_rcvr_.ends(), chunks, num_chunks, 0);
+ break;
+
+ case RBCC:
+ // get the number of required chunks for giving AckVec
+ num_chunks = tfrc_rcvr_.numvec();
+ chunks = (u_int16_t *)malloc(num_chunks * sizeof(u_int16_t));
+
+ // set/printing chunks
+ //fprintf(stderr, "\t printing chunks: ");
+ for (int i = 0; i < num_chunks; i++) {
+ chunks[i] = tfrc_rcvr_.getvec(i);
+ // fprintf(stderr, "[%d:%x] ", i, chunks[i]);
+ }
+ //fprintf(stderr, "...........%s +%d\n",__FILE__,__LINE__);
+
+ // send_xreport (receiver's report)
+ // - sending AckVec
+ send_xreport(ch, XR_BT_1, 0, 0, tfrc_rcvr_.begins(),
+ tfrc_rcvr_.ends(), chunks, num_chunks, 0);
+ break;
+ } // switch (cc_type_)
}
else if (bt == XR_BT_3) {
/*XXX*/
}
} // end of if (am_i_sender())
+ // -----------------------------------------------------------------*
}
// New version
@@ -1049,18 +1071,19 @@
switch (cc_type_) {
case WBCC:
- // pass seqno to tfwc receiver to build up AckVec
- tfwc_rcvr_.recv_seqno(seqno);
- fprintf(stderr, "\n\treceived seqno: %d\n\n", seqno);
-
- // send receiver side XR report (AckVec)
- ch_->send_ackv();
- //ch_[0].send_ts_echo();
- break;
+ // pass seqno to tfwc receiver to build up AckVec
+ fprintf(stderr, "\n\treceived seqno: %d\n\n", seqno);
+ tfwc_rcvr_.recv_seqno(seqno);
+ break;
case RBCC:
- ch_->send_p();
- break;
+ // pass seqno to tfrc receiver to build up AckVec
+ fprintf(stderr, "\n\treceived seqno: %d\n\n", seqno);
+ tfrc_rcvr_.recv_seqno(seqno);
+ break;
}
+
+ // send receiver side XR report (AckVec)
+ ch_->send_ackv();
}
//bp += sizeof(*rh);
@@ -1335,45 +1358,54 @@
// parse XR chunks
u_int16_t *chunk = (u_int16_t *) ++xr1;
- // i am an RTP data sender, so do the sender stuffs (AoA)
+ // -----------------------------------------------------------------*
+ // i am an RTP data sender (AoA) *
+ // -----------------------------------------------------------------*
if (am_i_sender()) {
- fprintf(stderr, ">>> parse_xr - i_am_sender\n");
- //sender_xr_info(begin, end, xr1, xrlen);
- switch (cc_type_) {
+ fprintf(stderr, ">>> parse_xr - i_am_sender\n");
+ fprintf(stderr, "\tincomingXR\tnow: %f\n", recv_ts_);
+ //sender_xr_info(__FILE__,__LINE__,begin, end, xr1, xrlen);
+ switch (cc_type_) {
case WBCC:
- fprintf(stderr, "\tincomingXR\tnow: %f\n", recv_ts_);
- // SO_TIMESTAMP
- //so_rtime = ch_[0].net()->recv_so_time();
- //sender_xr_ts_info(so_rtime);
-
- // TFWC sender (getting AckVec)
- tfwc_sndr_.recv(xr->BT, begin, end, chunk, recv_ts_, recv_by_ch, pb);
-
- // we need to call Transmitter::output(pb) to make Ack driven
- if(recv_by_ch)
- tfwc_output(recv_by_ch);
- break;
+ // SO_TIMESTAMP
+ //so_rtime = ch_[0].net()->recv_so_time();
+ //sender_xr_ts_info(so_rtime);
+
+ // TFWC sender (getting AckVec)
+ tfwc_sndr_.recv(xr->BT,begin,end,chunk,recv_ts_,recv_by_ch,pb);
+
+ // we need to call Transmitter::output(pb) to make Ack driven
+ if(recv_by_ch)
+ tfwc_output(recv_by_ch);
+ break;
case RBCC:
- break;
- }
+ // TFRC sender (getting AckVec)
+ tfrc_sndr_.recv(xr->BT,begin,end,chunk,recv_ts_,recv_by_ch,pb);
+
+ if(recv_by_ch)
+ tfrc_output(recv_by_ch);
+ break;
+ } // switch (cc_type_)
}
- // i am an RTP data receiver, so receive ackofack
+ // -----------------------------------------------------------------*
+ // i am an RTP data receiver (receive ackofack) *
+ // -----------------------------------------------------------------*
else {
+ fprintf(stderr, ">>> parse_xr - i_am_receiver\n");
+ receiver_xr_info(__FILE__,__LINE__,chunk);
switch (cc_type_) {
+ // TFWC receiver (getting ackofack)
case WBCC:
- fprintf(stderr, ">>> parse_xr - i_am_receiver\n");
- receiver_xr_info(chunk);
-
- // TFWC receiver (getting ackofack)
- tfwc_rcvr_.recv_aoa(xr->BT, chunk);
- break;
-
+ tfwc_rcvr_.recv_aoa(xr->BT, chunk);
+ break;
+ // TFRC receiver
case RBCC:
- // do nothing
- break;
+ tfrc_rcvr_.recv_aoa(xr->BT, chunk);
+ break;
}
} // end of XR block type 1
+ // -----------------------------------------------------------------*
} else {
// XXX
debug_msg("UNKNOWN RTCP XR Packet: BT:%d\n", xr->BT);
Modified: vic/branches/cc/rtp/session.h
==============================================================================
--- vic/branches/cc/rtp/session.h (original)
+++ vic/branches/cc/rtp/session.h Sun May 9 02:16:38 2010
@@ -244,18 +244,15 @@
}
inline void print_rtp_seqno(pktbuf* pb) {
rtphdr* rh = (rtphdr *) pb->data;
- fprintf(stderr, "\n\tnow: %f\tseqno: %d\n\n",
- tx_get_now(),ntohs(rh->rh_seqno));
+ fprintf(stderr, "\n\tnow: %f\tseqno: %d\n\n",tx_get_now(),ntohs(rh->rh_seqno));
}
// print sender's XR info
- inline void sender_xr_info(u_int16_t b,
- u_int16_t e,
- rtcp_xr_BT_1_hdr* xrh,
- u_int16_t l)
+ inline void sender_xr_info(const char* str, const int i,
+ u_int16_t b, u_int16_t e, rtcp_xr_BT_1_hdr* xrh, u_int16_t l)
{
- debug_msg("beg:%d, end:%d, xr1len:%d (xrlen:%d)\n",
- b,e,ntohs(xrh->xr_len),l);
+ fprintf(stderr, " [%s +%d] beg:%d, end:%d, xr1len:%d (xrlen:%d)\n",
+ str, i, b, e, ntohs(xrh->xr_len),l);
}
// print sender's XR info
inline void sender_xr_ts_info(double ts) {
@@ -263,8 +260,8 @@
recv_ts_, ts, recv_ts_-ts);
}
// print receiver's XR info
- inline void receiver_xr_info(u_int16_t *c) {
- debug_msg("chunk[0]:%d\n", ntohs(c[0]));
+ inline void receiver_xr_info(const char* str, const int i, u_int16_t *c) {
+ fprintf(stderr, " [%s +%d] chunk[0]:%d\n",str, i, ntohs(c[0]));
}
// print parse XR banner
inline void parse_xr_banner_top() {
Modified: vic/branches/cc/rtp/transmitter.cpp
==============================================================================
--- vic/branches/cc/rtp/transmitter.cpp (original)
+++ vic/branches/cc/rtp/transmitter.cpp Sun May 9 02:16:38 2010
@@ -244,114 +244,114 @@
// window-based congestion control (TFWC)
//
case WBCC:
- // pb is empty - try sending a packet
- if(is_buf_empty_) {
- if (head_ != 0) {
- tail_->next = pb;
- tail_ = pb;
- } else
- tail_ = head_ = pb;
- pb->next = 0;
- tfwc_output();
- is_buf_empty_ = false;
- }
- // if not, check if cwnd allows send this packet
- else {
- if (head_ != 0) {
- tail_->next = pb;
- tail_ = pb;
- } else
- tail_ = head_ = pb;
- pb->next = 0;
- tfwc_output(pb);
- }
- break;
+ // pb is empty - try sending a packet
+ if(is_buf_empty_) {
+ if (head_ != 0) {
+ tail_->next = pb;
+ tail_ = pb;
+ } else
+ tail_ = head_ = pb;
+ pb->next = 0;
+ tfwc_output();
+ is_buf_empty_ = false;
+ }
+ // if not, check if cwnd allows send this packet
+ else {
+ if (head_ != 0) {
+ tail_->next = pb;
+ tail_ = pb;
+ } else
+ tail_ = head_ = pb;
+ pb->next = 0;
+ tfwc_output(pb);
+ }
+ break;
//
// rate-based congestion control (TFRC)
//
case RBCC:
- // pb is empty
- if(is_buf_empty_) {
- if (head_ != 0) {
- tail_->next = pb;
- tail_ = pb;
- } else
- tail_ = head_ = pb;
- pb->next = 0;
- cc_tfrc_output();
- is_buf_empty_ = false;
- }
- // pb is not emtpy
- else {
- if (head_ != 0) {
- tail_->next = pb;
- tail_ = pb;
- } else
- tail_ = head_ = pb;
- pb->next = 0;
- }
- break;
+ // pb is empty
+ if(is_buf_empty_) {
+ if (head_ != 0) {
+ tail_->next = pb;
+ tail_ = pb;
+ } else
+ tail_ = head_ = pb;
+ pb->next = 0;
+ tfrc_output();
+ is_buf_empty_ = false;
+ }
+ // pb is not emtpy
+ else {
+ if (head_ != 0) {
+ tail_->next = pb;
+ tail_ = pb;
+ } else
+ tail_ = head_ = pb;
+ pb->next = 0;
+ tfrc_output(pb);
+ }
+ break;
//
// without congestion control
//
case NOCC:
default:
- // CC is not active, so just go for the normal operation
- if (!busy_) {
- double delay = txtime(pb);
- nextpkttime_ = gettimeofday_secs() + delay;
- output(pb);
- /*
- * emulate a transmit interrupt --
- * assume we will have more to send.
- */
- msched(int(delay * 1e-3));
- busy_ = 1;
- } else {
- if (head_ != 0) {
- tail_->next = pb;
- tail_ = pb;
- } else
- tail_ = head_ = pb;
- pb->next = 0;
- }
+ // CC is not active, so just go for the normal operation
+ if (!busy_) {
+ double delay = txtime(pb);
+ nextpkttime_ = gettimeofday_secs() + delay;
+ output(pb);
+ /*
+ * emulate a transmit interrupt --
+ * assume we will have more to send.
+ */
+ msched(int(delay * 1e-3));
+ busy_ = 1;
+ } else {
+ if (head_ != 0) {
+ tail_->next = pb;
+ tail_ = pb;
+ } else
+ tail_ = head_ = pb;
+ pb->next = 0;
+ }
} // switch (cc_type)
}
void Transmitter::tfwc_output(pktbuf* pb)
{
- //cc_output_banner_top();
-
+ //cc_output_banner_top("tfwc");
// byte mode? or packet mode?
switch (cwnd_mode_) {
case BYM:
{
- int len = 0;
- if(pb->len < tfwc_sndr_.b_magic() - len) {
- len += pb->len;
- // move head pointer
- head_ = pb->next;
- // call Transmitter::output_data_only w/ XR reception
- output_data_only(pb, XR_RECV);
- }
+ int len = 0;
+ if(pb->len < tfwc_sndr_.b_magic() - len) {
+ len += pb->len;
+ // move head pointer
+ head_ = pb->next;
+ // call Transmitter::output_data_only w/ XR reception
+ output_data_only(pb, XR_RECV);
+ }
}
break;
case PKM:
{
- // pb is not null, hence parse it.
- rtphdr* rh = (rtphdr *) pb->data;
+ // pb is not null, hence parse it.
+ rtphdr* rh = (rtphdr *) pb->data;
- if (ntohs(rh->rh_seqno) <= tfwc_sndr_.magic() + tfwc_sndr_.jacked()) {
- //debug_msg("cwnd: %d\n", tfwc_sndr_.magic());
- //debug_msg("jack: %d\n", tfwc_sndr_.jacked());
+ if (ntohs(rh->rh_seqno) <= tfwc_sndr_.magic() + tfwc_sndr_.jacked()) {
+ //debug_msg("cwnd: %d\n", tfwc_sndr_.magic());
+ //debug_msg("jack: %d\n", tfwc_sndr_.jacked());
- // move head pointer
- head_ = pb->next;
- // call Transmitter::output_data_only w/ XR reception
- output_data_only(pb, XR_RECV);
- }
+ // move head pointer
+ head_ = pb->next;
+ // call Transmitter::output_data_only w/ XR reception
+ output_data_only(pb, XR_RECV);
+ }
}
break;
} // switch (cwnd_mode_)
@@ -380,45 +380,45 @@
switch (cwnd_mode_) {
case BYM:
{
- int len = 0;
- while(pb->len < tfwc_sndr_.b_magic() - len) {
- len += pb->len;
- // move head pointer
- head_ = pb->next;
- // call Transmitter::output(pb)
- output(pb, recv_by_ch);
-
- if (head_ != 0)
- pb = head_;
- else
- break;
- }
+ int len = 0;
+ while(pb->len < tfwc_sndr_.b_magic() - len) {
+ len += pb->len;
+ // move head pointer
+ head_ = pb->next;
+ // call Transmitter::output(pb)
+ output(pb, recv_by_ch);
+
+ if (head_ != 0)
+ pb = head_;
+ else
+ break;
+ }
}
break;
case PKM:
{
- // pb is not null, hence parse it.
- rtphdr* rh = (rtphdr *) pb->data;
+ // pb is not null, hence parse it.
+ rtphdr* rh = (rtphdr *) pb->data;
- // while packet seqno is within "cwnd + jack", send that packet
- while (ntohs(rh->rh_seqno) <= tfwc_sndr_.magic() + tfwc_sndr_.jacked()) {
- //debug_msg("cwnd: %d\n", tfwc_sndr_.magic());
- //debug_msg("jack: %d\n", tfwc_sndr_.jacked());
-
- // move head pointer
- head_ = pb->next;
- // call Transmitter::output(pb)
- output(pb, recv_by_ch);
-
- // if the moved head pointer is not null, parse packet buffer.
- // otherwise, break while statement.
- if (head_ != 0) {
- pb = head_;
- rh = (rtphdr *) pb->data;
- } else {
- break;
- }
- } // end while ()
+ // while packet seqno is within "cwnd + jack", send that packet
+ while (ntohs(rh->rh_seqno) <= tfwc_sndr_.magic() + tfwc_sndr_.jacked()) {
+ //debug_msg("cwnd: %d\n", tfwc_sndr_.magic());
+ //debug_msg("jack: %d\n", tfwc_sndr_.jacked());
+
+ // move head pointer
+ head_ = pb->next;
+ // call Transmitter::output(pb)
+ output(pb, recv_by_ch);
+
+ // if the moved head pointer is not null, parse packet buffer.
+ // otherwise, break while statement.
+ if (head_ != 0) {
+ pb = head_;
+ rh = (rtphdr *) pb->data;
+ } else {
+ break;
+ }
+ } // end while ()
}
break;
} // switch (cwnd_mode_)
@@ -452,8 +452,40 @@
/*
* main TFRC CC output
*/
-void Transmitter::cc_tfrc_output() {
- // TBA
+void Transmitter::tfrc_output(pktbuf* pb) {
+ cc_output_banner_top("tfrc");
+ // move head pointer
+ head_ = pb->next;
+ // call Transmitter::output_data_only w/ XR reception
+ output_data_only(pb, XR_RECV);
+ cc_output_banner_bottom();
+}
+
+void Transmitter::tfrc_output(bool recv_by_ch) {
+ cc_output_banner_top("tfrc");
+ // head of the RTP data packet buffer
+ pktbuf* pb = head_;
+
+ // if pb is null, then set the next available packet as the first packet of
+ // the packet buffer. and then, return - i.e., do not try sending packets.
+ if (pb == 0) {
+ is_buf_empty_ = true;
+ return;
+ }
+
+ while ( pb != 0) {
+ // move head pointer
+ head_ = pb->next;
+ // call Transmitter::output(pb)
+ output(pb, recv_by_ch);
+
+ if (head_ != 0) {
+ pb = head_;
+ } else {
+ break;
+ }
+ }
+ cc_output_banner_bottom();
}
void Transmitter::timeout()
Modified: vic/branches/cc/rtp/transmitter.h
==============================================================================
--- vic/branches/cc/rtp/transmitter.h (original)
+++ vic/branches/cc/rtp/transmitter.h Sun May 9 02:16:38 2010
@@ -100,10 +100,13 @@
void flush();
void send(pktbuf*);
inline bool is_cc_on() { return is_cc_active_; }
+ // TFWC output
virtual void tfwc_output(bool recv_by_ch=0);
virtual void tfwc_output(pktbuf*);
virtual void cc_tfwc_trigger(pktbuf*);
- void cc_tfrc_output();
+ // TFRC output
+ virtual void tfrc_output(bool recv_by_ch=0);
+ virtual void tfrc_output(pktbuf*);
/*
* Buffer allocation hooks.
More information about the Sumover-dev
mailing list