📄 rlc-umts.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 "ll.h"#include "queue.h"#include "phy-umts.h"#include "cmu-trace.h"#include "rlc-umts.h"/******************************** Timers *********************************/void rTxTimer::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 rTxTimer::stop(void){ Scheduler &s = Scheduler::instance(); if(paused_ == 0) s.cancel(&intr); busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0;}void rTxTimer::handle(Event *e){ Scheduler &s = Scheduler::instance(); busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; rlc->rTxHandler(flow_);}//////////////////////////////////////////////////////////////////////////////////////////* TUEList Implementation *//////////////////////////////////////////////////////////////////////////////////////////rTxList:: ~rTxList(){ rTxTimerPtr temp = Head; CurrentPtr = Head; while(CurrentPtr != NULL) {CurrentPtr = CurrentPtr->Next; delete temp; temp=CurrentPtr; }}void rTxList::AddANode(int flow){Tail->Next = new rTxTimer(rlc); Tail=Tail->Next; Tail->flow_ = flow; return;}rTxTimerPtr rTxList::Previous(rTxTimerPtr index){rTxTimerPtr temp=Head; if(index==Head) //special case, index IS the head :) { return Head; } while(temp->Next != index) { temp=temp->Next; } return temp;}void rTxList::DeleteANode(rTxTimerPtr corpse){ rTxTimerPtr 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 rTxList::DeleteANode(int flow){ rTxTimerPtr temp, corpse; corpse = GetNode(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}rTxTimerPtr rTxList::GetNode(int flow){ rTxTimerPtr t=Head; while (t!=NULL){ if (t->flow_==flow){ return t; } t=t->Next; } return NULL;}void rTxList::start(int flow, double time){ rTxTimerPtr corpse; corpse = GetNode(flow); corpse->stop(); corpse->start(time); return;}void rTxList::stop(int flow){ rTxTimerPtr corpse; corpse = GetNode(flow); corpse->stop(); return;}/****************************** RlcUmts **********************************/int hdr_rlc_umts::offset_;static class RlcUmtsHeaderClass : public PacketHeaderClass {public: RlcUmtsHeaderClass(): PacketHeaderClass("PacketHeader/RlcUmts", sizeof(hdr_rlc_umts)) { bind_offset(&hdr_rlc_umts::offset_); }} class_hdr_rlc_umts;static class RlcUmtsClass : public TclClass {public: RlcUmtsClass() : TclClass("Rlc/Umts") {} TclObject* create(int, const char*const*) { return (new RlcUmts); }} class_rlc_umts;int RlcUmts::rlcverbose_ = {0};RlcUmts::RlcUmts() : LinkDelay(), downtarget_(0), uptarget_(0){ bind_time("rlctime_",&rlctime_); bind("rlcverbose_",&rlcverbose_); bind("rlcfragsz_",&rlcfragsz_); length_ = 0; handover_ = 0; buf_= new PacketQueue(); int i; for (i=0; i<MAX_FLOWS; i++){ info_[i].Txbuf_ = new PacketQueue(); info_[i].Rxbuf_ = new PacketQueue(); info_[i].flow_ = -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].unackseqno_ = 0; info_[i].numdups_ = 0; } for (i=0; i<MAX_FLOWS; i++){ hinfo_[i].Txbuf_ = new PacketQueue(); hinfo_[i].Rxbuf_ = new PacketQueue(); hinfo_[i].flow_ = -1; hinfo_[i].fraged_ = 1; hinfo_[i].acked_ = 0; hinfo_[i].seqno_ = 0; // link-layer sequence number hinfo_[i].ackno_ = 0; // ACK received so far hinfo_[i].rackno_ = -1; // seq no of left most pkt hinfo_[i].window_ = 500; // window size for sack hinfo_[i].unackseqno_ = 0; hinfo_[i].numdups_ = 0; } rtx_ = new rTxList(this);}int RlcUmts::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], "getlen") == 0) { tcl.resultf("%d", info_[0].Txbuf_->length()); return (TCL_OK); } 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 RlcUmts::look_for(int flow){ int i; for (i=0; i<MAX_FLOWS; i++) { if (info_[i].flow_ == flow) { return(i); } } return(-1);}int RlcUmts::get_acked(int flow){ int pos = look_for(flow); return(info_[pos].acked_);}int RlcUmts::get_fraged(int flow){ int pos = look_for(flow); return(info_[pos].fraged_);}void RlcUmts::remove_flow(int flowid){ int i; for (i=0; i<MAX_FLOWS; i++) { if (info_[i].flow_ == flowid) { info_[i].flow_ = -1; info_[i].fraged_ = 1; info_[i].acked_ = 0; rtx_->DeleteANode(flowid); if (rlcverbose_) printf("UE %d at %f RLC: //////////////////////////////////// REMOVE FLOW %d\n\n", ip_ue_, NOW, flowid); return; } }}void RlcUmts::store_flow(int acked, int fraged, int flowid){ int i; for (i=0; i<MAX_FLOWS; i++) { if (info_[i].flow_ == flowid){ info_[i].rackno_ = -1; info_[i].unackseqno_ = 0; return; } } for (i=0; i<MAX_FLOWS; i++) { if (info_[i].flow_ < 0){ info_[i].flow_ = flowid; info_[i].acked_ = acked; info_[i].fraged_ = fraged; if (rlcverbose_) printf("UE %d at %f RLC: ///////////////////////////////// STORE FLOW %d\n\n",ip_ue_, NOW, flowid); rtx_->AddANode(flowid); return; } } return;}void RlcUmts::handover(int flag){ int i; handover_ = flag; if (flag == 1) { for (i=0; i<MAX_FLOWS; i++) { hinfo_[i].flow_ = info_[i].flow_; hinfo_[i].fraged_ = info_[i].fraged_; hinfo_[i].acked_ = info_[i].acked_; hinfo_[i].seqno_ = info_[i].seqno_; hinfo_[i].ackno_ = info_[i].ackno_; hinfo_[i].rackno_ = info_[i].rackno_; hinfo_[i].window_ = 200; hinfo_[i].unackseqno_ = info_[i].unackseqno_; if (rlcverbose_) printf("UE %d at %f RLC: HANDOVER!!!!!!!!!!!!!!!!!!! hinfo_[i].unackseqno_ %d info_[i].unackseqno_ %d\n",ip_ue_, NOW, hinfo_[i].unackseqno_,info_[i].unackseqno_); hinfo_[i].numdups_ = info_[i].numdups_; } } else { for (i=0; i<MAX_FLOWS; i++){ hinfo_[i].flow_ = -1; hinfo_[i].fraged_ = 1; hinfo_[i].acked_ = 0; hinfo_[i].seqno_ = 0; hinfo_[i].ackno_ = 0; hinfo_[i].rackno_ = -1; hinfo_[i].window_ = 500; hinfo_[i].unackseqno_ = 0; hinfo_[i].numdups_ = 0; } } return;}void RlcUmts::recv(Packet* p, Handler*){ hdr_cmn *ch = HDR_CMN(p); hdr_rlc_umts *rlch = HDR_RLC_UMTS(p); hdr_ip *iph =HDR_IP(p); hdr_ll *lh = HDR_LL(p);// if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: recv pkt_type=%s uid=%d ipsrc=%d ipdst=%d\n",// ip_ue_, NOW, packet_info.name(ch->ptype()), ch->uid_,// Address::instance().get_nodeaddr(iph->saddr()),// Address::instance().get_nodeaddr(iph->daddr())); if(ch->ptype() == PT_ACK){ recvACK(p); return; } else { if (ch->channel_t() == DTCH) { //if ack pkt or data pkt... recvDATA(p); } else { Scheduler& s = Scheduler::instance(); if (ch->direction() == hdr_cmn::UP) { ch->size() -= RLC_HDR_SZ; s.schedule(uptarget_, p, delay_); } if (ch->direction() == hdr_cmn::DOWN) { if (lh->lltype() == LL_RES_REQ) { int i = look_for(iph->flowid()); rlch->ack() = info_[i].acked_;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -