📄 mac-timers_802_11e.cc
字号:
//* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* * Copyright (c) 1997 Regents of the University of California. * 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 must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#undef NDEBUG#include <assert.h>#include <delay.h>#include <connector.h>#include <packet.h>#include <random.h>#include <iostream.h>#define BDEBUG 0 //#include <debug.h>#include <arp.h>#include <ll.h>#include <mac.h>#include <mac/802_11e/mac-timers_802_11e.h>#include <mac/802_11e/mac-802_11e.h> // set to 1 for EDCA, 0 for older EDCF#define EDCA 0 // set to one if retry counter should not be increased// due to internal collision (not standard conform!)#define NO_RTX_INC 0#define INF (1e12)#define ROUND (1e-12)#define MU(x) x * (1e+6)/* ====================================================================== Timers ====================================================================== */voidMacTimer_802_11e::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);}voidMacTimer_802_11e::stop(void){ Scheduler &s = Scheduler::instance(); assert(busy_); if(paused_ == 0) s.cancel(&intr); busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0;}/* ====================================================================== Defer Timer ====================================================================== */voidDeferTimer_802_11e::start(int pri, double time){ Scheduler &s = Scheduler::instance(); bool another = 0; assert(defer_[pri] == 0); for(int i = 0; i < MAX_PRI; i++ ){ if(defer_[i] && busy_) { another = 1; } } if(another){ pause(); } busy_ = 1; defer_[pri] = 1; stime_[pri] = s.clock(); rtime_[pri] = time; double delay = INF; int prio = MAX_PRI + 1; for(int pri = 0; pri < MAX_PRI; pri++){ if(defer_[pri]){ stime_[pri] = s.clock(); double delay_ = rtime_[pri]; if((delay_ < delay)) { delay = delay_; prio = pri; } } } if(prio < MAX_PRI + 1) { assert(rtime_[prio] >=0); s.schedule(this, &intr, rtime_[prio]); paused_ = 0; } else { exit(0); }}void DeferTimer_802_11e::stop(){ busy_ = 0; for(int pri = 0; pri < MAX_PRI;pri++){ if(defer_[pri]) mac->defer_stop(pri); defer_[pri] = 0; stime_[pri] = 0; rtime_[pri] = 0; } Scheduler &s = Scheduler::instance(); s.cancel(&intr);}voidDeferTimer_802_11e::pause(){ Scheduler &s = Scheduler::instance(); for(int pri = 0; pri < MAX_PRI; pri++ ){ if(defer_[pri] && busy_){ double st = s.clock(); //now double rt = stime_[pri]; // Start-Time of defer double sr = st - rt; assert(busy_ && !paused_); if(rtime_[pri] - sr >= 0.0) { rtime_[pri] -= sr; assert(rtime_[pri] >= 0.0); } else{ if(rtime_[pri] + ROUND - sr >= 0.0){ rtime_[pri] = 0; } else { cout<<"ERROR in DeferTimer::pause(), rtime_["<<pri<<"] is "<<rtime_[pri]<<", sr:"<<sr<<" \n"; exit(0); } } } } s.cancel(&intr); paused_ = 1;}void DeferTimer_802_11e::handle(Event *){ Scheduler &s = Scheduler::instance(); double delay = INF; int prio = MAX_PRI + 1; for( int pri = 0; pri < MAX_PRI; pri++) { if(rtime_[pri] >= 0 && defer_[pri]){ double delay_ = rtime_[pri]; if((delay_ < delay) && defer_[pri]) { delay = delay_; prio = pri; } } } if(prio < MAX_PRI + 1){ busy_ = 0; paused_ = 0; defer_[prio] = 0; stime_[prio] = 0.0; rtime_[prio] = 0.0; mac->deferHandler(prio); } else { cout<<"handling ERROR in DeferTimer::handler \n"; exit(0); } //check if there is another DeferTimer active for( int pri = 0; pri < MAX_PRI; pri++) { if(rtime_[pri] >= 0 && defer_[pri]){ rtime_[pri] = 0.0; stime_[pri] = 0.0; defer_[pri] = 0; mac->defer_stop(pri); } } }intDeferTimer_802_11e::defer(int pri) { return defer_[pri];}/* ====================================================================== NAV Timer ====================================================================== */void NavTimer_802_11e::handle(Event *){ busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; mac->navHandler();}/* ====================================================================== Receive Timer ====================================================================== */void RxTimer_802_11e::handle(Event *){ busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; mac->recvHandler();}/* ====================================================================== Send Timer ====================================================================== */void TxTimer_802_11e::handle(Event *){ busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; mac->sendHandler();}/* ====================================================================== Interface Timer ====================================================================== */voidIFTimer_802_11e::handle(Event *){ Scheduler &s = Scheduler::instance(); busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; mac->txHandler(); }/* ====================================================================== Defer Timer for SIFS ====================================================================== */voidSIFSTimer_802_11e::start(int pri, double time){ Scheduler &s = Scheduler::instance(); if(busy_ == 1){cout<<"Mac "<<mac->index_<<", ERROR in SIFSTimer!"; exit(0);} assert(sifs_[pri] == 0); busy_ = 1; sifs_[pri] = 1; stime_[pri] = s.clock(); rtime_[pri] = time; s.schedule(this, &intr, rtime_[pri]);}voidSIFSTimer_802_11e::handle(Event *){ Scheduler &s = Scheduler::instance(); busy_ = 0; prio = 0; for(int pri = 0; pri < MAX_PRI; pri++){ if(sifs_[pri]) { prio = pri; break; } } for(int i = 0; i < MAX_PRI; i++){ sifs_[i] = 0; stime_[i] = 0.0; rtime_[i] = 0.0; } mac->deferHandler(prio); }/* ====================================================================== Backoff Timer ====================================================================== *//* * round to the next slot, * this is needed if a station initiates a transmission * and has not been synchronized by the end of last frame on channel */inline void BackoffTimer_802_11e::round_time(int pri){ if(BDEBUG>2) printf("now %4.8f Mac: %d in BackoffTimer::round_time\n", Scheduler::instance().clock(), mac->index_); if(BDEBUG==1) printf("1 now %4.8f Mac: %d slottime %2.2f rtime_[pri] %2.2f \n", Scheduler::instance().clock(),mac->index_,MU(slottime),MU(rtime_[pri])); // double slottime = mac->phymib_.getSlotTime(); double rmd = remainder(rtime_[pri], slottime); if(rmd + ROUND < 0){ printf("ERROR: in BackoffTimer_802_11e:: round_time, remainder < 0 ?! rmd: %4.20f\n",rmd); exit(1); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -