📄 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"/** * 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 () : cl_head_(0), cl_tail_(0), ctrlagent_(0){ debug2 ("BSScheduler created\n"); LIST_INIT (&t17_head_); LIST_INIT (&scan_stations_); LIST_INIT (&fast_ranging_head_); bw_peer_ = NULL; bw_node_index_ = 0; default_mod_ = OFDM_BPSK_1_2; contention_size_ = MIN_CONTENTION_SIZE; sendDCD = false; dlccc_ = 0; sendUCD = false; ulccc_ = 0;} /* * 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(); /*print debug information */ int nbPS = (int) round((mac_->getFrameDuration()/mac_->getPhy()->getPS())); debug2 ("duration=%f, PStime=%f, nbPS=%d,Symbol time=%f, %d \n",mac_->getFrameDuration(), mac_->getPhy()->getPS(), nbPS, mac_->getPhy()->getSymbolTime (), mac_->getPhy()->getSymbolPS()); //At initialization, allocate one DL burst //and contention windows //1-create one profile to be used for broadcast // packets (and DL_MAP...) Profile *p = map_->getDlSubframe()->addProfile ((int)round((mac_->getPhy()->getFreq()/1000)), default_mod_); p->setIUC (DIUC_PROFILE_1); map_->getDlSubframe()->getPdu ()->setPreamble (DL_PREAMBLE); //preamble + fch //2-add the burst to carry the broadcast message DlBurst *b = (DlBurst*) map_->getDlSubframe()->getPdu ()->addBurst (0); b->setCid ( BROADCAST_CID ); b->setIUC (p->getIUC()); b->setStarttime (0); //after preamble and fch b->setDuration (INIT_DL_DURATION); //enough to send DL_MAP... b->setPreamble(true); //this is the first burst after preamble //3-Add the End of map element b = (DlBurst*) map_->getDlSubframe()->getPdu ()->addBurst (1); b->setIUC (DIUC_END_OF_MAP); b->setStarttime (INIT_DL_DURATION); //create uplink //start of UL subframe is after DL and TTG and unit is PS int starttime = (INIT_DL_DURATION+DL_PREAMBLE)*mac_->getPhy()->getSymbolPS()+mac_->phymib_.ttg; map_->getUlSubframe()->setStarttime (starttime); int slotleft = nbPS - starttime - mac_->phymib_.rtg; //duration is in unit of ofdm symbols int rangingslot = slotleft/2; int rangingduration =(int) round(((mac_->getPhy()->getPS()*rangingslot)/mac_->getPhy()->getSymbolTime())); int bwduration = (int) round(((mac_->getPhy()->getPS()*(slotleft - rangingslot))/mac_->getPhy()->getSymbolTime())); //we open the uplink to initial ranging and bw requests //add profile for the ranging burst p = map_->getUlSubframe()->addProfile (0, default_mod_); p->setIUC (UIUC_INITIAL_RANGING); ContentionSlot *slot = map_->getUlSubframe()->getRanging (); slot->setSize (getInitRangingopportunity ()); slot->setBackoff_start (mac_->macmib_.rng_backoff_start); slot->setBackoff_stop (mac_->macmib_.rng_backoff_stop); //create burst to represent the contention slot Burst* b2 = map_->getUlSubframe()->addPhyPdu (0,0)->addBurst (0); b2->setIUC (UIUC_INITIAL_RANGING); b2->setDuration (rangingduration); b2->setStarttime (0); //we put the contention at the begining //now the bw request //add profile for the bw burst p = map_->getUlSubframe()->addProfile (0, default_mod_); p->setIUC (UIUC_REQ_REGION_FULL); slot = map_->getUlSubframe()->getBw_req (); slot->setSize (getBWopportunity ()); slot->setBackoff_start (mac_->macmib_.bw_backoff_start); slot->setBackoff_stop (mac_->macmib_.rng_backoff_stop); b2 = map_->getUlSubframe()->addPhyPdu (1,0)->addBurst (0); b2->setIUC (UIUC_REQ_REGION_FULL); b2->setDuration (bwduration); b2->setStarttime (rangingduration); //start after the ranging slot //end of map b2 = map_->getUlSubframe()->addPhyPdu (2,0)->addBurst (0); b2->setIUC (UIUC_END_OF_MAP); b2->setStarttime (rangingduration+bwduration); //schedule the first frame by using a random backoff to avoid //synchronization between BSs. double stime = Random::uniform(0, mac_->getFrameDuration ()); dl_timer_->sched (stime); ul_timer_->sched (stime+starttime*mac_->getPhy()->getPS()); //also start the DCD and UCD timer dcdtimer_ = new WimaxDCDTimer (mac_); ucdtimer_ = new WimaxUCDTimer (mac_); nbradvtimer_ = new WimaxMobNbrAdvTimer (mac_); dcdtimer_->start (mac_->macmib_.dcd_interval); ucdtimer_->start (mac_->macmib_.ucd_interval); nbradvtimer_->start (mac_->macmib_.nbr_adv_interval+stime);}/** * Compute and return the bandwidth request opportunity size * @return The bandwidth request opportunity size */int BSScheduler::getBWopportunity (){ int nbPS = BW_REQ_PREAMBLE * mac_->getPhy()->getSymbolPS(); //add PS for carrying header nbPS += (int) round((mac_->getPhy()->getTrxTime (HDR_MAC802_16_SIZE, map_->getUlSubframe()->getProfile(UIUC_REQ_REGION_FULL)->getEncoding())/mac_->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 * mac_->getPhy()->getSymbolPS(); //add PS for carrying header nbPS += (int) round((mac_->getPhy()->getTrxTime (RNG_REQ_SIZE+HDR_MAC802_16_SIZE, map_->getUlSubframe()->getProfile(UIUC_INITIAL_RANGING)->getEncoding())/mac_->getPhy()->getPS ())); //printf ("Init ranging opportunity size=%d\n", nbPS); return nbPS; }/** * Called when a timer expires * @param The timer ID */void BSScheduler::expire (timer_id id){ switch (id) { case WimaxDCDTimerID: sendDCD = true; mac_->debug ("At %f in Mac %d DCDtimer expired\n", NOW, mac_->addr()); dcdtimer_->start (mac_->macmib_.dcd_interval); break; case WimaxUCDTimerID: sendUCD = true; mac_->debug ("At %f in Mac %d UCDtimer expired\n", NOW, mac_->addr()); ucdtimer_->start (mac_->macmib_.ucd_interval); break; case WimaxMobNbrAdvTimerID: send_nbr_adv(); nbradvtimer_->start (mac_->macmib_.nbr_adv_interval); break; default: mac_->debug ("Warning: unknown timer expired in BSScheduler\n"); }}/** * Set the control agent */void BSScheduler::setCtrlAgent (WimaxCtrlAgent *agent){ assert (agent); ctrlagent_ = agent;}/** * Process a packet received by the Mac. Only scheduling related packets should be sent here (BW request, UL_MAP...) * @param p The packet to process */void BSScheduler::process (Packet * p){ //assert (mac_); //debug2 ("BSScheduler received packet to process\n"); assert (mac_ && HDR_CMN(p)->ptype()==PT_MAC); debug2 ("BSScheduler received packet to process\n"); hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(p); gen_mac_header_t header = wimaxHdr->header; //check if this is a bandwidth request if (header.ht == 1) { process_bw_req (p); return; } //we cast to this frame because all management frame start with //a type mac802_16_dl_map_frame *frame = (mac802_16_dl_map_frame*) p->accessdata(); switch (frame->type) { case MAC_RNG_REQ: process_ranging_req (p); break; case MAC_REG_REQ: process_reg_req (p); break; case MAC_MOB_SCN_REQ: if (ctrlagent_) ctrlagent_->process_scan_request (p); else fprintf (stderr, "Warning: no controler to handle scan request in BS %d\n", mac_->addr()); break; case MAC_MOB_MSHO_REQ: process_msho_req (p); break; case MAC_MOB_HO_IND: process_ho_ind (p); break; default: mac_->debug ("unknown packet in BS\n"); } Packet::free (p);}/** * Return the type of STA this scheduler is good for * @return STA_BS */station_type_t BSScheduler::getNodeType (){ return STA_BS;}/** * Start a new frame */void BSScheduler::start_ulsubframe (){ //mac_->debug ("At %f in Mac %d BS scheduler ulsubframe expires\n", NOW, mac_->addr()); //change PHY state mac_->getPhy()->setMode (OFDM_RECV); //start handler of ulsubframe map_->getUlSubframe()->getTimer()->sched (0); //reschedule for next frame ul_timer_->resched (mac_->getFrameDuration());}/** * Start a new frame */void BSScheduler::start_dlsubframe (){ debug2 ("At %f in Mac %d BS scheduler dlsubframe expires (frame=%d)\n", NOW, mac_->addr(), mac_->frame_number_+1); assert (map_); Packet *p; Burst *b; struct hdr_cmn *ch; double txtime; int txtime_s; OFDMPhy *phy = mac_->getPhy();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -