Changeset 4804

Show
Ignore:
Timestamp:
05/09/10 02:16:38 (4 years ago)
Author:
soohyunc
Message:

added TFRC sending and receiving mechanisms
(currently, TFRC's send rate calculation is omitted)

Location:
vic/branches/cc
Files:
8 modified

Legend:

Unmodified
Added
Removed
  • vic/branches/cc/cc/tfrc_rcvr.h

    r4803 r4804  
    4343        TfrcRcvr(); 
    4444 
     45        // receive AoA 
    4546        void recv_aoa(u_int16_t type, u_int16_t *chunk); 
     47        // receive RTP data  
    4648        void recv_seqno(u_int16_t seqno); 
     49    // AckVec clone 
     50    inline u_int16_t getvec(int i) { return tfrcAV[i]; } 
     51    // AckVec begin seqno 
     52    inline u_int16_t begins() { return begins_; } 
     53    // AckVec end seqno plus one 
     54    inline u_int16_t ends() { return ends_; } 
     55    // number of AckVec array 
     56    inline u_int16_t numvec() { return numVec_; } 
    4757 
    4858        // TfrcRcvr instance 
  • vic/branches/cc/cc/tfrc_sndr.h

    r4803 r4804  
    4141 
    4242class TfrcSndr; 
    43 class Transmitter; 
    4443 
    4544// TFRC sender class 
     
    6261        void recv(u_int16_t, u_int16_t, u_int16_t, 
    6362                u_int16_t*, double, bool, pktbuf*); 
     63 
     64        // return ackofack 
     65        inline u_int16_t get_aoa() { return aoa_; } 
    6466 
    6567        u_int16_t seqno_;       // packet sequence number 
  • vic/branches/cc/cc/tfwc_rcvr.h

    r4793 r4804  
    4242public: 
    4343        TfwcRcvr(); 
     44 
     45        // receive AoA 
    4446        void recv_aoa(u_int16_t type, u_int16_t *chunk); 
     47        // receive RTP data 
    4548        void recv_seqno(u_int16_t seqno); 
     49 
    4650        // AckVec clone 
    4751        inline u_int16_t getvec(int i) { return tfwcAV[i]; } 
  • vic/branches/cc/cc/tfwc_sndr.h

    r4798 r4804  
    4545 
    4646class TfwcSndr; 
    47 class Transmitter; 
    4847 
    4948// re-transmission timer 
  • vic/branches/cc/rtp/session.cpp

    r4802 r4804  
    451451void SessionManager::transmit(pktbuf* pb, bool recv_by_ch) 
    452452{ 
    453         //mh_.msg_iov = pb->iov; 
    454         //      dh_[.net()->send(mh_); 
    455                 //debug_msg("L %d,",pb->layer); 
     453        // mh_.msg_iov = pb->iov; 
     454        // dh_[.net()->send(mh_); 
     455        // debug_msg("L %d,",pb->layer); 
    456456 
    457457        // receive XR before sending 
     
    475475                switch (cc_type_) { 
    476476                case WBCC: 
    477                         ch_[0].send_aoa();      // send ack of ack 
     477                        ch_->send_aoa();        // send ack of ack 
    478478                        break; 
    479479                case RBCC: 
     480                        ch_->send_aoa();        // send ack of ack 
    480481                        break; 
    481482                } 
     
    681682        u_int16_t num_chunks = 0; 
    682683 
    683         // i am an RTP data sender 
     684        // -----------------------------------------------------------------* 
     685        // i am an RTP data sender                                          * 
     686        // -----------------------------------------------------------------* 
    684687        if (am_i_sender()) { 
    685688                if(bt == XR_BT_1) { 
    686                         num_chunks = 1; 
    687                         chunks = (u_int16_t *) malloc(num_chunks * sizeof(u_int16_t)); 
    688  
    689                         switch (cc_type_) { 
    690                         case WBCC: 
    691                                 // this block is used for giving ackofack 
    692                                 // set AckofAck 
    693                                 chunks[num_chunks-1] = tfwc_sndr_.get_aoa(); 
    694  
    695                                 // send_xreport (sender's report) 
    696                                 // - just sending ackofack information 
    697                                 send_xreport(ch, XR_BT_1, 0, 0, 0, 0, chunks, num_chunks, 0); 
    698                                 break; 
    699  
    700                         case RBCC: 
    701                                 // for TFRC, no action needed here. 
    702                                 break; 
    703                         } 
     689                num_chunks = 1; 
     690                chunks = (u_int16_t *) malloc(num_chunks * sizeof(u_int16_t)); 
     691 
     692                switch (cc_type_) { 
     693                  case WBCC: 
     694                        // this block is used for giving ackofack 
     695                        chunks[num_chunks-1] = tfwc_sndr_.get_aoa(); 
     696                  break; 
     697 
     698                  case RBCC: 
     699                        // this block is used for giving ackofack 
     700                        chunks[num_chunks-1] = tfrc_sndr_.get_aoa(); 
     701                        break; 
     702                  } // switch (cc_type_) 
     703 
     704                  // send_xreport (sender's report) 
     705                  // - just sending ackofack information 
     706                  send_xreport(ch, XR_BT_1, 0, 0, 0, 0, chunks, num_chunks, 0); 
    704707                } 
    705708                else if (bt == XR_BT_3) { 
    706709                        /*XXX*/ 
    707710                }  
    708         }  
    709         // i am an RTP data receiver 
     711        } 
     712        // -----------------------------------------------------------------* 
     713        // i am an RTP data receiver                                        * 
     714        // -----------------------------------------------------------------* 
    710715        else { 
    711716                // this block is used for giving ackvec 
    712717                if (bt == XR_BT_1) { 
    713                         switch (cc_type_) { 
    714                         case WBCC: 
    715                                 // get the number of required chunks for giving AckVec 
    716                                 num_chunks = tfwc_rcvr_.numvec(); 
    717                                 chunks = (u_int16_t *)  
    718                                         malloc(num_chunks * sizeof(u_int16_t)); 
     718                switch (cc_type_) { 
     719                  case WBCC: 
     720                  // get the number of required chunks for giving AckVec 
     721                  num_chunks = tfwc_rcvr_.numvec(); 
     722                  chunks = (u_int16_t *)malloc(num_chunks * sizeof(u_int16_t)); 
    719723                         
    720                                 // set/printing chunks 
    721                                 //fprintf(stderr, "\t   printing chunks: "); 
    722                                 for (int i = 0; i < num_chunks; i++) { 
    723                                         chunks[i] = tfwc_rcvr_.getvec(i); 
    724                                 //      fprintf(stderr, "[%d:%x] ", i, chunks[i]); 
    725                                 }  
    726                                 //fprintf(stderr, "...........%s +%d\n",__FILE__,__LINE__); 
    727                                 break; 
    728  
    729                         case RBCC: 
    730                                 break; 
    731                         } 
    732                         // send_xreport (receiver's report) 
    733                         // - sending AckVec 
    734                         send_xreport(ch, XR_BT_1, 0, 0, tfwc_rcvr_.begins(),  
    735                                         tfwc_rcvr_.ends(), chunks, num_chunks, 0); 
     724                  // set/printing chunks 
     725                  //fprintf(stderr, "\t   printing chunks: "); 
     726                  for (int i = 0; i < num_chunks; i++) { 
     727                        chunks[i] = tfwc_rcvr_.getvec(i); 
     728                        //      fprintf(stderr, "[%d:%x] ", i, chunks[i]); 
     729                  }  
     730                  //fprintf(stderr, "...........%s +%d\n",__FILE__,__LINE__); 
     731 
     732                  // send_xreport (receiver's report) 
     733                  // - sending AckVec 
     734                  send_xreport(ch, XR_BT_1, 0, 0, tfwc_rcvr_.begins(),  
     735                  tfwc_rcvr_.ends(), chunks, num_chunks, 0); 
     736                  break; 
     737 
     738                  case RBCC: 
     739                  // get the number of required chunks for giving AckVec 
     740                  num_chunks = tfrc_rcvr_.numvec(); 
     741                  chunks = (u_int16_t *)malloc(num_chunks * sizeof(u_int16_t)); 
     742 
     743                  // set/printing chunks 
     744                  //fprintf(stderr, "\t   printing chunks: "); 
     745                  for (int i = 0; i < num_chunks; i++) { 
     746                        chunks[i] = tfrc_rcvr_.getvec(i); 
     747                        //      fprintf(stderr, "[%d:%x] ", i, chunks[i]); 
     748                  } 
     749                  //fprintf(stderr, "...........%s +%d\n",__FILE__,__LINE__); 
     750 
     751                  // send_xreport (receiver's report) 
     752                  // - sending AckVec 
     753                  send_xreport(ch, XR_BT_1, 0, 0, tfrc_rcvr_.begins(),  
     754                  tfrc_rcvr_.ends(), chunks, num_chunks, 0); 
     755                  break; 
     756                  } // switch (cc_type_) 
    736757                } 
    737758                else if (bt == XR_BT_3) { 
     
    739760                }  
    740761        } // end of if (am_i_sender()) 
     762        // -----------------------------------------------------------------* 
    741763} 
    742764 
     
    10501072                switch (cc_type_) { 
    10511073                case WBCC: 
    1052                         // pass seqno to tfwc receiver to build up AckVec 
    1053                         tfwc_rcvr_.recv_seqno(seqno); 
    1054                         fprintf(stderr, "\n\treceived seqno: %d\n\n", seqno); 
    1055  
    1056                         // send receiver side XR report (AckVec) 
    1057                         ch_->send_ackv(); 
    1058                         //ch_[0].send_ts_echo(); 
    1059                         break; 
     1074                  // pass seqno to tfwc receiver to build up AckVec 
     1075                  fprintf(stderr, "\n\treceived seqno: %d\n\n", seqno); 
     1076                  tfwc_rcvr_.recv_seqno(seqno); 
     1077                  break; 
    10601078                case RBCC: 
    1061                         ch_->send_p(); 
    1062                         break; 
    1063                 } 
     1079                  // pass seqno to tfrc receiver to build up AckVec 
     1080                  fprintf(stderr, "\n\treceived seqno: %d\n\n", seqno); 
     1081                  tfrc_rcvr_.recv_seqno(seqno); 
     1082                  break; 
     1083                } 
     1084 
     1085                // send receiver side XR report (AckVec) 
     1086                ch_->send_ackv(); 
    10641087        } 
    10651088         
     
    13361359                u_int16_t *chunk = (u_int16_t *) ++xr1; 
    13371360 
    1338                 // i am an RTP data sender, so do the sender stuffs (AoA) 
     1361                // -----------------------------------------------------------------* 
     1362                // i am an RTP data sender (AoA)                                    * 
     1363                // -----------------------------------------------------------------* 
    13391364                if (am_i_sender()) { 
    1340                         fprintf(stderr, ">>> parse_xr - i_am_sender\n"); 
    1341                         //sender_xr_info(begin, end, xr1, xrlen); 
     1365                  fprintf(stderr, ">>> parse_xr - i_am_sender\n"); 
     1366                  fprintf(stderr, "\tincomingXR\tnow: %f\n", recv_ts_); 
     1367                  //sender_xr_info(__FILE__,__LINE__,begin, end, xr1, xrlen); 
     1368                  switch (cc_type_) { 
     1369                        case WBCC: 
     1370                        // SO_TIMESTAMP 
     1371                        //so_rtime = ch_[0].net()->recv_so_time(); 
     1372                        //sender_xr_ts_info(so_rtime); 
     1373 
     1374                        // TFWC sender (getting AckVec) 
     1375                        tfwc_sndr_.recv(xr->BT,begin,end,chunk,recv_ts_,recv_by_ch,pb); 
     1376 
     1377                        // we need to call Transmitter::output(pb) to make Ack driven 
     1378                        if(recv_by_ch) 
     1379                        tfwc_output(recv_by_ch); 
     1380                        break; 
     1381 
     1382                        case RBCC: 
     1383                        // TFRC sender (getting AckVec) 
     1384                        tfrc_sndr_.recv(xr->BT,begin,end,chunk,recv_ts_,recv_by_ch,pb); 
     1385 
     1386                        if(recv_by_ch) 
     1387                        tfrc_output(recv_by_ch); 
     1388                        break; 
     1389                  } // switch (cc_type_) 
     1390                } 
     1391                // -----------------------------------------------------------------* 
     1392                // i am an RTP data receiver (receive ackofack)                     * 
     1393                // -----------------------------------------------------------------* 
     1394                else { 
     1395                        fprintf(stderr, ">>> parse_xr - i_am_receiver\n"); 
     1396                        receiver_xr_info(__FILE__,__LINE__,chunk); 
    13421397                        switch (cc_type_) { 
     1398                        // TFWC receiver (getting ackofack) 
    13431399                        case WBCC: 
    1344                                 fprintf(stderr, "\tincomingXR\tnow: %f\n", recv_ts_); 
    1345                                 // SO_TIMESTAMP 
    1346                                 //so_rtime = ch_[0].net()->recv_so_time(); 
    1347                                 //sender_xr_ts_info(so_rtime); 
    1348  
    1349                                 // TFWC sender (getting AckVec) 
    1350                                 tfwc_sndr_.recv(xr->BT, begin, end, chunk, recv_ts_, recv_by_ch, pb); 
    1351  
    1352                                 // we need to call Transmitter::output(pb) to make Ack driven 
    1353                                 if(recv_by_ch) 
    1354                                 tfwc_output(recv_by_ch); 
    1355                                 break; 
    1356  
     1400                          tfwc_rcvr_.recv_aoa(xr->BT, chunk); 
     1401                          break; 
     1402                        // TFRC receiver 
    13571403                        case RBCC: 
    1358                                 break; 
    1359                         } 
    1360                 } 
    1361                 // i am an RTP data receiver, so receive ackofack  
    1362                 else { 
    1363                         switch (cc_type_) { 
    1364                         case WBCC: 
    1365                                 fprintf(stderr, ">>> parse_xr - i_am_receiver\n"); 
    1366                                 receiver_xr_info(chunk); 
    1367  
    1368                                 // TFWC receiver (getting ackofack) 
    1369                                 tfwc_rcvr_.recv_aoa(xr->BT, chunk); 
    1370                                 break; 
    1371  
    1372                         case RBCC: 
    1373                                 // do nothing 
    1374                                 break; 
     1404                          tfrc_rcvr_.recv_aoa(xr->BT, chunk); 
     1405                          break; 
    13751406                        } 
    13761407                } // end of XR block type 1 
     1408                // -----------------------------------------------------------------* 
    13771409        } else { 
    13781410                // XXX 
  • vic/branches/cc/rtp/session.h

    r4766 r4804  
    245245        inline void print_rtp_seqno(pktbuf* pb) { 
    246246        rtphdr* rh = (rtphdr *) pb->data; 
    247         fprintf(stderr, "\n\tnow: %f\tseqno: %d\n\n", 
    248                 tx_get_now(),ntohs(rh->rh_seqno)); 
     247        fprintf(stderr, "\n\tnow: %f\tseqno: %d\n\n",tx_get_now(),ntohs(rh->rh_seqno)); 
    249248        } 
    250249 
    251250        // print sender's XR info 
    252         inline void sender_xr_info(u_int16_t b,  
    253                 u_int16_t e,  
    254                 rtcp_xr_BT_1_hdr* xrh, 
    255                 u_int16_t l)  
     251        inline void sender_xr_info(const char* str, const int i, 
     252        u_int16_t b, u_int16_t e, rtcp_xr_BT_1_hdr* xrh, u_int16_t l)  
    256253        { 
    257                 debug_msg("beg:%d, end:%d, xr1len:%d (xrlen:%d)\n", 
    258                 b,e,ntohs(xrh->xr_len),l); 
     254        fprintf(stderr, "  [%s +%d] beg:%d, end:%d, xr1len:%d (xrlen:%d)\n", 
     255                str, i, b, e, ntohs(xrh->xr_len),l); 
    259256        } 
    260257        // print sender's XR info 
     
    264261        } 
    265262        // print receiver's XR info 
    266         inline void receiver_xr_info(u_int16_t *c) { 
    267                 debug_msg("chunk[0]:%d\n", ntohs(c[0])); 
     263        inline void receiver_xr_info(const char* str, const int i, u_int16_t *c) { 
     264        fprintf(stderr, "  [%s +%d] chunk[0]:%d\n",str, i, ntohs(c[0])); 
    268265        } 
    269266        // print parse XR banner 
  • vic/branches/cc/rtp/transmitter.cpp

    r4797 r4804  
    245245        // 
    246246        case WBCC: 
    247                 // pb is empty - try sending a packet 
    248                 if(is_buf_empty_) { 
    249                         if (head_ != 0) { 
    250                                 tail_->next = pb; 
    251                                 tail_ = pb; 
    252                         } else 
    253                                 tail_ = head_ = pb; 
    254                         pb->next = 0; 
    255                         tfwc_output(); 
    256                         is_buf_empty_ = false; 
    257                 }  
    258                 // if not, check if cwnd allows send this packet 
    259                 else { 
    260                         if (head_ != 0) { 
    261                                 tail_->next = pb; 
    262                                 tail_ = pb; 
    263                         } else 
    264                                 tail_ = head_ = pb; 
    265                         pb->next = 0; 
    266                         tfwc_output(pb); 
    267                 } 
    268                 break; 
     247          // pb is empty - try sending a packet 
     248          if(is_buf_empty_) { 
     249                if (head_ != 0) { 
     250                  tail_->next = pb; 
     251                  tail_ = pb; 
     252                } else 
     253                  tail_ = head_ = pb; 
     254                pb->next = 0; 
     255                tfwc_output(); 
     256                is_buf_empty_ = false; 
     257          }  
     258          // if not, check if cwnd allows send this packet 
     259          else { 
     260                if (head_ != 0) { 
     261                  tail_->next = pb; 
     262                  tail_ = pb; 
     263                } else 
     264                  tail_ = head_ = pb; 
     265                pb->next = 0; 
     266                tfwc_output(pb); 
     267          } 
     268          break; 
    269269 
    270270        // 
     
    272272        // 
    273273        case RBCC: 
    274                 // pb is empty 
    275                 if(is_buf_empty_) { 
    276                         if (head_ != 0) { 
    277                                 tail_->next = pb; 
    278                                 tail_ = pb; 
    279                         } else 
    280                                 tail_ = head_ = pb; 
    281                         pb->next = 0; 
    282                         cc_tfrc_output(); 
    283                         is_buf_empty_ = false; 
    284                 } 
    285                 // pb is not emtpy 
    286                 else { 
    287                         if (head_ != 0) { 
    288                                 tail_->next = pb; 
    289                                 tail_ = pb; 
    290                         } else 
    291                                 tail_ = head_ = pb; 
    292                         pb->next = 0; 
    293                 } 
    294                 break; 
     274          // pb is empty 
     275          if(is_buf_empty_) { 
     276                if (head_ != 0) { 
     277                  tail_->next = pb; 
     278                  tail_ = pb; 
     279                } else 
     280                  tail_ = head_ = pb; 
     281                pb->next = 0; 
     282                tfrc_output(); 
     283                is_buf_empty_ = false; 
     284          } 
     285          // pb is not emtpy 
     286          else { 
     287                if (head_ != 0) { 
     288                  tail_->next = pb; 
     289                  tail_ = pb; 
     290                } else 
     291                  tail_ = head_ = pb; 
     292                pb->next = 0; 
     293                tfrc_output(pb); 
     294          } 
     295          break; 
    295296 
    296297        // 
     
    299300        case NOCC: 
    300301        default: 
    301                 // CC is not active, so just go for the normal operation 
    302                 if (!busy_) { 
    303                         double delay = txtime(pb); 
    304                         nextpkttime_ = gettimeofday_secs() + delay; 
    305                         output(pb); 
    306                         /* 
    307                         * emulate a transmit interrupt -- 
    308                         * assume we will have more to send. 
    309                         */ 
    310                         msched(int(delay * 1e-3)); 
    311                         busy_ = 1; 
    312                 } else { 
    313                         if (head_ != 0) { 
    314                                 tail_->next = pb; 
    315                                 tail_ = pb; 
    316                         } else 
    317                                 tail_ = head_ = pb; 
    318                         pb->next = 0; 
    319                 } 
     302          // CC is not active, so just go for the normal operation 
     303          if (!busy_) { 
     304                double delay = txtime(pb); 
     305                nextpkttime_ = gettimeofday_secs() + delay; 
     306                output(pb); 
     307                /* 
     308                * emulate a transmit interrupt -- 
     309                * assume we will have more to send. 
     310                */ 
     311                msched(int(delay * 1e-3)); 
     312                busy_ = 1; 
     313          } else { 
     314                if (head_ != 0) { 
     315                  tail_->next = pb; 
     316                  tail_ = pb; 
     317                } else 
     318                  tail_ = head_ = pb; 
     319                pb->next = 0; 
     320          } 
    320321        } // switch (cc_type) 
    321322} 
     
    323324void Transmitter::tfwc_output(pktbuf* pb)  
    324325{ 
    325         //cc_output_banner_top(); 
    326          
     326        //cc_output_banner_top("tfwc"); 
    327327        // byte mode? or packet mode? 
    328328        switch (cwnd_mode_) { 
    329329        case BYM: 
    330330        { 
    331                 int len = 0; 
    332                 if(pb->len < tfwc_sndr_.b_magic() - len) { 
    333                         len += pb->len; 
    334                         // move head pointer 
    335                         head_ = pb->next; 
    336                         // call Transmitter::output_data_only w/ XR reception 
    337                         output_data_only(pb, XR_RECV); 
    338                 } 
     331          int len = 0; 
     332          if(pb->len < tfwc_sndr_.b_magic() - len) { 
     333                len += pb->len; 
     334                // move head pointer 
     335                head_ = pb->next; 
     336                // call Transmitter::output_data_only w/ XR reception 
     337                output_data_only(pb, XR_RECV); 
     338          } 
    339339        } 
    340340        break; 
    341341        case PKM: 
    342342        { 
    343                 // pb is not null, hence parse it. 
    344                 rtphdr* rh = (rtphdr *) pb->data; 
    345  
    346                 if (ntohs(rh->rh_seqno) <= tfwc_sndr_.magic() + tfwc_sndr_.jacked()) { 
    347                         //debug_msg("cwnd: %d\n", tfwc_sndr_.magic()); 
    348                         //debug_msg("jack: %d\n", tfwc_sndr_.jacked()); 
     343          // pb is not null, hence parse it. 
     344          rtphdr* rh = (rtphdr *) pb->data; 
     345 
     346          if (ntohs(rh->rh_seqno) <= tfwc_sndr_.magic() + tfwc_sndr_.jacked()) { 
     347                //debug_msg("cwnd: %d\n", tfwc_sndr_.magic()); 
     348                //debug_msg("jack: %d\n", tfwc_sndr_.jacked()); 
    349349                         
    350                         // move head pointer 
    351                         head_ = pb->next; 
    352                         // call Transmitter::output_data_only w/ XR reception 
    353                         output_data_only(pb, XR_RECV); 
    354                 } 
     350                // move head pointer 
     351                head_ = pb->next; 
     352                // call Transmitter::output_data_only w/ XR reception 
     353                output_data_only(pb, XR_RECV); 
     354          } 
    355355        } 
    356356        break; 
     
    381381        case BYM: 
    382382        { 
    383                 int len = 0; 
    384                 while(pb->len < tfwc_sndr_.b_magic() - len) { 
    385                         len += pb->len; 
    386                         // move head pointer 
    387                         head_ = pb->next; 
    388                         // call Transmitter::output(pb) 
    389                         output(pb, recv_by_ch); 
    390  
    391                         if (head_ != 0) 
    392                                 pb = head_; 
    393                         else 
    394                                 break; 
    395                 } 
     383          int len = 0; 
     384          while(pb->len < tfwc_sndr_.b_magic() - len) { 
     385                len += pb->len; 
     386                // move head pointer 
     387                head_ = pb->next; 
     388                // call Transmitter::output(pb) 
     389                output(pb, recv_by_ch); 
     390 
     391                if (head_ != 0) 
     392                        pb = head_; 
     393                else 
     394                        break; 
     395          } 
    396396        } 
    397397        break; 
    398398        case PKM: 
    399399        { 
    400                 // pb is not null, hence parse it. 
    401                 rtphdr* rh = (rtphdr *) pb->data; 
    402  
    403                 // while packet seqno is within "cwnd + jack", send that packet 
    404                 while (ntohs(rh->rh_seqno) <= tfwc_sndr_.magic() + tfwc_sndr_.jacked()) { 
    405                         //debug_msg("cwnd: %d\n", tfwc_sndr_.magic()); 
    406                         //debug_msg("jack: %d\n", tfwc_sndr_.jacked()); 
    407  
    408                         // move head pointer 
    409                         head_ = pb->next; 
    410                         // call Transmitter::output(pb) 
    411                         output(pb, recv_by_ch); 
    412  
    413                         // if the moved head pointer is not null, parse packet buffer. 
    414                         // otherwise, break while statement. 
    415                         if (head_ != 0) { 
    416                                 pb = head_; 
    417                                 rh = (rtphdr *) pb->data; 
    418                         } else { 
    419                                 break; 
    420                         } 
    421                 } // end while () 
     400          // pb is not null, hence parse it. 
     401          rtphdr* rh = (rtphdr *) pb->data; 
     402 
     403          // while packet seqno is within "cwnd + jack", send that packet 
     404          while (ntohs(rh->rh_seqno) <= tfwc_sndr_.magic() + tfwc_sndr_.jacked()) { 
     405                //debug_msg("cwnd: %d\n", tfwc_sndr_.magic()); 
     406                //debug_msg("jack: %d\n", tfwc_sndr_.jacked()); 
     407 
     408                // move head pointer 
     409                head_ = pb->next; 
     410                // call Transmitter::output(pb) 
     411                output(pb, recv_by_ch); 
     412 
     413                // if the moved head pointer is not null, parse packet buffer. 
     414                // otherwise, break while statement. 
     415                if (head_ != 0) { 
     416                        pb = head_; 
     417                        rh = (rtphdr *) pb->data; 
     418                } else { 
     419                        break; 
     420                } 
     421          } // end while () 
    422422        } 
    423423        break; 
     
    453453 * main TFRC CC output 
    454454 */ 
    455 void Transmitter::cc_tfrc_output() { 
    456         // TBA 
     455void Transmitter::tfrc_output(pktbuf* pb) { 
     456        cc_output_banner_top("tfrc"); 
     457        // move head pointer 
     458        head_ = pb->next; 
     459        // call Transmitter::output_data_only w/ XR reception 
     460        output_data_only(pb, XR_RECV); 
     461        cc_output_banner_bottom(); 
     462} 
     463 
     464void Transmitter::tfrc_output(bool recv_by_ch) { 
     465        cc_output_banner_top("tfrc"); 
     466        // head of the RTP data packet buffer 
     467        pktbuf* pb = head_; 
     468 
     469        // if pb is null, then set the next available packet as the first packet of 
     470        // the packet buffer. and then, return - i.e., do not try sending packets. 
     471        if (pb == 0) { 
     472                is_buf_empty_ = true; 
     473                return; 
     474        } 
     475 
     476        while ( pb != 0) { 
     477                // move head pointer 
     478                head_ = pb->next; 
     479                // call Transmitter::output(pb) 
     480                output(pb, recv_by_ch); 
     481 
     482                if (head_ != 0) { 
     483                        pb = head_; 
     484                } else { 
     485                        break; 
     486                } 
     487        } 
     488        cc_output_banner_bottom(); 
    457489} 
    458490 
  • vic/branches/cc/rtp/transmitter.h

    r4797 r4804  
    101101        void send(pktbuf*); 
    102102        inline bool is_cc_on() { return is_cc_active_; } 
     103        // TFWC output 
    103104        virtual void tfwc_output(bool recv_by_ch=0); 
    104105        virtual void tfwc_output(pktbuf*); 
    105106        virtual void cc_tfwc_trigger(pktbuf*); 
    106         void cc_tfrc_output(); 
     107        // TFRC output 
     108        virtual void tfrc_output(bool recv_by_ch=0); 
     109        virtual void tfrc_output(pktbuf*); 
    107110 
    108111        /*