📄 bsscheduler.cc
字号:
//increment frame number mac_->frame_number_ ++; //adjust frame start information map_->setStarttime(NOW); /* First lets clear the peers we haven't heard of for long time */ for (PeerNode *pn = mac_->getPeerNode_head() ; pn ; ) { PeerNode *tmp = pn->next_entry(); //next elem if (isPeerScanning(pn->getPeerNode())) { //since a scanning node cannot send data we push the //timeout while it is scanning pn->setRxTime(NOW); } else if (NOW-pn->getRxTime()>mac_->macmib_.client_timeout) { mac_->debug ("Client timeout for node %d\n", pn->getPeerNode()); mac_->removePeerNode(pn); } pn = tmp; } /**** Step one : burst allocation ****/ int nbPS = (int) round((mac_->getFrameDuration()/phy->getPS())); int nbPS_left = nbPS - mac_->phymib_.rtg - mac_->phymib_.ttg; int nbSymbols = (int) ((phy->getPS()*nbPS_left)/phy->getSymbolTime()); int dlduration = INIT_DL_DURATION+DL_PREAMBLE; int ulduration = 0; 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); //remove control messages nbSymbols -= INIT_DL_DURATION+DL_PREAMBLE; nbSymbols -=10; for (Connection *c = mac_->getCManager()->get_down_connection (); c && nbSymbols>0 ; c=c->next_entry()) { if (c->getPeerNode() && !isPeerScanning (c->getPeerNode()->getPeerNode())) { int queuesize = c->queueByteLength(); int tmp = (int) round((phy->getTrxTime (queuesize, map_->getDlSubframe()->getProfile (DIUC_PROFILE_1)->getEncoding())/phy->getSymbolTime())); if (tmp < nbSymbols) { dlduration += tmp; nbSymbols -= tmp; }else{ dlduration +=nbSymbols; nbSymbols -= nbSymbols; break; } } } nbSymbols +=10; map_->getDlSubframe()->getPdu()->getBurst(0)->setDuration (dlduration); map_->getUlSubframe()->setStarttime (dlduration*phy->getSymbolPS()+mac_->phymib_.rtg); ul_timer_->resched (map_->getUlSubframe()->getStarttime()*mac_->getPhy()->getPS()); debug2 ("dlduration=%d, ", dlduration); //update the END_OF_MAP start time b = (DlBurst*) map_->getDlSubframe()->getPdu ()->getBurst (1); b->setStarttime (dlduration); while (map_->getUlSubframe()->getNbPdu()>0) { PhyPdu *pdu = map_->getUlSubframe()->getPhyPdu(0); map_->getUlSubframe()->removePhyPdu(pdu); delete (pdu); } int rangingduration = 0; int bwduration = 0; int pduIndex = 0; debug2 ("In Mac %d Nb symbols left before contention =%d\n", mac_->addr(), nbSymbols); int contentionslots = (int) round((contention_size_*((getBWopportunity()+getInitRangingopportunity())*mac_->getPhy()->getPS()/mac_->getPhy()->getSymbolTime()))); if (nbSymbols > contentionslots) { int starttime, slotleft, rangingslot, bwslot; //create uplink //start of UL subframe is after DL and TTG and unit is PS starttime = map_->getUlSubframe()->getStarttime(); slotleft = nbPS - starttime - mac_->phymib_.rtg; //if there is at least one peer, then use only contention_size_ symbols, //otherwise use all the bw if (mac_->getPeerNode_head() || fast_ranging_head_.lh_first) { rangingslot = contention_size_*getInitRangingopportunity(); bwslot = contention_size_*getBWopportunity(); nbSymbols -= contentionslots; debug2 ("nbSymbols after contention=%d\n", nbSymbols); } else { rangingslot = (int) (floor (slotleft/(2.0*getInitRangingopportunity()))*getInitRangingopportunity()); bwslot = (int) (floor ((slotleft-rangingslot)/getBWopportunity())*getBWopportunity()); nbSymbols = 0; } rangingduration =(int) round(((mac_->getPhy()->getPS()*rangingslot)/mac_->getPhy()->getSymbolTime())); bwduration = (int) round (((mac_->getPhy()->getPS()*bwslot)/mac_->getPhy()->getSymbolTime())); //we open the uplink to initial ranging and bw requests ContentionSlot *slot = map_->getUlSubframe()->getRanging (); //create burst to represent the contention slot Burst* b2 = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0); pduIndex++; b2->setIUC (UIUC_INITIAL_RANGING); b2->setDuration (rangingduration); b2->setStarttime (ulduration); //we put the contention at the begining ulduration += rangingduration; //now the bw request slot = map_->getUlSubframe()->getBw_req (); b2 = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0); pduIndex++; b2->setIUC (UIUC_REQ_REGION_FULL); b2->setDuration (bwduration); b2->setStarttime (ulduration); //start after the ranging slot ulduration += bwduration; } //check if there is Fast Ranging allocation to do while (fast_ranging_head_.lh_first !=NULL && fast_ranging_head_.lh_first->frame() == mac_->getFrameNumber()) { //we need to include a fast ranging allocation b = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0); pduIndex++; int tmp =(int) round(((mac_->getPhy()->getPS()*getInitRangingopportunity())/mac_->getPhy()->getSymbolTime())); b->setIUC (UIUC_EXT_UIUC); b->setDuration (tmp); b->setStarttime (ulduration); //start after previous slot ((UlBurst*)b)->setFastRangingParam (fast_ranging_head_.lh_first->macAddr(), UIUC_INITIAL_RANGING); ulduration += tmp; mac_->debug ("At %f in Mac %d adding fast ranging for %d\n", NOW, mac_->addr(), fast_ranging_head_.lh_first->macAddr()); fast_ranging_head_.lh_first->remove_entry(); } //get the next node to allocate bw. //PB: the node may have been removed. We need to check that PeerNode *peer = mac_->getPeerNode_head(); PeerNode *start_peer = mac_->getPeerNode_head(); int i=0; if (start_peer != NULL) { //we have at least one element in the list for (peer = mac_->getPeerNode_head(); peer->next_entry() ; peer=peer->next_entry()); debug2 ("start_peer=%d, peer=%d\n", start_peer->getPeerNode(), peer->getPeerNode()); while (start_peer != peer) { if (!isPeerScanning(peer->getPeerNode())) { debug2 ("peer %d not scanning take it\n", peer->getPeerNode()); break; //we found next station } debug2 ("peer %d scanning move it\n", peer->getPeerNode()); peer->remove_entry(); mac_->addPeerNode (peer); //we put it at head of the list for (peer = mac_->getPeerNode_head(); peer->next_entry() ; peer=peer->next_entry()); } } if (peer) debug2 ("final pick is %d\n", peer->getPeerNode()); //update variables bw_node_index_ = i; bw_peer_ = peer; //the next peer node takes the rest of the bw if (nbSymbols > 0 && peer && !isPeerScanning(peer->getPeerNode())) { debug2 ("Allocate uplink for STA %d\n", peer->getPeerNode()); peer->remove_entry(); mac_->addPeerNode (peer); //we put it at head of the list //printf ("NbSymbols for node=%d\n", nbSymbols); //add burst Burst *b3 = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0); pduIndex++; b3->setIUC (UIUC_PROFILE_1); b3->setCid (peer->getPrimary()->get_cid()); b3->setDuration (nbSymbols); b3->setStarttime (ulduration); //add profile if not existing Profile *p = map_->getUlSubframe()->getProfile (UIUC_PROFILE_1); if (p==NULL) { p = map_->getUlSubframe()->addProfile (0, default_mod_); p->setIUC (UIUC_PROFILE_1); } } //end of map Burst *b2 = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0); pduIndex++; b2->setIUC (UIUC_END_OF_MAP); b2->setStarttime (rangingduration+bwduration+nbSymbols); //we need to fill up the outgoing queues for (int index = 0 ; index < map_->getDlSubframe()->getPdu ()->getNbBurst() ; index++) { b = map_->getDlSubframe()->getPdu ()->getBurst (index); int duration = 0; if (b->getIUC()==DIUC_END_OF_MAP) { //consistency check.. assert (index == map_->getDlSubframe()->getPdu ()->getNbBurst()-1); break; } //we can get the next one after we check END_OF_MAP //b2 = map_->getDlSubframe()->getPdu ()->getBurst (index+1); //if this is the first buffer, add DL_MAP...messages if (index==0) { p = map_->getDL_MAP(); ch = HDR_CMN(p); txtime = phy->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding()); ch->txtime() = txtime; txtime_s = (int) round(txtime/phy->getSymbolTime ()); //in units of symbol assert ((duration+txtime_s) <= b->getDuration()); b->enqueue(p); //enqueue into burst duration += txtime_s; p = map_->getUL_MAP(); ch = HDR_CMN(p); txtime = phy->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding()); ch->txtime() = txtime; txtime_s = (int) round(txtime/phy->getSymbolTime ()); //in units of symbol assert ((duration+txtime_s) <= b->getDuration()); b->enqueue(p); //enqueue into burst duration += txtime_s; if (sendDCD || map_->getDlSubframe()->getCCC()!= dlccc_) { p = map_->getDCD(); ch = HDR_CMN(p); txtime = phy->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding()); ch->txtime() = txtime; txtime_s = (int) round(txtime/phy->getSymbolTime ()); //in units of symbol assert ((duration+txtime_s) <= b->getDuration()); b->enqueue(p); //enqueue into burst duration += txtime_s; sendDCD = false; dlccc_ = map_->getDlSubframe()->getCCC(); //reschedule timer dcdtimer_->stop(); dcdtimer_->start (mac_->macmib_.dcd_interval); } if (sendUCD || map_->getUlSubframe()->getCCC()!= ulccc_) { p = map_->getUCD(); ch = HDR_CMN(p); txtime = phy->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding()); ch->txtime() = txtime; txtime_s = (int) round(txtime/phy->getSymbolTime ()); //in units of symbol assert ((duration+txtime_s) <= b->getDuration()); b->enqueue(p); //enqueue into burst duration += txtime_s; sendUCD = false; ulccc_ = map_->getUlSubframe()->getCCC(); //reschedule timer ucdtimer_->stop(); ucdtimer_->start (mac_->macmib_.ucd_interval); } } //get the packets from the connection with the same CID //Connection *c=mac_->getCManager ()->get_connection (b->getCid()); int nb_down = 0; for (Connection *c = mac_->getCManager()->get_down_connection (); c ; c=c->next_entry()){ nb_down++;} Connection **tmp_con = (Connection **) malloc (nb_down*sizeof (Connection *)); int i=0; for (Connection *c = mac_->getCManager()->get_down_connection (); c ; c=c->next_entry()){ tmp_con[i] = c; i++; } //we randomly pick the connection we'll start serving first int start_index = (int) round (Random::uniform(0, nb_down)); debug2 ("Picked connection %d as first\n", start_index); //for (Connection *c = mac_->getCManager()->get_down_connection (); c ; c=c->next_entry()) { for (i=0; i < nb_down ; i++) { int index = (i+start_index)%nb_down; Connection *c=tmp_con[index]; if (c->getPeerNode() && isPeerScanning (c->getPeerNode()->getPeerNode())) continue; duration = transfer_packets (c, b, duration); } } //change PHY state mac_->getPhy()->setMode (OFDM_SEND); //start handler of dlsubframe map_->getDlSubframe()->getTimer()->sched (0); //reschedule for next time (frame duration) dl_timer_->resched (mac_->getFrameDuration()); }/** Add a new Fast Ranging allocation * @param time The time when to allocate data * @param macAddr The MN address */void BSScheduler::addNewFastRanging (double time, int macAddr){ //compute the frame where the allocation will be located int frame = int ((time-NOW)/mac_->getFrameDuration()) +2 ; frame += mac_->getFrameNumber(); //printf ("Added fast RA for frame %d (current=%d) for time (%f)\n", // frame, mac_->getFrameNumber(), time); FastRangingInfo *info= new FastRangingInfo (frame, macAddr); info->insert_entry(&fast_ranging_head_);}/**** Packet processing methods ****//** * Process a RNG-REQ message * @param p The packet containing the ranging request information */void BSScheduler::process_ranging_req (Packet *p){ UlSubFrame *ulsubframe = map_->getUlSubframe(); mac802_16_rng_req_frame *req = (mac802_16_rng_req_frame *) p->accessdata(); if (HDR_MAC802_16(p)->header.cid != INITIAL_RANGING_CID) { //process request for DIUC } else { //here we can make decision to accept the SS or not. //for now, accept everybody //check if CID already assigned for the SS PeerNode *peer = mac_->getPeerNode (req->ss_mac_address); if (peer==NULL) { mac_->debug ("New peer node requesting ranging (%d)\n",req->ss_mac_address); //Assign Management CIDs Connection *basic = new Connection (CONN_BASIC); Connection *upbasic = new Connection (CONN_BASIC, basic->get_cid()); Connection *primary = new Connection (CONN_PRIMARY); Connection *upprimary = new Connection (CONN_PRIMARY, primary->get_cid()); //Create Peer information peer = new PeerNode (req->ss_mac_address); peer->setBasic (basic); peer->setPrimary (primary); upbasic->setPeerNode (peer); upprimary->setPeerNode (peer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -