📄 rlc-umts-nodeb.cc
字号:
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* Modified and extended 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.*//* By Sandeep Kumar, Kopparapu Suman and Richa Jain, * Indian Institute of Technology, Bombay. * June, 2001.*//* Copyright (c) 2001 Indian Insitute of Technology, Bombay. * 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 Indian Insitute of * Technology, Bombay. * * 3. The name of the Institute may not be used to endorse or promote * products derived from this software without specific prior written * permission. * INDIAN INSTITUTE OF TECHNOLOGY, BOMBAY, 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 "queue.h"#include "cmu-trace.h"#include "rlc-umts-nodeb.h"/******************************** Timers *********************************/void rTxNodebTimer::start(double time){ Scheduler &s = Scheduler::instance(); assert(busy_ == 0); busy_ = 1; paused_ = 0; stime = s.clock(); rtime = time; assert(rtime >= 0.0); s.schedule(this, &intr, rtime);}void rTxNodebTimer::stop(void){ Scheduler &s = Scheduler::instance(); if(paused_ == 0) s.cancel(&intr); busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0;}void rTxNodebTimer::handle(Event *e){ Scheduler &s = Scheduler::instance(); busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; rlc->rTxHandler(src_, flow_);}//////////////////////////////////////////////////////////////////////////////////////////* TUEList Implementation *//////////////////////////////////////////////////////////////////////////////////////////rTxNodebList:: ~rTxNodebList(){ rTxNodebTimerPtr temp = Head; CurrentPtr = Head; while(CurrentPtr != NULL) {CurrentPtr = CurrentPtr->Next; delete temp; temp=CurrentPtr; }}void rTxNodebList::AddANode(nsaddr_t src, int flow){Tail->Next = new rTxNodebTimer(rlc); Tail=Tail->Next; Tail->flow_ = flow; Tail->src_ = src; return;}rTxNodebTimerPtr rTxNodebList::Previous(rTxNodebTimerPtr index){rTxNodebTimerPtr temp=Head; if(index==Head) //special case, index IS the head :) { return Head; } while(temp->Next != index) { temp=temp->Next; } return temp;}void rTxNodebList::DeleteANode(rTxNodebTimerPtr corpse){ rTxNodebTimerPtr temp; if(corpse == Head) //case 1 corpse = Head {temp=Head; Head=Head->Next; delete temp; } else if(corpse == Tail) //case 2 corpse is at the end { temp=Previous(corpse); temp->Next=NULL; delete corpse; Tail=temp; } else //case 3 corpse is in middle somewhere {temp=Previous(corpse); temp->Next=corpse->Next; delete corpse; } CurrentPtr=Head; //Reset the class tempptr}void rTxNodebList::DeleteANode(nsaddr_t src, int flow){ rTxNodebTimerPtr temp, corpse; corpse = GetNode(src, flow); corpse->stop(); if(corpse == Head) //case 1 corpse = Head {temp=Head; Head=Head->Next; delete temp; } else if(corpse == Tail) //case 2 corpse is at the end { temp=Previous(corpse); temp->Next=NULL; delete corpse; Tail=temp; } else //case 3 corpse is in middle somewhere {temp=Previous(corpse); temp->Next=corpse->Next; delete corpse; } CurrentPtr=Head; //Reset the class tempptr}rTxNodebTimerPtr rTxNodebList::GetNode(nsaddr_t src, int flow){ rTxNodebTimerPtr t=Head; while (t!=NULL){ if ((t->flow_==flow) && (t->src_==src)){ return t; } t=t->Next; } return NULL;}void rTxNodebList::start(nsaddr_t src, int flow, double time){ rTxNodebTimerPtr corpse; corpse = GetNode(src, flow); corpse->stop(); corpse->start(time); return;}void rTxNodebList::stop(nsaddr_t src, int flow){ rTxNodebTimerPtr corpse; corpse = GetNode(src, flow); corpse->stop(); return;}/****************************** RlcUmtsNodeb *************************************/static class RlcUmtsNodebClass : public TclClass {public: RlcUmtsNodebClass() : TclClass("Rlc/UmtsNodeB") {} TclObject* create(int, const char*const*) { return (new RlcUmtsNodeb); }} class_rlc_umts_nodeb;int RlcUmtsNodeb::rlcverbose_ = {0};RlcUmtsNodeb::RlcUmtsNodeb() : LinkDelay(), downtarget_(0), uptarget_(0){ bind("rlcverbose_",&rlcverbose_); bind("rlcfragsz_",&rlcfragsz_); buf_= new PacketQueue(); length_ = 0; int i; for (i=0; i<MAX_LOAD; i++){ info_[i].Txbuf_ = new PacketQueue(); info_[i].Rxbuf_ = new PacketQueue(); info_[i].flow_ = -1; info_[i].src_ = -1; info_[i].fraged_ = 1; info_[i].acked_ = 0; info_[i].seqno_ = 0; // link-layer sequence number info_[i].ackno_ = 0; // ACK received so far info_[i].rackno_ = -1; // seq no of left most pkt info_[i].window_ = 500; // window size for sack info_[i].inseq_ = 1; info_[i].unackseqno_ = 0; info_[i].numdups_ = 0; info_[i].handover_ = 0; } rtxnodeb_ = new rTxNodebList(this);}int RlcUmtsNodeb::command(int argc, const char*const* argv){ Tcl& tcl = Tcl::instance(); if (argc == 3) { 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);}int RlcUmtsNodeb::look_for(int flow, nsaddr_t src){ int i; for (i=0; i<MAX_LOAD; i++) { if ((info_[i].flow_ == flow) && (info_[i].src_ == src)) return(i); } return(-1);}void RlcUmtsNodeb::remove_flow(int flowid, nsaddr_t src){ int i; for (i=0; i<MAX_LOAD; i++) { if ((info_[i].flow_ == flowid) && (info_[i].src_ == src)) { info_[i].src_ = -1; info_[i].flow_ = -1; info_[i].acked_ = 0; info_[i].fraged_ = 1; rtxnodeb_->DeleteANode(src, flowid); if (rlcverbose_) printf("Nodeb %d at %f RLC: /////////////////////////////////REMOVE FLOW %d\n\n",ip_nodeb_, NOW, flowid); return; } } return;}void RlcUmtsNodeb::store_flow(int acked, int fraged, int flowid, nsaddr_t src, int handover){ int i; for (i=0; i<MAX_LOAD; i++) { if ((info_[i].flow_ == flowid) && (info_[i].src_ == src)) return; } for (i=0; i<MAX_LOAD; i++) { if (info_[i].flow_ < 0){ info_[i].src_ = src; info_[i].flow_ = flowid; info_[i].acked_ = acked; info_[i].fraged_ = fraged; info_[i].handover_ = handover; if (rlcverbose_) printf("Nodeb %d at %f RLC: STORE FLOW//////////////////////////// flow %d\n\n\n",ip_nodeb_, NOW, flowid); rtxnodeb_->AddANode(src, flowid); return; } } return;}int RlcUmtsNodeb::getip(hdr_ip* hdr){ return (Address::instance().get_nodeaddr(hdr->saddr()));}void RlcUmtsNodeb::recv(Packet* p, Handler*){ hdr_cmn *ch = HDR_CMN(p); hdr_ip *iph =HDR_IP(p); hdr_ll *lh = HDR_LL(p);// if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLCNodeb: recv pkt_type=%s uid=%d ipsrc=%d ipdst=%d\n",// ip_nodeb_, NOW, packet_info.name(ch->ptype()), ch->uid_,// Address::instance().get_nodeaddr(iph->saddr()),// Address::instance().get_nodeaddr(iph->daddr())); if (ch->channel_t() == DTCH) { recvDATA(p); } else { Scheduler& s = Scheduler::instance(); if (ch->direction() == hdr_cmn::UP) { if(ch->ptype() == PT_ACK){ recvACK(p); } else { ch->size() -= RLC_HDR_SZ; s.schedule(uptarget_, p, delay_); } } if (ch->direction() == hdr_cmn::DOWN) { ch->size() += RLC_HDR_SZ; s.schedule(downtarget_, p, delay_); } } return;}void RlcUmtsNodeb::recvDATA(Packet* p){ int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -