📄 bsscheduler.cc
字号:
/* This software was developed at the National Institute of Standards and * Technology by employees of the Federal Government in the course of * their official duties. Pursuant to title 17 Section 105 of the United * States Code this software is not subject to copyright protection and * is in the public domain. * NIST assumes no responsibility whatsoever for its use by other parties, * and makes no guarantees, expressed or implied, about its quality, * reliability, or any other characteristic. * <BR> * We would appreciate acknowledgement if the software is used. * <BR> * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING * FROM THE USE OF THIS SOFTWARE. * </PRE></P> * @author rouil */#include "bsscheduler.h"#include "burst.h"#include "dlburst.h"#include "ulburst.h"#include "random.h"#include "wimaxctrlagent.h"#include "mac802_16BS.h"/** * Bridge to TCL for BSScheduler */static class BSSchedulerClass : public TclClass {public: BSSchedulerClass() : TclClass("WimaxScheduler/BS") {} TclObject* create(int, const char*const*) { return (new BSScheduler()); }} class_bsscheduler;/* * Create a scheduler */BSScheduler::BSScheduler () { debug2 ("BSScheduler created\n"); default_mod_ = OFDM_BPSK_1_2; bind ("dlratio_", &dlratio_); //dlratio_ = DEFAULT_DL_RATIO; contention_size_ = MIN_CONTENTION_SIZE; nextDL_ = -1; nextUL_ = -1;} /** * Return the MAC casted to BSScheduler * @return The MAC casted to BSScheduler */Mac802_16BS* BSScheduler::getMac(){ return (Mac802_16BS*)mac_;}/* * Interface with the TCL script * @param argc The number of parameter * @param argv The list of parameters */int BSScheduler::command(int argc, const char*const* argv){ if (argc == 3) { if (strcmp(argv[1], "set-default-modulation") == 0) { if (strcmp(argv[2], "OFDM_BPSK_1_2") == 0) default_mod_ = OFDM_BPSK_1_2; else if (strcmp(argv[2], "OFDM_QPSK_1_2") == 0) default_mod_ = OFDM_QPSK_1_2; else if (strcmp(argv[2], "OFDM_QPSK_3_4") == 0) default_mod_ = OFDM_QPSK_3_4; else if (strcmp(argv[2], "OFDM_16QAM_1_2") == 0) default_mod_ = OFDM_16QAM_1_2; else if (strcmp(argv[2], "OFDM_16QAM_3_4") == 0) default_mod_ = OFDM_16QAM_3_4; else if (strcmp(argv[2], "OFDM_64QAM_2_3") == 0) default_mod_ = OFDM_64QAM_2_3; else if (strcmp(argv[2], "OFDM_64QAM_3_4") == 0) default_mod_ = OFDM_64QAM_3_4; else return TCL_ERROR; return TCL_OK; } else if (strcmp(argv[1], "set-contention-size") == 0) { contention_size_ = atoi (argv[2]); assert (contention_size_>=0); return TCL_OK; } } return TCL_ERROR;}/** * Initializes the scheduler */void BSScheduler::init (){ WimaxScheduler::init(); // If the user did not set the profiles by hand, let's do it // automatically if (getMac()->getMap()->getDlSubframe()->getProfile (DIUC_PROFILE_1)==NULL) { Profile *p = getMac()->getMap()->getDlSubframe()->addProfile ((int)round((getMac()->getPhy()->getFreq()/1000)), OFDM_BPSK_1_2); p->setIUC (DIUC_PROFILE_1); p = getMac()->getMap()->getDlSubframe()->addProfile ((int)round((getMac()->getPhy()->getFreq()/1000)), OFDM_QPSK_1_2); p->setIUC (DIUC_PROFILE_2); p = getMac()->getMap()->getDlSubframe()->addProfile ((int)round((getMac()->getPhy()->getFreq()/1000)), OFDM_QPSK_3_4); p->setIUC (DIUC_PROFILE_3); p = getMac()->getMap()->getDlSubframe()->addProfile ((int)round((getMac()->getPhy()->getFreq()/1000)), OFDM_16QAM_1_2); p->setIUC (DIUC_PROFILE_4); p = getMac()->getMap()->getDlSubframe()->addProfile ((int)round((getMac()->getPhy()->getFreq()/1000)), OFDM_16QAM_3_4); p->setIUC (DIUC_PROFILE_5); p = getMac()->getMap()->getDlSubframe()->addProfile ((int)round((getMac()->getPhy()->getFreq()/1000)), OFDM_64QAM_2_3); p->setIUC (DIUC_PROFILE_6); p = getMac()->getMap()->getDlSubframe()->addProfile ((int)round((getMac()->getPhy()->getFreq()/1000)), OFDM_64QAM_3_4); p->setIUC (DIUC_PROFILE_7); p = getMac()->getMap()->getUlSubframe()->addProfile (0, default_mod_); p->setIUC (UIUC_INITIAL_RANGING); p = getMac()->getMap()->getUlSubframe()->addProfile (0, default_mod_); p->setIUC (UIUC_REQ_REGION_FULL); p = getMac()->getMap()->getUlSubframe()->addProfile (0, OFDM_BPSK_1_2); p->setIUC (UIUC_PROFILE_1); p = getMac()->getMap()->getUlSubframe()->addProfile (0, OFDM_QPSK_1_2); p->setIUC (UIUC_PROFILE_2); p = getMac()->getMap()->getUlSubframe()->addProfile (0, OFDM_QPSK_3_4); p->setIUC (UIUC_PROFILE_3); p = getMac()->getMap()->getUlSubframe()->addProfile (0, OFDM_16QAM_1_2); p->setIUC (UIUC_PROFILE_4); p = getMac()->getMap()->getUlSubframe()->addProfile (0, OFDM_16QAM_3_4); p->setIUC (UIUC_PROFILE_5); p = getMac()->getMap()->getUlSubframe()->addProfile (0, OFDM_64QAM_2_3); p->setIUC (UIUC_PROFILE_6); p = getMac()->getMap()->getUlSubframe()->addProfile (0, OFDM_64QAM_3_4); p->setIUC (UIUC_PROFILE_7); } //init contention slots ContentionSlot *slot = getMac()->getMap()->getUlSubframe()->getRanging (); slot->setSize (getInitRangingopportunity ()); slot->setBackoff_start (getMac()->macmib_.rng_backoff_start); slot->setBackoff_stop (getMac()->macmib_.rng_backoff_stop); slot = getMac()->getMap()->getUlSubframe()->getBw_req (); slot->setSize (getBWopportunity ()); slot->setBackoff_start (getMac()->macmib_.bw_backoff_start); slot->setBackoff_stop (getMac()->macmib_.rng_backoff_stop);}/** * Compute and return the bandwidth request opportunity size * @return The bandwidth request opportunity size */int BSScheduler::getBWopportunity (){ int nbPS = BW_REQ_PREAMBLE * getMac()->getPhy()->getSymbolPS(); //add PS for carrying header nbPS += (int) round((getMac()->getPhy()->getTrxTime (HDR_MAC802_16_SIZE, getMac()->getMap()->getUlSubframe()->getProfile(UIUC_REQ_REGION_FULL)->getEncoding())/getMac()->getPhy()->getPS ())); //printf ("BWopportunity size=%d\n", nbPS); return nbPS;}/** * Compute and return the initial ranging opportunity size * @return The initial ranging opportunity size */int BSScheduler::getInitRangingopportunity (){ int nbPS = INIT_RNG_PREAMBLE * getMac()->getPhy()->getSymbolPS(); //add PS for carrying header nbPS += (int) round((getMac()->getPhy()->getTrxTime (RNG_REQ_SIZE+HDR_MAC802_16_SIZE, getMac()->getMap()->getUlSubframe()->getProfile(UIUC_INITIAL_RANGING)->getEncoding())/getMac()->getPhy()->getPS ())); //printf ("Init ranging opportunity size=%d\n", nbPS); return nbPS; }/** * Schedule bursts/packets */void BSScheduler::schedule (){ //The scheduler will perform the following steps: //1-Clear DL map //2-Allocate Burst for Broadcast message //3-Pick Unicast bursts for Downlink (Best Effort) in a RR fashion //4-Clear UL map //5-Allocate contention slots for initial ranging //6-Allocate contention slots for bandwidth requests //7-Allocate unicast burst for Uplink according to bandwidth requests received (RR fashion) Packet *p; struct hdr_cmn *ch; double txtime; //tx time for some data (in second) int txtime_s; //number of symbols used to transmit the data DlBurst *db; PeerNode *peer; OFDMPhy *phy = mac_->getPhy(); //variables for scheduling FrameMap *map = mac_->getMap(); int nbPS = (int) floor((mac_->getFrameDuration()/phy->getPS())); assert (nbPS*phy->getPS()<=mac_->getFrameDuration()); //check for rounding errors int nbPS_left = nbPS - mac_->phymib_.rtg - mac_->phymib_.ttg; int nbSymbols = (int) floor((phy->getPS()*nbPS_left)/phy->getSymbolTime()); assert (nbSymbols*phy->getSymbolTime()+(mac_->phymib_.rtg + mac_->phymib_.ttg)*phy->getPS() < mac_->getFrameDuration()); int maxdlduration = (int) (nbSymbols / (1.0/dlratio_)); //number of symbols for downlink int dlduration = DL_PREAMBLE; //number of symbols currently used for downlink int nbdlbursts = 0; int maxulduration = nbSymbols - maxdlduration; //number of symbols for uplink int ulduration = 0; //number of symbols currently used for uplink int nbulpdus = 0; //printf ("%d %9f\n",phy->getSymbolPS(), (nbSymbols*phy->getSymbolPS()+mac_->phymib_.rtg + mac_->phymib_.ttg)*phy->getPS()); assert ((nbSymbols*phy->getSymbolPS()+mac_->phymib_.rtg + mac_->phymib_.ttg)*phy->getPS()< mac_->getFrameDuration()); assert (maxdlduration*phy->getSymbolTime()+mac_->phymib_.rtg*phy->getPS()+maxulduration*phy->getSymbolTime()+mac_->phymib_.ttg*phy->getPS() < mac_->getFrameDuration()); debug2 ("Frame: duration=%f, PSduration=%e, symboltime=%e, nbPS=%d, rtg=%d, ttg=%d, PSleft=%d, nbSymbols=%d, ", \ mac_->getFrameDuration(), phy->getPS(), phy->getSymbolTime(), nbPS, mac_->phymib_.rtg, mac_->phymib_.ttg, nbPS_left, nbSymbols); debug2 ("maxdlduration=%d, maxulduration=%d\n",maxdlduration, maxulduration); map->getDlSubframe()->getPdu()->removeAllBursts(); //1-First burst for broadcast messages are using DIUC_PROFILE_4 db = (DlBurst*) map->getDlSubframe()->getPdu ()->addBurst (nbdlbursts++); db->setCid ( BROADCAST_CID ); db->setIUC (map->getDlSubframe()->getProfile (DIUC_PROFILE_4)->getIUC()); db->setStarttime (dlduration); //after preamble and fch db->setPreamble(true); //this is the first burst after preamble //time to send DL_MAP and UL_MAP txtime = phy->getTrxSymbolTime (2*sizeof (struct gen_mac_header_t)+sizeof (struct mac802_16_dl_map_frame)+sizeof (struct mac802_16_ul_map_frame), map->getDlSubframe()->getProfile (db->getIUC())->getEncoding()); txtime_s = (int) round(txtime/phy->getSymbolTime ()); //in units of symbol if ((dlduration+txtime_s) > maxdlduration) { fprintf (stderr, "Error: Not enough symbols on the downlink subframe to send synchronization messages\n"); fprintf (stderr, " maxdlduration=%d, needed=%d\n", maxdlduration, dlduration+txtime_s); fprintf (stderr, " Consider incrementing the dlratio_ or using a better modulation\n"); exit(0); } db->setDuration (txtime_s); //enough to send DL_MAP... //check if we have to add DCD and/or UCD to transmit and increase burst size if //necessary if (getMac()->sendDCD || map->getDlSubframe()->getCCC()!= getMac()->dlccc_) { p = map->getDCD(); ch = HDR_CMN(p); txtime = phy->getTrxTime (ch->size(), map->getDlSubframe()->getProfile (db->getIUC())->getEncoding()); ch->txtime() = txtime; txtime_s = (int) ceil(txtime/phy->getSymbolTime ()); //in units of symbol assert ((dlduration+db->getDuration()+txtime_s) <= maxdlduration); //if this occurs, increase dlratio db->setDuration (db->getDuration()+txtime_s); } if (getMac()->sendUCD || map->getUlSubframe()->getCCC()!= getMac()->ulccc_) { p = map->getUCD(); ch = HDR_CMN(p); txtime = phy->getTrxTime (ch->size(), map->getDlSubframe()->getProfile (db->getIUC())->getEncoding());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -