📄 ll-nodeb.cc
字号:
case 0: // TURBO php->c_coding() = TURBO; break; case 1: // CONV_HALF php->c_coding() = CONV_HALF; break; case 2: // CONV_THIRD php->c_coding() = CONV_THIRD; break; } } if (verbose_) printf("Nodeb %d at %f RRC: sending LL_DATA to UE: %d\n", ip_nodeb_, NOW,php->da()); s.schedule(downtarget_, p, delay_); // send the packet down through the scheduler return;}// send SETUP REPLY message for setup procedure and handovervoid LLNodeb::send_setup_reply(Packet* p){ Scheduler& s = Scheduler::instance(); hdr_cmn *ch = HDR_CMN(p); hdr_phy *ph = HDR_PHY_UMTS(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_ll *lh = HDR_LL(p); Packet* sp = Packet::alloc(); struct hdr_cmn *chsp = HDR_CMN(sp); struct hdr_ll *lhsp = HDR_LL(sp); struct hdr_ip *ihsp = HDR_IP(sp); struct hdr_phy *phsp = HDR_PHY_UMTS(sp); // fill physical, ll, common and ip headers lhsp->lltype() = LL_SETUP_REPLY; lhsp->tx_rate() = lh->tx_rate(); // physical rate requested phsp->sa() = phy_->nodeb_address_; phsp->da() = ph->sa(); phsp->sf() = 256; phsp->c_coding() = CONV_HALF; phsp->freq() = Random::integer(MAX_NUM_FREQ -1); // randomly chosen frequency chsp->channel_t() = CCCH; // ch allocation chsp->next_hop_ = ih->saddr(); chsp->direction() = hdr_cmn::DOWN; chsp->size() = 5; chsp->error() = 0; ihsp->saddr() = ip_nodeb_; ihsp->daddr() = ih->saddr(); if (verbose_) printf("Nodeb %d at %f RRC: sending LL_SETUP_REPLY to UE %d\n",ip_nodeb_, NOW, ih->saddr()); s.schedule(downtarget_, sp->copy(), delay_); // send the packet down through the scheduler // for registering in classifiers and routing table s.schedule(uptarget_, sp, delay_); // send the packet up through the scheduler Packet::free(p); p = NULL; return;}// send the resource reply message or a failure// must be checked if the response has to be for a ue in our cell or in other cell.void LLNodeb::send_res_reply(Packet* p, int state){ int i; Scheduler& s = Scheduler::instance(); hdr_phy *ph = HDR_PHY_UMTS(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_ll *lh = HDR_LL(p); Packet* sp = p->copy(); struct hdr_cmn *chsp = HDR_CMN(sp); struct hdr_ll *lhsp = HDR_LL(sp); struct hdr_ip *ihsp = HDR_IP(sp); struct hdr_phy *phsp = HDR_PHY_UMTS(sp); // fill physical, ll and common headers lhsp->lltype() = LL_RES_REPLY; phsp->sa() = phy_->nodeb_address_; phsp->sf() = 256; phsp->c_coding() = CONV_HALF; phsp->freq() = Random::integer(MAX_NUM_FREQ -1); // randomly chosen frequency i = look_for(ih->saddr()); // fill the destination address (physical) if (i != -1) { phsp->da() = ue_info_[i].phyaddr_; } chsp->channel_t() = CCCH; // ch allocation chsp->direction() = hdr_cmn::DOWN; chsp->size() = 5; chsp->error() = 0; if (state == 0) // if was a FAILURE, fill the packet type properly chsp->ptype() = PT_RRC_FAILURE; if (look_for(ihsp->saddr()) >= 0) { // the requesting party is in our cell if (verbose_) printf("Nodeb %d at %f RRC: sending LL_RES_REPLY from ip: %d to ip: %d\n", ip_nodeb_, NOW, phsp->sa(), getip(ihsp->saddr()), getip(ihsp->daddr())); chsp->next_hop_ = ih->saddr(); s.schedule(downtarget_, sp, delay_); // send the packet down through the scheduler } else { // it is in another cell chsp->ptype() = PT_CBR; chsp->channel_t() = FROM_RRC; // ch allocation ihsp->saddr() = ih->daddr(); ihsp->daddr() = ih->saddr(); ihsp->ttl() = 200; if (verbose_) printf("Nodeb %d at %f RRC: sending LL_RES_REPLY to other cell from ip: %d to ip: %d\n", ip_nodeb_, NOW, phsp->sa(), getip(ihsp->saddr()), getip(ihsp->daddr())); s.schedule(uptarget_, sp, delay_); // send the packet up through the scheduler } Packet::free(p); p = NULL; return;}// send paging message to the destination of the incoming flowvoid LLNodeb::pag_proc(Packet* p, int pos){ int i, j; Scheduler& s = Scheduler::instance(); hdr_cmn *ch = HDR_CMN(p); hdr_phy *ph = HDR_PHY_UMTS(p); hdr_ll *lh = HDR_LL(p); hdr_rlc_umts *rh = HDR_RLC_UMTS(p); struct hdr_ip *ih = HDR_IP(p); Packet* sp = Packet::alloc(); struct hdr_cmn *chsp = HDR_CMN(sp); struct hdr_ll *lhsp = HDR_LL(sp); struct hdr_ip *ihsp = HDR_IP(sp); struct hdr_phy *phsp = HDR_PHY_UMTS(sp); struct hdr_rlc_umts *rhsp = HDR_RLC_UMTS(sp); // fill physical, ll, rlc, common and ip headers lhsp->lltype() = LL_PAGING; lhsp->tx_rate() = lh->tx_rate(); phsp->sa() = phy_->nodeb_address_; phsp->da() = ue_info_[pos].phyaddr_; phsp->freq() = ue_info_[pos].dlfreq_; chsp->channel_t() = PCCH; // ch allocation chsp->next_hop_ = ih->daddr(); chsp->direction() = hdr_cmn::DOWN; chsp->size() = 5; chsp->error() = 0; ihsp->flowid() = ih->flowid(); ihsp->saddr() = ih->saddr(); ihsp->daddr() = ih->daddr(); rhsp->ack() = rh->ack(); // ack mode rhsp->frag() = rh->frag(); // frag mode if (verbose_) printf("Nodeb %d at %f RRC: initiating PAGING PROCEDURE to UE %d\n",ip_nodeb_, NOW, phsp->da()); s.schedule(downtarget_, sp, delay_); // send the packet down through the scheduler Packet::free(p); p = NULL; return;}// send the packet to the routing agentvoid LLNodeb::send_to_ra(Packet* p){ Scheduler& s = Scheduler::instance(); struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); ch->ptype() = PT_CBR; ih->ttl() = 200; if (verbose_) printf("Nodeb %d at %f RRC: pkt for ue(ip): %d which is in other cell. ttl %d delay %f\n", ip_nodeb_, NOW, getip(ih->daddr()), ih->ttl(), delay_); s.schedule(uptarget_, p, delay_); // send the packet up through the scheduler return;}// returns the maximum rate allowed for the SFdouble get_rate(int sf){ return((2*2560 / sf) / UMTS_SlotTime);}// returns the physical rate corresponding for the user rate, channel coding and packet size passeddouble LLNodeb::phy_rate(double rate, int code, int psize){ double rt, time; int rlcfsize = rlc_->rlcfragsize(); // rlc fragment size int rlchdrsize = RLC_HDR_SZ; // rlc-umts header size int machdrsize = MAC_HDR_SZ; // mac-umts header size int phyhdrsize = PHY_HDR_SZ; // phy-umts header size time = (psize * 8)/ rate; // time between two user packets int npkts = (int)(psize / rlcfsize); // n of rlc packet per user packet if ((psize % rlcfsize) > 0) npkts++; rt = (npkts * rlcfsize * 8)/time; // effective user rate rt = (rt * (rlcfsize + rlchdrsize + machdrsize))/rlcfsize; // user rate // before channel coding switch (code) { // adjust rate depending of the channel coding case 0: // TURBO rt = 3*rt; break; case 1: // CONV_HALF rt = 2*rt; break; case 2: // CONV_THIRD rt = 3*rt; break; default: break; } if (verbose_) printf("Nodeb %d at %f RRC: ********************* rate %f for code %d\n" ,ip_nodeb_, NOW, rt, code); return(rt);}// allocate downlink resources in this layer and OSVF trees if there are enough available (returns 1)// and returns 0 if not.int LLNodeb::free_res(Packet* p){ int i, sf, pos, code; double temp_rate, user_rate; struct hdr_ll *lh = HDR_LL(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_phy *ph = HDR_PHY_UMTS(p); struct hdr_cmn *ch = HDR_CMN(p); pos = look_for(ih->daddr()); if (!ue_node(ih->saddr())) { // the originating party is a fixed node Node * node_ = (Node*)(phy_->netif_->node()); user_rate = node_->list->lookforrate(getip(ih->saddr()), ih->flowid()); // get user rate code = getcode(ih->saddr(), ih->flowid()); // get channel coding temp_rate = phy_rate(user_rate, code, ch->size()); // get physical rate needed for the flow } else { temp_rate = lh->tx_rate(); // is a UE, take the physical rate needed from the LL header } if (ue_info_[pos].dlsf_ > 0){ // flows already allocated for that node double tr = get_rate(ue_info_[pos].dlsf_); // get maximum physical rate allowed for the // allocated SF for that UE in downlink if (tr >= (ue_info_[pos].dltotalr_ + temp_rate)) { // is able to support new flow if (verbose_) printf("Nodeb %d at %f RRC: UE %d stored rate %f and new rate arrived %f\n", ip_nodeb_, NOW, ue_info_[pos].ipaddr_,ue_info_[pos].dltotalr_,temp_rate); ue_info_[pos].dltotalr_ += temp_rate; // update registers if (verbose_) printf("Nodeb %d at %f RRC: UE %d total rate stored %f\n", ip_nodeb_, NOW, ue_info_[pos].ipaddr_, ue_info_[pos].dltotalr_); return(1); // OK } else { // is not able to support new flow, new resources has to be allocated ue_info_[pos].dltempsf_ = ue_info_[pos].dlsf_; remove_res(pos); // remove resources from OSVF trees sf = cal_sf(temp_rate + ue_info_[pos].dltotalr_); // calculate needed SF if (alloc_res(p,sf)) { // allocate resources in OSVF downlink trees if (verbose_) printf("Nodeb %d at %f RRC: UE %d stored rate %f and new rate arrived %f\n", ip_nodeb_, NOW, ue_info_[pos].ipaddr_, ue_info_[pos].dltotalr_,temp_rate); ue_info_[pos].dltotalr_ += temp_rate; // update registers if (verbose_) printf("Nodeb %d at %f RRC: UE %d total rate stored %f\n", ip_nodeb_, NOW, ue_info_[pos].dltotalr_); return(1); // OK } else { // not possible to allocate resuorces in OSVF trees ue_info_[pos].dlsf_ = ue_info_[pos].dltempsf_; ue_info_[pos].dltempsf_ = -1; alloc_res(p,ue_info_[pos].dlsf_); // give the previous resources return(0); // not possible } } } else { // no flows already allocated for that node sf = cal_sf(p); // get the needed SF for the flow ue_info_[pos].dltempsf_ = -1; if (alloc_res(p,sf)) { // allocate resources in OSVF trees if (verbose_) printf("Nodeb %d at %f RRC: UE %d stored rate %f and new rate arrived %f\n", ip_nodeb_, NOW, ue_info_[pos].ipaddr_, ue_info_[pos].dltotalr_,temp_rate); ue_info_[pos].dltotalr_ += temp_rate; // update resgisters if (verbose_) printf("Nodeb %d at %f RRC: UE %d total rate stored %f\n", ip_nodeb_, NOW, ue_info_[pos].ipaddr_, ue_info_[pos].dltotalr_); return(1); // OK } } return (0); // not possible}// fill rlc header fields: frag_ and ack_ depending on the flowvoid LLNodeb::filltype(Packet* p){ hdr_ip *ih = HDR_IP(p); hdr_rlc_umts *rh = HDR_RLC_UMTS(p); int acked, fraged; Node * node_ = (Node*)(phy_->netif_->node()); // get node int type = node_->list->lookfortype(getip(ih->saddr()), ih->flowid()); // get type of application switch (type) { case 0: // audio fraged = 1; acked = 0; break; case 1: // video fraged = 1; acked = 0; break; case 2: // mail fraged = 1; acked = 1; break; case 3: // fax fraged = 1; acked = 0; break; case 4: // speech fraged = 1; acked = 0; break; case 5: // ftp fraged = 1; acked = 1; break; case 6: // http fraged = 1; acked = 1; break; default: fraged = -1; acked = -1; break; } rh->frag() = fraged; // assign value rh->ack() = acked; // assign value return;}// give resources in RLC layer for the flowvoid LLNodeb::update_flow(int acked, int fraged, int flowid, nsaddr_t src, int handover){ if (verbose_) printf("Nodeb %d at %f RRC: Updating flow %d of source %d Nodeb: ack, frag [%d %d]\n" ,ip_nodeb_, NOW, flowid, src, acked, fraged); rlc_->store_flow(acked, fraged, flowid, src, handover); // update RLC layer return;}// send release reply messagevoid LLNodeb::send_release_reply(Packet* p){ Scheduler& s = Scheduler::instance(); hdr_phy *ph = HDR_PHY_UMTS(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ll *lh = HDR_LL(p); // fill physical, ll and common headers lh->lltype() = LL_RELEASE_REPLY; ph->sa() = phy_->nodeb_address_; ch->channel_t() = CCCH; // ch allocation ch->direction() = hdr_cmn::DOWN; if (verbose_) printf("Nodeb %d at %f RRC: sending RELEASE REPLY from ip: %d to ip: %d with da phy %d\n", ip_nodeb_, NOW, getip(ih->saddr()), getip(ih->daddr()), ph->da()); ch->next_hop_ = ih->daddr(); s.schedule(downtarget_, p, delay_); // send the packet down through the scheduler return;}// handler for ReleaseUETimer, release resources in physical layer and mac layervoid LLNodeb::RemoveUEHandler(int addr){ if (verbose_) printf("\nNodeb %d at %f RRC: REMOVING RESOURCES OF Source %d+++++++++++++++++++++++++++++++++++++\n\n" ,ip_nodeb_, NOW, addr); phy_->slot_bytes(addr, 0); // slot bytes = 0 in physical layer phy_->remove_ue(addr); // remove UE in physical layer mac_->remove(addr); // remove resources in MAC layer remove_->DeleteANode(addr); return;}// handler for AppsNodebTimer (contained in TNodebList), send a Connection release messagevoid LLNodeb::RemoveFlowHandler(nsaddr_t src, nsaddr_t dest, int size, int flow){ // The application has finished, a Connection release has to be sent Scheduler& s = Scheduler::instance(); int pos = look_for(dest); Packet* sp = Packet::alloc(); // contruct the packet to send struct hdr_cmn *chsp = HDR_CMN(sp); struct hdr_ll *lhsp = HDR_LL(sp); struct hdr_ip *ihsp = HDR_IP(sp); struct hdr_phy *phsp = HDR_PHY_UMTS(sp); // fill physical, ll, common and ip headers Node * node_ = (Node*)(phy_->netif_->node()); double user_rate = node_->list->lookforrate(getip(src), flow); // get user rate int code = getcode(src, flow); // get channel coding lhsp->tx_rate() = phy_rate(user_rate, code, size); // fill physical rate lhsp->lltype() = LL_RELEASE_REQ; // fill type of message phsp->sa() = phy_->nodeb_address_; phsp->da() = ue_info_[pos].phyaddr_; phsp->c_coding() = CONV_HALF; chsp->channel_t() = CCCH; // ch allocation chsp->next_hop_ = dest; chsp->direction() = hdr_cmn::DOWN; chsp->size() = 5; chsp->error() = 0; ihsp->flowid() = flow; ihsp->saddr() = src; ihsp->daddr() = dest; if (verbose_) printf("\nNodeb %d at %f RRC: sending RELEASE_REQ from ue(ip): %d to ue(ip): %d\n" ,ip_nodeb_, NOW, getip(ihsp->saddr()),getip(ihsp->daddr())); s.schedule(downtarget_, sp->copy(), delay_); // send the packet down through the scheduler Packet::free(sp); sp = NULL; return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -