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

📄 phy-umts-nodeb.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 "phy-umts-nodeb.h"#include "cmu-trace.h"// TCL class for PhyUmtsNodeBstatic class PhyUmtsNodebClass : public TclClass {public:	PhyUmtsNodebClass() : TclClass("Phy/UmtsNodeB") {}	TclObject* create(int, const char*const*) {		return (new PhyUmtsNodeb());	}} class_phy_nodeb_umts;// variablesdouble PhyUmtsNodeb::slot_time_ = 0;double PhyUmtsNodeb::aich_slot_time_ = 0;int PhyUmtsNodeb::verbose_ = {0};static int PhyNodeBIndex_ = 1000;//constructorPhyUmtsNodeb::PhyUmtsNodeb() : LinkDelay(), pDownSlot_(this), pAichSlot_(this), pTxPkt_(this),	pRxPkt_(this), pPaging_(this), pBler_(this), downtarget_(0), uptarget_(0), ll_(0){	int i,j;	bind("verbose_", &verbose_);	nodeb_address_ = PhyNodeBIndex_++;	pkttoTx_= new PacketQueue();	aichtoTx_= new PacketQueue();	pchtoTx_= new PacketQueue();	pch_recv_ = NULL;	paging_temp_ = new PacketQueue();	slot_time_= 0.000667 ;//umts slot is of 666.6 microseconds	aich_slot_time_= 0.00125 ;//umts slot is of 1.25 miliseconds	tx_rate = (int) ((8*80) / slot_time_) ;	radio_active_ = 0;	tti_ = 0.0;	ip_nodeb_ = -1;	wait_ = 0;	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_ = nodeb_address_ + 1000;	for (j=0; j<MAX_NUM_UE; j++){		data_temp_[j] = new PacketQueue();	}	for (j=0; j<MAX_NUM_UE; j++){		ue_id[j] = -1;		error[j] = 1000000000;		addr[j] = -1;	}	for (j=0; j<MAX_NUM_UE; j++){		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;	}	for (j=0; j<MAX_NUM_UE; j++){		for (i=0; i<MAX_NUM_DPDCH; i++){			rx_dpdch[j][i] = NULL;		}	}	for (j=0; j<MAX_NUM_FREQ; j++){		Ioth[j] = 0;  		noIoth[j] = 0;	}	BTable = new BlerTable();	intr1_ = intr_ ; //reqd for the slot timers	intr = intr_ ;	intrb = intr_;	// start timers	pDownSlot_.start((Packet *) (& intr_), 0);	pAichSlot_.start((Packet *) (& intr1_), 0);	pBler_.start((Packet *) (& intrb), 0);}int PhyUmtsNodeb::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);}// checks the number of dpdch receivedint PhyUmtsNodeb::n_rx_dpdch(int id){	int i, n = 0;	for (i=0 ; i < MAX_NUM_DPDCH ; i++) {		if (rx_dpdch[id][i] != NULL)			n++;	}	return (n); // number of dpdch received and stored of a user}// check if the packet is for this Node Bint PhyUmtsNodeb::packet_for_me(Packet* p){	int i;	hdr_phy *ph = HDR_PHY_UMTS(p);	i = look_for(ph->sa());   // checks if the user is in its table of addresses	if (i != -1){		// the user is already registered		ph->sa() = i; // change the user address with the internal addressing		return (1);	}	// the user is not registered	if (ph->first_access_ == 1){		// if the first access of that user: setup or handover		for (i=0; i<MAX_NUM_UE; i++){			if (ue_id[i] < 0){				// registered the user in the table of addresses				ue_id[i] = ph->sa();				ph->sa() = i; // change the user address with the internal addressing				if (verbose_==1)					printf("Nodeb %d at %f PHY: registering UE with phyaddr %d\n", ip_nodeb_, NOW, ue_id[i]);				return (1);			}		}	}	// the user is not registered in our cell	return (0);}// process the packets received from the air interfacevoid PhyUmtsNodeb::recv_from_phy(Packet* p, Handler *h){	int i, j, len;	hdr_cmn *ch = HDR_CMN(p);	hdr_phy *ph = HDR_PHY_UMTS(p);	if (ch->error() == 1) { // if the packet is erroneus drop packet		Packet::free(p);		p = NULL;		return;	}	switch (ch->channel_t()) {		case PRACH:			// it can be a RACH preamble or a RACH message			if (ch->ptype_ == PT_PREAMBLE){				// RACH preamble received				if (verbose_==1)					printf("Nodeb %d at %f PHY: preamble from UE phyaddr %d and signature %d\n",ip_nodeb_, NOW, ph->sa(), ph->signature_);				if (w_control.free_res_[ph->scrambling_c_][ph->signature_] == 0) {					// store the signature used by the preamble to use it in AICH					sig_ue_[ph->sa()] = ph->signature_;					tx_aich(p);  // transmit AICH message				} else {   // the signature was not free					Packet::free(p);					break;				}			} else {  // message RACH				// RACH control part, we don't need it, so drop it				if ((ph->sf_ == 256) && (ph->k_ == 16 * sig_ue_[ph->sa()] + 15)) {					Packet::free(p);					p = NULL;					break;				} else { //  RACH data part					if (ph->bofsec_ == 1) {						// begin of RACH data part, check if the resources were free						if (w_control.free_res_[ph->scrambling_c_][0] == 0) {							// the resources were free, allocate them							w_control.free_res_[ph->scrambling_c_][0] == 1;							// now the resources are not available							// check if is the paging response							hdr_ll *lh = HDR_LL(p);							if (lh->paging_ok_) {								// is a paging response, take the paging message stored								hdr_phy *php = HDR_PHY_UMTS(pch_recv_);								if (ue_id[ph->sa()] == php->da()){									// is the paging response expected									if (verbose_==1)										printf("Nodeb %d at %f PHY: Paging_ok_ rec from UE phyaddr %d\n", ip_nodeb_, NOW, ph->sa());									pPaging_.stop(); // stop the paging timer									// empty pch queue									while(pchtoTx_->length() > 0) {										Packet::free(pchtoTx_->deque());									}									wait_ = 0;   // to begin more paging procedures									ch->channel_t() = RACH;  // ch mapping									uptarget_->recv(p, this);  // send to MAC									Packet::free(pch_recv_);									pch_recv_ = NULL;									// check if there is other rach waiting to be transmited									if (paging_temp_->length() > 0){										wait_ = 1;										// take other PCH, and begin paging request										pch_recv_ = paging_temp_->deque();										tx_pich(pch_recv_->copy()); // transmit PICH									}									break;								} else {									// is not the response expected, drop packet									Packet::free(p);									p = NULL;								}							}						} else {							Packet::free(p);							break;						}//						if (verbose_==1)//							printf("Nodeb %d at %f PHY: rach with sf %d, k %d\n", ip_nodeb_, NOW,ph->sf_, ph->k_);						ch->channel_t() = RACH;  // ch mapping						ph->sa_ = ue_id[ph->sa()];	// change the source address						uptarget_->recv(p, this); // send the RACH to MAC					} else {						// is the end of RACH message						if (ph->eofsec_ == 1){							// free resources							w_control.free_res_[ph->scrambling_c_][0] == 0;						}						Packet::free(p);						p = NULL;					}				}			}			break;		case DPCCH:			if (verbose_==1)				printf("Nodeb %d at %f PHY: DPCCH arrived with %d DPDCHs and rx power %e\n",					ip_nodeb_, NOW, ph->dpcch_control().n_dpdch_, ph->rx_power());			if ((ph->sf_ == 256) && (ph->k_ == 0)) {				// taking power meassurement for calculating the interference				ue_info_[ph->sa()].Prx = ph->rx_power();  // power				ue_info_[ph->sa()].lastRate = ph->dpcch_control().dpdch_rate_; // transmission rate				ue_info_[ph->sa()].nSamples ++;				ue_info_[ph->sa()].IntPower += ph->rx_power();				// take number of dpdch				d_control[ph->sa()].n_dpdch_ = ph->dpcch_control().n_dpdch_;				len = n_rx_dpdch(ph->sa());  // check the number of dpdchs received				// check if all dpdchs transmitted has been received				if (len != d_control[ph->sa()].n_dpdch_){					// they have not been received, drop the dpdch stored					for (j=0; j<len; j++) {						Packet::free(rx_dpdch[ph->sa()][j]);						rx_dpdch[ph->sa()][j] = NULL;					}					break;				}				// all dpdch has been received				decode(ph->sa());  // decode the dpdchs				Packet::free(p);			} else {				Packet::free(p);			}			break;		case DPDCH:			// store DPDCH packet in buffer in the next free possition			len = n_rx_dpdch(ph->sa());			rx_dpdch[ph->sa()][len] = p;			break;		default:			break;	}	return;}// receive all the packets, either with UP or DOWN directionvoid PhyUmtsNodeb::recv(Packet* p, Handler *h){	hdr_cmn *ch = HDR_CMN(p);	hdr_phy *ph = HDR_PHY_UMTS(p);	hdr_ll *lh = HDR_LL(p);	double stime;	int i,len;	if (ch->direction() == hdr_cmn::UP) {		// for the interference model		if ((ch->channel_t() == DPCCH) && (ph->freq() < 12)){			// cpcch received in uplink frequence			Ioth[ph->freq()] += ph->rx_power();			noIoth[ph->freq()]++;		}		if (ch->error() == 1) {			// if packet with error, drops it			Packet::free(p);			return;		}		if (nodeb_address_ == ph->da()) {			// if the packet is for me			if (packet_for_me(p)) {   // checks if the user is registered in its cell				// simulation of reception time				radioSwitch(ON); // turns the radio ON				stime = TX_Time(p);  // calculates transmission time				pRxPkt_.start(p, stime);  // stats reception timer			} else { // the user is not register in this cell				Packet::free(p);				p=NULL;			}		} else {			// the packet is not for me, drop it			Packet::free(p);			p=NULL;		}	}	if (ch->direction() == hdr_cmn::DOWN) {		switch (ch->channel_t()) {			//case BCH:			case PCH:				// paging request received in PCH channel				// checks if there is another paging procedure before				if (wait_) { // there's another paging procedure running					paging_temp_->enque(p);				} else {					// there is not paging procedure running					wait_ = 1;					pch_recv_ = p->copy();  // stores the paging message					tx_pich(p);  // transmits PICH				}				break;			case FACH:				// this channel is goint to be used for:				// setup and handover reply, resource allocation and RLC ACK mode				if (lh->lltype() == LL_SETUP_REPLY) {					// setup or handover procedure					ue_registry(p);  // registries the new UE					i = look_for(ph->da());  // looks for the UE in the addresses registry					ue_info_[i].ul_freq = ph->freq();				}				if (lh->lltype() == LL_RES_REPLY) {					// for resource allocation					i = look_for(ph->da());					ue_info_[i].ul_freq = ph->freq();				}				tx_fach(p);  // transmits FACH message				break;			case DCH:				// user dedicated data channel//				if (verbose_==1)//					printf("Nodeb %d at %f PHY: pkt arrived at NodeB from MAC with %d and direction:%d\n", ip_nodeb_, NOW, ch->uid(), ch->direction());				dl_mux(p);  // calls to the downlink multiplexing channel				break;			default:				Packet::free(p);				p = NULL;				break;		}

⌨️ 快捷键说明

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