📄 rlc.cc
字号:
if (rlch->ackno_==ackno_) { if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: recvd duplicate RLC_ACK num %d\n", mac_->addr(), NOW, rlch->ackno_); sendDownDATAonACK(); return; } else if(ackno_ < rlch->ackno_){ ackno_ = rlch->ackno_; lhSend_.stop(); datacounter=0; } if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: recvd RLC_ACK num %d\n", mac_->addr(), NOW, rlch->ackno_); Packet* sp=Txbuf_->head(); int Txlen=Txbuf_->length(); //delete pkts with seqno < ackno for (int i=1; i<Txlen; i++){ hdr_rlc *rlchsp= HDR_RLC(sp); if((rlchsp->seqno_)<ackno_){ Txbuf_->remove(sp); if (rlcverbose_==1) fprintf(stderr, "<%d> %f RLC: removed ie deleted pkt from tx buffer; rlc seqno=%d\n", mac_->addr(), NOW, rlchsp->seqno_); } sp = sp->next_; } // I dont want to send down apkt when i get an ack. rj if(Txbuf_->length()==window_){ //if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: txbuf full, calling sendDownDATAonACK\n", mac_->addr(), NOW); // sendDownDATAonACK(); } else{ if(buf_->length()==0){ // if (rlcverbose_==1) fprintf (stderr, "<%d> %f RLC: no more new pkts to send, calling sendDownDATAonACK\n", // mac_->addr(), NOW); // sendDownDATAonACK(); } else{ if (rlcverbose_==1) fprintf (stderr, "<%d> %f RLC: got an ack. calling sendDOWNDATA\n" , mac_->addr(), NOW); sendDownDATA(); //hmm, this not called at all rj } }}void RLC::sendDownDATAonACK(){ Packet* sp=Txbuf_->head(); int Txlen_=Txbuf_->length(); for(int i=1; i<Txlen_; i++){ hdr_rlc *rlchsp= HDR_RLC(sp); if((rlchsp->seqno_)==ackno_){ pktTx_ = sp->copy(); if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: retx pkt from txbuf seqno=%d, eopno=%d\n", mac_->addr(), NOW,rlchsp->seqno_,rlchsp->eopno_); Scheduler& s = Scheduler::instance(); s.schedule(downtarget_, sp->copy(), delay_); lhSend_.stop(); lhSend_.start(0.4); return; } sp = sp->next_; } }void RLC::sendUpDATA(Packet* p){ acSend_.stop(); ackcounter=0; if (hdr_cmn::access(p)->error() > 0) drop(p); else{ hdr_cmn *ch = HDR_CMN(p); hdr_rlc *rlch = HDR_RLC(p); hdr_ll *llch = HDR_LL(p); hdr_ip *iph = HDR_IP(p); if((acked_==0)||(ch->next_hop()==-1)){ if (rlch->seqno_==unackseqno_) unackseqno_++; else{ inseq_=0; unackseqno_=rlch->seqno_; } if (rlch->seqno_ == rlch->eopno_ ){ if(inseq_){ // ch->uid_=rlch->psize_; //sandy; if (rlcverbose_==1) fprintf(stderr ,"<%d> %f RLC: nonack. recvd all rlc frags for pktuid=%d ll_seqno=%d \n", mac_->addr(), NOW, ch->uid_, llch->seqno_); Scheduler& s = Scheduler::instance(); s.schedule(uptarget_, p, delay_); } else { if (rlcverbose_==1) fprintf(stderr ,"<%d> %f RLC: nonack. pkts not inseq. not sent up\n",mac_->addr(), NOW); } inseq_=1; unackseqno_=0; } else { if (rlcverbose_==1) fprintf(stderr ,"<%d> %f RLC: nonack. recvd rlc_seqno=%d for pkt uid=%d \n" , mac_->addr(), NOW, rlch->seqno_, ch->uid_ ); Packet::free(p); } return; }else{ if(rlch->seqno_==(rackno_+1)){ rackno_++; numdups=0; // ch->uid_=rlch->psize_; //sandy; if (rlcverbose_==1) fprintf(stderr , "<%d> %f RLC: rackno=%d, src=%d \n", mac_->addr(), NOW,rackno_, Address::instance().get_nodeaddr(iph->saddr()) );//rj if ( rlch->seqno_ == rlch->eopno_ ){ ch->size_=rlch->psize_; if (rlcverbose_==1) fprintf(stderr , "<%d> %f RLC:ACK:. send up to LL pktuid=%d llseqno=%d \n", mac_->addr(), NOW,ch->uid_, llch->seqno_); Scheduler& s = Scheduler::instance(); s.schedule(uptarget_, p, delay_); } else { if (rlcverbose_==1) fprintf(stderr ,"<%d> %f RLC:ACK: recvd rlc_seqno=%d for pkt uid=%d ll_seqno=%d \n" , mac_->addr(), NOW, rlch->seqno_, ch->uid_ , llch->seqno_); // Packet::free(p); }// int choose=1; int flag=1;// Packet * spcpy; while(flag){ flag=0; if(Rxbuf_->length()!=0){ Packet* sp=Rxbuf_->head(); int Rxlen_=Rxbuf_->length(); for(int i=1;i<=Rxlen_;i++){ hdr_rlc* rlcsp = HDR_RLC(sp); if(rlcsp->seqno_==(rackno_+1)){ rackno_++; flag=1;// choose=0;// Packet * spcpy=sp->copy(); hdr_cmn* chsp=HDR_CMN(sp); if ( rlcsp->seqno_ == rlcsp->eopno_ ){//??rj chsp->size_=rlcsp->psize_; if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: pkt in rxbuf: send up uid=%d seqno=%d bopno=%d eopno=%d \n", mac_->addr(), NOW,ch->uid_,rlch->seqno_,rlch->bopno_,rlch->eopno_); Scheduler& s = Scheduler::instance(); s.schedule(uptarget_, sp->copy(), delay_); } else { if (rlcverbose_==1) fprintf(stderr , "<%d> %f RLC: pkt in rxbuf: drop uid=%d seqno=%d bopno=%d eopno=%d next_hop %d \n", mac_->addr(), NOW,chsp->uid_,rlcsp->seqno_,rlcsp->bopno_,rlcsp->eopno_,chsp->next_hop()); } Rxbuf_->remove(sp); } sp=sp->next_; } } }// if (choose) sendACK(p);// else// sendACK(spcpy); }else if(rlch->seqno_>(rackno_+1)){ Rxbuf_->enque(p); if (numdups<1){ if (rlcverbose_==1) fprintf (stderr,"<%d> %f RLC: pkt out of seq, buf in rxbuf;send duplicate ackseqno=%d\n", mac_->addr(), NOW,rlch->seqno_); sendACK(p); //rj numdups ++; } } } }}void RLC::sendACK(Packet* p){ hdr_cmn *ch = HDR_CMN(p);// hdr_rlc *rlch = HDR_RLC(p); hdr_ip *iph = HDR_IP(p); hdr_mac_gprs *dh =HDR_MAC_GPRS(p);// char *mh = (char*)p->access(hdr_mac::offset_); Packet* sp = Packet::alloc(); hdr_cmn *chsp = HDR_CMN(sp); hdr_rlc *rlchsp = HDR_RLC(sp); hdr_ip *iphsp = HDR_IP(sp); char *mhsp = (char *)HDR_MAC(sp);// char *mhsp = (char*)sp->access(hdr_mac::offset_); // iphsp->src_ = iph->dst_;// iphsp->dst_ = iph->src_;// chsp->next_hop_ = ch->last_hop_;// chsp->last_hop_ = ch->next_hop_; chsp->next_hop_=Address::instance().get_nodeaddr(iph->saddr()); chsp->prev_hop_=Address::instance().get_nodeaddr(iph->daddr()); chsp->addr_type_ = ch->addr_type_; chsp->direction_ = hdr_cmn::DOWN; chsp->ptype_=PT_RLCACK; chsp->size_=6; chsp->iface()= -2; chsp->error()= 0; chsp->uid()= rackno_+1; u_int32_t dst_=ETHER_ADDR(dh->dh_sa); mac_->hdr_src(mhsp, mac_->addr()); mac_->hdr_type(mhsp, ETHERTYPE_IP); mac_->hdr_dst(mhsp, dst_);// mac_->hdr_dst(mhsp, chsp->next_hop()); rlchsp->rlctype() = RLC_ACK; rlchsp->ackno_ = rackno_+1; pktRx_ = sp->copy(); Scheduler& s = Scheduler::instance(); s.schedule(downtarget_, sp, delay_); acSend_.stop(); acSend_.start(0.4); if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: send RLCACK num %d to mac_dst=%d\n", mac_->addr(), NOW, rlchsp->ackno_, dst_); // Packet::free(p); }void RLC::sendHandler(){ send_timer();}void RLC::sendackHandler(){ send_acktimer();}void RLC::send_timer(){ RetransmitDATA();// RetransmitACK();}void RLC::send_acktimer(){ RetransmitACK();}void RLC::RetransmitDATA(){ datacounter =datacounter + 1; assert(pktTx_); hdr_rlc* rlch=HDR_RLC(pktTx_); if (datacounter <3){ if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: retx rlc frag seqno=%d bopno=%d eopno=%d for %dth time\n", mac_->addr(), NOW,rlch->seqno_,rlch->bopno_,rlch->eopno_,datacounter); Scheduler& s = Scheduler::instance(); s.schedule(downtarget_, pktTx_->copy(), delay_); lhSend_.stop(); lhSend_.start(0.4); } else{ if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: retxed rlc frag 5 times. giveup. rlc seqno=%d bopno=%d eopno=%d\n", mac_->addr(), NOW,rlch->seqno_,rlch->bopno_,rlch->eopno_); //datacounter=0; ackno_++; sendDownDATA(); }}void RLC::RetransmitACK(){ ackcounter =ackcounter +1; assert(pktRx_); hdr_rlc *rlch=HDR_RLC(pktRx_); if (ackcounter < 3){ if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: retransmit rlc ack %d for %dth time\n", mac_->addr(), NOW,rlch->ackno_,ackcounter); Scheduler& s = Scheduler::instance(); s.schedule(downtarget_,pktRx_->copy(),delay_); acSend_.stop(); acSend_.start(0.4); } else{ if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: transmitted rlc ack num %d 3 times giveup\n", mac_->addr(), NOW, rlch->ackno_);// rackno_++; ackcounter=0; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -