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

📄 ll-nodeb.cc

📁 对ns2软件进行UMTS扩展
💻 CC
📖 第 1 页 / 共 4 页
字号:
								// resources already allocated								send_msg(p,i);	// send packet								return;							}						} else {							// is the first pkt of that flow rx							if (free_res(p)) {   // in the downlink								if (verbose_) printf("Nodeb %d at %f RRC: first packet of flow %d with direction DOWN received from UE %d. Giving resources\n"									,ip_nodeb_, NOW, ihp->flowid(), ihp->saddr());								if (!ue_node(ihp->saddr())) {									filltype(p);									// Add a timer to the list of timers									removeflow_->AddANode(ihp->saddr(), ihp->daddr(), ch->size(), ihp->flowid());									// start timer									removeflow_->start(ihp->saddr(), ihp->flowid(), 1.0);								}								pag_proc(p->copy(),i);	// begin paging procedure								flows_->AddANode(ihp->saddr(), ihp->daddr(), ihp->flowid(), 1);								fl_->enque(p);	// store packet until response								return;							} else {								if (verbose_) printf("Nodeb %d at %f RRC: first packet DOWN of flow %d received from UE %d. No resources available\n"									,ip_nodeb_, NOW, ihp->flowid(), ihp->saddr());								refused->add(ihp->flowid());								// send failure message								if (ue_node(ihp->saddr())) {									// fill ll, common and ip headers									lh->lltype() = LL_FAILURE;									ch->ptype() = PT_RRC_FAILURE;									nsaddr_t temp = ihp->daddr();									ihp->daddr() = ihp->saddr();									ihp->saddr() = temp;									ihp->ttl() = 200;									ch->channel_t() = FROM_RRC;	// ch allocation									s.schedule(uptarget_, p, delay_);  // send the packet up through the scheduler									return;								}							}						}					}				}			}			if (verbose_) printf("Nodeb %d at %f RRC: pkt dropped\n",ip_nodeb_, NOW);			Packet::free(p);			p = NULL;			break;	}	}	return;}// registers the new UE in its internal structureint LLNodeb::register_ue(Packet* p){	int i, j;	hdr_cmn *ch = HDR_CMN(p);	hdr_ip *ih = HDR_IP(p);	hdr_phy *ph = HDR_PHY_UMTS(p);	for (i=0; i<MAX_NUM_UE; i++){		if (ue_info_[i].phyaddr_ == -1){			// register the new UE in array ue_info_[]			ue_info_[i].phyaddr_ = ph->sa();			ue_info_[i].ipaddr_ = ih->saddr();			if (verbose_) printf("Nodeb %d at %f RRC: LL_SETUP received. Reistering UE %d\n"				,ip_nodeb_, NOW, ue_info_[i].ipaddr_);			for (j=0; j<MAX_NUM_FLOWS; j++){				if (*ph->flows_[j][2] > 0) {					// Handover: has flows already running					// register flows in RLC layer					update_flow(*ph->flows_[j][0],*ph->flows_[j][1],*ph->flows_[j][2], ih->saddr(),1);				} else {					break;				}			}			return (1);		}	}	return (0);}// gets bytes per tti for a specific user in IFQdouble LLNodeb::get_bytes(int pos){	double bits, sum;	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	if (ue_info_[pos].dlsf_ > 0) {		bits = 2 * (2560 / ue_info_[pos].dlsf_) * (ifq_->tti() / UMTS_SlotTime);  // bits per tti		sum = ue_info_[pos].dltotalr_;		if (verbose_) printf("Nodeb %d at %f RRC: UE %d with DL sf %d and rate %f\n",			ip_nodeb_,NOW,ue_info_[pos].ipaddr_,ue_info_[pos].dlsf_,ue_info_[pos].dltotalr_);		if (sum > 0) {			if (sum > 1920000)  // more than one dpdch is needed				bits = bits * ((int)(sum / 1920000) + 1);		}		bits = bits/2;	// apply Convolutional Half Rate coding		bits = (bits * rlcfsize) / (rlcfsize + rlchdrsize + machdrsize);		if (verbose_) printf("Nodeb %d at %f RRC: ~~~~~~~~~~~~~~~ bytes_tti in IFQNodeB %f ~~~~~~~~~~~~~~\n",ip_nodeb_, NOW, bits / 8);		return(bits/8);	} else {		return (0.0);	}}// calculate and update bytes in physical layervoid LLNodeb::update_phy_bytes_slot(int pos){	double bytes_slot;	if (ue_info_[pos].dltotalr_ > 0) {		// bytes per slot in physical layer for the actual SF for that UE		bytes_slot = (2 * (2560 / (double)ue_info_[pos].dlsf_) / 8);		if (ue_info_[pos].dltotalr_ > 1920000)			// case of several DPDCHs			bytes_slot = bytes_slot * ((int)(ue_info_[pos].dltotalr_ / 1920000) + 1);	} else {		bytes_slot = 0.0;	// none application for that UE	}	if (verbose_) printf("Nodeb %d at %f RRC: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bytes_slot in PHY %f for UE %d~~~~~~~~~~~~~~\n"		,ip_nodeb_, NOW, bytes_slot, ue_info_[pos].phyaddr_);	ip_nodeb_, NOW, phy_->slot_bytes(ue_info_[pos].phyaddr_, bytes_slot);	// pass the result to phy layer	return;}// returns the code for applications originated in fixed nodesint LLNodeb::getcode(nsaddr_t src, int flow){	int code;	// 0 TURBO, 1 CONV_HALF, 2 CONV_THIRD	Node * node_ = (Node*)(phy_->netif_->node());	// get the type of channel coding for the flow	int type = node_->list->lookfortype(getip(src), flow);	switch (type) {		case 0:	// audio			code = 0;			break;		case 1:	// video			code = 0;			break;		case 2:	// mail			code = 2;			break;		case 3:	// fax			code = 1;			break;		case 4:	// speech			code = 1;			break;		case 5:	// ftp			code = 0;			break;		case 6:	// http			code = 1;			break;		default:			code = -1;			break;	}	return code;}// calculates the spreading factor for a given packetint LLNodeb::cal_sf(Packet* p){	hdr_ll *lh = HDR_LL(p);	hdr_ip *ih = HDR_IP(p);	hdr_cmn *ch = HDR_CMN(p);	double index; 	// bits per slot	if (!ue_node(ih->saddr())) {		// if the source is a fixed node takes the inf from list		Node * node_ = (Node*)(phy_->netif_->node());		index = node_->list->lookforrate(getip(ih->saddr()), ih->flowid());		int code = getcode(ih->saddr(), ih->flowid());	// take channel coding		index = phy_rate(index, code, ch->size());	// get physical rate for the application										// with the channel coding already calc.		index = index * UMTS_SlotTime / 8; // bytes per slot in physical layer	} else {		// takes the information from the packet		index = lh->tx_rate() * UMTS_SlotTime / 8; // bytes per slot in physical layer	}	if (index > 0) { // calculate the SF for that physical rate		index = (2*320 / index);		index = (int)(log(index)/log(2));		int i, r, sf_ = 2;		if (index > 9) index = 9;		if (index < 2) index = 2;		for (i=0; i<((int)index - 1); i++) {			sf_ *= 2;		}		if (verbose_) printf("Nodeb %d at %f RRC: the DL SF given is %d\n", ip_nodeb_, NOW,sf_);		return(sf_);	} else		return(0);}// calculates the spreading factor for a given physical rateint LLNodeb::cal_sf(double rate){	double index; 	// bits per slot	index = rate * UMTS_SlotTime / 8; // bytes per slot in physical layer	if (index > 0) { // calculate the SF for that physical rate		index = (2*320 / index);		index = (int)(log(index)/log(2));		int i, r, sf_ = 2;		if (index > 9) index = 9;		if (index < 2) index = 2;		for (i=0; i<((int)index - 1); i++) {			sf_ *= 2;		}		if (verbose_) printf("Nodeb %d at %f RRC: the DL SF given is %d\n", ip_nodeb_, NOW,sf_);		return(sf_);	} else		return(0);}// allocate resources in the OSVF treesint LLNodeb::alloc_res(Packet* p, int sf){	hdr_ip *ih = HDR_IP(p);	int i, r;	if (verbose_) printf("\nNodeb %d at %f RRC: Trying to give sf %d from OVSF trees\n", ip_nodeb_, NOW,sf);	int j = Random::integer(MAX_NUM_FREQ-1);	for (i=0; i<MAX_NUM_FREQ; i++) {	// for any frequencies		if (dl_sftree[j]->insert_sf(getip(ih->daddr()), sf)) {// allocate resources			r = look_for(ih->daddr());			ue_info_[r].dlsf_ = sf;		// update SF for that UE			ue_info_[r].dlfreq_ = j + 12; // update freq for that UE (downlink)			return(1);		}		j++;		if (j == MAX_NUM_FREQ) j = 0;	}	return(0);}// remove resources in the OSVF treesint LLNodeb::remove_res(int pos){	int i;	if (verbose_) printf("Nodeb %d at %f RRC: Removing UE %d with sf %d and freq %d from OSVF\n",		ip_nodeb_, NOW,ue_info_[pos].ipaddr_, ue_info_[pos].dlsf_,ue_info_[pos].dlfreq_ - 12);	if (dl_sftree[ue_info_[pos].dlfreq_ - 12]->remove_sf(ue_info_[pos].ipaddr_, ue_info_[pos].dlsf_)) {		// resources removed successfully		return(1);	}	// resuorces not removed successfully	return(0);}// remove downlink resources allocated for that flowvoid LLNodeb::remove_flow_dl(Packet* p){	hdr_ip *ihp = HDR_IP(p);	hdr_phy *ph = HDR_PHY_UMTS(p);	hdr_ll *lh = HDR_LL(p);	int temp;	int i = look_for(ihp->saddr());	if (verbose_) printf("Nodeb %d at %f RRC: remove_flow_dl of UE with ip %d total rate stored %e rate in the message %e\n",		ip_nodeb_, NOW, ihp->saddr(),ue_info_[i].dltotalr_,lh->tx_rate());	if (ue_info_[i].dlsf_ > 0) {	// flows already allocated for that node		remove_res(i);	//remove downlink resources from OSVF trees		rlc_->remove_flow(ihp->flowid(),ue_info_[i].ipaddr_);	// remove resources in RLC layer		ue_info_[i].dltotalr_ -= lh->tx_rate();	// decrease physical rate for that UE		if (ue_info_[i].dltotalr_ > 0) {			// there are still active flows for that UE; reallocate resources			if (verbose_) printf("Nodeb %d at %f RRC: remove_flow_dl: given resources again\n", ip_nodeb_, NOW);			int sf = cal_sf(ue_info_[i].dltotalr_);	// recalculate the needed SF			nsaddr_t tempd = ihp->daddr();			ihp->daddr() = ihp->saddr();			alloc_res(p->copy(),sf);	// reallocate resources in OSVF trees			ihp->daddr() = tempd;		} else {			// that UE has not got any other application running			ue_info_[i].dltotalr_ = 0;			ue_info_[i].dlsf_ = -1;		}		ph->sa() = ue_info_[i].phyaddr_;		ifq_->reg(ihp->saddr(), get_bytes(i));	// update IFQ layer for that UE		update_phy_bytes_slot(i);		// update physical rate needed for that UE		FListPtr ptr = flows_->GetNode(ihp->daddr(), ihp->saddr(), ihp->flowid());		if (ptr != NULL) {			// delete flow from the list			flows_->DeleteANode(ptr);			temp = fl_->length();			while (temp > 0) {	// free packets of that flow waiting for resource allocation				Packet* prov;				prov = fl_->deque();				struct hdr_ip *ihprov = HDR_IP(prov);				if ((ihprov->flowid() == ihp->flowid()) && (ihprov->daddr() == ihp->saddr())){					drop(prov);				}else					fl_->enque(prov);				--temp;			}		}	}	return;}// remove the uplink resources allocated for that flowvoid LLNodeb::remove_flow_ul(Packet* p, int pos){	hdr_ip *ihp = HDR_IP(p);	if (verbose_) printf("Nodeb %d at %f RRC: Removing UL resources to UE %d\n"		,ip_nodeb_, NOW,ue_info_[pos].ipaddr_);	rlc_->remove_flow(ihp->flowid(),ue_info_[pos].ipaddr_);	// remove resources in RLC layer	if (ue_info_[pos].ipaddr_ == ihp->saddr()){	// update addresses		ihp->saddr() = ihp->daddr();		ihp->daddr() = ue_info_[pos].ipaddr_;	}	return;}// update the static structure registry_void LLNodeb::update_db(Packet* p){	int i, j;	hdr_cmn *ch = HDR_CMN(p);	hdr_phy *ph = HDR_PHY_UMTS(p);	hdr_ip *ih = HDR_IP(p);	// UE already registered (handover procedure)	for (i=0; i<MAX_NUM_NODES; i++){		if (registry_[i].ue_ == ih->saddr()){			update_nodeb(p->copy(), registry_[i].nodeb_);// send a HANDOVER message to the former Nodeb			registry_[i].nodeb_ = ip_nodeb_;	// update the registry_			if (verbose_) printf("Nodeb %d at %f RRC: Handover procedure, ue(ip): %d updated\n"				,ip_nodeb_, NOW, getip(ih->saddr()));			break;		}	}	// UE not registered in the system (turn on procedure)	if (i == MAX_NUM_NODES) {		for (i=0; i<MAX_NUM_NODES; i++){			if (registry_[i].ue_ < 0){		// update registry_				registry_[i].ue_ = ih->saddr();				registry_[i].nodeb_ = ip_nodeb_;				if (verbose_) printf("Nodeb %d at %f RRC: Turn on procedure, ue(ip): %d updated\n",					ip_nodeb_, NOW,  getip(ih->saddr()));				break;			}		}	}	return;}// send a HANDOVER message to the former Nodeb for the incoming UEvoid LLNodeb::update_nodeb(Packet* p, nsaddr_t addr){	hdr_ip *ih = HDR_IP(p);	hdr_ll *lh = HDR_LL(p);	hdr_cmn *ch = HDR_CMN(p);	// fill common and ip headers	ch->direction() = hdr_cmn::DOWN;	ch->channel_t() = FROM_RRC;	// ch allocation	ch->next_hop() = addr;	ih->daddr() = addr;	lh->lltype() = LL_HANDOVER;	// set type of message	send_to_ra(p);	// send the packet to the routing agent	return;}// returns the position in ue_info_[] fo that UEint LLNodeb::look_for(nsaddr_t ad){	int i;	for (i=0; i<MAX_NUM_UE; i++) {		if (ue_info_[i].ipaddr_ == ad)			return(i);	// found it	}	return(-1);	// not found it}// returns if the UE is a fixed node (0) or a UE (1)int LLNodeb::ue_node(nsaddr_t source){	int i;	int dir = getip(source);	for (i=0; i<MAX_NUM_NODES; i++){		if (registry_[i].ue_ == source){	// UE			return(1);		}	}	return(0);	// fixed node}// send data packets downwardsvoid LLNodeb::send_msg(Packet* p, int loc){	int i;	Scheduler& s = Scheduler::instance();	hdr_cmn *chp = HDR_CMN(p);	hdr_ll *lhp = HDR_LL(p);	hdr_ip *ihp = HDR_IP(p);	hdr_phy *php = HDR_PHY_UMTS(p);	// fill physical, ll, rlc, common and ip headers	lhp->lltype() = LL_DATA;	php->sa() = phy_->nodeb_address_;	php->da() = ue_info_[loc].phyaddr_;	php->freq() = ue_info_[loc].dlfreq_;	chp->channel_t() = DTCH;	// ch allocation	chp->next_hop_ = ihp->daddr();	chp->prev_hop_ = ip_nodeb_;	chp->direction() = hdr_cmn::DOWN;	chp->error() = 0;	// if it is a flow generated in a wired node, rlc in frag mode (default)	if (!ue_node(ihp->saddr())) {		hdr_rlc_umts *rhp = HDR_RLC_UMTS(p);		rhp->frag() = 1;		rhp->bopno() = 0;		rhp->rlctype() = RLC_DATA;		i = getcode(ihp->saddr(), ihp->flowid());	// get channel coding		switch (i){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -