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

📄 phy-umts-nodeb.cc

📁 对ns2软件进行UMTS扩展
💻 CC
📖 第 1 页 / 共 3 页
字号:
	switch (php->c_coding()) {		case TURBO:  // turbo coding			chp->size() = (int)(chp->size()/3);			break;		case CONV_HALF:   // convolutional half			chp->size() = (int)(chp->size()/2);			break;		case CONV_THIRD:   // convolutional third			chp->size() = (int)(chp->size()/3);			break;		default:			break;	}	return;}// builds the pdpdchs and dpcch to transmitvoid PhyUmtsNodeb::mk_dpxch(void){	int i, j, uid, k, sf_, k_, index_c_, n_dpdch, freq;	double index, temp, sum, mod, total_size, tbytes;	nsaddr_t ipdaddr;	hdr_cmn * chp;	hdr_phy * php;	hdr_ip * ihp;	// builds dpdchs and dpcch for each UE receiving in its cell	for (uid=0; uid < MAX_NUM_UE; uid++) {		freq = -1;		tbytes = 0.0;		ipdaddr = -1;		total_size = ue_info_[uid].bytes_slot;		if (data_temp_[uid]->length() > 0) {			index_c_ = w_control.p_scrambling_;  // primary scrambling code			Packet* p;			if (total_size > MAX_NUM_BYTES_PER_SLOT_DL){				// it is necessary two or more dpdchs				n_dpdch = (int)(total_size / MAX_NUM_BYTES_PER_SLOT_DL);				mod = (int)(total_size) % MAX_NUM_BYTES_PER_SLOT_DL;				if (mod > 0)					n_dpdch++;				if (n_dpdch > MAX_NUM_DPDCH)					n_dpdch = MAX_NUM_DPDCH;				// n_dpdch is the number of dpdchs requiered				// building dpdchs				for (i=0; i<n_dpdch; i++){					Packet* sp = Packet::alloc();					hdr_cmn *chsp = HDR_CMN(sp);					hdr_phy *phsp = HDR_PHY_UMTS(sp);					phsp->dpdch_control_ = new PacketQueue();					phsp->da() = uid;					phsp->size() = 0;					phsp->n_dpdch_ = i+1;					sum = 0.0;					// if there are messages in the queue to be sent					while (data_temp_[uid]->length() > 0){						p = data_temp_[uid]->deque();						php = HDR_PHY_UMTS(p);						ihp = HDR_IP(p);						ipdaddr = ihp->daddr();						freq = php->freq();						sum += php->size();						// check if there is enough space in that DPDCH						if (sum <= MAX_NUM_BYTES_PER_SLOT_DL) {							// there is enough space for the whole packet							php->seqno_ = ue_info_[uid].count;							php->eofsec_ = 1;							phsp->dpdch_control_->enque(p->copy());							phsp->size() += php->size();							ue_info_[uid].count = 0;							Packet::free(p);							if (sum == MAX_NUM_BYTES_PER_SLOT_DL){								break;							}						} else {							// no space to allocate all the packet in the current DPDCH							sum -= php->size();							temp = php->size();							php->size() = MAX_NUM_BYTES_PER_SLOT_DL - sum;							php->seqno_ = ue_info_[uid].count;							php->eofsec_ = 0;							// sending a part of the message							phsp->dpdch_control_->enque(p->copy());							phsp->size() = phsp->size() + MAX_NUM_BYTES_PER_SLOT_DL - sum;							php->size() = temp - (MAX_NUM_BYTES_PER_SLOT_DL - sum);							ue_info_[uid].count++;							// storing the rest of the packet in the buffer							data_temp_[uid]->enqueHead(p);							break;						}					}					sf_ = 4; // spreading factor					// calculates k_					if (i==0 || i==1)						k_ = 1;					if (i==2 || i==3)						k_ = 3;					if (i==4 || i==5)						k_ = 2;					chsp->channel_t()=DPDCH; // ch mapping					chsp->next_hop() = ipdaddr;					phsp->freq() = freq;  // downlink freq for that user					send_msg(sp->copy(), index_c_, sf_, k_);  // sending DPDCH					Packet::free(sp);					sp = NULL;				}			} else {				// only 1 DPDCH is needed				// building DPDCH packet				n_dpdch = 1;				// calculate the necessary spreading factor for that application				index = total_size;				index = (2 * 320 / total_size);				index = (int)(log(index)/log(2));				sf_ = 2;				for (i=0; i<((int)index - 1); i++) {					sf_ *= 2;				}				// sf_ is the spreading factor chosen				Packet* sp = Packet::alloc();				hdr_cmn *chsp = HDR_CMN(sp);				hdr_phy *phsp = HDR_PHY_UMTS(sp);				phsp->dpdch_control_ = new PacketQueue();				phsp->da() = uid;				phsp->size() = 0;				phsp->n_dpdch_ = 1;				n_dpdch = 1;				// extract packets from the buffer to transmit				while ((tbytes < total_size) && (data_temp_[uid]->length() > 0)){					p = data_temp_[uid]->deque();					php = HDR_PHY_UMTS(p);					ihp = HDR_IP(p);					ipdaddr = ihp->daddr();					freq = php->freq();					hdr_rlc_umts *rhp = HDR_RLC_UMTS(p);					tbytes += php->size();					if (tbytes <= total_size) {						// checks if is possible to send the whole packet						php->seqno_ = ue_info_[uid].count;						php->eofsec_ = 1;						phsp->dpdch_control_->enque(p->copy());						phsp->size() += php->size();						ue_info_[uid].count = 0;						Packet::free(p);					} else {						// no space to allocate all the packet in the current DPDCH						tbytes -= php->size();						temp = php->size();						php->size() = total_size - tbytes;						php->seqno_ = ue_info_[uid].count;						php->eofsec_ = 0;						// sending a part of the message						phsp->dpdch_control_->enque(p->copy());						phsp->size() = phsp->size() + total_size - tbytes;						php->size() = temp - (total_size - tbytes);						ue_info_[uid].count++;						// storing the rest of the packet in the buffer						data_temp_[uid]->enqueHead(p);						break;					}				}				k_ = sf_/4;  // calculates k_				chsp->channel_t()=DPDCH;  // ch mapping				phsp->freq() = freq;				chsp->next_hop() = ipdaddr;				// meter paquete en la cola de tx.				send_msg(sp->copy(), index_c_, sf_, k_); // send packet over the air interface				Packet::free(sp);				sp = NULL;			}			// building DPCCH			Packet* sp = Packet::alloc();			hdr_cmn *chsp = HDR_CMN(sp);			hdr_phy *phsp = HDR_PHY_UMTS(sp);			// calculate de physical rate transmitted			phsp->dpcch_control().dpdch_rate_ = (2 * 2560 / (UMTS_SlotTime * sf_)) * n_dpdch;			phsp->da() = uid;			chsp->channel_t()=DPCCH;			phsp->freq() = freq;			phsp->size() = 1.25;			phsp->dpcch_control().n_dpdch_ = n_dpdch;			if (verbose_==1)			printf("Nodeb %d at %f PHY: DPCCH/%dDPDCH with SF=%d sent to UE phyaddr %d in downslot %d\n"				,ip_nodeb_, NOW, phsp->dpcch_control_.n_dpdch_, sf_, phsp->da(), down_slot_);			chsp->next_hop() = ipdaddr;			send_msg(sp->copy(), index_c_, 256, 0);			Packet::free(sp);			sp = NULL;			continue;		}	}	return;}// sends data packets to the terminalsvoid PhyUmtsNodeb::send_msg(Packet* p, int scram_c, int sf, int k){	int i, ue_address;	hdr_cmn *chp = HDR_CMN(p);	hdr_phy *php = HDR_PHY_UMTS(p);	// get the ue destination address	ue_address = ue_id[php->da()];	php->sa_ = nodeb_address_;	// source address	php->da_ = ue_address;		// destination address	php->scrambling_c_ = scram_c;	// scrambling code	php->sf_ = sf;  			// spreading factor	php->k_ = k;			// k for the channelisation code	// calculates size in bytes depending on the spreading factor chosen	chp->size_=(int)(UMTS_TBLength / (php->sf_ * 8));  // bytes	if ((UMTS_TBLength % (php->sf_ * 8)) != 0){		chp->size_++;	}	chp->error()= 0;	pkttoTx_->enque(p->copy());		// prepare pkt to tx onto air interface	Packet::free(p);	p=NULL;	return;}// sends directives directly to the RRC layervoid PhyUmtsNodeb::send_to_rrc(Packet* p)// method for communicating with the RRC layer. Possible types of messages are://	- PT_RRC_FAILURE	Failure when trying to tx RACH//	- LL_HANDOVER	For handover decission//	- LL_PAGING		Check the paging group broadcasted in PICH{	hdr_cmn *chp = HDR_CMN(p);	hdr_phy *php = HDR_PHY_UMTS(p);	chp->direction_ = hdr_cmn::UP; // puts direction UP	chp->error()= 0;	ll_->recv(p, (Handler*) 0);  // sends to RRC}// Turn on / off the radiovoid PhyUmtsNodeb::radioSwitch(int i){	radio_active_ = i;	EnergyModel *em = netif_->node()->energy_model();	if (i == ON) {   // turns the radio on		if (em && em->sleep()){			em->set_node_sleep(0);		}	}	if (i == OFF) {  // turns the radio off		if (em && !em->sleep()) {			em->set_node_sleep(1);		};	}}// calculates the transmission timedouble PhyUmtsNodeb::TX_Time(Packet *p) {	double len=(HDR_CMN(p))->size();	double t = (double)(len*8)/tx_rate;    return t;}// transmits the packet to the terminalsvoid PhyUmtsNodeb::tx_to_ue(Packet *p){	double stime;	double temp;	hdr_cmn* ch = HDR_CMN(p);	hdr_phy* ph  = HDR_PHY_UMTS(p);	ph->rx_power() = 0;	stime = TX_Time(p);	// calculate tx time//	if (verbose_==1)//		printf("Nodeb %d at %f PHY: txing pkt, sendtime=%f, size=%d\n", ip_nodeb_, NOW, stime, ch->size());	pTxPkt_.start(p->copy(), stime);	// start tx timer	downtarget_->recv(p, this);}// store bytes_slot for the UEvoid PhyUmtsNodeb::slot_bytes(int pdest, double bytes){	int j;	j = look_for(pdest);	ue_info_[j].bytes_slot = bytes;	return;}// Remove UE from ue_info_[]void PhyUmtsNodeb::remove_ue(int addr){	int j = look_for(addr);	// Remove this ue from our structures	ue_info_[j].paging_group = -1;	ue_info_[j].bytes_slot = 0.0;	ue_info_[j].in_seq_ = 0;	ue_info_[j].count = 0;	ue_info_[j].ul_ErrorRate = 1000000000;	ue_info_[j].lastRate = 0;	ue_info_[j].Prx = 0;	ue_info_[j].ul_freq = -1;	ue_info_[j].nSamples = 0;	ue_info_[j].IntPower = 0;	ue_id[j] = -1;	return;}/********************************* HANDLERS **********************************/void PhyUmtsNodeb::PagingHandler(Event *e){	// We have not received response to the paging. Send failure message to RRC	if (verbose_==1)		printf("Nodeb %d at %f PHY: No response to the paging procedure....\n", ip_nodeb_, NOW);	hdr_cmn *ch = HDR_CMN(pch_recv_);	ch->channel_t() = TO_RRC;	ch->ptype() = PT_RRC_FAILURE;	ch->direction() = hdr_cmn::UP;	wait_ = 0;	send_to_rrc(pch_recv_);}// Called after transmission a packet ie when txTimer expires.// Frees the pkt. Turns off the radio.void PhyUmtsNodeb::sendHandler(Event *e){    	Packet::free((Packet *)e);	radioSwitch(OFF);	return;}// Called when BlerTimer expires.// Timer for calculating the Interferencevoid PhyUmtsNodeb::blerHandler(Event *e){	double Eb_No, bler, I = 0;	int i, j = 0;	// Restart timer for next time.	pBler_.start((Packet *)e, 5*UMTS_FrameTime);	for (i=0; i<MAX_NUM_UE; i++) {		if (ue_info_[i].ul_freq < 0) {			// there is not interference for i freq			continue;		}		if ((ue_info_[i].lastRate > 0) && (noIoth[ue_info_[i].ul_freq] > 0)) {			// if there has been any interference			if ((noIoth[ue_info_[i].ul_freq] - ue_info_[i].nSamples) > 0) {				I = (Ioth[ue_info_[i].ul_freq] - ue_info_[i].IntPower)/ (noIoth[ue_info_[i].ul_freq] - ue_info_[i].nSamples);				Eb_No = (CHIP_RATE * ue_info_[i].Prx) / (ue_info_[i].lastRate * I);			} else {				// no interference at all				Eb_No = 1e38;			}		} else {			// no interference at all			Eb_No = 1e38;		}		bler = BTable->getbler(Eb_No);		// consult table (Eb_No)		ue_info_[i].ul_ErrorRate = (int)(1/bler) + 1;		if (verbose_)			printf("Nodeb %d at %f PHY: blerHandler,,, {lastRate Ioth noIoth I Prx EbNo ue freq bler ul_ErrorRate}\n[%f %e %d %e %e %e %d %d %e %lu]\n",				ip_nodeb_, NOW, ue_info_[i].lastRate, Ioth[ue_info_[i].ul_freq],noIoth[ue_info_[i].ul_freq], I, ue_info_[i].Prx, Eb_No, ue_id[i],ue_info_[i].ul_freq, bler, ue_info_[i].ul_ErrorRate);		error[j] = ue_info_[i].ul_ErrorRate;		addr[j] = ue_id[i];		ue_info_[i].nSamples = 0;		ue_info_[i].IntPower = 0;		j++;	}	for (i=0; i<MAX_NUM_FREQ; i++){		Ioth[i] = 0;  		noIoth[i] = 0;	}	// put bounds to the arrays error[] and addr[]	error[j] = 0;	addr[j] = -1;	mac_->ul_interference(addr, error);	// send the results to MAC	return;}// Called after the reception of a packet when RxPktNodebTimer expires.// Turns the radio off and call recv_from_phyvoid PhyUmtsNodeb::recvHandler(Event *e){	u_int32_t dst, src;	int size;	Packet * p = (Packet * )e;	radioSwitch(OFF);	// turn the radio OFF	recv_from_phy(p, this);	// send the packet to analize in method recv_from_phy()	return;}// Called when DownSlotUmtsTimer expiersvoid PhyUmtsNodeb::downslotHandler(Event *e){  	int i,len;	// Restart timer for next slot.	pDownSlot_.start((Packet *)e, slot_time_);	mk_dpxch();		// DPDCH Multiplexing and DPCCH creation	mk_pccpch();	// PCCPCH tx	while (pkttoTx_->length() > 0) {		//start transmission		radioSwitch(ON);	// turn the radio ON		tx_to_ue(pkttoTx_->deque());	// transmit to UE	}	if (pchtoTx_->length() > 0) {		radioSwitch(ON);	// turn the radio ON		tx_to_ue(pchtoTx_->deque());	// transmit to UE	}	// program next slot	down_slot_ ++;	if (down_slot_ == SLOTS_PER_FRAME) {		down_slot_ = 0; //ie wrap around.	}	// load broadcast information for the next slot.	if (down_slot_ == 0)		mk_sch();		// SCH tx	// empty dl_used_scrambling codes array./*	for (i=0; i< MAX_NUM_SCRAM -1; i++) {		w_control.dl_scramb_[i] = 0;	}*/	return;}// Called when AichSlotUmtsTimer expires.void PhyUmtsNodeb::aichslotHandler(Event *e){  	int i,len;	// Restart timer for next slot.	pAichSlot_.start((Packet *)e, aich_slot_time_);	// transmit 1 packet from queue	if (aichtoTx_->length() > 0) {		//start transmission		radioSwitch(ON);//		if (verbose_==1)//			    printf("Nodeb %d at %f PHY: in upslothandler. AICH TX slot=%d \n",//				ip_nodeb_, NOW, down_slot_ );		tx_to_ue(aichtoTx_->deque());	// transmit to UE	}	return;}

⌨️ 快捷键说明

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