wimaxscheduler.cc
上传用户:hzie11
上传日期:2013-10-07
资源大小:1487k
文件大小:7k
源码类别:

网络

开发平台:

C/C++

  1. /* This software was developed at the National Institute of Standards and
  2.  * Technology by employees of the Federal Government in the course of
  3.  * their official duties. Pursuant to title 17 Section 105 of the United
  4.  * States Code this software is not subject to copyright protection and
  5.  * is in the public domain.
  6.  * NIST assumes no responsibility whatsoever for its use by other parties,
  7.  * and makes no guarantees, expressed or implied, about its quality,
  8.  * reliability, or any other characteristic.
  9.  * <BR>
  10.  * We would appreciate acknowledgement if the software is used.
  11.  * <BR>
  12.  * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  13.  * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  14.  * FROM THE USE OF THIS SOFTWARE.
  15.  * </PRE></P>
  16.  * @author  rouil
  17.  */
  18. #include "wimaxscheduler.h"
  19. /** Subframe timers **/
  20. void DlTimer::expire (Event *e)
  21. {
  22.   s_->start_dlsubframe();
  23. }
  24. void UlTimer::expire (Event *e)
  25. {
  26.   s_->start_ulsubframe();
  27. }
  28. /*
  29.  * Create a scheduler
  30.  * @param mac The Mac where it is located
  31.  */
  32. WimaxScheduler::WimaxScheduler ()
  33. {
  34.   map_ = NULL;
  35.   dl_timer_ = new DlTimer (this);
  36.   ul_timer_ = new UlTimer (this);
  37.   nbr_db_ = new NeighborDB ();
  38. }
  39. /*
  40.  * Set the mac
  41.  * @param mac The Mac where it is located
  42.  */
  43. void WimaxScheduler::setMac (Mac802_16 *mac)
  44. {
  45.   assert (mac!=NULL);
  46.   mac_ = mac;
  47.   init ();
  48. }
  49. /**
  50.  * Initialize the scheduler.
  51.  */
  52. void WimaxScheduler::init()
  53. {
  54.   //create map structure
  55.   map_ = new FrameMap (mac_);
  56. }
  57. /**
  58.  * Called when a timer expires
  59.  * @param The timer ID
  60.  */
  61. void WimaxScheduler::expire (timer_id id)
  62. {
  63.   
  64. }
  65. /**
  66.  * Return the type of STA this scheduler is good for.
  67.  * Must be overwritten by subclass.
  68.  */
  69. station_type_t WimaxScheduler::getNodeType ()
  70. {
  71.   return STA_UNKNOWN;
  72. }
  73. /**
  74.  * Start a new DL dlframe
  75.  */
  76. void WimaxScheduler::start_dlsubframe ()
  77. {
  78.   //must be overwritten by subclasses.
  79. }
  80. /**
  81.  * Start a new UL subframe
  82.  */
  83. void WimaxScheduler::start_ulsubframe ()
  84. {
  85.   //must be overwritten by subclasses.
  86. }
  87. /**
  88.  * Process a packet received by the Mac. 
  89.  * Only scheduling related packets should be sent here (BW request, UL_MAP...)
  90.  */
  91. void WimaxScheduler::process (Packet * p) {
  92.   
  93. }
  94. /**
  95.  * Transfert the packets from the given connection to the given burst
  96.  * @param con The connection
  97.  * @param b The burst
  98.  * @param duration The current occupation of the burst
  99.  * @return the new burst occupation
  100.  */
  101. int WimaxScheduler::transfer_packets (Connection *c, Burst *b, int duration)
  102. {
  103.   Packet *p;
  104.   hdr_cmn* ch;
  105.   hdr_mac802_16 *wimaxHdr;
  106.   double txtime;
  107.   int txtime_s;
  108.   bool pkt_transfered = false;
  109.   OFDMPhy *phy = mac_->getPhy();
  110.   
  111.   p = c->get_queue()->head(); 
  112.   int max_data;
  113.   if (getNodeType ()==STA_BS)
  114.     max_data = phy->getMaxPktSize (b->getDuration()-duration, map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding());
  115.   else 
  116.     max_data = phy->getMaxPktSize (b->getDuration()-duration, map_->getUlSubframe()->getProfile (b->getIUC())->getEncoding());
  117.   debug2 ("max data=%d (burst duration=%d, used duration=%dn", max_data, b->getDuration(), duration);
  118.   if (max_data < HDR_MAC802_16_SIZE ||
  119.       (c->getFragmentationStatus()!=FRAG_NOFRAG && max_data < HDR_MAC802_16_SIZE+HDR_MAC802_16_FRAGSUB_SIZE))
  120.     return duration; //not even space for header
  121.   while (p) {
  122.     ch = HDR_CMN(p);
  123.     wimaxHdr = HDR_MAC802_16(p);
  124.     
  125.     if (getNodeType ()==STA_BS)
  126.       max_data = phy->getMaxPktSize (b->getDuration()-duration, map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding());
  127.     else 
  128.       max_data = phy->getMaxPktSize (b->getDuration()-duration, map_->getUlSubframe()->getProfile (b->getIUC())->getEncoding());
  129.     
  130.     if (max_data < HDR_MAC802_16_SIZE ||
  131. (c->getFragmentationStatus()!=FRAG_NOFRAG && max_data < HDR_MAC802_16_SIZE+HDR_MAC802_16_FRAGSUB_SIZE))
  132.       return duration; //not even space for header
  133.     
  134.     if (c->getFragmentationStatus()!=FRAG_NOFRAG) {
  135.       if (max_data >= ch->size()-c->getFragmentBytes()+HDR_MAC802_16_FRAGSUB_SIZE) {
  136. //add fragmentation header
  137. wimaxHdr->frag_subheader = true;
  138. //no need to fragment again
  139. wimaxHdr->fc = FRAG_LAST;
  140. wimaxHdr->fsn = c->getFragmentNumber ();
  141. ch->size() = ch->size()-c->getFragmentBytes()+HDR_MAC802_16_FRAGSUB_SIZE; //new packet size
  142. //remove packet from queue
  143. c->dequeue();
  144. //update fragmentation
  145. debug2 ("End of fragmentation %d (max_data=%d, bytes to send=%dn", wimaxHdr->fsn&0x7, max_data, ch->size());
  146. c->updateFragmentation (FRAG_NOFRAG, 0, 0);
  147.       } else {
  148. //need to fragment the packet again
  149. p = p->copy(); //copy packet to send
  150. ch = HDR_CMN(p);
  151. wimaxHdr = HDR_MAC802_16(p);
  152. //add fragmentation header
  153. wimaxHdr->frag_subheader = true;
  154. wimaxHdr->fc = FRAG_CONT;
  155. wimaxHdr->fsn = c->getFragmentNumber ();
  156. ch->size() = max_data; //new packet size
  157. //update fragmentation
  158. c->updateFragmentation (FRAG_CONT, (c->getFragmentNumber ()+1)%8, c->getFragmentBytes()+max_data-(HDR_MAC802_16_SIZE+HDR_MAC802_16_FRAGSUB_SIZE));
  159. debug2 ("Continue fragmentation %dn", wimaxHdr->fsn&0x7);
  160.       }
  161.     } else {
  162.       if (max_data < ch->size() && c->isFragEnable()) {
  163. //need to fragment the packet for the first time
  164. p = p->copy(); //copy packet to send
  165. ch = HDR_CMN(p);
  166. wimaxHdr = HDR_MAC802_16(p);
  167. //add fragmentation header
  168. wimaxHdr->frag_subheader = true;
  169. wimaxHdr->fc = FRAG_FIRST;
  170. wimaxHdr->fsn = c->getFragmentNumber ();
  171. ch->size() = max_data; //new packet size
  172. //update fragmentation
  173. c->updateFragmentation (FRAG_FIRST, 1, c->getFragmentBytes()+max_data-(HDR_MAC802_16_SIZE+HDR_MAC802_16_FRAGSUB_SIZE));
  174. debug2 ("First fragmentationn");
  175.       } else if (max_data < ch->size() && !c->isFragEnable()) {
  176. //the connection does not support fragmentation
  177. //can't move packets anymore
  178. return duration;
  179.       } else {
  180. //no fragmentation necessary
  181. c->dequeue();
  182.       }
  183.     }
  184.     if (getNodeType ()==STA_BS)
  185.       txtime = phy->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding());
  186.     else
  187.       txtime = phy->getTrxTime (ch->size(), map_->getUlSubframe()->getProfile (b->getIUC())->getEncoding());
  188.     ch->txtime() = txtime;
  189.     txtime_s = (int)round (txtime/phy->getSymbolTime ()); //in units of symbol 
  190.     //printf ("symbtime=%fn", phy->getSymbolTime ());
  191.     //printf ("Check packet to send: size=%d txtime=%f(%d) duration=%d(%f)n", ch->size(),txtime, txtime_s, b->getDuration(), b->getDuration()*phy->getSymbolTime ());
  192.     assert ( (duration+txtime_s) <= b->getDuration() );
  193.     //printf ("transfert to burstn");
  194.     //p = c->dequeue();   //dequeue connection queue      
  195.     b->enqueue(p);      //enqueue into burst
  196.     duration += txtime_s; //increment time
  197.     if (!pkt_transfered && getNodeType ()!=STA_BS){ //if we transfert at least one packet, remove bw request
  198.       pkt_transfered = true;
  199.       map_->getUlSubframe()->getBw_req()->removeRequest (c->get_cid());
  200.     }
  201.     p = c->get_queue()->head(); //get new head
  202.   }
  203.   return duration;
  204. }