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

📄 ll-ue.cc

📁 对ns2软件进行UMTS扩展
💻 CC
📖 第 1 页 / 共 2 页
字号:
		if (apps_[i].flowid_ == ih->flowid()){			// flowid already registered			if (apps_[i].wait_ == 1){				// resources already allocated				appstimer_->start(ih->flowid(), 1.0);   // start time				send_msg(p->copy());		// send packet to IFQ				return (1);			} else if (apps_[i].wait_ == 0) {				// flow waiting for resource reply				appstimer_->start(ih->flowid(), 1.0);	// start time				q_[i]->enque(p);		// store the packet in the queue until response				return (1);			} else {				// is the first packet of that flow				// calculate the physical rate that is going to send over the air interface				apps_[i].rate_ = get_rate(apps_[i].user_rate_, apps_[i].c_coding_, ch->size());				// calculate the interval between two packets				apps_[i].interval_ = (ch->size() * 8)/ apps_[i].user_rate_;				// add a timer for this flow in the list of timers				appstimer_->AddANode(ih->flowid());				appstimer_->start(ih->flowid(), 1.0);  // start timer				// update field of the array apps_[]				apps_[i].dest_ = ih->daddr();				// spreading factor needed in physical layer				apps_[i].sf_ = get_sf(apps_[i].rate_);				send_res_req(p->copy(), i);  // send the resource request message				apps_[i].wait_ = 0;   // put wait = 0 to prevent sending messages				if (verbose_) printf("UE %d at %f RRC: STORING flow %d with physical rate %e and SF %d\n"					,ip_ue_, NOW, ih->flowid(),apps_[i].rate_,apps_[i].sf_);				q_[i]->enque(p->copy());  // store the packet in the queue until response				return (1);			}		}	}	return (0);}// for release procedure: send a release reply messagevoid LLUE::send_release_reply(Packet* p){	Scheduler& s = Scheduler::instance();	Packet *sp = p->copy();	hdr_ll *lh = HDR_LL(sp);	hdr_ip *ih = HDR_IP(sp);	hdr_phy *ph = HDR_PHY_UMTS(sp);	hdr_cmn *ch = HDR_CMN(sp);	// fill ip, common and physical headers	ih->daddr() = ih->saddr();	ih->saddr() = ip_ue_;	lh->lltype() = LL_RELEASE_REPLY;	ph->sa() = ue_address_;	ph->da() = nodeb_address_;	ch->direction() = hdr_cmn::DOWN;	ch->channel_t() = CCCH;  // ch allocation	if (verbose_) printf("UE %d at %f RRC: LL_RELEASE_REPLY sent related to the flowid %d\n",		ip_ue_, NOW, ih->flowid());	s.schedule(downtarget_, sp, delay_);  // send the packet down	Packet::free(p);	return;}// send data packets received from the application to the IFQvoid LLUE::send_msg(Packet* p){	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 ll, physical and common headers	lhp->lltype() = LL_DATA;	for (i=0; i<MAX_NUM_FLOWS; i++) {		if (ihp->flowid() == apps_[i].flowid_) {			lhp->tx_rate() = apps_[i].rate_;  // puts the fisical rate in the packet			break;		}	}	php->c_coding() = apps_[i].c_coding_;  // channel coding	chp->channel_t() = DTCH;  // ch allocation	chp->next_hop_ = ip_nodeb_;	chp->direction() = hdr_cmn::DOWN;	chp->error() = 0;	if (verbose_) printf("UE %d at %f RRC: sending DATA DOWN with uid: %d to destination(ip) %d and flow %d\n",  ip_ue_, NOW, chp->uid(), Address::instance().get_nodeaddr(ihp->daddr()), ihp->flowid());	s.schedule(downtarget_, p, delay_);  // send the packet down through the scheduler	return;}// for paging procedure: send the paging responsevoid LLUE::send_paging_ok(Packet* p){	Scheduler& s = Scheduler::instance();	hdr_ip *ih = HDR_IP(p);	hdr_rlc_umts *rh = HDR_RLC_UMTS(p);	Packet* sp = Packet::alloc();	hdr_ip *ihsp = HDR_IP(sp);	hdr_cmn *chsp = HDR_CMN(sp);	hdr_ll *lhsp = HDR_LL(sp);	hdr_phy *phsp = HDR_PHY_UMTS(sp);	struct hdr_rlc_umts *rhsp = HDR_RLC_UMTS(sp);	// fill physical, ll, rlc, common and ip headers	phsp->sa() = ue_address_;	phsp->da() = nodeb_address_;	phsp->c_coding() = CONV_HALF;	lhsp->lltype() = LL_PAGING;	lhsp->paging_ok_ = 1;	// reponse ok	rhsp->ack() = rh->ack();	rhsp->frag() = rh->frag();	chsp->channel_t() = CCCH;  // ch allocation	chsp->next_hop_ = ip_nodeb_;	chsp->direction() = hdr_cmn::DOWN;	chsp->error() = 0;	chsp->size() = 5;	ihsp->flowid() = ih->flowid();	ihsp->saddr() = ih->saddr();	ihsp->daddr() = ih->daddr();	if (verbose_) printf("UE %d at %f RRC: sending PAGING_OK\n", ip_ue_, NOW);	s.schedule(downtarget_, sp, delay_);  // send the packet down through the scheduler	Packet::free(p);	p = NULL;	return;}// calculate bytes per slot in physical layer and update themvoid LLUE::update_phy_bytes_slot(void){	int i;	double bytes_slot, sum = 0.0;	// add the physical rates of all the applications currently running	for (i=0; i<MAX_NUM_FLOWS; i++) {		if (apps_[i].flowid_ != -1) {			sum += apps_[i].rate_;		}	}	if (sum > 0) {		// gets the spreading factor needed for supporting the total rate		bytes_slot = (2560 / get_sf(sum)) / 8;	// calculate bytes in physical layer		if (sum > 960000)		// if more than one dpdch is requiered			bytes_slot = bytes_slot * ((int)(sum / 960000) + 1);	} else {		// no applications running in that moment		bytes_slot = 0.0;	} 	if (verbose_) printf("UE %d at %f RRC: ~~~~~~~~~~~~~~~~~~~~~ bytes_slot in PHY %f ~~~~~~~~~~~~~~\n", ip_ue_, NOW, bytes_slot);	phy_->bytes_slot = bytes_slot;  // update bytes per slot in physical layer	return;}// register a new application in RRC layerint LLUE::insert_flow(int flow, double rate, Chan_Coding code){	int i;	for (i=0; i<MAX_NUM_FLOWS; i++) {		// looks for a free position		if (apps_[i].flowid_ < 0){			// update apps_[] fieds with the new information			apps_[i].flowid_ = flow;			apps_[i].wait_ = -1;			apps_[i].user_rate_ = rate;			apps_[i].c_coding_ = code;			if (verbose_) printf("UE %d at %f RRC: trying to insert flow %d rate %f sf %d\n",				 ip_ue_, NOW, apps_[i].flowid_, apps_[i].rate_, apps_[i].sf_);			return(i);		}	}	// there is not free position, ERROR	return (-1);}// bytes in ifq per ttidouble LLUE::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	bits = (2560 / apps_[pos].sf_) * (ifq_->tti() / UMTS_SlotTime);  // bits per tti	sum = apps_[pos].rate_;	if (sum > 0) {		if (sum > 960000) // more than one dpdch is required			bits = bits * ((int)(sum / 960000) + 1);	}	bits = (bits * (rlcfsize + rlchdrsize + machdrsize)) / (rlcfsize + rlchdrsize + machdrsize + phyhdrsize);	// apply decoding	switch (apps_[pos].c_coding_) {		case TURBO:  // turbo coding			bits = bits/3;			break;		case CONV_HALF:  // convolutional half			bits = bits/2;			break;		case CONV_THIRD:   // convolutional third			bits = bits/3;			break;		default:			break;	}	// bytes in IFQ for an application per TTI	bits = (bits * rlcfsize) / (rlcfsize + rlchdrsize + machdrsize); 	if (verbose_) printf("UE %d at %f RRC: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bytes_tti in IFQ %f ~~~~~~~~~~~~~~\n", ip_ue_, NOW, bits/8);	return(bits/8);  // bits in IFQ for that application per TTI}// calculate the physical ratedouble LLUE::get_rate(double rate, Chan_Coding code, int psize){	double rt, time;	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	time = (psize * 8)/ rate;		// time between two user packets	int npkts = (int)(psize / rlcfsize);	// number of rlc fragments per user packet	if ((psize % rlcfsize) > 0)		npkts++;	rt = (npkts * rlcfsize * 8)/time;	// effective user rate	rt = (rt * (rlcfsize + rlchdrsize + machdrsize))/rlcfsize;	// user rate before channel coding	// apply channel coding	switch (code) {		case 0:	// turbo coding   			rt = 3*rt;			break;		case 1:	// convolutional half   			rt = 2*rt;			break;		case 2:	// convolutional third   			rt = 3*rt;			break;		default:			break;	}	return(rt);}// send a resource request messagevoid LLUE::send_res_req(Packet* p, int i){	Scheduler& s = Scheduler::instance();	hdr_ip *ih = HDR_IP(p);	hdr_cmn *ch = HDR_CMN(p);	Packet* sp = Packet::alloc();	struct hdr_cmn *chsp = HDR_CMN(sp);	struct hdr_ll *lhsp = HDR_LL(sp);	struct hdr_ip *ihsp = HDR_IP(sp);	struct hdr_phy *phsp = HDR_PHY_UMTS(sp);	// fill ll, common and ip headers	lhsp->lltype() = LL_RES_REQ;	lhsp->tx_rate() = apps_[i].rate_;	lhsp->psize() = ch->size();	lhsp->paging_ok_ = 0;	phsp->c_coding() = CONV_HALF;	chsp->channel_t() = CCCH;  // ch allocation	chsp->next_hop_ = ip_nodeb_;	chsp->direction() = hdr_cmn::DOWN;	chsp->size() = 5;	chsp->error() = 0;	ihsp->flowid() = ih->flowid();	ihsp->saddr() = ih->saddr();	ihsp->daddr() = ih->daddr();	if (verbose_) printf("UE %d at %f RRC: sending RESOURCE_REQUEST from ue(ip): %d to ue(ip): %d\n",  ip_ue_, NOW, Address::instance().get_nodeaddr(ihsp->saddr()),Address::instance().get_nodeaddr(ihsp->daddr()));	s.schedule(downtarget_, sp->copy(), delay_);  // send the packet down through the scheduler	Packet::free(sp);	sp = NULL;	return;}// for setup and handover procedures: send a setup request messagevoid LLUE::send_setup(void){	Packet* sp = Packet::alloc();	struct hdr_cmn *chsp = HDR_CMN(sp);	struct hdr_ll *lhsp = HDR_LL(sp);	struct hdr_ip *ihsp = HDR_IP(sp);	struct hdr_phy *phsp = HDR_PHY_UMTS(sp);	MobileNode * node_ = (MobileNode*)(phy_->netif_->node());	Scheduler& s = Scheduler::instance();	// fill physical, ll, common and ip headers	chsp->direction_ = hdr_cmn::DOWN;	lhsp->tx_rate() = 0;	chsp->size_=32;	chsp->error()= 0;	chsp->channel_t()=CCCH;  // ch allocation	chsp->next_hop_= -1;	phsp->c_coding() = CONV_HALF;	int k, i = 0;	for (k=0; k<MAX_NUM_FLOWS; k++){		phsp->flows_[k][0] = new int;		phsp->flows_[k][1] = new int;		phsp->flows_[k][2] = new int;		*phsp->flows_[k][0] = -1;		*phsp->flows_[k][1] = -1;		*phsp->flows_[k][2] = -1;	}	if (handover_){		// handover procedure		for (k=0; k<MAX_NUM_FLOWS; k++){			if (apps_[k].flowid_ > 0){				// inform the new Node B about the flows already running, and their mode				*phsp->flows_[i][0] = rlc_->get_acked(apps_[k].flowid_);				*phsp->flows_[i][1] = rlc_->get_fraged(apps_[k].flowid_);				*phsp->flows_[i][2] = apps_[k].flowid_;				i++;			}		}	}	ihsp->saddr() = node_->address();	lhsp->lltype() = LL_SETUP;	if (verbose_) printf("UE %d at %f RRC: Trying to Switched ON......\n",  ip_ue_, NOW);	s.schedule(downtarget_, sp, delay_);  // send the packet down through the scheduler	return;}// for switching ON the mobilevoid LLUE::switch_on(void){	ue_state_ = 1;	// change the state in RRC from 0 to 1	phy_->ue_state_ = 1;	// change the state in physical layer from 0 to 1	send_setup();	// begin cell search procedure	return;}// register a new flow in RLC layervoid LLUE::update_flow(int acked, int fraged, int flowid){	if (verbose_) printf("UE %d at %f RRC: Update_flow: ack, frag, flowid [%d %d %d]\n", ip_ue_, NOW, acked, fraged, flowid);	rlc_->store_flow(acked, fraged, flowid);   // register the flow with its characteristics	return;}// configure a new flow in RRC layervoid LLUE::configure_flow(int flow, const char*const& type , double rate){	int acked, fraged;	Chan_Coding code;	// depending on the type of application, chose the mode (ACK or non-ACK),	// the channel coding and if is necessary fragmentation (default fragmentation)	if (strcmp(type, "audio") == 0) {		code = TURBO;	// turbo coding		fraged = 1;		// fragmentation		acked = 0;		// non-ACK mode	}	if (strcmp(type, "video") == 0) {		code = TURBO;	// turbo coding		fraged = 1;		// fragmentation		acked = 0;		// non-ACK mode	}	if (strcmp(type, "mail") == 0) {		code = CONV_THIRD;	// convolutional third		fraged = 1;		// fragmentation		acked = 1;		// ACK mode	}	if (strcmp(type, "fax") == 0) {		code = CONV_HALF;	// convolutional half		fraged = 1;		// fragmentation		acked = 0;		// non-ACK mode	}	if (strcmp(type, "speech") == 0) {		code = CONV_HALF;	// convolutional half		fraged = 1;		// fragmentation		acked = 0;		// non-ACK mode	}	if (strcmp(type, "ftp") == 0) {		code = TURBO;	// turbo coding		fraged = 1;		// fragmentation		acked = 1;		// ACK mode	}	if (strcmp(type, "http") == 0) {		code = CONV_HALF;	// convolutional half		fraged = 1;		// fragmentation		acked = 1;		// ACK mode	}	// register the new flow with its characteristics in the apps_[] array	int i = insert_flow(flow, rate, code);	if (i == -1) {		// too many applications in this terminal		if (verbose_) printf("UE %d at %f RRC: ERROR: Trying to allocate in UE %d more than the MAX_NUM_FLOWS %d permissible\n"			,ip_ue_, NOW, MAX_NUM_FLOWS);		exit(-1);	}	// register the new flow in RLC layer	update_flow(acked, fraged, flow);	return;}// remove resources allocated for a flowvoid LLUE::remove_flow(Packet* p){	int i;	hdr_ip *ih = HDR_IP(p);	// looks for the flow in the array	for (i=0; i<MAX_NUM_FLOWS; i++) {		if (apps_[i].flowid_ == ih->flowid()){			break;		}	}	rlc_->remove_flow(apps_[i].flowid_);	// remove resources from RLC	ifq_->reg(apps_[i].flowid_,0.0);		// remove resources from IFQ	// remove resources from RRC layer	apps_[i].flowid_ = -1;	apps_[i].dest_ = -1;	apps_[i].wait_ = -1;	apps_[i].sf_ = -1;	apps_[i].rate_ = -1;	apps_[i].user_rate_ = -1;	apps_[i].interval_ = -1;	apps_[i].c_coding_ = CONV_HALF;	update_phy_bytes_slot();			// remove resources from PHY	Packet::free(p);	p = NULL;	return;}// begin the release procedurevoid LLUE::AppsHandler(int flow){	// The application has finished;	// we have to send a release request to the Node B and to the node destiny	Scheduler& s = Scheduler::instance();	int pos;	// look for the flow	for (pos=0; pos<MAX_NUM_FLOWS; pos++) {		if (apps_[pos].flowid_ == flow)			break;	}	Packet* sp = Packet::alloc();	struct hdr_cmn *chsp = HDR_CMN(sp);	struct hdr_ll *lhsp = HDR_LL(sp);	struct hdr_ip *ihsp = HDR_IP(sp);	struct hdr_phy *phsp = HDR_PHY_UMTS(sp);	// fill physical, ll, common and ip headers	lhsp->lltype() = LL_RELEASE_REQ;	lhsp->tx_rate() = apps_[pos].rate_;	lhsp->paging_ok_ = 0;	phsp->sa() = ue_address_;	phsp->da() = nodeb_address_;	phsp->c_coding() = CONV_HALF;	chsp->channel_t() = CCCH;  // ch allocation	chsp->next_hop_ = ip_nodeb_;	chsp->direction() = hdr_cmn::DOWN;	chsp->size() = 5;	chsp->error() = 0;	ihsp->flowid() = apps_[pos].flowid_;	ihsp->saddr() = ip_ue_;	ihsp->daddr() = apps_[pos].dest_;	if (verbose_) printf("\nUE %d at %f RRC: ******************* sending RELEASE_REQ to ue(ip): %d\n",  ip_ue_, NOW, Address::instance().get_nodeaddr(ihsp->daddr()));	s.schedule(downtarget_, sp->copy(), delay_);   // send the packet down through the scheduler	Packet::free(sp);	sp = NULL;	return;}

⌨️ 快捷键说明

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