⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssscheduler.cc

📁 This documentation is based on the following versions:- pre-release of the wimax model developed by
💻 CC
📖 第 1 页 / 共 4 页
字号:
/* 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 "ssscheduler.h"#include "burst.h"/** * Tcl hook for creating SS scheduler  */static class SSschedulerClass : public TclClass {public:  SSschedulerClass() : TclClass("WimaxScheduler/SS") {}  TclObject* create(int, const char*const*) {    return (new SSscheduler());      }} class_ssscheduler;/* * Create a scheduler */SSscheduler::SSscheduler (): t1timer_(0),t2timer_(0),t6timer_(0), t12timer_(0),			     t21timer_(0), lostDLMAPtimer_(0), lostULMAPtimer_(0),			     t44timer_(0), scan_info_(0){  debug2 ("SSscheduler created\n");}/** * Initializes the scheduler */void SSscheduler::init (){  WimaxScheduler::init();    //At initialization, the SS is looking for synchronization  mac_->setMacState (MAC802_16_WAIT_DL_SYNCH);  mac_->getPhy()->setMode (OFDM_RECV);  //start timer for expiration  t21timer_ = new WimaxT21Timer (mac_);  t21timer_->start (mac_->macmib_.t21_timeout);  //creates other timers  t1timer_ = new WimaxT1Timer (mac_);  t12timer_ = new WimaxT12Timer (mac_);  t2timer_ = new WimaxT2Timer (mac_);  lostDLMAPtimer_ = new WimaxLostDLMAPTimer (mac_);  lostULMAPtimer_ = new WimaxLostULMAPTimer (mac_);  nb_scan_req_ = 0;  scan_info_ = (struct scanning_structure *) malloc (sizeof (struct scanning_structure));  memset (scan_info_, 0, sizeof (struct scanning_structure));  scan_info_->nbr = NULL;  scan_info_->substate = NORMAL;}/** * Interface with the TCL script * @param argc The number of parameter * @param argv The list of parameters */int SSscheduler::command(int argc, const char*const* argv){  if (argc == 2) {    if (strcmp(argv[1], "send-scan") == 0) {      send_scan_request();      return TCL_OK;    }  }    return TCL_ERROR;}/** * Start a new frame */void SSscheduler::start_dlsubframe (){  //mac_->debug ("At %f in Mac %d SS scheduler dlsubframe expires %d\n", NOW, mac_->addr(), scan_info_->substate);  mac_->frame_number_++;  switch (scan_info_->substate) {  case SCAN_PENDING:     if (scan_info_->count == 0) {      resume_scanning();      return;    }     scan_info_->count--;    break;  case HANDOVER_PENDING:    if (scan_info_->handoff_timeout == 0) {      assert (scan_info_->nbr);#ifdef USE_802_21      mac_->debug ("At %f in Mac %d link handoff proceeding\n", NOW, mac_->addr());      mac_->send_link_handoff_proceeding (mac_->addr(), mac_->getPeerNode_head()->getPeerNode(), scan_info_->nbr->getID());#endif       scan_info_->substate = HANDOVER;      //restore previous state       //mac_->restore_state (scan_info_->nbr->getState()->state_info);      mac_->setChannel (scan_info_->nbr->getState()->state_info->channel);      lost_synch ();      //add target as peer      mac_->addPeerNode (new PeerNode(scan_info_->nbr->getID()));      return;    }    scan_info_->handoff_timeout--;    break;  default:    break;  }      //change state of PHY  //mac_->getPhy()->setMode (OFDM_RECV);    //this is the begining of new frame  map_->setStarttime (NOW);  //start handler of dlsubframe  map_->getDlSubframe()->getTimer()->sched (0);  //reschedule for next frame  dl_timer_->resched (mac_->getFrameDuration());}/** * Start a new frame */void SSscheduler::start_ulsubframe (){  //mac_->debug ("At %f in Mac %d SS scheduler ulsubframe expires\n", NOW, mac_->addr());    //change state of PHY: even though it should have been done before  //there are some cases where it does not (during scanning)  mac_->getPhy()->setMode (OFDM_SEND);  //1-Transfert the packets from the queues in Connections to burst queues  Burst *b;  OFDMPhy *phy = mac_->getPhy();  //printf ("SS has %d ul bursts\n", map_->getUlSubframe()->getNbPdu ());  PeerNode *peer = mac_->getPeerNode_head(); //this is the BS  assert (peer!=NULL);  for (int index = 0 ; index < map_->getUlSubframe()->getNbPdu (); index++) {    b = map_->getUlSubframe()->getPhyPdu (index)->getBurst (0);    if (b->getIUC()==UIUC_END_OF_MAP) {      //consistency check..      assert (index == map_->getUlSubframe()->getNbPdu ()-1);      break;    }            if (b->getIUC()==UIUC_INITIAL_RANGING || b->getIUC()==UIUC_REQ_REGION_FULL)      continue;    int duration = 0;     //get the packets from the connection with the same CID    //printf ("\tBurst CID=%d\n", b->getCid());    Connection *c=mac_->getCManager ()->get_connection (b->getCid(), true);    //assert (c);    if (!c)      continue; //I do not have this CID. Must be for another node    //transfert the packets until it reaches burst duration or no more packets    assert (c->getType()==CONN_PRIMARY);    if (peer->getBasic()!= NULL)       duration = transfer_packets (peer->getBasic(), b, duration);    if (peer->getPrimary()!= NULL)      duration = transfer_packets (peer->getPrimary(), b, duration);    if (peer->getSecondary()!= NULL)      duration = transfer_packets (peer->getSecondary(), b, duration);    if (peer->getOutData()!=NULL)      duration = transfer_packets (peer->getOutData(), b, duration);  }  //2-compute size of data left to create bandwidth requests  if (peer->getBasic()!= NULL)     create_request (peer->getBasic());  if (peer->getPrimary()!= NULL)    create_request (peer->getPrimary());  if (peer->getSecondary()!= NULL)    create_request (peer->getSecondary());  if (peer->getOutData()!=NULL)    create_request (peer->getOutData());  //start handler for ulsubframe  b = map_->getUlSubframe()->getPhyPdu (0)->getBurst (0);  map_->getUlSubframe()->getTimer()->sched (b->getStarttime()*phy->getSymbolTime());  //reschedule for next frame  ul_timer_->resched (mac_->getFrameDuration());      }/** * Create a request for the given connection * @param con The connection to check */void SSscheduler::create_request (Connection *con){  if (con->queueLength()==0)    return; //queue is empty  else if (map_->getUlSubframe()->getBw_req()->getRequest (con->get_cid())!=NULL) {    debug2 ("At %f in Mac %d already pending requests for cid=%d\n", NOW, mac_->addr(), con->get_cid());    return; //there is already a pending request  }  Packet *p= mac_->getPacket();  hdr_cmn* ch = HDR_CMN(p);  bw_req_header_t *header = (bw_req_header_t *)&(HDR_MAC802_16(p)->header);  header->ht=1;  header->ec=1;  header->type = 0; //incremental..to check meaning  header->br = con->queueByteLength();  header->cid = con->get_cid();  double txtime = mac_->getPhy()->getTrxTime (ch->size(), map_->getUlSubframe()->getProfile (UIUC_REQ_REGION_FULL)->getEncoding());  ch->txtime() = txtime;  map_->getUlSubframe()->getBw_req()->addRequest (p, con->get_cid(), con->queueByteLength());  debug2 ("SSscheduler enqueued request for cid=%d len=%d\n", con->get_cid(), con->queueByteLength());  //start timeout for request}/** * 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 SSscheduler::process (Packet * p){  assert (mac_ && HDR_CMN(p)->ptype()==PT_MAC);  debug2 ("SSScheduler received packet to process\n");    hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(p);  gen_mac_header_t header = wimaxHdr->header;  //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_DL_MAP:     map_->setStarttime (NOW-HDR_CMN(p)->txtime());    //printf ("At %f frame start at %f\n", NOW, map_->getStarttime());    process_dl_map (frame);    break;  case MAC_DCD:     process_dcd ((mac802_16_dcd_frame*)frame);    break;  case MAC_UL_MAP:     process_ul_map ((mac802_16_ul_map_frame*)frame);    break;  case MAC_UCD:     process_ucd ((mac802_16_ucd_frame*)frame);    break;  case MAC_RNG_RSP:    process_ranging_rsp ((mac802_16_rng_rsp_frame*) frame);    break;  case MAC_REG_RSP:    process_reg_rsp ((mac802_16_reg_rsp_frame*) frame);    break;      case MAC_MOB_SCN_RSP:    process_scan_rsp ((mac802_16_mob_scn_rsp_frame *) frame);    break;  case MAC_MOB_BSHO_RSP:    process_bsho_rsp ((mac802_16_mob_bsho_rsp_frame *) frame);    break;  case MAC_MOB_NBR_ADV:    process_nbr_adv ((mac802_16_mob_nbr_adv_frame *) frame);    break;  default:    mac_->debug ("unknown packet in SS %d\n", mac_->addr());    //exit (0);  }  Packet::free (p);}/** * Return the type of STA this scheduler is good for * @return STA_SS */station_type_t SSscheduler::getNodeType (){  return STA_MN;}/** * Called when lost synchronization */void SSscheduler::lost_synch (){  //reset timers  if (t1timer_->busy()!=0)    t1timer_->stop();  if (t12timer_->busy()!=0)    t12timer_->stop();  if (t21timer_->busy()!=0)    t21timer_->stop();  if (lostDLMAPtimer_->busy()!=0)    lostDLMAPtimer_->stop();   if (lostULMAPtimer_->busy()!=0)    lostULMAPtimer_->stop();   if (t2timer_->busy()!=0)    t2timer_->stop();   if (t44timer_ && t44timer_->busy()!=0)    t44timer_->stop();  //we need to go to receiving mode  //printf ("Set phy to recv %x\n", mac_->getPhy());  mac_->getPhy()->setMode (OFDM_RECV);  if (mac_->getMacState()==MAC802_16_CONNECTED) {    //remove possible pending requests    map_->getUlSubframe()->getBw_req()->removeRequests(); #ifdef USE_802_21    mac_->debug ("At %f in Mac %d, send link down\n", NOW, mac_->addr());    mac_->send_link_down (mac_->addr(), RC_FAIL_NORESOURCE);#endif  }  //remove information about peer node  if (mac_->getPeerNode_head())    mac_->removePeerNode (mac_->getPeerNode_head());  //start waiting for DL synch  mac_->setMacState (MAC802_16_WAIT_DL_SYNCH);  t21timer_->start (mac_->macmib_.t21_timeout);  if (dl_timer_->status()==TIMER_PENDING)    dl_timer_->cancel();  map_->getDlSubframe()->getTimer()->reset();  if (ul_timer_->status()==TIMER_PENDING)    ul_timer_->cancel();  map_->getUlSubframe()->getTimer()->reset();} /** * Called when a timer expires * @param The timer ID */void SSscheduler::expire (timer_id id){  switch (id) {  case WimaxT21TimerID:    mac_->debug ("At %f in Mac %d, synchronization failed\n", NOW, mac_->addr());    //go to next channel    mac_->nextChannel();    t21timer_->start (mac_->macmib_.t21_timeout);    break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -