📄 ll-nodeb.cc
字号:
return (TCL_OK); } } return LL::command(argc, argv);}// get the IP addressint LLNodeb::getip(nsaddr_t addr){ return (Address::instance().get_nodeaddr(addr));}void LLNodeb::recv(Packet* p, Handler* /*h*/){ int i, j, temp; hdr_cmn *ch = HDR_CMN(p); hdr_ll *lh = HDR_LL(p); struct hdr_ip *ihp = HDR_IP(p); hdr_rlc_umts *rh = HDR_RLC_UMTS(p); hdr_phy *ph = HDR_PHY_UMTS(p); FListPtr ptr; assert(initialized()); Scheduler& s = Scheduler::instance(); if (ch->direction() == hdr_cmn::UP){ switch (ch->channel_t()){ case CCCH: // received setup request message, in setup or handover procedures if (lh->lltype() == LL_SETUP) { // try to register the UE if (register_ue(p)) { // UE register in RRC layer update_db(p); // update the static location matrix send_setup_reply(p); // send the setup response message return; } // it has been impossible to register the UE // send a failure message if (verbose_) printf("Nodeb %d at %f RRC: LL_SETUP received. FAILURE, not enough resources for UE %d\n" ,ip_nodeb_, NOW, ue_info_[i].ipaddr_); lh->lltype() = LL_FAILURE; ch->direction() = hdr_cmn::DOWN; ch->next_hop() = ihp->saddr(); s.schedule(downtarget_, p->copy(), delay_); // send the packet down through the scheduler return; } // received release request message, in release procedure if (lh->lltype() == LL_RELEASE_REQ) { if (verbose_) printf("Nodeb %d at %f RRC: LL_RELEASE_REQ received\n", ip_nodeb_, NOW); // check if the node destiny is a mobile node if (ue_node(ihp->daddr())) { // the destination is a moble, check if is in my cell i = look_for(ihp->daddr()); if (i != -1) { // the destination is in my cell // fill physical and common headers ph->sa() = phy_->nodeb_address_; ph->da() = ue_info_[i].phyaddr_; ch->channel_t() = CCCH; // ch allocation ch->direction() = hdr_cmn::DOWN; ch->next_hop() = ihp->saddr(); // send the release request message to the node destiny down through the scheduler s.schedule(downtarget_, p->copy(), delay_); } else { // the destination is not in my cell ch->channel_t() = FROM_RRC; // ch allocation ch->direction() = hdr_cmn::UP; send_to_ra(p); // send the packet to the routing agent } } else { // the destination is a fixed node i = look_for(ihp->saddr()); remove_flow_ul(p,i); // remove the uplink resources allocated for that flow ph->da() = ue_info_[i].phyaddr_; send_release_reply(p); // send release reply message } return; } // received release reply message, in release procedure if (lh->lltype() == LL_RELEASE_REPLY) { if (verbose_) printf("Nodeb %d at %f RRC: LL_RELEASE_REPLY received from ip %d to %d\n", ip_nodeb_, NOW, ihp->saddr(), ihp->daddr()); remove_flow_dl(p->copy()); // remove downlink resources allocated for that flow // check if the release procedure initiator is a mobile i = look_for(ihp->daddr()); if (i != -1) { // the release_req initiator is a UE in my cell remove_flow_ul(p,i); // remove the uplink resources allocated for that flow ph->da() = ue_info_[i].phyaddr_; send_release_reply(p); // send release reply message } else if (ue_node(ihp->daddr())){ // the release_req initiator is a UE in other cell ch->channel_t() = FROM_RRC; // ch allocation ch->direction() = hdr_cmn::UP; send_to_ra(p); // send the packet to the routing agent } else { // the release_req initiator is a fixed node // Delete the timer from the list of timers removeflow_->DeleteANode(ihp->daddr(), ihp->flowid()); } return; } // received resource request message if (lh->lltype() == LL_RES_REQ) { if (verbose_) printf("Nodeb %d at %f RRC: RES_REQ received from ue(ip) %d, to ue(ip) %d\n", ip_nodeb_, NOW, getip(ihp->saddr()), getip(ihp->daddr())); // look for the node destiny i = look_for(ihp->daddr()); if (i != -1) { // the destination is in my cell if (free_res(p)) { // there are enough resources in the downlink update_flow(rh->ack(), rh->frag(), ihp->flowid(), ihp->saddr(),0); pag_proc(p,i); // begin paging procedure } else { // there are not enough resources in the downlink send_res_reply(p, 0); // send a failure } } else { // the UE destination is not in my cell for (j=0; j<MAX_NUM_NODES; j++){ if (registry_[j].ue_ == ihp->daddr()) { // send the request to other Node B send_to_ra(p->copy()); Packet::free(p); break; } } // is a fixed node, give resources if (j == MAX_NUM_NODES) { update_flow(rh->ack(), rh->frag(), ihp->flowid(), ihp->saddr(),0); send_res_reply(p, 1); // send the resource reply message } } return; } // paging response received if (lh->lltype() == LL_PAGING){ i = look_for(ihp->daddr()); if (verbose_) printf("Nodeb %d at %f RRC: PAGING response received from UE %d\n" ,ip_nodeb_, NOW, ihp->daddr()); ifq_->reg(ihp->daddr(), get_bytes(i)); // registring in IFQ update_phy_bytes_slot(i); // updating physical bytes update_flow(rh->ack(), rh->frag(), ihp->flowid(), ihp->daddr(),0); if (ue_node(ihp->saddr())) { // the origin is a mobile node send_res_reply(p->copy(), 1); // send the resource reply message } ue_info_[i].dltempsf_ = -1; // go through the queue sending this flow pkts ptr = flows_->GetNode(ihp->saddr(), ihp->daddr(), ihp->flowid()); if (ptr != NULL) { flows_->wait(ihp->saddr(), ihp->daddr(), ihp->flowid(), 0); temp = fl_->length(); while (temp > 0) { Packet* prov; prov = fl_->deque(); struct hdr_ip *ihprov = HDR_IP(prov); if ((ihprov->flowid() == ihp->flowid()) && (ihprov->daddr() == ihp->daddr())){ // packet belonging to that flow send_msg(prov->copy(),i); }else{ // packet belonging to other flow fl_->enque(prov->copy()); } --temp; Packet::free(prov); } Packet::free(p); p = NULL; return; } } break; case DTCH: // data packet arrived if (ihp->daddr() != ip_nodeb_) { i = look_for(ihp->daddr()); if (i != -1) { // the destiny is in my cell ph->sa() = phy_->nodeb_address_; ph->da() = ue_info_[i].phyaddr_; ch->direction() = hdr_cmn::DOWN; if (verbose_) printf("\nNodeb %d at %f RRC: DTCH to UE(phy): %d\n", ip_nodeb_, NOW,ph->da()); ch->next_hop_ = ue_info_[i].ipaddr_; ch->prev_hop_ = ip_nodeb_; s.schedule(downtarget_, p->copy(), delay_); // send the packet down through the scheduler Packet::free(p); p = NULL; return; } } // packet for me or for a mobile in other cell or for a fixed node if (verbose_) printf("Nodeb %d at %f RRC: sending packet UP with uid:%d and size %d\n", ip_nodeb_, NOW, ch->uid(), ch->size()); s.schedule(uptarget_, p, delay_); // send the packet up through the scheduler break; case TO_RRC: // directives from the physical layer if (ch->ptype() == PT_RRC_FAILURE) { // x.e. no paging response refused->add(ihp->flowid()); int dest = look_for(ihp->daddr()); // remove resources allocated for that flow from OSVF trees remove_res(dest); if (ue_info_[dest].dltempsf_ > 0){ // re-allocate resources alloc_res(p,ue_info_[dest].dltempsf_); ue_info_[dest].dltempsf_ = -1; ue_info_[dest].dltotalr_ -= lh->tx_rate(); } if (ue_node(ihp->saddr())) { // the source is a mobile node send_res_reply(p->copy(),0); // send a failure } else { // Delete the timer from the list of timers removeflow_->DeleteANode(ihp->saddr(), ihp->flowid()); } flows_->DeleteANode(ihp->saddr(), ihp->daddr(), ihp->flowid()); // goes through the queue dropping this flow packets temp = 0; if (fl_->length() > 0) { temp = fl_->length(); while (temp > 0) { Packet* prov = fl_->deque(); struct hdr_ip *ihprov = HDR_IP(prov); if ((ihprov->flowid() == ihp->flowid()) && (ihprov->daddr() == ihp->daddr())){ Packet::free(prov); prov = NULL; } else { // the packet does not belong to this flow fl_->enque(prov); } temp--; } } } Packet::free(p); p = NULL; break; default: Packet::free(p); p = NULL; break; } ///////// direction: DOWN ///////////////// } else { switch (ch->channel_t()){ case FROM_RRC: // packet received from other Node B // Resource reply message received from other cell if (lh->lltype() == LL_RES_REPLY) { nsaddr_t prov = ihp->daddr(); ihp->daddr() = ihp->saddr(); ihp->saddr() = prov; if (ch->ptype() != PT_RRC_FAILURE) { // reply not failure if (verbose_) printf("Nodeb %d at %f RRC: RES_REPLY OK received from other NodeB\n", ip_nodeb_, NOW); // update resources update_flow(rh->ack(), rh->frag(), ihp->flowid(), ihp->saddr(),0); send_res_reply(p->copy(),1); // send the resource reply message } else { // reply failure if (verbose_) printf("Nodeb %d at %f RRC: rx RES_REPLY FAILURE received from other NodeB\n", ip_nodeb_, NOW); // remove resources from the RLC layer rlc_->remove_flow(ihp->flowid(),ihp->daddr()); send_res_reply(p->copy(),0); // send a failure } } // Release request message received from other cell if (lh->lltype() == LL_RELEASE_REQ) { if (verbose_) printf("Nodeb %d at %f RRC: LL_RELEASE_REQ arrived from other cell\n", ip_nodeb_, NOW); i = look_for(ihp->daddr()); // fill physical and common headers ph->sa() = phy_->nodeb_address_; ph->da() = ue_info_[i].phyaddr_; ch->direction() = hdr_cmn::DOWN; ch->channel_t() = CCCH; // ch allocation ch->next_hop() = ihp->daddr(); s.schedule(downtarget_, p, delay_); // send the packet down through the scheduler return; } // Release reply message received from other cell if (lh->lltype() == LL_RELEASE_REPLY) { if (verbose_) printf("Nodeb %d at %f RRC: LL_RELEASE_REPLY arrived from other cell\n", ip_nodeb_, NOW); int j = look_for(ihp->daddr()); remove_flow_ul(p, j); // remove the uplink resources allocated for that flow ph->da() = ue_info_[j].phyaddr_; send_release_reply(p); // send release reply message return; } // message notifing a handover received from the new node B if (lh->lltype() == LL_HANDOVER) { i = look_for(ihp->saddr()); if (i != -1) { if (verbose_) printf("Nodeb %d at %f RRC: HANDOVER received from other NodeB to delete UE %d\n", ip_nodeb_, NOW,ue_info_[i].ipaddr_); if (ue_info_[i].dlsf_ > 0) { remove_res(i); //remove from OSVF trees ue_info_[i].ipaddr_ = -1; //ph->sa() = ue_info_[i].phyaddr_; // deregister that user in the IFQ ifq_->reg(ihp->saddr(), 0.0); // start the timer for removing physical resources remove_->AddANode(ue_info_[i].phyaddr_); remove_->start(ue_info_[i].phyaddr_, 40 * UMTS_FrameTime); // send all the packets stored in the queue to the new node B ptr = flows_->GetNode(ihp->saddr()); if (ptr != NULL) { while (ptr != NULL) { if (!ue_node(ptr->srcaddr_)) { // Delete the timer from the list of timers removeflow_->DeleteANode(ptr->srcaddr_, ptr->flowid_); } flows_->DeleteANode(ptr); ptr = flows_->GetNode(ihp->saddr()); } temp = fl_->length(); while (temp > 0) { Packet* prov; prov = fl_->deque(); struct hdr_ip *ihprov = HDR_IP(prov); if ((ihprov->daddr() == ihp->saddr())){ struct hdr_cmn *chprov = HDR_CMN(prov); chprov->channel_t() = DTCH; // ch allocation chprov->direction() = hdr_cmn::UP; send_to_ra(prov->copy()); // send the packet to the routing agent }else fl_->enque(prov->copy()); --temp; Packet::free(prov); } } } // update fields ue_info_[i].ipaddr_ = -1; ue_info_[i].phyaddr_ = -1; ue_info_[i].dltempsf_ = -1; ue_info_[i].dlsf_ = -1; ue_info_[i].dlfreq_ = -1; ue_info_[i].dltotalr_ = 0; Packet::free(p); p = NULL; return; } } if ((lh->lltype() == LL_FAILURE) && (ch->ptype() == PT_RRC_FAILURE)){ // No resources in other NodeB to support the flow, remove resources int pos = look_for(ihp->daddr()); if (pos >= 0) { if (verbose_) printf("Nodeb %d at %f RRC: FAILURE arrived for flow %d and UE %d\n", ip_nodeb_, NOW, ihp->flowid(), ihp->daddr()); rlc_->remove_flow(ihp->flowid(),ihp->daddr()); double rtemp = lh->tx_rate(); remove_res(pos); // remove resources from OSVF trees lh->tx_rate() = ue_info_[pos].dltotalr_ - rtemp; ue_info_[pos].dltotalr_ = 0; ue_info_[pos].dlsf_ = 0; if (lh->tx_rate() > 0){ // re-allocate resources for the other applications if (free_res(p)){ cal_sf(p); ifq_->reg(ihp->daddr(), get_bytes(pos)); // update bytes in IFQ } } else // deregister that UE in IFQ ifq_->reg(ihp->daddr(), 0.0); // fill physical, ll and common headers lh->tx_rate() = rtemp; update_phy_bytes_slot(pos); // update bytes in physical layer ch->channel_t() = CCCH; // ch allocation ch->direction() = hdr_cmn::DOWN; ph->sa() = phy_->nodeb_address_; ph->da() = ue_info_[pos].phyaddr_; ch->next_hop() = ue_info_[pos].ipaddr_; s.schedule(downtarget_, p->copy(), delay_); // send the packet down through the scheduler } } Packet::free(p); p = NULL; break; default: i = look_for(ihp->daddr()); if (i != -1) { // Resource request message received from other cell if (lh->lltype() == LL_RES_REQ){ if (free_res(p)) { // there are enough resources, register flow flows_->AddANode(ihp->saddr(), ihp->daddr(), ihp->flowid(), 1); if (verbose_) printf("Nodeb %d at %f RRC: LL_RES_REQ arrived from a UE in other cell\n",ip_nodeb_, NOW); pag_proc(p->copy(),i); // begins paging procedure return; } else { // there are not enough resources send_res_reply(p,0); // send a failure } } else { // data packet received // pkt originated in other UE from different cell or in a fixed node if (!refused->refused_flow(ihp->flowid())){ // flow not refused ptr = flows_->GetNode(ihp->saddr(), ihp->daddr(), ihp->flowid()); if (ptr !=NULL) { if (verbose_) printf("Nodeb %d at %f RRC: packet with direction DOWN received from UE %d\n" ,ip_nodeb_, NOW, ihp->saddr()); // is not the first pkt rx if (!ue_node(ihp->saddr())) { // the source is a fixed node, start timer removeflow_->start(ihp->saddr(), ihp->flowid(), 1.0); } if (ptr->wait_ == 1) { // waiting for paging response fl_->enque(p); // store packet until response return; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -