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

📄 phy-umts.cc

📁 对ns2软件进行UMTS扩展
💻 CC
📖 第 1 页 / 共 3 页
字号:
				}				if (wait_ == 1) {	// already in other RACH procedure.					prach_temp_->enque(p);				} else {					wait_ = 1;					rach_recv_ = p->copy();					if (lh->lltype() == LL_SETUP){	// switch on procedure or handover						if (verbose_==1)							printf("UE %d at %f PHY: Cell search procedure starts. Listen to SCH\n", ip_ue_, NOW);						listen_sch_ = 1;						pCell_.start(20*slot_time_); // start timer for cell search procedure					} else {						tx_preamble();	// send preamble for RACH procedure					}					Packet::free(p);					p = NULL;				}				break;			case DCH:				// if (verbose_==1)					//printf("UE %d at %f PHY: DCH with flow %d arrived at PHY with uid:%d\n", ip_ue_, NOW, ih->flowid(), ch->uid());				ul_mux(p);	// to uplink multiplexing chain				break;			default:				if (verbose_==1)					printf("UE %d at %f PHY: Pkt of flow %d arrived at PHY with uid:%d and direction%d:\n",ip_ue_, NOW, ih->flowid(), ch->uid(), ch->direction());				pkttoTx_->enque(p);				break;		}	}return;}// looking for an available Scrambling Codeint PhyUmts::scrambling_allot(){	int index_c_, i = 0;	// begin in an aleatory place	index_c_ = Random::integer(MAX_NUM_SCRAM-1);	while (i < MAX_NUM_SCRAM) {		if (w_control.free_res_[0][index_c_] == 0)			return (index_c_); // index_c is an available scrambling code		i++;		index_c_++;		if (index_c_ == MAX_NUM_SCRAM)			index_c_ = 0;	}	return (-1);  // no free resources}// For Setup and Handover Procedurevoid PhyUmts::cell_selection(Packet* p){	hdr_phy *ph = HDR_PHY_UMTS(p);	if (verbose_==1)		printf("UE %d at %f PHY: analizing SCH power: %e from NodeB with phyaddr %d.....\n\n", ip_ue_,NOW, ph->rx_power(), ph->p_scrambling_c());	if (ph->rx_power() > power_sch_){		// higher power than the one that we have stored, store the new one		selected_sc_ = ph->p_scrambling_c();  // new node B primary scrambling code		selected_p_ = ph->sa();	// new node B physical address		power_sch_ = ph->rx_power();		if (verbose_==1)			printf("UE %d at %f PHY: Nodeb with higher power and scram: %d\n", ip_ue_,NOW, ph->p_scrambling_c());	}	Packet::free(p);	p = NULL;	return;}// for transmitting the RACH preamblevoid PhyUmts::tx_preamble(){	int i, j, index_c_, index_s_;	// looking for an available RACH	i = 0;	j = Random::integer(MAX_NUM_RACH-1);	while (i < MAX_NUM_RACH) {		if (w_control.free_rach_[j] == 0)  // j is an available RACH			break;		i++;		j++;		if (j == MAX_NUM_RACH)			j = 0;	}	// check if there is an available RACH	if (i == MAX_NUM_RACH) {		// there is not any available RACH		// arbitly limited the backoff timer from 4 to 12 slots.-		pPreamble_.stop();		pPreamble_.start();	//start Preamble timer		return;	} else {		// j is the available RACH to use		// looking for an available Scrambling Code		index_c_ = scrambling_allot();		// check if there is an available Scrambling Code		if (index_c_ == -1) {			// there is not any available Scrambling Code			// arbitly limited the backoff timer from 4 to 12 slots.-			pPreamble_.stop();			pPreamble_.start();	//start Preamble timer			return;		} else {			// index_c_ is the available Scrambling Code			// looking for an available Signature			i = 0;			index_s_ = Random::integer(MAX_NUM_SIG-1)+1;			while (i < MAX_NUM_SIG) {				if (w_control.free_res_[index_s_][index_c_] == 0)  // available Signature					break;				i++;				index_s_++;				if (index_s_ == MAX_NUM_SIG + 1)					index_s_ = 1;			}			// check if there is an available Signature			if (i == MAX_NUM_SIG) {				// there is not any available Signature				// arbitly limited the backoff timer from 4 to 12 slots.-				pPreamble_.stop();				pPreamble_.start();	//start Preamble timer				return;			} else {	 		// Preamble with parameters: j, index_c_, index_s_				if (verbose_==1)					printf("UE %d at %f PHY: PREAMBLE with rach: %d, sc: %d, sign: %d\n", ip_ue_,NOW,j, index_c_, index_s_);				// storing preamble characteristics				w_control.signature_ = index_s_;				w_control.rach_tx_ = j;				w_control.scram_tx_ = index_c_;				// building the preamble message				Packet* sp = Packet::alloc();				struct hdr_cmn *chsp = HDR_CMN(sp);				hdr_phy *phsp = HDR_PHY_UMTS(sp);				hdr_ip *ihsp = HDR_IP(sp);				hdr_ll *lhrach_recv = HDR_LL(rach_recv_);				hdr_ip *ihrach_recv = HDR_IP(rach_recv_);				if (lhrach_recv->lltype() == LL_SETUP){					// for setup and handover procedures					phsp->first_access_ = 1;					phsp->da_ = selected_p_;		// destination address				} else {					// for resource allocation					phsp->first_access_ = 0;					phsp->da_ = nodeb_address_;		// destination address				}				phsp->sa_ = ue_address_;	// source address				phsp->scrambling_c_ = index_c_;	// scrambling code				phsp->signature_ = w_control.signature_;	// signature				phsp->used_rach_ = w_control.rach_tx_;		// RACH				phsp->sf_ = 16;  			// spreading factor				phsp->k_ = w_control.signature_;	// k for the channelisation code				chsp->direction_ = hdr_cmn::DOWN;				chsp->ptype() = PT_PREAMBLE;				// calculating message size				chsp->size_=(int)(UMTS_TBLength / (phsp->sf_ * 8));  // bits = 2560/SF				if ((UMTS_TBLength % (phsp->sf_ * 8)) != 0){					chsp->size_++;				}				chsp->error()= 0;				chsp->channel_t()=PRACH; // channel allocation				chsp->next_hop() = ip_nodeb_;				chsp->prev_hop_ = ip_ue_;				ihsp->saddr() = ihrach_recv->saddr();				ihsp->daddr() = ihrach_recv->daddr();				rachtoTx_->enque(sp);  // store preamble in the RACH transmission queue				// arbitly limited the backoff timer from 4 to 12 slots.-				pPreamble_.stop();				pPreamble_.start(); //start Preamble timer				num_preambles_++;			}		}	}	return;}// for channel codingvoid PhyUmts::c_coding(Packet* p){	hdr_cmn *chp = HDR_CMN(p);	hdr_phy *php = HDR_PHY_UMTS(p);	switch (php->c_coding()) {		case TURBO: // turbo coding			chp->size() = 3*chp->size();			break;		case CONV_HALF: // convolutional half			chp->size() = 2*chp->size();			break;		case CONV_THIRD:  // convolutional third			chp->size() = 3*chp->size();			break;		default:			break;	}	return;}// for channel decodingvoid PhyUmts::c_decoding(Packet* p){	hdr_cmn *chp = HDR_CMN(p);	hdr_phy *php = HDR_PHY_UMTS(p);	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;}// uplink multiplexing chainvoid PhyUmts::ul_mux(Packet* p){	int i;	hdr_cmn *chp = HDR_CMN(p);	hdr_phy *php = HDR_PHY_UMTS(p);	c_coding(p);			// for Channel Coding	php->size() = chp->size_;   // store size	php->sa_ = ue_address_;	// source address	php->da_ = nodeb_address_;	// destination address	data_temp_->enque(p);  // store packet for sending it over the air interface	return;}// decoding packets with direction UPvoid PhyUmts::decode(){	int i, j;	Packet* p;	hdr_cmn *chp;	hdr_ip *ihp;	hdr_phy *php;	hdr_phy *phrecv;	// demux DPDCH and extract packets	for (i=0; i<d_control.n_dpdch_; i++) {		phrecv = HDR_PHY_UMTS(rx_dpdch[i]);		// go through the array extracting packets		while (phrecv->dpdch_control_->length() > 0) {			p = phrecv->dpdch_control_->deque();			chp = HDR_CMN(p);			ihp = HDR_IP(p);			php = HDR_PHY_UMTS(p);			hdr_rlc_umts *rhp = HDR_RLC_UMTS(p);			if (php->sa() == nodeb_address_) {				if (in_seq_ == -1) {					// Previusly packets arrived not in sequence					if (php->seqno_ == 0) {						// first physical fragment of a packet						if (php->eofsec_ == 1) {							// last physical fragment of a packet							chp->channel_t() = DCH; // ch mapping							dl_demux(p->copy()); // send it to demux chain							if (verbose_==1)								printf("UE %d at %f PHY: decode: sending end of sequence of flow %d uid %d and size %d from NodeB %d\n",									ip_ue_,NOW, ihp->flowid(),chp->uid(),chp->size(),php->sa());							in_seq_ = 0; // waiting for fragment 0						} else {							// is not the last fragment, drop it							if (verbose_==1)								printf("UE %d at %f PHY: a decode: pkt in seq: %d ue %d flow %d uid %d and size %d from NodeB %d\n",									ip_ue_,NOW, php->seqno_, php->sa(), ihp->flowid(),chp->uid(),chp->size(),php->sa());							in_seq_ = 1; // waiting fragment number 1							Packet::free(p);						}					} else {						// is not the first fragment, drop the packet						if (verbose_==1)							printf("UE %d at %f PHY: decode: not seq: Drop pkt from NodeB %d\n",ip_ue_,NOW, php->sa());						Packet::free(p);					}				} else if (php->seqno_ == in_seq_) {  // Previous packets arrived in sequence					// is the fragment that we expected					if (php->eofsec_ == 1) {						// is the last physical fragment, send it to MAC						chp->channel_t() = DCH;   // ch mapping						dl_demux(p->copy());   // send it to demux chain						in_seq_ = 0;  // waiting fragment number 0						if (verbose_==1)							printf("UE %d at %f PHY: decode: sending end of sequence of flow %d uid %d and size %d from NodeB %d dpdch con size %f\n",								ip_ue_,NOW, ihp->flowid(),chp->uid(),chp->size(),php->sa(),phrecv->size());					} else {						// is not the last fragment, drop the packet						if (verbose_==1)							printf("UE %d at %f PHY: decode: pkt in seq: %d ue %d flow %d uid %d and size %d from NodeB %d dpdch con size %f\n",								ip_ue_, NOW, php->seqno_, php->sa(), ihp->flowid(),chp->uid(),chp->size(),php->sa(),phrecv->size());						in_seq_++;						Packet::free(p);					}				} else {  // Previous packets arrived in sequence					// Previous packets arrived in sequence					if (verbose_==1)						printf("UE %d at %f PHY: decode: pkt not in seq: %d waiting %d ue %d flow %d uid %d and size %d from NodeB %d\n",							ip_ue_,NOW, php->seqno_, in_seq_, php->sa(), ihp->flowid(),chp->uid(),chp->size(),php->sa());					in_seq_ = -1; // not in sequence					Packet::free(p);				}			// used during Handover Procedure			} else if (php->sa() == hnodeb_) {				if (hin_seq_ == -1) {		// Previusly packets arrived in not sequence					if (php->seqno_ == 0) {						// first physical fragment of a packet						if (php->eofsec_ == 1) {							// last physical fragment of a packet							chp->channel_t() = DCH; // ch mapping							dl_demux(p->copy());  // send it to demux chain							if (verbose_==1)								printf("UE %d at %f PHY: decode: pkt UP of flow %d uid %d and size %d from NodeB %d\n",									ip_ue_,NOW, ihp->flowid(),chp->uid(),chp->size(),php->sa());							hin_seq_ = 0;  // waiting fragment number 0						} else {							// is not the last fragment, drop the packet							if (verbose_==1)								printf("UE %d at %f PHY: decode: pkt in seq: %d ue %d flow %d uid %d and size %d from NodeB %d\n",								ip_ue_, NOW, php->seqno_, php->sa(), ihp->flowid(),chp->uid(),chp->size(),php->sa());							hin_seq_ = 1; // waiting for fragment number 1							Packet::free(p);						}					} else {						// is not the first fragment, drop the packet						if (verbose_==1)							printf("UE %d at %f PHY: decode: not seq: Drop pkt from NodeB %d\n",ip_ue_,NOW,php->sa());						Packet::free(p);					}				} else if (php->seqno_ == hin_seq_) {	// Previusly packets arrived in sequence					// is the fragment number that we expected					if (php->eofsec_ == 1) {						// last physical fragment of a packet						chp->channel_t() = DCH;  // ch mapping						dl_demux(p->copy());  // send it to demux chain						hin_seq_ = 0;  // waiting fragment number 0						if (verbose_==1)							printf("UE %d at %f PHY: decode: pkt UP of flow %d uid %d and size %d from NodeB %d\n",								ip_ue_,NOW, ihp->flowid(),chp->uid(),chp->size(),php->sa());					} else {						// is not the last fragment, drop the packet						if (verbose_==1)							printf("UE %d at %f PHY: decode: pkt in seq: %d ue %d flow %d uid %d and size %d from NodeB %d\n",								ip_ue_,NOW, php->seqno_, php->sa(), ihp->flowid(),chp->uid(),chp->size(),php->sa());						hin_seq_++;						Packet::free(p);					}				} else {  // Previous packets arrived in sequence					// is not the fragment number that we expected					if (verbose_==1)						printf("UE %d at %f PHY: decode: pkt not in seq: %d waiting %d ue %d flow %d uid %d and size %d from NodeB %d\n",							ip_ue_,NOW, php->seqno_, hin_seq_, php->sa(), ihp->flowid(),chp->uid(),chp->size(),php->sa());					hin_seq_ = -1;					Packet::free(p);				}			}		}		Packet::free(rx_dpdch[i]); // remove resources		rx_dpdch[i] = NULL;	}	return;}// downlink demultiplexing channelvoid PhyUmts::dl_demux(Packet* p){	int i;	hdr_cmn *chp = HDR_CMN(p);	hdr_phy *php = HDR_PHY_UMTS(p);	chp->direction_ = hdr_cmn::UP;	//if (verbose_==1)	//printf("UE %d at %f PHY: phy --->> mac pkt con uid: %d y size: %d, direccion: %d\n", ip_ue_, NOW,chp->uid(), chp->size(), chp->direction());	c_decoding(p);			// channel decoding	uptarget_->recv(p, this);  // send the packet to MAC layer	return;}// Building dedicated channels depending on the given bytes per slotvoid PhyUmts::mk_dpxch(void){	// Rate matching	int i, j, sf_, k_, n_dpdch;	double index, temp, sum, mod, tbytes, total_size;	hdr_cmn * chp;	hdr_phy * php;	hdr_rlc_umts * rh;	tbytes = 0.0;	sum = 0.0;	total_size = bytes_slot;  // maximum physical bytes that is possible sending in one slot	if (data_temp_->length() > 0) {  // no flows to tx		Packet* p;		// looking for an available Scrambling Code		if (up_slot_ == 0) {			d_sc_ = scrambling_allot();		}		// d_sc_ is the available Scrambling Code		if (total_size > MAX_NUM_BYTES_PER_SLOT){			// is necesary 2 or more DPDCH, with SF=4			// building DPDCH packets			n_dpdch = (int)(total_size / MAX_NUM_BYTES_PER_SLOT);			mod = (int)(total_size) % (MAX_NUM_BYTES_PER_SLOT);			if (mod > 0)				n_dpdch++;			if (n_dpdch > MAX_NUM_DPDCH)				n_dpdch = MAX_NUM_DPDCH;			// n_dpdch is the number of necessary DPDCH for that application			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->size() = 0;				phsp->n_dpdch_ = i+1;				sum = 0.0;				// extracting packets from the buffer to transmit				while (data_temp_->length() > 0){					p = data_temp_->deque();					php = HDR_PHY_UMTS(p);					rh = HDR_RLC_UMTS(p);					sum += php->size();					// check if there is enough space in that DPDCH					if (sum <= MAX_NUM_BYTES_PER_SLOT) {						// there is enough space for the whole packet						php->seqno_ = count;						php->eofsec_ = 1;						phsp->dpdch_control_->enque(p->copy());						phsp->size() += php->size();						count = 0;						Packet::free(p);						if (sum == MAX_NUM_BYTES_PER_SLOT)							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 - sum;						php->seqno_ = 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 - sum;						php->size() = temp - (MAX_NUM_BYTES_PER_SLOT - sum);						count++;						// storing the rest of the packet in the buffer						data_temp_->enqueHead(p);						break;					}				}				sf_ = 4; // spreading factor				// calculate 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

⌨️ 快捷键说明

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