⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ll-nodeb.cc

📁 对ns2软件进行UMTS扩展
💻 CC
📖 第 1 页 / 共 4 页
字号:
			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 + -