?? rlc.cc
字號:
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* 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 <errmodel.h>#include <mac.h>#include <rlc.h>#include <address.h>#include <dsr/hdr_sr.h>#include <mac-gprs.h>int hdr_rlc::offset_; static class RLCHeaderClass : public PacketHeaderClass {public: RLCHeaderClass(): PacketHeaderClass("PacketHeader/RLC", sizeof(hdr_rlc)) { bind_offset(&hdr_rlc::offset_); }} class_hdr_rlc;static class RLCClass : public TclClass {public: RLCClass() : TclClass("RLC") {} TclObject* create(int, const char*const*) { return (new RLC); }} class_rlc;int RLC::rlcverbose_ = {0};//rjRLC::RLC() : LinkDelay(), seqno_(0), ackno_(0), macDA_(0), ifq_(0), mac_(0), lanrouter_(0), arptable_(0), varp_(0), downtarget_(0), uptarget_(0), lhSend_(this), acSend_(this), datacounter(0), ackcounter(0), window_(60), rackno_(-1), acked_(0), rlcfraged_(1), rlcfragsz_(500),inseq_(1),unackseqno_(0),numdups(0){ bind("macDA_", &macDA_); bind("acked_", &acked_); bind("rlcfraged_",&rlcfraged_); bind("rlcfragsz_",&rlcfragsz_); bind("rlcverbose_",&rlcverbose_); buf_= new PacketQueue(); Txbuf_ = new PacketQueue(); Rxbuf_ = new PacketQueue();}int RLC::command(int argc, const char*const* argv){ Tcl& tcl = Tcl::instance(); if (argc == 3) { if (strcmp(argv[1], "ifq") == 0) { ifq_ = (Queue*) TclObject::lookup(argv[2]); return (TCL_OK); } if(strcmp(argv[1], "arptable") == 0) { arptable_ = (ARPTable*)TclObject::lookup(argv[2]); assert(arptable_); return TCL_OK; } if(strcmp(argv[1], "varp") == 0) { varp_ = (VARPTable*)TclObject::lookup(argv[2]); assert(varp_); return TCL_OK; } if (strcmp(argv[1], "mac") == 0) { mac_ = (Mac*) TclObject::lookup(argv[2]); assert(mac_); 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); } if (strcmp(argv[1], "lanrouter") == 0) { lanrouter_ = (LanRouter*) TclObject::lookup(argv[2]); return (TCL_OK); } } else if (argc == 2) { if (strcmp(argv[1], "ifq") == 0) { tcl.resultf("%s", ifq_->name()); return (TCL_OK); } if (strcmp(argv[1], "mac") == 0) { tcl.resultf("%s", mac_->name()); 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);}void RLC::recv(Packet* p, Handler* /*h*/){ hdr_cmn *ch = HDR_CMN(p); hdr_rlc *rlch = HDR_RLC(p);//sandy hdr_ip *iph =HDR_IP(p); if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: recv pkt_type=%s uid=%d ipsrc=%d ipdst=%d\n", mac_->addr(), NOW, packet_info.name(ch->ptype()), ch->uid_, Address::instance().get_nodeaddr(iph->saddr()), Address::instance().get_nodeaddr(iph->daddr()));// Sanity Check assert(initialized()); if(p->incoming) { p->incoming = 0; }//if arp packet send to approprite place //sandy if(ch->direction()==hdr_cmn::UP){ if(ch->ptype_ == PT_ARP){ if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: sent an ARP going up to arptable\n", mac_->addr(), NOW); /* arptable_->arpinput(p, this); */ Scheduler& s = Scheduler::instance(); s.schedule(uptarget_, p, delay_); return; } if(ch->ptype_ == PT_LLACK) { if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: sent an llack going up \n", mac_->addr(), NOW); Scheduler& s = Scheduler::instance(); s.schedule(uptarget_, p, delay_); return; } } if(ch->direction()==hdr_cmn::DOWN){ if(ch->ptype_ == PT_ARP){ if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: sent an ARP going down to arptable\n", mac_->addr(), NOW); Scheduler& s = Scheduler::instance(); return; } if(ch->ptype_ == PT_LLACK){ if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: sent an llack going down\n", mac_->addr(), NOW); Scheduler& s = Scheduler::instance(); s.schedule(downtarget_, p, delay_); return; } }//if ack pkt or data pkt... //sandy if(rlch->rlctype_==RLC_ACK) recvACK(p); else recvDATA(p);}void RLC::recvDATA(Packet* p){ hdr_cmn *ch = HDR_CMN(p); if(ch->direction() == hdr_cmn::UP){ if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: DATA on its way up. call sendupDATA\n", mac_->addr(), NOW); sendUpDATA(p); }else{ ch->direction() = hdr_cmn::DOWN; if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: DATA going down. call enqueDATA\n", mac_->addr(), NOW); enqueDATA(p); }}void RLC::enqueDATA(Packet* p){ hdr_cmn *ch = HDR_CMN(p); hdr_ip *ih = HDR_IP(p); hdr_rlc *rlch = HDR_RLC(p); rlch->rlctype() = RLC_DATA; //fragmenting to start here....//sandy int psize; if(rlcfraged_==1) psize=rlcfragsz_; else psize=ch->size_; int bopno=seqno_; int eopno=bopno + (int)((ch->size_-1)/psize); if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: eopno=%d, bopno=%d \n", mac_->addr(), NOW, eopno, bopno); int i=seqno_; for ( i = bopno; i <= eopno; i++){ Packet * sp = p->copy(); hdr_cmn *chsp = HDR_CMN(sp); hdr_rlc *rlchsp = HDR_RLC(sp); rlchsp->seqno_ = 0; rlchsp->bopno_ = bopno; rlchsp->eopno_ = eopno; rlchsp->psize_ = chsp->size_; //hack for now to remeber uid chsp->size_ = psize; chsp->uid_= i; //rj // chsp->next_hop_ = -1; //was a debug option for non-ack mode if((acked_==0)||(chsp->next_hop()==-1)){ rlchsp->seqno_=i; Scheduler& s = Scheduler::instance(); s.schedule(downtarget_, sp, delay_); if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: sending NON-acked down. pkt uid=%d\n", mac_->addr(), NOW,chsp->uid_); }else{ rlchsp->seqno_ =i; seqno_++; buf_->enque(sp); if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: buffering frag. rlc_seqno=%d for pkt uid=%d buf_len=%d\n" , mac_->addr(), NOW, rlchsp->seqno_,chsp->uid_, buf_->length()); } } if((acked_==1)) sendDownDATA();}void RLC::sendDownDATA(void){ Packet* sp; if(!(sp = buf_->deque())){ if (rlcverbose_==1) fprintf(stderr,"<%d> %f RLC: que is empty. length=%d\n", mac_->addr(), NOW,buf_->length()); return; } hdr_rlc *rlcsp=HDR_RLC(sp); if(Txbuf_->length()<window_){ Txbuf_->enque(sp); pktTx_ = sp->copy(); Scheduler& s = Scheduler::instance(); s.schedule(downtarget_, sp->copy(), delay_); lhSend_.stop(); lhSend_.start(0.4); if (rlcverbose_==1) fprintf (stderr, "<%d> %f RLC: Txbuf not full. sending a data pkt down, rlc_seqno=%d from buffer \n", mac_->addr(), NOW, rlcsp->seqno_); sendDownDATA(); }else{ buf_->enqueHead(sp); if (rlcverbose_==1) fprintf (stderr, "<%d> %f RLC: Txbuf full. couldnt send rlc_seqno=%d \n", mac_->addr(), NOW, rlcsp->seqno_); }}void RLC::recvACK(Packet* p){ hdr_rlc *rlch = HDR_RLC(p); //rj
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -