📄 rlc-umts-nodeb.cc
字号:
hdr_cmn *ch = HDR_CMN(p); hdr_ip *ih = HDR_IP(p); hdr_rlc_umts *rh = HDR_RLC_UMTS(p); Scheduler& s = Scheduler::instance(); if (ch->direction() == hdr_cmn::UP){ i = look_for(ih->flowid(), ih->saddr()); if (rlcverbose_==1) fprintf(stderr,"<%d> RLCNodeb: DATA dir UP: uid %d pos %d frag %d ack %d \n", ip_nodeb_, ch->uid(),i,info_[i].fraged_,info_[i].acked_); if ((info_[i].fraged_) || (info_[i].acked_)){ ch->size() -= RLC_HDR_SZ; sendUpDATA(p, i); } else { ch->size() -= RLC_HDR_SZ; s.schedule(uptarget_, p, delay_); } }else{ ch->direction() = hdr_cmn::DOWN; i = look_for(ih->flowid(), ih->daddr()); if (rlcverbose_==1) fprintf(stderr,"<%d> RLCNodeb: DATA dir DOWN: uid %d pos %d frag %d ack %d \n", ip_nodeb_, ch->uid(),i,info_[i].fraged_,info_[i].acked_); if ((info_[i].fraged_) || (info_[i].acked_)){ enqueDATA(p, i); } else { ch->size() += RLC_HDR_SZ; s.schedule(downtarget_, p, delay_); } }}void RlcUmtsNodeb::enqueDATA(Packet* p, int pos){ hdr_cmn *ch = HDR_CMN(p); hdr_ip *ih = HDR_IP(p); hdr_rlc_umts *rlch = HDR_RLC_UMTS(p); rlch->rlctype() = RLC_DATA; //fragmenting to start here.... int psize, mod; if(info_[pos].fraged_ == 1) psize = rlcfragsz_; else psize = ch->size_; int bopno = info_[pos].seqno_; int eopno = bopno + (int)((ch->size_-1)/psize); int i; for ( i = bopno; i <= eopno; i++){ Packet * sp = p->copy(); hdr_cmn *chsp = HDR_CMN(sp); hdr_rlc_umts *rlchsp = HDR_RLC_UMTS(sp); rlchsp->frag_ = info_[pos].fraged_; rlchsp->ack_ = info_[pos].acked_; rlchsp->seqno_ = 0; rlchsp->bopno_ = bopno; rlchsp->eopno_ = eopno; rlchsp->psize_ = chsp->size_; //hack for now to remeber uid chsp->size_ = psize; chsp->size() += RLC_HDR_SZ; if((info_[pos].acked_ == 0)||(chsp->next_hop() == -1)){ rlchsp->seqno_ = i; info_[pos].seqno_++; Scheduler& s = Scheduler::instance(); if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLCNodeb: sending NON-acked down. pkt uid=%d seqno %d\n", ip_nodeb_, NOW,chsp->uid_, rlchsp->seqno_); s.schedule(downtarget_, sp, delay_); }else{ rlchsp->seqno_ = i; info_[pos].seqno_++; buf_->enque(sp); if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLCNodeb: buffering frag. rlc_seqno=%d for pkt uid=%d buf_len=%d\n" , ip_nodeb_, NOW, rlchsp->seqno_,chsp->uid_, buf_->length()); } } if((info_[pos].acked_==1)) sendDownDATA(pos); return;}void RlcUmtsNodeb::sendDownDATA(int pos){ Packet* sp; // not more pkts of this flow to tx if (length_ >= buf_->length()) { length_ = 0; return; } if(!(sp = buf_->deque())){ length_ = 0; return; } length_++; hdr_ip *ihsp = HDR_IP(sp); if (ihsp->flowid() != info_[pos].flow_) { buf_->enque(sp); sendDownDATA(pos); } else { hdr_rlc_umts *rlcsp = HDR_RLC_UMTS(sp); if(info_[pos].Txbuf_->length() < info_[pos].window_){ info_[pos].Txbuf_->enque(sp->copy()); if (rlcverbose_==1) fprintf (stderr, "<%d> %f RLC: Txbuf not full[%d]=%d,sending a data down, rlc_seq=%d from buf\n", ip_nodeb_, NOW, pos,info_[pos].Txbuf_->length(),rlcsp->seqno_); Scheduler& s = Scheduler::instance(); s.schedule(downtarget_, sp->copy(), delay_); length_--; sendDownDATA(pos); }else{ length_ = 0; if (rlcverbose_==1) fprintf (stderr, "<%d> %f RLCNodeb: Txbuf full. couldnt send rlc_seqno=%d \n", ip_nodeb_, NOW, rlcsp->seqno_); buf_->enqueHead(sp); } } return;}void RlcUmtsNodeb::recvACK(Packet* p){ int i, first, last, temp; hdr_rlc_umts *rlch = HDR_RLC_UMTS(p); hdr_ip *ih = HDR_IP(p); i = look_for(ih->flowid(), ih->saddr()); if (rlch->ackno_==info_[i].ackno_) { if (rlcverbose_==1) fprintf(stderr,"\n<%d> %f RLCNodeb: recvd duplicate RLC_ACK num %d until %d\n", ip_nodeb_, NOW, rlch->ackno_,rlch->eopno_); first = rlch->bopno_; last = rlch->eopno_; for (temp=first; temp<last; temp++){ sendDownDATAonACK(i, temp); } Packet::free(p); return; } else if(info_[i].ackno_ < rlch->ackno_){ info_[i].ackno_ = rlch->ackno_; } else { Packet::free(p); return; } if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLCNodeb: recvd RLC_ACK num %d waiting %d buf length %d\n", ip_nodeb_, NOW, rlch->ackno_, info_[i].ackno_, info_[i].Txbuf_->length()); Packet* sp=info_[i].Txbuf_->head(); int Txlen=info_[i].Txbuf_->length(); //delete pkts with seqno < ackno for (int j=0; j<Txlen; j++){ hdr_rlc_umts *rlchsp= HDR_RLC_UMTS(sp); if((rlchsp->seqno_)<info_[i].ackno_){ info_[i].Txbuf_->remove(sp); if (rlcverbose_==1) fprintf(stderr, "<%d> %f RLCNodeb: removed ie deleted pkt from tx buffer; rlc seqno=%d\n", ip_nodeb_, NOW, rlchsp->seqno_); } sp = sp->next_; } if ((info_[i].Txbuf_->length() > 0) && (info_[i].Txbuf_->length() < info_[i].window_)){ sendDownDATA(i); }}void RlcUmtsNodeb::sendDownDATAonACK(int pos, int seqno){ Packet* sp=info_[pos].Txbuf_->head(); int Txlen_=info_[pos].Txbuf_->length(); for(int i=0; i<Txlen_; i++){ hdr_rlc_umts *rlchsp= HDR_RLC_UMTS(sp); if((rlchsp->seqno_) == seqno){ if (rlcverbose_==1) fprintf(stderr,"\n<%d> %f RLC: retx pkt from txbuf seqno=%d, eopno=%d\n", ip_nodeb_, NOW,rlchsp->seqno_,rlchsp->eopno_); Scheduler& s = Scheduler::instance(); s.schedule(downtarget_, sp->copy(), delay_); return; } sp = sp->next_; }}void RlcUmtsNodeb::sendUpDATA(Packet* p, int pos){ if (hdr_cmn::access(p)->error() > 0) drop(p); else{ hdr_cmn *ch = HDR_CMN(p); hdr_rlc_umts *rlch = HDR_RLC_UMTS(p); hdr_ll *llch = HDR_LL(p); hdr_ip *iph = HDR_IP(p); if(info_[pos].acked_==0){ if (rlch->seqno_ == info_[pos].unackseqno_){ info_[pos].unackseqno_++; } else if ((rlch->seqno() == rlch->bopno()) && (rlch->bopno() == 0)){ // in case wired--> wireless info_[pos].unackseqno_ = 1; } else { info_[pos].inseq_ = 0; info_[pos].unackseqno_ = rlch->seqno_ + 1; } if (rlch->seqno_ == rlch->eopno_ ){ if(info_[pos].inseq_){ ch->size_ = rlch->psize_; if (rlcverbose_ == 1) fprintf(stderr ,"<%d> %f RLCNodeb: nonack. recvd all rlc frags for pktuid=%d ll_seqno=%d \n", ip_nodeb_, NOW, ch->uid_, llch->seqno_); Scheduler& s = Scheduler::instance(); s.schedule(uptarget_, p, delay_); } else { if (rlcverbose_==1) fprintf(stderr ,"<%d> %f RLCNodeb: nonack. pkts not inseq. not sent up\n",ip_nodeb_, NOW); Packet::free(p); } info_[pos].inseq_ = 1; } else { if (rlcverbose_==1) fprintf(stderr ,"<%d> %f RLCNodeb: nonack. recvd rlc_seqno=%d for pkt uid=%d\n" , ip_nodeb_, NOW, rlch->seqno_, ch->uid_ ); Packet::free(p); } return; }else{ if((info_[pos].handover_ == 1) && (info_[pos].rackno_+1 == 0)){ info_[pos].handover_ = 0; info_[pos].rackno_ = rlch->seqno_; goto GO; } else if(rlch->seqno_ == (info_[pos].rackno_+1)){ info_[pos].rackno_++;GO: info_[pos].numdups_ = 0; info_[pos].lastRx_ = p->copy(); if (rlcverbose_ == 1) fprintf(stderr , "<%d> %f RLCNodeb: rackno=%d, src=%d \n", ip_nodeb_, NOW, info_[pos].rackno_, Address::instance().get_nodeaddr(iph->saddr()) ); if ( rlch->seqno_ == rlch->eopno_ ){ ch->size_ = rlch->psize_; if (rlcverbose_==1) fprintf(stderr , "<%d> %f RLCNodeb:ACK:. send up to LL pktuid=%d llseqno=%d \n", ip_nodeb_, NOW,ch->uid_, llch->seqno_); Scheduler& s = Scheduler::instance(); s.schedule(uptarget_, p, delay_); } else { if (rlcverbose_==1) fprintf(stderr ,"<%d> %f RLCNodeb:ACK: recvd rlc_seqno=%d for pkt uid=%d ll_seqno=%d \n" , ip_nodeb_, NOW, rlch->seqno_, ch->uid_ , llch->seqno_); } int flag=1; while(flag){ flag=0; if(info_[pos].Rxbuf_->length()!=0){ Packet* sp = info_[pos].Rxbuf_->head(); int Rxlen_ = info_[pos].Rxbuf_->length(); for(int i=1; i<=Rxlen_; i++){ hdr_rlc_umts* rlcsp = HDR_RLC_UMTS(sp); if(rlcsp->seqno_ == (info_[pos].rackno_+1)){ info_[pos].rackno_++; info_[pos].lastRx_ = sp->copy(); flag=1; hdr_cmn* chsp=HDR_CMN(sp); if ( rlcsp->seqno_ == rlcsp->eopno_ ){ chsp->size_ = rlcsp->psize_; if (rlcverbose_ == 1) fprintf(stderr,"<%d> %f RLCNodeb: pkt in rxbuf: send up uid=%d seqno=%d bopno=%d eopno=%d \n", ip_nodeb_, 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 RLCNodeb: pkt in rxbuf: drop uid=%d seqno=%d bopno=%d eopno=%d next_hop %d \n", ip_nodeb_, NOW,chsp->uid_,rlcsp->seqno_,rlcsp->bopno_,rlcsp->eopno_,chsp->next_hop()); } info_[pos].Rxbuf_->remove(sp); } sp=sp->next_; } } } sendACK(p, pos); }else if(rlch->seqno_ > (info_[pos].rackno_+1)){ info_[pos].Rxbuf_->enque(p); if (info_[pos].numdups_ < 1){ if (rlcverbose_==1) fprintf (stderr,"<%d> %f RLCNodeb: pkt out of seq, buf in rxbuf;send duplicate ackseqno=%d\n", ip_nodeb_, NOW,rlch->seqno_); sendACK(p, pos); info_[pos].numdups_ ++; } } } }}void RlcUmtsNodeb::sendACK(Packet* p, int pos){ hdr_cmn *ch = HDR_CMN(p); hdr_phy *ph = HDR_PHY_UMTS(p); hdr_ip *iph = HDR_IP(p); Packet* sp = Packet::alloc(); hdr_cmn *chsp = HDR_CMN(sp); hdr_rlc_umts *rlchsp = HDR_RLC_UMTS(sp); hdr_phy *phsp = HDR_PHY_UMTS(sp); hdr_ip *iphsp = HDR_IP(sp); chsp->next_hop_=Address::instance().get_nodeaddr(iph->saddr()); chsp->prev_hop_=Address::instance().get_nodeaddr(ip_nodeb_); chsp->channel_t() = CCCH; chsp->addr_type_ = ch->addr_type_; chsp->direction_ = hdr_cmn::DOWN; chsp->ptype_=PT_ACK; chsp->size_=6; chsp->iface()= -2; chsp->error()= 0; chsp->uid()= info_[pos].rackno_+1; chsp->txtime()= NOW; iphsp->saddr() = ip_nodeb_; iphsp->daddr() = iph->saddr(); iphsp->flowid() = iph->flowid(); rlchsp->rlctype() = RLC_ACK; rlchsp->ackno_ = info_[pos].rackno_+1; //mio rlchsp->bopno_ = info_[pos].rackno_+1; int len, vt; len=info_[pos].Rxbuf_->length(); Packet* ptemp=info_[pos].Rxbuf_->head(); if (ptemp != NULL) { struct hdr_rlc_umts *pth = HDR_RLC_UMTS(ptemp); vt = pth->seqno_; ptemp = ptemp->next_; for (int j=1; j<len; j++) { pth = HDR_RLC_UMTS(ptemp); if (pth->seqno_ < vt){ vt = pth->seqno_; } ptemp = ptemp->next_; } rlchsp->eopno_ = vt; } else { rlchsp->eopno_ = rlchsp->bopno_+1; } phsp->sa() = ph->da(); phsp->da() = ph->sa(); Scheduler& s = Scheduler::instance(); s.schedule(downtarget_, sp, delay_); rtxnodeb_->start(info_[pos].src_, info_[pos].flow_, 0.05); if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLCNodeb: send RLCACK num %d in pos %d to ue %d with first %d last %d\n", ip_nodeb_, NOW, rlchsp->ackno_, pos, iphsp->daddr(),rlchsp->bopno_,rlchsp->eopno_);}void RlcUmtsNodeb::rTxHandler(nsaddr_t src, int flow){ if (rlcverbose_) printf("Nodeb %d at %f RLC: Timer of flow %d and source %d expired. Retransmit ack\n", ip_nodeb_, NOW, flow, src); int pos = look_for(flow, src); sendACK(info_[pos].lastRx_, pos); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -