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

📄 phy-umts.cc

📁 对ns2软件进行UMTS扩展
💻 CC
📖 第 1 页 / 共 3 页
字号:
/* -*-	Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* By Pablo Martin and Paula Ballester, * Strathclyde University, Glasgow. * June, 2003.*//* Copyright (c) 2003 Strathclyde University of Glasgow, Scotland. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code and binary code must contain * the above copyright notice, this list of conditions and the following * disclaimer. * * 2. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed at Strathclyde University of * Glasgow, Scotland. * * 3. The name of the University may not be used to endorse or promote * products derived from this software without specific prior written * permission. * STRATHCLYDE UNIVERSITY OF GLASGOW, MAKES NO REPRESENTATIONS * CONCERNING EITHER THE MERCHANTABILITY OF THIS SOFTWARE OR THE * SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE.  The software * is provided "as is" without express or implied warranty of any kind.*/#include <packet.h>#include "delay.h"#include "connector.h"#include "packet.h"#include "random.h"#include "mobilenode.h"#include "address.h"#include <unistd.h>#include "arp.h"#include "ll.h"#include "rlc-umts.h"#include "queue.h"#include "mac.h"#include "phy-umts.h"#include "cmu-trace.h"/////////////////////// bler table /////////////////////////////////double BlerTable::table[2][8] = {		{6.31, 7.94, 10, 15.85, 25.12, 100, 2000, 10000000000},		{0.2, 0.15, 0.1, 0.05, 0.02, 0.001, 0.0001, 0.00001}	};BlerTable::BlerTable() {}double BlerTable::getbler(double ebno) {	int i;	double bler;	bler = 1e-38;	for (i=7; i>-1; i--) {		if (table[0][i] > ebno) {			bler = table[1][i];		} else {			return bler;		}	}	return bler;}/////////////////////////////////////////////////////////////////////int hdr_phy::offset_;// TCL Class for Headerstatic class PhyUmtsHeaderClass : public PacketHeaderClass {public:	PhyUmtsHeaderClass() : PacketHeaderClass("PacketHeader/PhyUmts",							sizeof(hdr_phy)){		bind_offset(&hdr_phy::offset_);	}} class_hdr_phy;// TCL Class for PhyUmtsstatic class PhyUmtsClass : public TclClass {public:	PhyUmtsClass() : TclClass("Phy/Umts") {}	TclObject* create(int, const char*const*) {		return (new PhyUmts());	}} class_phy_umts;// static variablesdouble PhyUmts::slot_time_ = 0;double PhyUmts::rach_slot_time_ = 0;int PhyUmts::verbose_ = {0};static int PhyIndex_ = 0;//constructorPhyUmts::PhyUmts() : LinkDelay(), pUpSlot_(this), pRachUpSlot_(this), pTxPkt_(this), pRxPkt_(this),    pPreamble_(this), pCell_(this), pBler_(this), downtarget_(0), uptarget_(0), ll_(0), netif_(0), mac_(0){	int i,j;	bind("verbose_", &verbose_);	ue_address_ = PhyIndex_++;	nodeb_address_ = -1;	ue_state_ = 0;	pkttoTx_= new PacketQueue();	rachtoTx_= new PacketQueue();	rach_recv_ = NULL;	prach_temp_ = new PacketQueue();	data_temp_ = new PacketQueue();	slot_time_= 0.000667 ;//umts slot is of 666.6 microseconds	rach_slot_time_= 0.00125 ;//umts slot is of 1.25 miliseconds	tx_rate = (int) ((8*80) / slot_time_) ;	error_rate_ = 0;	rx_power_ = 0;	tx_power_ = 0;	threshold_ = 4.652e-10; // the value of Rxthresh_ in WirelessPhy *100	//max_num_ms shud be less that MAX_NUM_NODES	if (PhyIndex_ > MAX_NUM_NODES) {		if (verbose_==1)		   printf("UE %d at %f PHY: Too many nodes taking part. shud be less than %d \n",ip_ue_,NOW, MAX_NUM_NODES);		exit (-1);	}	radio_active_ = 0;	bytes_slot = 0.0;	num_preambles_ = 0;	wait_ = 0;	listen_sccpch_ = 0;	listen_sch_ = 0;	selected_sc_ = -1;	selected_p_ = -1;	handover_ = 0;	in_seq_ = 0;	hin_seq_ = 0;	hnodeb_ = 0;	count = 0;	ip_nodeb_ = -1;	ip_ue_ = -1;	tti_ = 0.0;	power_sch_ = 0;	dl_ErrorRate = 1000000000;  	lastRate = 0;  	Prx = 0;  	dlfreq = -1;  	ulfreq = -1;  	Ioth = 0;  	noIoth = 0;	BTable = new BlerTable();	for (i=0; i<MAX_NUM_SCRAM; i++) {		for (j=0; j< MAX_NUM_SIG + 1; j++) {			w_control.free_res_[i][j] = 0;		}	}//	for (i=0; i< MAX_NUM_SCRAM -1; i++) {//		w_control.dl_scramb_[i] = 0;//	}	for (i=0; i< MAX_NUM_RACH; i++) {		w_control.free_rach_[i] = 0;	}	w_control.p_scrambling_ = -1;	w_control.signature_ = -1;	for (i=0 ; i < MAX_NUM_DPDCH ; i++) {		rx_dpdch[i] = NULL;	}	paging_group_ = -1;	up_slot_=0;	intr1_ = intr_ ; //reqd for the slot timers	intr = intr_ ;	intrb = intr_;	// initialization of timers	pUpSlot_.start((Packet *) (& intr_), 0);	pRachUpSlot_.start((Packet *) (& intr1_), 0);	pBler_.start((Packet *) (& intrb), 0);}int PhyUmts::command(int argc, const char*const* argv){	Tcl& tcl = Tcl::instance();	if (argc == 3) {		if (strcmp(argv[1], "log-target") == 0) {			logtarget_ = (NsObject*) TclObject::lookup(argv[2]);			if(logtarget_ == 0)				return TCL_ERROR;			return TCL_OK;		}		if (strcmp(argv[1], "ll") == 0) {			ll_ = (LL*) TclObject::lookup(argv[2]);                  assert(ll_);			return (TCL_OK);		}		if (strcmp(argv[1], "mac") == 0) {			mac_ = (Mac*) TclObject::lookup(argv[2]);                  assert(mac_);			return (TCL_OK);		}		if (strcmp(argv[1], "netif") == 0) {			netif_ = (Phy*) TclObject::lookup(argv[2]);			return TCL_OK;		}		if (strcmp(argv[1], "down-target") == 0) {			downtarget_ = (NsObject*) TclObject::lookup(argv[2]);			return (TCL_OK);		}		if (strcmp(argv[1], "up-target") == 0) {			uptarget_ = (NsObject*) TclObject::lookup(argv[2]);			return (TCL_OK);		}	}	else if (argc == 2) {		if (strcmp(argv[1], "down-target") == 0) {			tcl.resultf("%s", downtarget_->name());			return (TCL_OK);		}		if (strcmp(argv[1], "up-target") == 0) {			tcl.resultf("%s", uptarget_->name());			return (TCL_OK);		}	}	return LinkDelay::command(argc, argv);}// Return the number of DPDCHs arrivedint PhyUmts::n_rx_dpdch(){	int i, n = 0;	for (i=0 ; i < MAX_NUM_DPDCH ; i++) {		if (rx_dpdch[i] != NULL)			n++;	}	return (n);}// Packets received from NodeBvoid PhyUmts::recv_from_phy(Packet* p, Handler *h){	int i, j, len;	struct hdr_cmn *ch = HDR_CMN(p);	struct hdr_phy *ph = HDR_PHY_UMTS(p);	// if error, drop packet	if ((ch->error() == 1) && (ch->channel_t() != DPCCH)) {		Packet::free(p);		p = NULL;		return;	}	switch (ch->channel_t()) {		case SCH:			if (listen_sch_ && (ph->p_scrambling_c() != w_control.p_scrambling_)) {				// Trying to find another NodeB with receiving power higher than ours				cell_selection(p);			} else{				Packet::free(p);				p = NULL;			}			break;		case AICH:			if ((ph->scrambling_c() == w_control.scram_tx_) && (ph->signature() == w_control.signature_) && (ph->da() == ue_address_)) {				// Response of a Preamble, now is possible to tx RACH				if (verbose_==1)					printf("UE %d at %f PHY: AICH correctly arrived with signature %d\n",ip_ue_,NOW, ph->signature());				pPreamble_.stop();	// stop the preamble timer				num_preambles_ = 0;				mk_msg_rach();	// send message part RACH			} else {				Packet::free(p);			}			break;		case PICH:			if ((ph->scrambling_c() == w_control.p_scrambling_) && (ph->pi() >= 0)) {				// Begin of Paging procedure for some mobile of my paging group				if (ph->pi() == paging_group_){					if (verbose_==1)						printf("UE %d at %f PHY: PICH with our paging group, listening to PCH\n",ip_ue_, NOW);					listen_sccpch_ = 1;	// for initiating procedure				}			}			Packet::free(p);			break;		case PCCPCH:			if (ph->scrambling_c() == w_control.p_scrambling_) {				// measurements of power				if ((ph->rx_power() <= threshold_) && (ph->rx_power() < power_sch_) && (!handover_)) {					struct hdr_ll *lh = HDR_LL(p);					if (verbose_==1)						printf("UE %d at %f PHY: initiating HANDOVER PROCEDURE power arrived %e and power_sch: %e\n"							,ip_ue_, NOW, ph->rx_power(), power_sch_);					lh->lltype() = LL_HANDOVER;					send_to_rrc(p->copy());	// directive to RRC				}				power_sch_ = ph->rx_power();	// take measurement from PCCPCH				for (i=0; i<MAX_NUM_SCRAM; i++){	// update free resources					for (j=0; j<MAX_NUM_SIG + 1; j++){						w_control.free_res_[i][j] = ph->free_resources_[i][j];					}				}//				for (i=0; i<MAX_NUM_SCRAM - 1; i++){//					w_control.dl_scramb_[i] = ph->used_dl_scramb_[i];//				}				for (i=0; i<MAX_NUM_RACH; i++){	// update free RACH					w_control.free_rach_[i] = ph->rach_[i];				}				Packet::free(p);			} else {				Packet::free(p);				p = NULL;				return;			}			break;		case SCCPCH:	// carrying FACH and PCH transport channels			if (((ph->scrambling_c() == w_control.p_scrambling_) || (ph->scrambling_c() == selected_sc_)) && (ph->da() == ue_address_)){				struct hdr_ll *lh = HDR_LL(p);				//Transport Channel: PCH, for Paging procedure				if (lh->lltype() == LL_PAGING) {					if (listen_sccpch_) {						if (verbose_==1)							printf("UE %d at %f PHY: PCH received\n",ip_ue_, NOW);						send_to_rrc(p);	// directive to RRC						listen_sccpch_ = 0;						break;					} else {						Packet::free(p);					}    				}				//Transport Channel: FACH, for Setup, Handover and Release procedures and Acknowledge				if (lh->lltype() == LL_SETUP_REPLY){					if (ph->bofsec_ == 1) {	// begin of sequence						struct hdr_ip *ih = HDR_IP(p);						paging_group_ = ph->paging_group_;	// take paging group						if (handover_ = 1)							ulfreq = ph->freq();	// take new uplink freq for transmitting						handover_ = 0;						w_control.p_scrambling_ = selected_sc_;						hnodeb_ = nodeb_address_;						nodeb_address_ = selected_p_;						ip_nodeb_ = ih->saddr();						hin_seq_ = in_seq_;						in_seq_ = 0;						selected_sc_ = -1;						selected_p_ = -1;						ch->channel_t() = FACH;	// ch mapping						uptarget_->recv(p, this);					} else {						Packet::free(p);						p = NULL;					}				}				if (lh->lltype() == LL_RES_REPLY){					if (ph->bofsec_ == 1) {						if (verbose_==1)							printf("UE %d at %f PHY: FACH with LL_RES_REPLY recived, ul_freq=%d\n",ip_ue_, NOW, ph->freq());						ulfreq = ph->freq();	// take new uplink freq for transmitting						ch->channel_t() = FACH; 	// ch mapping						uptarget_->recv(p, this);					} else {						Packet::free(p);						p = NULL;					}				}				if (ch->ptype() == PT_ACK){	// RLC-Acknowledge mode					//if (verbose_==1)					//	printf("UE %d at %f PHY: ACK received in PHY\n",ip_ue_, NOW);					ch->channel_t() = FACH;	// ch mapping					uptarget_->recv(p, this);				}				if ((lh->lltype() == LL_RELEASE_REPLY) || (lh->lltype() == LL_RELEASE_REQ)){					ch->channel_t() = FACH;	// ch mapping					uptarget_->recv(p, this);				}			} else {				Packet::free(p);				p = NULL;			}			break;		case DPCCH:			// Dedicated control channel			if (ph->da_ == ue_address_) {		// we are the destination				if (verbose_==1)					printf("UE %d at %f PHY: DPCCH arrived with %d DPDCHs and rx power %e\n",						ip_ue_, NOW, ph->dpcch_control().n_dpdch_, ph->rx_power());				Prx = ph->rx_power();		// take power measurements				lastRate = ph->dpcch_control().dpdch_rate_;	// and rate				d_control.n_dpdch_ = ph->dpcch_control().n_dpdch_;				len = n_rx_dpdch();				if (len != d_control.n_dpdch_) {	// check if all DPDCH have arrived					for (j=0; j<len; j++) {						Packet::free(rx_dpdch[j]);						rx_dpdch[j] = NULL;					}					Packet::free(p);					p = NULL;					break;				}				decode();		// all DPDCHs received, starting decoding				Packet::free(p);				p = NULL;			} else {		// For interference modelling				if ((ph->sa() != nodeb_address_) && (ph->freq() == dlfreq)) {					Ioth += ph->rx_power();	// take power measurements					noIoth++;				}				Packet::free(p);				p = NULL;			}			break;		case DPDCH:			// Dedicated data channel			if (ph->da_ == ue_address_) {	// we are the destination				len = n_rx_dpdch();				rx_dpdch[len] = p;	// store DPDCH packet in buffer			} else {				Packet::free(p);				p = NULL;			}			break;		default:			break;	}	return;}void PhyUmts::recv(Packet* p, Handler *h){	hdr_cmn *ch = HDR_CMN(p);	hdr_phy *ph = HDR_PHY_UMTS(p);	hdr_ip *ih = HDR_IP(p);	hdr_ll *lh = HDR_LL(p);	double stime;	int i,len;	if (ch->direction() == hdr_cmn::UP) {		if (ue_state_ == 0){	// UE is switched off, drop packet			Packet::free(p);			p = NULL;		} else {			if (ch->channel_t()==PCCPCH) {				recv_from_phy(p, this);				return;			}			radioSwitch(ON);			stime = TX_Time(p);	// simulation of reception time			pRxPkt_.start(p, stime);		}		return;	}	if (ch->direction() == hdr_cmn::DOWN) {		switch (ch->channel_t()) {			case RACH:				if ((ch->ptype() == PT_ACK) || (lh->lltype() == LL_RELEASE_REQ)) {					// ACK from RLC Layer and Release request from RRC layer					ph->sa() = ue_address_;					mk_msg_rach(p);	// send RACH message without preamble					return;

⌨️ 快捷键说明

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