00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "am.h"
00044 #include "mac.h"
00045 #include "flags.h"
00046 #include "random.h"
00047 #include "address.h"
00048 #include <iostream>
00049 #include <exception>
00050
00051 #ifndef NOW
00052 #define NOW (Scheduler::instance().clock())
00053 #endif
00054
00055
00056
00057
00058 static class AMRlcClass:public TclClass {
00059 public:
00060 AMRlcClass():TclClass("UMTS/RLC/AM") {
00061 }
00062 TclObject *create(int, const char *const *) {
00063 return (new AM);
00064 }
00065 } class_am;
00066
00067
00068 AM::AM():RLC(), sent_TTI_PDUs_(0), TTI_PDUs_(0), set_poll_(0), send_ack_(0),
00069 send_status_(0), SDU_size_(-1), dupacks_(0), rtt_seq_(-1),
00070 rtt_active_(0), prohibited_(0), FSN_(-1), b_bal_(0), maxseq_(-1),
00071 t_seqno_(0), highest_ack_(-1), maxseen_(-1), next_(0), tx_PDUs_before_poll(0),
00072 TTI_time_(-1), rtx_timer_(this, RLC_TIMER_RTX),
00073 poll_timer_((RLC *) this, RLC_TIMER_POLL), delsnd_timer_(this, RLC_TIMER_DELSND),
00074 stprob_timer_(this, RLC_TIMER_STPROB), tti_timer_(this, RLC_TIMER_TTI),
00075 mrwack_timer_(this, RLC_TIMER_MRWACK),
00076 address_(0), d_address_(0), MRW_delta(0),
00077 err_PDUs_(0), rx_PDUs_(0), rx_SDUs_(0), tot_PDUs_(0), ack_PDUs_(0), drop_PDUs_(0), drop_SDUs_(0)
00078 {
00079 bind("win_", &win_);
00080 bind_bw("maxRBSize_", &maxRBSize_);
00081 bind("ack_mode_", &ack_mode_);
00082 bind("poll_PDU_", &poll_PDU_);
00083 bind_time("rtx_timeout_", &rtx_timeout_);
00084 bind_time("poll_timeout_", &poll_timeout_);
00085 bind_time("overhead_", &overhead_);
00086 bind_time("stprob_timeout_", &stprob_timeout_);
00087 bind("noFastRetrans_", &noFastRetrans_);
00088 bind("numdupacks_", &numdupacks_);
00089 bind("payload_", &payload_);
00090 bind_bw("bandwidth_", &bandwidth_);
00091 bind_time("TTI_", &TTI_);
00092 bind("TTI_PDUs_", &TTI_PDUs_);
00093 bind("length_indicator_", &length_indicator_);
00094 bind("ack_pdu_header_", &ack_pdu_header_);
00095 bind("status_pdu_header_", &status_pdu_header_);
00096 bind("min_concat_data_", &min_concat_data_);
00097 bind_time("max_status_delay_", &max_status_delay_);
00098 bind_time("max_ack_delay_", &max_ack_delay_);
00099 bind("maxdat_", &maxdat_);
00100 bind("macDA_", &macDA_);
00101
00102 bind("tot_PDUs_",&tot_PDUs_);
00103 bind("err_PDUs_",&err_PDUs_);
00104 bind("ack_PDUs_",&ack_PDUs_);
00105 bind("ack_SDUs_",&ack_SDUs_);
00106 bind("drop_PDUs_",&drop_PDUs_);
00107 bind("drop_SDUs_",&drop_SDUs_);
00108 bind("sender_debug_",&sender_debug_);
00109 bind("receiver_debug_",&receiver_debug_);
00110
00111 memset(seen_, 0, sizeof(seen_));
00112
00113 seqno_ = -1;
00114
00115 tti_timer_.sched(TTI_ - 0.001);
00116
00117 set_poll_timer();
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 }
00128
00129 int AM::command(int argc, const char *const *argv)
00130 {
00131 if (argc == 2) {
00132 Tcl & tcl = Tcl::instance();
00133 if (strcmp(argv[1], "TTI") == 0) {
00134 tcl.resultf("%f", TTI_);
00135 return TCL_OK;
00136 } else if (strcmp(argv[1], "BW") == 0) {
00137 tcl.resultf("%f", bandwidth_);
00138 return TCL_OK;
00139 } else if (strcmp(argv[1], "start_TTI") == 0) {
00140 tti_timer_.sched(TTI_ - 0.001);
00141 TTI_PDUs_ = (int) (bandwidth_ * TTI_) / (payload_ * 8);
00142 return TCL_OK;
00143 }
00144 } else if (argc == 3) {
00145 if (strcmp(argv[1], "macDA") == 0) {
00146 macDA_ = atoi(argv[2]);
00147 return (TCL_OK);
00148 } else if (strcmp(argv[1], "addr") == 0) {
00149 address_ = Address::instance().str2addr(argv[2]);
00150 return (TCL_OK);
00151 } else if (strcmp(argv[1], "daddr") == 0) {
00152 d_address_ = Address::instance().str2addr(argv[2]);
00153 return (TCL_OK);
00154 }
00155 }
00156 return RLC::command(argc, argv);
00157 }
00158
00159 void AM::recv(Packet * p, Handler * h)
00160 {
00161 hdr_cmn *ch = HDR_CMN(p);
00162
00163
00164
00165
00166 if (ch->direction() == hdr_cmn::UP) {
00167
00168 if (ch->ptype() != PT_AM){
00169 drop(p);
00170 return;
00171 }
00172
00173 hdr_rlc *llh = hdr_rlc::access(p);
00174
00175 if (llh->dst() != address_ || ch->error() > 0) {
00176 assert(0);
00177 Packet::free(p);
00178
00179 return;
00180 }
00181
00182
00183 flowID_ = hdr_ip::access(p)->flowid();
00184
00185
00186 if (llh->lltype() & RLC_MRWACK) {
00187
00188 MRW_delta = std::max((FSN_ - llh->SN_MRW_ACK), 0);
00189
00190 if (sender_debug_)
00191 {
00192 cerr << NOW
00193 << " FSN_=" << FSN_
00194 << " llh->SN_MRW_ACK=" << llh->SN_MRW_ACK
00195 << " MRW_delta=" << MRW_delta
00196 << " t_seqno_=" << t_seqno_
00197 << " b_bal_=" << b_bal_
00198 << endl;
00199
00200 }
00201
00202
00203
00204 if (MRW_delta == 0)
00205 {
00206 mrwack_timer_.cancel();
00207 if(sender_debug_) cerr << "Receiver window moved (" << llh->SN_MRW_ACK << ")" << endl;
00208 }
00209 else
00210 {
00211 if(sender_debug_) cerr << "Receiver window moved (" << llh->SN_MRW_ACK
00212 << ") but not enough (" << FSN_ << ")" << endl;
00213 }
00214
00215 }
00216
00217 if (llh->lltype() & RLC_ACK) {
00218 if (llh->a_seqno() > highest_ack_) {
00219 newack(p);
00220 } else if (llh->a_seqno() == highest_ack_) {
00221 if (++dupacks_ == numdupacks_ && !noFastRetrans_) {
00222 reset_rtx_timer();
00223 }
00224 }
00225 }
00226
00227 if (llh->lltype() & RLC_BITMAP) {
00228 if (debug_) cerr << NOW << " received BITMAP SUFI" << endl;
00229 newback(p);
00230 }
00231
00232
00233 if (llh->lltype() & RLC_MRW) {
00234 if (next_ < llh->SN_MRW)
00235 {
00236 if (receiver_debug_)
00237 cerr << NOW << " Moving Receiver Window from "
00238 << next_ << " to " << llh->SN_MRW << endl;
00239
00240 next_ = llh->SN_MRW;
00241 sduB_.dropTill(next_-1);
00242 }
00243 else
00244 {
00245 if (receiver_debug_)
00246 cerr << NOW << " NOT moving Receiver Window to " << llh->SN_MRW
00247 << " since current RW is " << next_ << endl;
00248 }
00249 send_status_ |= SEND_STATUS_MRWACK;
00250 }
00251
00252
00253
00254 if (llh->lltype() & RLC_DATA)
00255 {
00256 if (debug_>2 ) cerr << NOW << "received data" << endl;
00257
00258 if ((receiver_debug_)&&(llh->seqno() >= next_ + win_))
00259 {
00260 cerr << NOW << " AM::recv()"
00261 << " llh->seqno=" << llh->seqno()
00262 << " next_=" << next_
00263 << " win_=" << win_
00264 << endl;
00265 }
00266
00267
00268
00269
00270 int numSDU = update(llh->seqno(), llh->eopno());
00271
00272 ack(p);
00273
00274
00275 if (llh->seqno() == llh->eopno() && numSDU >= 0)
00276 {
00277 sduB_.orderedEnque(p);
00278 }
00279 else
00280 {
00281 Packet::free(p);
00282 }
00283
00284 if (numSDU > 0) {
00285 makeSDU(numSDU);
00286 }
00287
00288 }
00289 else
00290 {
00291
00292
00293
00294
00295 Packet::free(p);
00296 }
00297
00298
00299 } else {
00300 ch->direction() = hdr_cmn::DOWN;
00301 sendDown(p);
00302 }
00303
00304 }
00305
00306 bool AM::chk_size(Packet * p)
00307 {
00308 hdr_rlc *llh = hdr_rlc::access(p);
00309
00310
00311 int size = 0;
00312
00313 size += llh->lengthInd_;
00314 size += llh->payload_[0];
00315 size += llh->payload_[1];
00316 size += llh->payload_[2];
00317 size += llh->padding_;
00318
00319 if (size != payload_)
00320 std::cerr << "AM::chk_size(p) size=" << size
00321 << "payload_=" << payload_ << std::endl;
00322
00323 return size == payload_;
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 }
00337
00338
00339
00340 void AM::sendDown(Packet * p)
00341 {
00342 if ((rcvB_.size() + hdr_cmn::access(p)->size()) <= maxRBSize_) {
00343 rcvB_.enque(p);
00344 } else {
00345
00346
00347 cerr << "AM::sendDown(p) queue full, packet dropped" << endl;
00348 drop(p);
00349 }
00350
00351
00352 }
00353
00354
00355
00356 Packet *AM::makePDU(int PB_bytes)
00357 {
00358 hdr_cmn *ch;
00359 hdr_ip *iph;
00360 hdr_tcp *tcph;
00361 hdr_rlc *llh;
00362 char *mh;
00363
00364
00365 int available = payload_;
00366 int concat_data = 0;
00367 int end_PDU = 0;
00368 int padding = 0;
00369 int force_length_indicator = 0;
00370
00371 Packet *c;
00372
00373
00374
00375 Packet *p = rcvB_.dequeCopy();
00376
00377
00378 if (PB_bytes != 0)
00379 {
00380 available = payload_ - ((length_indicator_ + 1) / 8) - PB_bytes;
00381 if (hdr_cmn::access(p)->size() <= available)
00382 {
00383 end_PDU = 1;
00384 concat_data = available - hdr_cmn::access(p)->size()
00385 - ((length_indicator_ + 1) / 8);
00386 padding = available - hdr_cmn::access(p)->size();
00387
00388 }
00389 }
00390 else if (hdr_cmn::access(p)->size() < available)
00391 {
00392 if (hdr_cmn::access(p)->size() <=
00393 available - ((length_indicator_ + 1) / 8))
00394 {
00395 end_PDU = 1;
00396 concat_data = available - hdr_cmn::access(p)->size()
00397 - (2 * ((length_indicator_ + 1) / 8));
00398 padding = available - hdr_cmn::access(p)->size()
00399 - ((length_indicator_ + 1) / 8);
00400 }
00401 force_length_indicator = 1;
00402 }
00403 else if (hdr_cmn::access(p)->size() == available)
00404 {
00405 end_PDU = 1;
00406 }
00407 if (concat_data < min_concat_data_ || (rcvB_.size(2) <= concat_data))
00408 {
00409 concat_data = 0;
00410 }
00411 else
00412 {
00413 padding = 0;
00414 }
00415 if (end_PDU)
00416 {
00417
00418
00419
00420 Packet *temp = rcvB_.deque();
00421 Packet::free(temp);
00422
00423 c = p;
00424 ch = HDR_CMN(c);
00425 llh = hdr_rlc::access(c);
00426
00427 llh->lptype() = ch->ptype();
00428 llh->lerror_ = ch->error();
00429 llh->lts_ = ch->timestamp();
00430
00431 if (SDU_size_ > 0) {
00432 llh->lsize_ = SDU_size_;
00433 } else {
00434 llh->lsize_ = ch->size();
00435 }
00436
00437 SDU_size_ = -1;
00438
00439 llh->lltype() = RLC_DATA;
00440 llh->seqno_ = ++seqno_;
00441 llh->eopno_ = llh->seqno_;
00442 llh->dst() = d_address_;
00443 llh->src() = address_;
00444 llh->lengthInd_ = 0;
00445
00446 if (PB_bytes || concat_data || padding || force_length_indicator) {
00447 llh->lengthInd_++;
00448 }
00449
00450 for (int i = 1; i < 3; i++) {
00451 llh->payload_[i] = 0;
00452 }
00453
00454 llh->payload_[0] = hdr_cmn::access(c)->size();
00455
00456 if (concat_data) {
00457 llh->lengthInd_++;
00458 llh->payload_[1] = concat_data;
00459
00460 if (PB_bytes != 0) {
00461 llh->padding_ = PB_bytes;
00462 } else {
00463 llh->padding_ = 0;
00464 }
00465 SDU_size_ = rcvB_.red_size(concat_data);
00466 } else if (PB_bytes != 0) {
00467 llh->padding_ = PB_bytes + padding;
00468 } else {
00469 llh->padding_ = padding;
00470 }
00471 ch->ptype() = PT_AM;
00472 ch->error() = 0;
00473 ch->timestamp() = Scheduler::instance().clock();
00474 ch->size() = payload_;
00475
00476 mh = (char *) c->access(hdr_mac::offset_);
00477 struct hdr_mac *dh = (struct hdr_mac *) mh;
00478
00479 dh->macDA_ = macDA_;
00480 dh->macSA_ = -1;
00481 dh->hdr_type() = ETHERTYPE_RLC;
00482
00483 }
00484 else
00485 {
00486 if (SDU_size_ < 0) {
00487 SDU_size_ = hdr_cmn::access(p)->size();
00488 }
00489 c = allocpkt(hdr_cmn::access(p)->uid());
00490 ch = HDR_CMN(c);
00491 iph = hdr_ip::access(c);
00492 tcph = hdr_tcp::access(c);
00493 llh = hdr_rlc::access(c);
00494 hdr_ip *piph = hdr_ip::access(p);
00495 hdr_tcp *ptcph = hdr_tcp::access(p);
00496 hdr_flags *phf = hdr_flags::access(p);
00497
00498 llh->lltype() = RLC_DATA;
00499 llh->seqno_ = ++seqno_;
00500 llh->eopno_ = -1;
00501 llh->dst() = d_address_;
00502 llh->src() = address_;
00503 llh->padding_ = 0;
00504 llh->lengthInd_ = 0;
00505
00506 if (PB_bytes || force_length_indicator) {
00507 llh->lengthInd_++;
00508 }
00509
00510 for (int i = 1; i < 3; i++) {
00511 llh->payload_[i] = 0;
00512 }
00513 if (force_length_indicator) {
00514 llh->payload_[0] = payload_ - ((length_indicator_ + 1) / 8);
00515 } else if (PB_bytes != 0) {
00516 llh->payload_[0] = payload_ - ((length_indicator_ + 1) / 8) - PB_bytes;
00517 llh->padding_ = PB_bytes;
00518 } else {
00519 llh->payload_[0] = payload_;
00520 }
00521
00522
00523
00524
00525
00526
00527
00528 rcvB_.red_size(llh->payload_[0]);
00529
00530 ch->ptype() = PT_AM;
00531 ch->size() = payload_;
00532
00533 iph->flowid() = piph->flowid();
00534 iph->saddr() = piph->saddr();
00535 iph->sport() = piph->sport();
00536 iph->daddr() = piph->daddr();
00537 iph->dport() = piph->dport();
00538 iph->ttl() = piph->ttl();
00539
00540 tcph->seqno() = ptcph->seqno();
00541
00542 hdr_flags *hf = hdr_flags::access(c);
00543
00544 hf->ecn_ = phf->ecn_;
00545 hf->cong_action_ = phf->cong_action_;
00546 hf->ecn_to_echo_ = phf->ecn_to_echo_;
00547 hf->fs_ = phf->fs_;
00548 hf->ecn_capable_ = phf->ecn_capable_;
00549
00550 mh = (char *) c->access(hdr_mac::offset_);
00551 struct hdr_mac *dh = (struct hdr_mac *) mh;
00552
00553 dh->macDA_ = macDA_;
00554 dh->macSA_ = -1;
00555 dh->hdr_type() = ETHERTYPE_RLC;
00556
00557
00558
00559
00560
00561 Packet::free(p);
00562 }
00563
00564 assert(llh == hdr_rlc::access(c));
00565 assert(llh->seqno_ >= FSN_);
00566 eopno_[(llh->seqno_) & MWM] = llh->eopno_;
00567
00568 return c;
00569 }
00570
00571
00572
00573
00574
00575 int AM::PB_S_PDU()
00576 {
00577 int position = 0;
00578
00579 if ((payload_ - StatusPDUSize() - (2 * ((length_indicator_ + 1) / 8)))
00580 < min_concat_data_) {
00581 return 0;
00582
00583 }
00584 if (t_seqno_ > highest_ack_ + win_ - b_bal_ - MRW_delta) {
00585 return 0;
00586
00587 }
00588
00589
00590
00591 for (int i = 1; i <= b_bal_; i++) {
00592
00593 Packet *p = rxtB_.dequeCopy(bRxtSeq(i));
00594
00595 if ((debug_ >1)&&(!p)) {
00596 cerr << "FSN_=" << FSN_
00597 << " bitmap_["<<length_<<"]:";
00598 for (int j=0; j<length_; j++)
00599 cerr << seen_[j];
00600 cerr<<endl;
00601 for (int j=0; j<i; j++) {
00602 cerr << "bRxtSeq(" << j <<")=" <<bRxtSeq(j)
00603 << " corresponding sn in rxtB_ queue: " ;
00604 if (Packet *q = rxtB_.dequeCopy(bRxtSeq(i)))
00605 {
00606 cerr << hdr_rlc::access(q)->seqno() << " "
00607 << hdr_rlc::access(q)->a_seqno()
00608 << endl;
00609 Packet::free(q);
00610 }
00611 else
00612 cerr << "NULL" << endl;
00613 }
00614 rxtB_.dump();
00615
00616 }
00617
00618 assert(p);
00619 if (S_Piggybackable(p)) {
00620 Packet::free(p);
00621 return ++position;
00622 }
00623 position++;
00624 Packet::free(p);
00625 }
00626
00627 if (rcvB_.size() != 0) {
00628 return ++position;
00629 }
00630 return 0;
00631 }
00632
00633
00634 int AM::PB_PA_PDU()
00635 {
00636 int position = 0;
00637
00638 if (payload_ - AckPDUSize() - (2 * ((length_indicator_ + 1) / 8)) <
00639 min_concat_data_) {
00640 return 0;
00641 } else if (t_seqno_ > highest_ack_ + win_) {
00642 return 0;
00643 } else if (t_seqno_ <= maxseq_) {
00644 for (int i = t_seqno_; i <= maxseq_; i++) {
00645 Packet *p = rxtB_.dequeCopy(i);
00646
00647 if (PA_Piggybackable(p)) {
00648 Packet::free(p);
00649 return ++position;
00650 }
00651 position++;
00652 Packet::free(p);
00653 }
00654 }
00655
00656 if (rcvB_.size() != 0) {
00657 return ++position;
00658 }
00659 return 0;
00660 }
00661
00662
00663 bool AM::PA_Piggybackable(Packet * p)
00664 {
00665 if (hdr_rlc::access(p)->padding()) {
00666 if (hdr_rlc::access(p)->padding() >=
00667 (AckPDUSize() + ((length_indicator_ + 1) / 8))) {
00668 return true;
00669 }
00670 }
00671 return false;
00672 }
00673
00674
00675 int AM::AckPDUSize()
00676 {
00677 int bytes;
00678
00679 if (ack_pdu_header_ % 8) {
00680 bytes = ack_pdu_header_ / 8 + 1;
00681 } else {
00682 bytes = ack_pdu_header_ / 8;
00683 }
00684 return bytes;
00685 }
00686
00687
00688 bool AM::S_Piggybackable(Packet * p)
00689 {
00690 if (hdr_rlc::access(p)->padding()) {
00691 if (hdr_rlc::access(p)->padding() >=
00692 (StatusPDUSize() + ((length_indicator_ + 1) / 8))) {
00693 return true;
00694 }
00695 }
00696 return false;
00697 }
00698
00699
00700
00701 int AM::StatusPDUSize()
00702 {
00703
00704
00705 int bits = 1 + 4;
00706
00707 if (send_status_ & SEND_STATUS_BITMAP) {
00708 bits += SUFI_bitmap_size();
00709 }
00710
00711 if (send_status_ & SEND_STATUS_MRW) {
00712 bits += SUFI_mrw_size();
00713 }
00714
00715 int bytes;
00716 if (bits % 8) {
00717 bytes = bits / 8 + 1;
00718 } else {
00719 bytes = bits / 8;
00720 }
00721
00722 return bytes;
00723 }
00724
00725
00726
00727
00728 int AM::SUFI_bitmap_size()
00729 {
00730 int first_missing = next_;
00731
00732 while (seen_[first_missing & MWM]) {
00733 ++first_missing;
00734 }
00735
00736 int fsn = first_missing - 1;
00737
00738 int bitmapoctets = ((maxseen_-fsn)/8) +1;
00739 assert(bitmapoctets>0);
00740 if (bitmapoctets>16)
00741 bitmapoctets = 16;
00742
00743
00744 return ( 4 + 12 + bitmapoctets*8);
00745
00746 }
00747
00748
00749
00750 int AM::SUFI_mrw_size()
00751 {
00752
00753 return ( 4 + 4 + 12 + 4);
00754
00755
00756
00757
00758
00759 }
00760
00761
00762
00763
00764 double AM::send_time(int position)
00765 {
00766 int PDUs_left_in_current_TTI = TTI_PDUs_ - sent_TTI_PDUs_;
00767 int i = 0;
00768
00769 while (1) {
00770 if (position <= (i * TTI_PDUs_ + PDUs_left_in_current_TTI)) {
00771 return (tti_timer_.timeOfExpiry() + TTI_ * i);
00772 }
00773 i++;
00774 }
00775 }
00776
00777
00778
00779
00780
00781 void AM::send_much(int force)
00782 {
00783 Packet *p = NULL;
00784
00785 if (!force && delsnd_timer_.status() == TIMER_PENDING) {
00786 return;
00787 }
00788
00789
00790
00791 while (((t_seqno_ < FSN_ + win_ - b_bal_ - MRW_delta)
00792 || set_poll_ || send_status_ || send_ack_)) {
00793
00794 if (debug_>2) cerr << NOW << " New send_much() cycle" << endl;
00795
00796
00797 if ((rcvB_.size() == 0) && (b_bal_ == 0)
00798 && (!set_poll_) && (!send_status_)
00799 && (!send_ack_) && (t_seqno_ > maxseq_)) {
00800 sent_TTI_PDUs_ = 0;
00801 return;
00802
00803 } else if (sent_TTI_PDUs_ == TTI_PDUs_) {
00804 sent_TTI_PDUs_ = 0;
00805 return;
00806 }
00807
00808 if (debug_>2) cerr << "send_status_ " << hex << send_status_ << dec << endl;
00809
00810
00811 if (overhead_ == 0 || force)
00812 {
00813
00814 if (send_status_) {
00815 int position = PB_S_PDU();
00816 if (position && ((send_time(position) - earliest_status_send_)
00817 <= max_status_delay_)) {
00818
00819
00820 } else {
00821 Packet *pkt = make_status(NULL);
00822 sent_TTI_PDUs_++;
00823 send_status_ = SEND_STATUS_NONE;
00824 set_status_prohibit_timer();
00825 downtarget_->recv(pkt);
00826 delsnd_timer_.resched(Random::uniform(overhead_));
00827 return;
00828 }
00829
00830 } else if (send_ack_) {
00831 int position = PB_PA_PDU();
00832 if (position && ((send_time(position) - earliest_ack_send_)
00833 <= max_ack_delay_)) {
00834
00835 } else {
00836 Packet *pkt = make_positive_ack(NULL);
00837 sent_TTI_PDUs_++;
00838 send_ack_ = 0;
00839 downtarget_->recv(pkt);
00840 delsnd_timer_.resched(Random::uniform(overhead_));
00841 return;
00842 }
00843 }
00844
00845
00846 int force_set_rtx_timer = 0;
00847
00848 if (set_poll_ && (rcvB_.size() == 0) && (b_bal_ == 0))
00849 {
00850
00851
00852 return;
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 }
00870 else if (b_bal_ != 0)
00871 {
00872
00873 int sn = bRxtSeq(0);
00874 txcount_[sn & MWM]++ ;
00875 p = rxtB_.dequeCopy(sn);
00876 if ((debug_ >1)&&(!p))
00877 {
00878 cerr << "FSN_=" << FSN_ << "sn=" <<sn <<endl;
00879 cerr << " bitmap_[]:";
00880 for (int j=0; j<length_; j++)
00881 cerr << seen_[j];
00882 cerr<<endl;
00883 for (int j=0; j<100; j++)
00884 cerr << "bRxtSeq(" << j <<")=" <<bRxtSeq(j)<<endl;
00885 cerr<<endl;
00886 }
00887 assert(p);
00888 if (send_status_ && S_Piggybackable(p)) {
00889 make_status(p);
00890 set_status_prohibit_timer();
00891 send_status_ = SEND_STATUS_NONE;
00892 }
00893 b_bal_--;
00894
00895
00896 if (b_bal_ == 0) {
00897 set_poll_ = 1;
00898 }
00899 }
00900 else if (t_seqno_ > maxseq_)
00901 {
00902
00903
00904
00905 if ((sender_debug_)&&(t_seqno_ >= FSN_ + win_ - MRW_delta))
00906 {
00907 cerr << NOW << " AM::send_much()"
00908 << " t_seqno_=" << t_seqno_
00909 << " FSN_=" << FSN_
00910 << " highest_ack_=" << highest_ack_
00911 << " win_=" << win_
00912 << " MRW_delta=" << MRW_delta
00913 << endl;
00914
00915 return;
00916 }
00917
00918 if (send_status_) {
00919 p = makePDU(StatusPDUSize()
00920 + ((length_indicator_ + 1) / 8));
00921 } else if (send_ack_) {
00922 p = makePDU(AckPDUSize()
00923 + ((length_indicator_ + 1) / 8));
00924 } else {
00925 p = makePDU(0);
00926 }
00927 assert(p);
00928
00929
00930
00931 rxtB_.enque(p->copy());
00932
00933 if (send_status_) {
00934 make_status(p);
00935 set_status_prohibit_timer();
00936 send_status_ = SEND_STATUS_NONE;
00937 } else if (send_ack_) {
00938 make_positive_ack(p);
00939 send_ack_ = 0;
00940 }
00941
00942 assert(t_seqno_ == hdr_rlc::access(p)->seqno());
00943 txcount_[t_seqno_ & MWM] = 1;
00944
00945
00946
00947 if (rcvB_.size() == 0) {
00948 set_poll_ = 1;
00949 }
00950 if (highest_ack_ == maxseq_) {
00951 force_set_rtx_timer = 1;
00952 }
00953 maxseq_ = t_seqno_;
00954 t_seqno_++;
00955 }
00956 else
00957 {
00958 if (t_seqno_ !=0)
00959 std::cerr << "AM::send_much() maxseq_=" << maxseq_
00960 << " t_seqno_" << t_seqno_
00961 << std::endl;;
00962 return;
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972 }
00973
00974 assert(p);
00975 tx_PDUs_before_poll++;
00976 tot_PDUs_++;
00977
00978 if (ack_mode_ == 1)
00979 {
00980
00981 assert(0);
00982 set_poll_ = 0;
00983 if (!rtt_active_) {
00984 rtt_active_ = 1;
00985 if (t_seqno_ > rtt_seq_) {
00986 rtt_seq_ = t_seqno_;
00987 }
00988 }
00989 if (!(rtx_timer_.status() == TIMER_PENDING)
00990 || force_set_rtx_timer) {
00991 set_rtx_timer();
00992
00993 }
00994 }
00995 else if (ack_mode_ == 2)
00996 {
00997
00998
00999 if ((poll_PDU_ > 0)&&(tx_PDUs_before_poll >= poll_PDU_))
01000 {
01001 set_poll_ = 1;
01002
01003 }
01004
01005 if (set_poll_)
01006 {
01007 hdr_rlc::access(p)->poll() = true;
01008
01009 set_poll_ = 0;
01010 tx_PDUs_before_poll = 0;
01011 set_poll_timer();
01012
01013 if (sender_debug_)
01014 cerr << NOW << " AM::send_much() sending POLL" << endl;
01015 }
01016 }
01017
01018
01019 sent_TTI_PDUs_++;
01020 downtarget_->recv(p);
01021 delsnd_timer_.resched(Random::uniform(overhead_));
01022 return;
01023 } else if (!(delsnd_timer_.status() == TIMER_PENDING)) {
01024
01025
01026
01027 delsnd_timer_.resched(Random::uniform(overhead_));
01028 return;
01029 }
01030
01031 }
01032 sent_TTI_PDUs_ = 0;
01033 }
01034
01035
01036
01037
01038
01039
01040 int AM::update(int seq, int eopno)
01041 {
01042 int numSDU = 0;
01043
01044
01045 bool just_marked_as_seen = false;
01046
01047
01048 if (receiver_debug_)
01049 cerr << NOW << " AM::update(" << seq << "," << eopno << ")"
01050 << " MWM=" << MWM
01051 << " maxseen_=" << maxseen_
01052 << " next_=" << next_ ;
01053
01054
01055 if (seq - next_ >= MWM) {
01056
01057
01058
01059
01060
01061 if (receiver_debug_)
01062 cerr << " MWM" << endl;
01063
01064 return -1;
01065 }
01066
01067 if (seq < next_) {
01068
01069
01070
01071
01072 if (receiver_debug_)
01073 cerr << " LEFT" << endl;
01074
01075 return -1;
01076 }
01077
01078 if (seq > maxseen_) {
01079
01080 int i;
01081
01082
01083
01084
01085 for (i = maxseen_ + 1; i < seq; ++i) {
01086 seen_[i & MWM] = 0;
01087 if (receiver_debug_)
01088 cerr << " U" ;
01089 }
01090
01091
01092
01093 if (seq == eopno) {
01094 seen_[seq & MWM] = 1;
01095 } else {
01096 seen_[seq & MWM] = 2;
01097 }
01098
01099
01100
01101 seen_[(seq + 1) & MWM] = 0;
01102
01103
01104 maxseen_ = seq;
01105
01106
01107 just_marked_as_seen = true;
01108
01109 } else {
01110
01111 assert(seq >= next_ && seq <= maxseen_);
01112
01113
01114
01115
01116
01117
01118 if (seen_[seq & MWM] && !just_marked_as_seen) {
01119
01120
01121
01122 return -1;
01123 }
01124
01125
01126 if (seq == eopno) {
01127 seen_[seq & MWM] = 1;
01128 } else {
01129 seen_[seq & MWM] = 2;
01130 }
01131
01132 }
01133
01134 if (receiver_debug_)
01135 cerr << " seen_[next_]=" << seen_[next_ & MWM]
01136 << " seen_:";
01137
01138 while (seen_[next_ & MWM] > 0) {
01139
01140
01141
01142 if (receiver_debug_)
01143 cerr << " " << next_ ;
01144
01145
01146
01147 if ((seen_[next_ & MWM] == 1)) {
01148
01149
01150
01151 numSDU++;
01152
01153 if (receiver_debug_)
01154 cerr << " S";
01155 }
01156
01157
01158 next_++;
01159 }
01160
01161
01162 if (receiver_debug_)
01163 cerr << " numSDU=" << numSDU << endl;
01164
01165
01166 return numSDU;
01167 }
01168
01169
01170
01171
01172
01173 void AM::newack(Packet * pkt)
01174 {
01175 hdr_rlc *llh = hdr_rlc::access(pkt);
01176
01177 dupacks_ = 0;
01178 highest_ack_ = llh->a_seqno();
01179
01180
01181 rxtB_.dropTill(highest_ack_);
01182
01183 if (t_seqno_ < highest_ack_ + 1) {
01184 t_seqno_ = highest_ack_ + 1;
01185 }
01186 if (rtt_active_ && llh->a_seqno() >= rtt_seq_) {
01187 rtt_active_ = 0;
01188 }
01189
01190
01191 if (llh->a_seqno() < maxseq_) {
01192 set_rtx_timer();
01193 } else {
01194 cancel_rtx_timer();
01195 }
01196 }
01197
01198
01199
01200
01201
01202 void AM::newback(Packet * pkt)
01203 {
01204 hdr_rlc *llh = hdr_rlc::access(pkt);
01205
01206 b_bal_ = 0;
01207 length_ = llh->length();
01208
01209 if (FSN_ > llh->FSN()) {
01210
01211
01212 return;
01213 }
01214
01215 ackSDU(FSN_, llh->FSN());
01216 FSN_ = llh->FSN();
01217 rxtB_.dropTill(FSN_);
01218
01219
01220 if (sender_debug_)
01221 {
01222 cerr << NOW << " AM::newback()"
01223 << " FSN_=" << FSN_
01224 << " llh->FSN=" << llh->FSN()
01225 << " MRW_delta=" << MRW_delta
01226 << " t_seqno_=" << t_seqno_
01227 << " b_bal_=" << b_bal_
01228 << endl;
01229 }
01230
01231 if (debug_ > 1) {
01232 cerr << NOW << " AM::newback() Queue after pruning:";
01233 rxtB_.dump();
01234 }
01235
01236
01237 assert(highest_ack_ <= FSN_ + length_ - 1);
01238
01239
01240 highest_ack_ = FSN_ + length_ - 1;
01241
01242
01243 if (debug_) cerr << NOW << " processing BITMAP acknowledgement " << endl;
01244
01245
01246 assert(length_<=BITMAP_LENGTH);
01247 for (int i = 0; i < length_; i++) {
01248 bitmap_[i] = llh->bitmap(i);
01249 }
01250
01251
01252 if (debug_ >1) {
01253 cerr << NOW << " AM::newback()"
01254 << " FSN_=" << FSN_
01255 << " length_=" << length_
01256 << " bitmap_[]:"
01257 << endl;
01258 for (int j=0; j<length_; j++)
01259 cerr << bitmap_[j];
01260 cerr<<endl;
01261 }
01262
01263
01264 int dropsn[length_];
01265 for (int j=0; j<length_; j++ )
01266 dropsn[j] = -1;
01267
01268 int ndropped=0;
01269
01270 for (int i = 0; i < length_; i++) {
01271 if (bitmap_[i] == 0)
01272 {
01273 err_PDUs_++;
01274 if (txcount_[(FSN_ + i) & MWM] == maxdat_)
01275 {
01276 dropsn[ndropped] = FSN_+i;
01277 ndropped++;
01278 }
01279 else
01280 {
01281 b_bal_++;
01282 }
01283 }
01284 else {
01285
01286 Packet *r = rxtB_.deque(FSN_ + i);
01287 if (r) Packet::free(r);
01288
01289 }
01290 }
01291
01292
01293
01294 for (int j=0; j<ndropped; j++) {
01295 if (debug_ > 1) {
01296 cerr << NOW << " AM::newback() Current queue: ";
01297 rxtB_.dump();
01298 }
01299 discardSDU(dropsn[j]);
01300
01301 rxtB_.dropTill(FSN_);
01302 if (debug_ > 1) {
01303 cerr << NOW << " AM::newback() Queue after pruning:";
01304 rxtB_.dump();
01305 }
01306 }
01307
01308
01309 assert(t_seqno_ > highest_ack_);
01310
01311
01312 }
01313
01314
01315 int AM::bRxtSeq(int position)
01316 {
01317 int counter = 0;
01318
01319 for (int i = 0; i < length_; i++) {
01320 if (bitmap_[i] == 0) {
01321 counter++;
01322 if (position == 0) {
01323 bitmap_[i] = 1;
01324
01325
01326 return (i + FSN_);
01327 } else if (counter == position) {
01328
01329 return (i + FSN_);
01330 }
01331 }
01332 }
01333 return -1;
01334 }
01335
01336
01337 void AM::ack(Packet * opkt)
01338 {
01339 int first_missing = next_;
01340
01341 while (seen_[first_missing & MWM]) {
01342 ++first_missing;
01343 }
01344 if (ack_mode_ == 1) {
01345
01346 if (send_ack_ == 1) {
01347
01348 } else {
01349 if (delsnd_timer_.status() == TIMER_PENDING
01350 && sent_TTI_PDUs_ < TTI_PDUs_) {
01351 earliest_ack_send_ = tti_timer_.timeOfExpiry();
01352 } else {
01353 earliest_ack_send_ = tti_timer_.timeOfExpiry() + TTI_;
01354 }
01355 send_ack_ = 1;
01356 }
01357 } else if (ack_mode_ == 2) {
01358 if (prohibited_) {
01359 return;
01360 }
01361
01362
01363 if (stprob_timer_.status() == TIMER_PENDING) {
01364 if (hdr_rlc::access(opkt)->poll()) {
01365 prohibited_ = 1;
01366 }
01367 return;
01368 }
01369
01370 if (first_missing < maxseen_ || hdr_rlc::access(opkt)->poll()) {
01371 if (send_status_ & SEND_STATUS_BITMAP) {
01372
01373 } else {
01374 if (delsnd_timer_.status()
01375 == TIMER_PENDING && sent_TTI_PDUs_ < TTI_PDUs_) {
01376 earliest_status_send_ = tti_timer_.timeOfExpiry();
01377 } else {
01378 earliest_status_send_ = tti_timer_.timeOfExpiry() + TTI_;
01379 }
01380 send_status_ |= SEND_STATUS_BITMAP;
01381 }
01382 }
01383 }
01384 }
01385
01386
01387 Packet *AM::make_positive_ack(Packet * p)
01388 {
01389 Packet *npkt;
01390 hdr_rlc *nrlc;
01391 hdr_cmn *nch;
01392
01393 assert(0);
01394
01395
01396
01397
01398
01399
01400
01401 int first_missing = next_;
01402
01403 while (seen_[first_missing & MWM]) {
01404 ++first_missing;
01405 }
01406
01407 if (p == NULL) {
01408 npkt = allocpkt(0);
01409 nrlc = hdr_rlc::access(npkt);
01410 nch = hdr_cmn::access(npkt);
01411 hdr_ip *niph = hdr_ip::access(npkt);
01412 hdr_tcp *ntcp = hdr_tcp::access(npkt);
01413
01414 nrlc->lltype() = RLC_ACK;
01415 nrlc->dst() = d_address_;
01416 nrlc->src() = address_;
01417 nrlc->a_seqno() = first_missing - 1;
01418 nrlc->seqno() = nrlc->a_seqno();
01419 nrlc->lengthInd_ = 0;
01420 nrlc->padding_ = payload_ - AckPDUSize();
01421
01422 for (int i = 1; i < 3; i++) {
01423 nrlc->payload_[i] = 0;
01424 }
01425
01426 nrlc->payload_[0] = AckPDUSize();
01427
01428
01429 nch->ptype() = PT_AM;
01430 nch->size() = payload_;
01431
01432 niph->flowid() = -1;
01433 niph->saddr() = -1;
01434 niph->sport() = -1;
01435 niph->daddr() = -1;
01436 niph->dport() = -1;
01437 niph->ttl() = 32;
01438
01439 ntcp->seqno() = -1;
01440
01441 char *mh = (char *) npkt->access(hdr_mac::offset_);
01442 struct hdr_mac *dh = (struct hdr_mac *) mh;
01443
01444 dh->macDA_ = macDA_;
01445 dh->macSA_ = -1;
01446 dh->hdr_type() = ETHERTYPE_RLC;
01447
01448 return npkt;
01449 }
01450 npkt = p;
01451
01452 nrlc = hdr_rlc::access(npkt);
01453 nch = hdr_cmn::access(npkt);
01454
01455 nrlc->lengthInd_++;
01456 nrlc->padding_ = nrlc->padding_ - AckPDUSize()
01457 - ((length_indicator_ + 1) / 8);
01458 nrlc->payload_[nrlc->lengthInd_ - 1] = AckPDUSize();
01459
01460 nrlc->a_seqno() = first_missing - 1;
01461
01462
01463
01464 nch->size() = payload_;
01465 nch->ptype() = PT_AM;
01466
01467 return npkt;
01468 }
01469
01470
01471
01472 Packet *AM::make_status(Packet * p)
01473 {
01474 Packet *npkt;
01475 hdr_rlc *nllh;
01476 hdr_cmn *nch;
01477
01478
01479
01480 if (p == NULL) {
01481
01482
01483 npkt = allocpkt(0);
01484
01485 nllh = hdr_rlc::access(npkt);
01486 nch = hdr_cmn::access(npkt);
01487 hdr_ip *niph = hdr_ip::access(npkt);
01488 hdr_tcp *ntcp = hdr_tcp::access(npkt);
01489 char *mh = (char *) npkt->access(hdr_mac::offset_);
01490
01491 nllh->lltype() = RLC_STATUS;
01492 nllh->dst() = d_address_;
01493 nllh->src() = address_;
01494 nllh->seqno() = -1;
01495 nllh->lengthInd_ = 0;
01496 nllh->padding_ = payload_ - StatusPDUSize();
01497
01498 for (int i = 1; i < 3; i++) {
01499 nllh->payload_[i] = 0;
01500 }
01501
01502 nllh->payload_[0] = StatusPDUSize();
01503
01504 niph->flowid() = flowID_;
01505 niph->saddr() = -1;
01506 niph->sport() = -1;
01507 niph->daddr() = -1;
01508 niph->dport() = -1;
01509 niph->ttl() = 32;
01510
01511 ntcp->seqno() = -1;
01512
01513 nch->ptype() = PT_AM;
01514 nch->size() = payload_;
01515
01516 struct hdr_mac *dh = (struct hdr_mac *) mh;
01517
01518 dh->macDA_ = macDA_;
01519 dh->macSA_ = -1;
01520 dh->hdr_type() = ETHERTYPE_RLC;
01521
01522 } else {
01523
01524
01525 npkt = p;
01526
01527 nch = hdr_cmn::access(npkt);
01528 nllh = hdr_rlc::access(npkt);
01529
01530 nch->ptype() = PT_AM;
01531
01532 nllh->lengthInd_++;
01533 nllh->padding_ = nllh->padding_ - StatusPDUSize()
01534 -((length_indicator_ + 1) / 8);
01535 nllh->payload_[nllh->lengthInd_ - 1] = StatusPDUSize();
01536 }
01537
01538
01539
01540 if (send_status_ & SEND_STATUS_BITMAP) make_bitmap_SUFI(npkt);
01541 if (send_status_ & SEND_STATUS_MRW) make_mrw_SUFI(npkt);
01542 if (send_status_ & SEND_STATUS_MRWACK) make_mrwack_SUFI(npkt);
01543
01544 return npkt;
01545 }
01546
01547
01548
01549 Packet *AM::make_bitmap_SUFI(Packet * p)
01550 {
01551 Packet *npkt;
01552 hdr_rlc *nllh;
01553 hdr_cmn *nch;
01554
01555 int first_missing = next_;
01556
01557 while (seen_[first_missing & MWM]) {
01558 ++first_missing;
01559 }
01560
01561 int fsn = first_missing - 1;
01562
01563 if (fsn < 0) {
01564
01565
01566 fsn = 0;
01567 }
01568
01569 npkt = p;
01570 nllh = hdr_rlc::access(npkt);
01571 nch = hdr_cmn::access(npkt);
01572
01573 nllh->lltype() |= RLC_BITMAP;
01574
01575
01576 nllh->FSN() = fsn;
01577
01578
01579
01580
01581
01582 nllh->length() = std::min(maxseen_ - fsn + 1, BITMAP_LENGTH);
01583
01584 if (debug_) cerr << NOW << " AM::make_bitmap_SUFI() adding BITMAP SUFI: "
01585 << hex << nllh->lltype() << dec
01586 << " length_:" << maxseen_ << "-"
01587 << fsn << "+1=" << nllh->length()
01588 << endl;
01589 if (debug_>1) {
01590 cerr << NOW << " AM::make_bitmap_SUFI() seen_[]:" << endl;
01591 for (int j=fsn; j<=maxseen_; j++)
01592 cerr << seen_[j];
01593 cerr<<endl;
01594 }
01595
01596
01597 for (int i = 0; i < nllh->length(); i++) {
01598 if (seen_[(fsn + i) & MWM])
01599 nllh->setbitmap(i);
01600 }
01601
01602
01603 if (debug_>1) {
01604 cerr << NOW << " AM::make_bitmap_SUFI() bitmap:"<< endl;
01605 for (int j=0; j<nllh->length(); j++)
01606 cerr << nllh->bitmap(j);
01607 cerr<<endl;
01608 }
01609
01610
01611
01612 return npkt;
01613 }
01614
01615
01616
01617
01618
01619 Packet *AM::make_mrw_SUFI(Packet * p)
01620 {
01621 hdr_rlc *nllh;
01622
01623 nllh = hdr_rlc::access(p);
01624 nllh->lltype() |= RLC_MRW;
01625 nllh->SN_MRW = FSN_;
01626
01627
01628 mrwack_timer_.resched(rtx_timeout_);
01629
01630 return p;
01631 }
01632
01633
01634
01635
01636 Packet *AM::make_mrwack_SUFI(Packet * p)
01637 {
01638 hdr_rlc *nllh;
01639
01640 nllh = hdr_rlc::access(p);
01641 nllh->lltype() |= RLC_MRWACK;
01642 nllh->SN_MRW_ACK = next_;
01643
01644 return p;
01645 }
01646
01647
01648
01649
01650
01651
01652 Packet *AM::allocpkt(int uid)
01653 {
01654 Packet *p = Packet::alloc();
01655 hdr_cmn *ch = hdr_cmn::access(p);
01656
01657
01658 ch->uid() = uid;
01659 ch->error() = 0;
01660 ch->timestamp() = Scheduler::instance().clock();
01661 ch->iface() = UNKN_IFACE.value();
01662 ch->direction() = hdr_cmn::DOWN;
01663
01664
01665 return (p);
01666 }
01667
01668
01669 void AM::makeSDU(int numSDU)
01670 {
01671
01672 Packet *p;
01673 hdr_cmn *ch;
01674 hdr_rlc *llh;
01675
01676 if (debug_>1)
01677 {
01678 cerr << NOW << " AM::makeSDU() SDU Queue before pruning:";
01679 sduB_.dump();
01680 }
01681
01682 for (int i = 0; i < numSDU; i++) {
01683
01684
01685 p = sduB_.deque();
01686 assert(p);
01687 ch = HDR_CMN(p);
01688 llh = hdr_rlc::access(p);
01689
01690
01691
01692 ch->ptype() = llh->lptype();
01693 ch->error() = llh->lerror();
01694 ch->timestamp() = llh->lts();
01695 ch->size() = llh->lsize();
01696
01697 uptarget_ ? sendUp(p) : Packet::free(p);
01698 }
01699
01700 if (debug_>1)
01701 {
01702 cerr << NOW << " AM::makeSDU() SDU Queue after pruning:";
01703 sduB_.dump();
01704 }
01705 }
01706
01707 void AM::CSwitch(double bandwidth, double TTI)
01708 {
01709 bandwidth_ = bandwidth;
01710 TTI_ = TTI;
01711 }
01712
01713
01714
01715
01716 void AM::timeout(int tno, int flowID)
01717 {
01718
01719
01720
01721
01722 if (tno == RLC_TIMER_POLL) {
01723
01724
01725 set_poll_timer();
01726
01727 if (maxseq_ == FSN_ && b_bal_ == 0) {
01728
01729
01730
01731 if (sender_debug_)
01732 cerr << NOW << " AM::timeout(RLC_TIMER_POLL) not sending POLL, no outstanding data" << endl;
01733
01734 return;
01735 }
01736
01737 set_poll_ = 1;
01738 if (sender_debug_)
01739 cerr << NOW << " AM::timeout(RLC_TIMER_POLL) sending POLL" << endl;
01740
01741 } else if (tno == RLC_TIMER_RTX) {
01742 if (highest_ack_ == maxseq_) {
01743
01744
01745
01746 return;
01747 }
01748 reset_rtx_timer();
01749
01750 } else if (tno == RLC_TIMER_STPROB) {
01751
01752 if (prohibited_)
01753 {
01754 send_status_ |= SEND_STATUS_BITMAP;
01755 if (receiver_debug_)
01756 cerr << NOW << " AM::timeout(RLC_TIMER_STPROB) SEND_STATUS_BITMAP" << endl;
01757 prohibited_ = 0;
01758 if (delsnd_timer_.status() == TIMER_PENDING
01759 && sent_TTI_PDUs_ < TTI_PDUs_) {
01760 earliest_status_send_ = tti_timer_.timeOfExpiry();
01761 } else {
01762 earliest_status_send_ = tti_timer_.timeOfExpiry() + TTI_;
01763 }
01764 }
01765 else
01766 {
01767 if (receiver_debug_)
01768 cerr << NOW << " AM::timeout(RLC_TIMER_STPROB) NOT sending BITMAP"
01769 << " prohibited_=" << prohibited_
01770 << endl;
01771 }
01772
01773
01774
01775 } else if (tno == RLC_TIMER_DELSND) {
01776 send_much(1);
01777
01778 } else if (tno == RLC_TIMER_TTI) {
01779 TTI_time_ = Scheduler::instance().clock();
01780 TTI_PDUs_ = (int) (bandwidth_ * TTI_) / (payload_ * 8);
01781 tti_timer_.resched(TTI_);
01782 send_much(0);
01783 } else if (tno == RLC_TIMER_MRWACK) {
01784 send_status_ |= SEND_STATUS_MRW;
01785 }
01786 }
01787
01788
01789
01790
01791
01792
01793 void AM::set_rtx_timer()
01794 {
01795 rtx_timer_.resched(rtx_timeout_);
01796 }
01797
01798
01799
01800
01801
01802
01803 void AM::reset_rtx_timer()
01804 {
01805 cancel_rtx_timer();
01806 t_seqno_ = highest_ack_ + 1;
01807
01808 rtt_active_ = 0;
01809 }
01810
01811
01812 void AM::cancel_rtx_timer()
01813 {
01814 rtx_timer_.force_cancel();
01815 }
01816
01817
01818 void AM::set_poll_timer()
01819 {
01820 poll_timer_.resched(poll_timeout_);
01821 }
01822
01823
01824 void AM::cancel_poll_timer()
01825 {
01826 poll_timer_.force_cancel();
01827 }
01828
01829
01830 void AM::set_status_prohibit_timer()
01831 {
01832 stprob_timer_.resched(stprob_timeout_ -
01833 (Scheduler::instance().clock() - TTI_time_)
01834 );
01835 }
01836
01837
01838 int AM::buff_size()
01839 {
01840 return (rcvB_.size() + rxtB_.size());
01841 }
01842
01843
01844
01845 void AM::discardSDU(int dsn)
01846 {
01847
01848
01849
01850
01851 bool sdu_ok = true;
01852 int sdu_begin;
01853 int sn;
01854
01855 if (debug_) cerr << "Discarding PDU " << dsn << endl;
01856
01857 if (debug_>1) {
01858 cerr << "FSN_ = " << FSN_ <<endl;
01859 cerr << " bitmap_[]:";
01860 for (int j=0; j<length_; j++)
01861 cerr << bitmap_[j];
01862 cerr<<endl;
01863 }
01864
01865 if (dsn < FSN_)
01866 {
01867 if (debug_) cerr << "WARNING -- AM::discardSDU(int dsn) -- dsn < FSN_ = " << FSN_ << endl;
01868 return;
01869 }
01870
01871 for (sn = FSN_; sn < dsn; sn++)
01872 {
01873 ack_PDUs_++;
01874 if (eopno_[sn & MWM] == sn)
01875 {
01876 ack_SDUs_++;
01877 sdu_begin = sn+1;
01878
01879 }
01880 }
01881
01882
01883 assert(sn == dsn);
01884 while (!(eopno_[sn & MWM] == sn))
01885 {
01886 drop_PDUs_++;
01887 sn++;
01888 assert(sn-dsn < MWM + 1);
01889 }
01890
01891
01892 MRW_delta = sn+1 - FSN_;
01893 FSN_ = sn+1;
01894 length_ -= MRW_delta;
01895 drop_SDUs_++;
01896 send_status_ |= SEND_STATUS_MRW;
01897
01898 if (sender_debug_)
01899 {
01900 cerr << "FSN_ incremented by " << MRW_delta << " -> " << FSN_ <<endl;
01901 cerr << "TOTAL:" << "PDUs " << ack_PDUs_ << "/" << ack_PDUs_ + drop_PDUs_
01902 << " SDUs " << ack_SDUs_ << "/" << ack_SDUs_ + drop_SDUs_ << endl;
01903 }
01904
01905
01906 b_bal_ = 0;
01907 for (int i = 0; i < length_; i++)
01908 {
01909 assert(i+MRW_delta < BITMAP_LENGTH);
01910 bitmap_[i] = bitmap_[i+MRW_delta];
01911 if (bitmap_[i] == 0)
01912 b_bal_++;
01913 }
01914
01915 if (sender_debug_>1) {
01916 cerr << "FSN_ = " << FSN_ <<endl;
01917 cerr << "new bitmap_[]:";
01918 for (int j=0; j<length_; j++)
01919 cerr << bitmap_[j];
01920 cerr<< " b_bal_=" << b_bal_
01921 << " t_seqno_=" << t_seqno_ << endl;
01922 cerr << " txcount_[]:";
01923 for (int j=FSN_; j<FSN_+100; j++)
01924 cerr << txcount_[j & MWM];
01925 cerr<<endl;
01926
01927 }
01928
01929 }
01930
01931
01932
01933
01934
01935 void AM::ackSDU(int oldFSN, int newFSN)
01936 {
01937
01938
01939
01940
01941
01942
01943 for (int sn = oldFSN; sn < newFSN; sn++)
01944 {
01945 ack_PDUs_++;
01946 if (eopno_[sn & MWM] == sn)
01947 {
01948 ack_SDUs_++;
01949 }
01950 }
01951 if (debug_) {
01952 cerr << "TOTAL:" << "PDUs " << ack_PDUs_ << "/" << ack_PDUs_ + drop_PDUs_
01953 << " SDUs " << ack_SDUs_ << "/" << ack_SDUs_ + drop_SDUs_
01954 << endl;
01955 }
01956 }
01957
01958
01959