patch-wimax-prerelease-092206
上传用户:hzie11
上传日期:2013-10-07
资源大小:1487k
文件大小:477k
源码类别:

网络

开发平台:

C/C++

  1. +{
  2. +  assert (agent);
  3. +  ctrlagent_ = agent;
  4. +}
  5. +
  6. +/**
  7. + * Process a packet received by the Mac. Only scheduling related packets should be sent here (BW request, UL_MAP...)
  8. + * @param p The packet to process
  9. + */
  10. +void BSScheduler::process (Packet * p)
  11. +{
  12. +  //assert (mac_);
  13. +  //debug2 ("BSScheduler received packet to processn");
  14. +
  15. +  assert (mac_ && HDR_CMN(p)->ptype()==PT_MAC);
  16. +  debug2 ("BSScheduler received packet to processn");
  17. +  
  18. +  hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(p);
  19. +  gen_mac_header_t header = wimaxHdr->header;
  20. +
  21. +  //check if this is a bandwidth request
  22. +  if (header.ht == 1) {
  23. +    process_bw_req (p);
  24. +    return;
  25. +  }
  26. +
  27. +  //we cast to this frame because all management frame start with
  28. +  //a type 
  29. +  mac802_16_dl_map_frame *frame = (mac802_16_dl_map_frame*) p->accessdata();
  30. +  
  31. +  switch (frame->type) {
  32. +  case MAC_RNG_REQ: 
  33. +    process_ranging_req (p);
  34. +    break;
  35. +  case MAC_REG_REQ: 
  36. +    process_reg_req (p);
  37. +    break;
  38. +  case MAC_MOB_SCN_REQ:
  39. +    if (ctrlagent_) 
  40. +      ctrlagent_->process_scan_request (p);
  41. +    else
  42. +      fprintf (stderr, "Warning: no controler to handle scan request in BS %dn", mac_->addr());
  43. +    break;
  44. +  case MAC_MOB_MSHO_REQ:
  45. +    process_msho_req (p);
  46. +    break;
  47. +  case MAC_MOB_HO_IND:
  48. +    process_ho_ind (p);
  49. +    break;
  50. +  default:
  51. +    mac_->debug ("unknown packet in BSn");
  52. +  }
  53. +
  54. +  Packet::free (p);
  55. +}
  56. +
  57. +
  58. +/**
  59. + * Return the type of STA this scheduler is good for
  60. + * @return STA_BS
  61. + */
  62. +station_type_t BSScheduler::getNodeType ()
  63. +{
  64. +  return STA_BS;
  65. +}
  66. +
  67. +/**
  68. + * Start a new frame
  69. + */
  70. +void BSScheduler::start_ulsubframe ()
  71. +{
  72. +  //mac_->debug ("At %f in Mac %d BS scheduler ulsubframe expiresn", NOW, mac_->addr());
  73. +
  74. +  //change PHY state
  75. +  mac_->getPhy()->setMode (OFDM_RECV);  
  76. +
  77. +  //start handler of ulsubframe
  78. +  map_->getUlSubframe()->getTimer()->sched (0);
  79. +
  80. +  //reschedule for next frame
  81. +  ul_timer_->resched (mac_->getFrameDuration());
  82. +}
  83. +
  84. +/**
  85. + * Start a new frame
  86. + */
  87. +void BSScheduler::start_dlsubframe ()
  88. +{
  89. +  debug2 ("At %f in Mac %d BS scheduler dlsubframe expires (frame=%d)n", 
  90. +        NOW, mac_->addr(), mac_->frame_number_+1);
  91. +
  92. +  assert (map_);
  93. +
  94. +  Packet *p;
  95. +  Burst *b;
  96. +  struct hdr_cmn *ch;
  97. +  double txtime;
  98. +  int txtime_s;
  99. +  OFDMPhy *phy = mac_->getPhy();
  100. +
  101. +  //increment frame number
  102. +  mac_->frame_number_ ++;
  103. +  
  104. +  //adjust frame start information
  105. +  map_->setStarttime(NOW);
  106. +
  107. +  /* First lets clear the peers we haven't heard of for long time */
  108. +  for (PeerNode *pn = mac_->getPeerNode_head() ; pn ; ) {
  109. +    PeerNode *tmp = pn->next_entry(); //next elem
  110. +    if (isPeerScanning(pn->getPeerNode())) {
  111. +      //since a scanning node cannot send data we push the 
  112. +      //timeout while it is scanning
  113. +      pn->setRxTime(NOW); 
  114. +    } else if (NOW-pn->getRxTime()>mac_->macmib_.client_timeout) {
  115. +      mac_->debug ("Client timeout for node %dn", pn->getPeerNode());
  116. +      mac_->removePeerNode(pn);
  117. +    }
  118. +    pn = tmp;
  119. +  }
  120. +
  121. +  /**** Step one : burst allocation ****/
  122. +  int nbPS = (int) round((mac_->getFrameDuration()/phy->getPS()));
  123. +  int nbPS_left = nbPS - mac_->phymib_.rtg - mac_->phymib_.ttg;
  124. +  int nbSymbols = (int) ((phy->getPS()*nbPS_left)/phy->getSymbolTime());
  125. +  int dlduration = INIT_DL_DURATION+DL_PREAMBLE;
  126. +  int ulduration = 0;
  127. +  debug2 ("Frame: duration=%f, PSduration=%e, symboltime=%e, nbPS=%d, rtg=%d, ttg=%d, PSleft=%d, nbSymbols=%d, ", 
  128. +    mac_->getFrameDuration(), phy->getPS(), phy->getSymbolTime(), nbPS, mac_->phymib_.rtg, mac_->phymib_.ttg, nbPS_left, nbSymbols);
  129. +
  130. +  //remove control messages
  131. +  nbSymbols -= INIT_DL_DURATION+DL_PREAMBLE;
  132. +  
  133. +  nbSymbols -=10;
  134. +  for (Connection *c = mac_->getCManager()->get_down_connection (); c && nbSymbols>0 ; c=c->next_entry()) {
  135. +    if (c->getPeerNode() && !isPeerScanning (c->getPeerNode()->getPeerNode())) {
  136. +      int queuesize = c->queueByteLength();
  137. +      int tmp = (int) round((phy->getTrxTime (queuesize, map_->getDlSubframe()->getProfile (DIUC_PROFILE_1)->getEncoding())/phy->getSymbolTime()));
  138. +      if (tmp < nbSymbols) {
  139. + dlduration += tmp;
  140. + nbSymbols -= tmp;
  141. +      }else{
  142. + dlduration +=nbSymbols;
  143. + nbSymbols -= nbSymbols;
  144. + break;
  145. +      }
  146. +    }
  147. +  }
  148. +  nbSymbols +=10;
  149. +
  150. +  map_->getDlSubframe()->getPdu()->getBurst(0)->setDuration (dlduration);
  151. +  map_->getUlSubframe()->setStarttime (dlduration*phy->getSymbolPS()+mac_->phymib_.rtg);
  152. +  ul_timer_->resched (map_->getUlSubframe()->getStarttime()*mac_->getPhy()->getPS());
  153. +
  154. +  debug2 ("dlduration=%d, ", dlduration);
  155. +  //update the END_OF_MAP start time
  156. +  b = (DlBurst*) map_->getDlSubframe()->getPdu ()->getBurst (1);
  157. +  b->setStarttime (dlduration);  
  158. +
  159. +  while (map_->getUlSubframe()->getNbPdu()>0) {
  160. +    PhyPdu *pdu = map_->getUlSubframe()->getPhyPdu(0);
  161. +    map_->getUlSubframe()->removePhyPdu(pdu);
  162. +    delete (pdu);
  163. +  }
  164. +  
  165. +  int rangingduration = 0;
  166. +  int bwduration = 0;
  167. +  int pduIndex = 0;
  168. +  debug2 ("In Mac %d Nb symbols left before contention =%dn", mac_->addr(), nbSymbols);
  169. +
  170. +  int contentionslots = (int) round((contention_size_*((getBWopportunity()+getInitRangingopportunity())*mac_->getPhy()->getPS()/mac_->getPhy()->getSymbolTime())));
  171. +  if (nbSymbols > contentionslots) {
  172. +    int starttime, slotleft, rangingslot, bwslot;
  173. +    //create uplink 
  174. +    //start of UL subframe is after DL and TTG and unit is PS
  175. +    starttime = map_->getUlSubframe()->getStarttime();
  176. +    slotleft = nbPS - starttime - mac_->phymib_.rtg;
  177. +    //if there is at least one peer, then use only contention_size_ symbols, 
  178. +    //otherwise use all the bw
  179. +    if (mac_->getPeerNode_head() || fast_ranging_head_.lh_first) {
  180. +      rangingslot = contention_size_*getInitRangingopportunity();
  181. +      bwslot = contention_size_*getBWopportunity();
  182. +      nbSymbols -= contentionslots;
  183. +      debug2 ("nbSymbols after contention=%dn", nbSymbols);
  184. +    }
  185. +    else {
  186. +      rangingslot = (int) (floor (slotleft/(2.0*getInitRangingopportunity()))*getInitRangingopportunity());
  187. +      bwslot = (int) (floor ((slotleft-rangingslot)/getBWopportunity())*getBWopportunity());
  188. +      nbSymbols = 0;
  189. +    }    
  190. +    rangingduration =(int) round(((mac_->getPhy()->getPS()*rangingslot)/mac_->getPhy()->getSymbolTime()));
  191. +    bwduration = (int) round (((mac_->getPhy()->getPS()*bwslot)/mac_->getPhy()->getSymbolTime()));
  192. +    //we open the uplink to initial ranging and bw requests
  193. +    ContentionSlot *slot = map_->getUlSubframe()->getRanging ();
  194. +    //create burst to represent the contention slot
  195. +    Burst* b2 = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0);
  196. +    pduIndex++;
  197. +    b2->setIUC (UIUC_INITIAL_RANGING);
  198. +    b2->setDuration (rangingduration);
  199. +    b2->setStarttime (ulduration); //we put the contention at the begining
  200. +    ulduration += rangingduration;
  201. +    
  202. +    //now the bw request
  203. +    slot = map_->getUlSubframe()->getBw_req ();
  204. +    b2 = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0);
  205. +    pduIndex++;
  206. +    b2->setIUC (UIUC_REQ_REGION_FULL);
  207. +    b2->setDuration (bwduration);
  208. +    b2->setStarttime (ulduration); //start after the ranging slot
  209. +    ulduration += bwduration;
  210. +  }
  211. +  
  212. +  //check if there is Fast Ranging allocation to do
  213. +  while (fast_ranging_head_.lh_first !=NULL 
  214. +  && fast_ranging_head_.lh_first->frame() == mac_->getFrameNumber()) {
  215. +    //we need to include a fast ranging allocation
  216. +    b = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0);
  217. +    pduIndex++;
  218. +    int tmp =(int) round(((mac_->getPhy()->getPS()*getInitRangingopportunity())/mac_->getPhy()->getSymbolTime()));    
  219. +    b->setIUC (UIUC_EXT_UIUC);
  220. +    b->setDuration (tmp);
  221. +    b->setStarttime (ulduration); //start after previous slot
  222. +    ((UlBurst*)b)->setFastRangingParam (fast_ranging_head_.lh_first->macAddr(), UIUC_INITIAL_RANGING);
  223. +    ulduration += tmp;
  224. +    mac_->debug ("At %f in Mac %d adding fast ranging for %dn", NOW, mac_->addr(), fast_ranging_head_.lh_first->macAddr());
  225. +    fast_ranging_head_.lh_first->remove_entry();
  226. +  }
  227. +
  228. +  //get the next node to allocate bw. 
  229. +  //PB: the node may have been removed. We need to check that
  230. +  PeerNode *peer = mac_->getPeerNode_head();
  231. +  PeerNode *start_peer = mac_->getPeerNode_head(); 
  232. +  int i=0;
  233. +
  234. +  if (start_peer != NULL) {
  235. +    //we have at least one element in the list
  236. +    for (peer = mac_->getPeerNode_head(); peer->next_entry() ; peer=peer->next_entry());
  237. +    debug2 ("start_peer=%d, peer=%dn", start_peer->getPeerNode(), peer->getPeerNode());
  238. +    while (start_peer != peer) {
  239. +      if (!isPeerScanning(peer->getPeerNode())) {
  240. + debug2 ("peer %d not scanning take itn", peer->getPeerNode());
  241. + break; //we found next station
  242. +      }
  243. +      debug2 ("peer %d scanning move itn", peer->getPeerNode());
  244. +      peer->remove_entry();
  245. +      mac_->addPeerNode (peer); //we put it at head of the list
  246. +      for (peer = mac_->getPeerNode_head(); peer->next_entry() ; peer=peer->next_entry());
  247. +    }
  248. +  }
  249. +  if (peer)
  250. +    debug2 ("final pick is %dn", peer->getPeerNode());
  251. +
  252. +  //update variables
  253. +  bw_node_index_ = i;
  254. +  bw_peer_ = peer;
  255. +  
  256. +  //the next peer node takes the rest of the bw
  257. +  if (nbSymbols > 0 && peer && !isPeerScanning(peer->getPeerNode())) {
  258. +    debug2 ("Allocate uplink for STA %dn", peer->getPeerNode());
  259. +    peer->remove_entry();
  260. +    mac_->addPeerNode (peer); //we put it at head of the list
  261. +    //printf ("NbSymbols for node=%dn", nbSymbols);
  262. +    //add burst
  263. +    Burst *b3 = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0);
  264. +    pduIndex++;
  265. +    b3->setIUC (UIUC_PROFILE_1);
  266. +    b3->setCid (peer->getPrimary()->get_cid());
  267. +    b3->setDuration (nbSymbols);
  268. +    b3->setStarttime (ulduration); 
  269. +    //add profile if not existing
  270. +    Profile *p = map_->getUlSubframe()->getProfile (UIUC_PROFILE_1);
  271. +    if (p==NULL) {
  272. +      p = map_->getUlSubframe()->addProfile (0, default_mod_);
  273. +      p->setIUC (UIUC_PROFILE_1);
  274. +    }
  275. +  }
  276. +  
  277. +  //end of map
  278. +  Burst *b2 = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0);
  279. +  pduIndex++;
  280. +  b2->setIUC (UIUC_END_OF_MAP);
  281. +  b2->setStarttime (rangingduration+bwduration+nbSymbols);
  282. +  
  283. +
  284. +
  285. +  //we need to fill up the outgoing queues
  286. +  for (int index = 0 ; index < map_->getDlSubframe()->getPdu ()->getNbBurst() ; index++) {
  287. +    b = map_->getDlSubframe()->getPdu ()->getBurst (index);
  288. +    int duration = 0; 
  289. +
  290. +    if (b->getIUC()==DIUC_END_OF_MAP) {
  291. +      //consistency check..
  292. +      assert (index == map_->getDlSubframe()->getPdu ()->getNbBurst()-1);
  293. +      break;
  294. +    }
  295. +    
  296. +    //we can get the next one after we check END_OF_MAP
  297. +    //b2 = map_->getDlSubframe()->getPdu ()->getBurst (index+1);
  298. +
  299. +    //if this is the first buffer, add DL_MAP...messages
  300. +    if (index==0) {
  301. +      p = map_->getDL_MAP();
  302. +      ch = HDR_CMN(p);
  303. +      txtime = phy->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding());
  304. +      ch->txtime() = txtime;
  305. +      txtime_s = (int) round(txtime/phy->getSymbolTime ()); //in units of symbol 
  306. +      assert ((duration+txtime_s) <= b->getDuration());
  307. +      b->enqueue(p);      //enqueue into burst
  308. +      duration += txtime_s;
  309. +      p = map_->getUL_MAP();
  310. +      ch = HDR_CMN(p);
  311. +      txtime = phy->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding());
  312. +      ch->txtime() = txtime;
  313. +      txtime_s = (int) round(txtime/phy->getSymbolTime ()); //in units of symbol 
  314. +      assert ((duration+txtime_s) <= b->getDuration());
  315. +      b->enqueue(p);      //enqueue into burst
  316. +      duration += txtime_s;
  317. +
  318. +      if (sendDCD || map_->getDlSubframe()->getCCC()!= dlccc_) {
  319. + p = map_->getDCD();
  320. + ch = HDR_CMN(p);
  321. + txtime = phy->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding());
  322. + ch->txtime() = txtime;
  323. + txtime_s = (int) round(txtime/phy->getSymbolTime ()); //in units of symbol 
  324. + assert ((duration+txtime_s) <= b->getDuration());
  325. + b->enqueue(p);      //enqueue into burst
  326. + duration += txtime_s;
  327. + sendDCD = false;
  328. + dlccc_ = map_->getDlSubframe()->getCCC();
  329. + //reschedule timer
  330. + dcdtimer_->stop();
  331. + dcdtimer_->start (mac_->macmib_.dcd_interval);
  332. +      }
  333. +      
  334. +      if (sendUCD || map_->getUlSubframe()->getCCC()!= ulccc_) {
  335. + p = map_->getUCD();
  336. + ch = HDR_CMN(p);
  337. + txtime = phy->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding());
  338. + ch->txtime() = txtime;
  339. + txtime_s = (int) round(txtime/phy->getSymbolTime ()); //in units of symbol 
  340. + assert ((duration+txtime_s) <= b->getDuration());
  341. + b->enqueue(p);      //enqueue into burst
  342. + duration += txtime_s;
  343. + sendUCD = false;
  344. + ulccc_ = map_->getUlSubframe()->getCCC();
  345. + //reschedule timer
  346. + ucdtimer_->stop();
  347. + ucdtimer_->start (mac_->macmib_.ucd_interval);
  348. +      }
  349. +    }
  350. +      
  351. +    //get the packets from the connection with the same CID
  352. +    //Connection *c=mac_->getCManager ()->get_connection (b->getCid());
  353. +    int nb_down = 0;
  354. +    for (Connection *c = mac_->getCManager()->get_down_connection (); c ; c=c->next_entry()){ nb_down++;}
  355. +    Connection **tmp_con = (Connection **) malloc (nb_down*sizeof (Connection *));
  356. +    int i=0;
  357. +    for (Connection *c = mac_->getCManager()->get_down_connection (); c ; c=c->next_entry()){
  358. +      tmp_con[i] = c;
  359. +      i++;
  360. +    }
  361. +    //we randomly pick the connection we'll start serving first
  362. +    int start_index = (int) round (Random::uniform(0, nb_down));
  363. +    debug2 ("Picked connection %d as firstn", start_index);
  364. +
  365. +    //for (Connection *c = mac_->getCManager()->get_down_connection (); c ; c=c->next_entry()) {
  366. +    for (i=0; i < nb_down ; i++) {
  367. +      int index = (i+start_index)%nb_down;
  368. +      Connection *c=tmp_con[index];
  369. +
  370. +      if (c->getPeerNode() && isPeerScanning (c->getPeerNode()->getPeerNode()))
  371. + continue;
  372. +
  373. +      duration = transfer_packets (c, b, duration);
  374. +    }
  375. +  }
  376. +
  377. +  //change PHY state
  378. +  mac_->getPhy()->setMode (OFDM_SEND);
  379. +
  380. +  //start handler of dlsubframe
  381. +  map_->getDlSubframe()->getTimer()->sched (0);
  382. +
  383. +  //reschedule for next time (frame duration)
  384. +  dl_timer_->resched (mac_->getFrameDuration());  
  385. +}
  386. +
  387. +/** Add a new Fast Ranging allocation
  388. + * @param time The time when to allocate data
  389. + * @param macAddr The MN address
  390. + */
  391. +void BSScheduler::addNewFastRanging (double time, int macAddr)
  392. +{
  393. +  //compute the frame where the allocation will be located
  394. +  int frame = int ((time-NOW)/mac_->getFrameDuration()) +2 ;
  395. +  frame += mac_->getFrameNumber();
  396. +  //printf ("Added fast RA for frame %d (current=%d) for time (%f)n", 
  397. +  //   frame, mac_->getFrameNumber(), time);
  398. +  FastRangingInfo *info= new FastRangingInfo (frame, macAddr);
  399. +  info->insert_entry(&fast_ranging_head_);
  400. +}
  401. +
  402. +
  403. +/**** Packet processing methods ****/
  404. +
  405. +/**
  406. + * Process a RNG-REQ message
  407. + * @param p The packet containing the ranging request information
  408. + */
  409. +void BSScheduler::process_ranging_req (Packet *p)
  410. +{
  411. +  UlSubFrame *ulsubframe = map_->getUlSubframe();
  412. +  mac802_16_rng_req_frame *req = (mac802_16_rng_req_frame *) p->accessdata();
  413. +
  414. +  if (HDR_MAC802_16(p)->header.cid != INITIAL_RANGING_CID) {
  415. +    //process request for DIUC
  416. +  } else {
  417. +    //here we can make decision to accept the SS or not.
  418. +    //for now, accept everybody
  419. +    //check if CID already assigned for the SS
  420. +    PeerNode *peer = mac_->getPeerNode (req->ss_mac_address);
  421. +    if (peer==NULL) {
  422. +      mac_->debug ("New peer node requesting ranging (%d)n",req->ss_mac_address);
  423. +      //Assign Management CIDs
  424. +      Connection *basic = new Connection (CONN_BASIC);
  425. +      Connection *upbasic = new Connection (CONN_BASIC, basic->get_cid());
  426. +      Connection *primary = new Connection (CONN_PRIMARY);
  427. +      Connection *upprimary = new Connection (CONN_PRIMARY, primary->get_cid());
  428. +      
  429. +      //Create Peer information
  430. +      peer = new PeerNode (req->ss_mac_address);
  431. +      peer->setBasic (basic);
  432. +      peer->setPrimary (primary);
  433. +      upbasic->setPeerNode (peer);
  434. +      upprimary->setPeerNode (peer);
  435. +      mac_->addPeerNode (peer);
  436. +      mac_->getCManager()->add_connection (upbasic, true);
  437. +      mac_->getCManager()->add_connection (basic, false);
  438. +      mac_->getCManager()->add_connection (upprimary, true);
  439. +      mac_->getCManager()->add_connection (primary, false);
  440. +      //schedule timer in case the node never register
  441. +      addtimer17 (req->ss_mac_address);
  442. +
  443. +      //create packet for answers
  444. +      Packet *rep = mac_->getPacket ();
  445. +      struct hdr_cmn *ch = HDR_CMN(rep);
  446. +      rep->allocdata (sizeof (struct mac802_16_rng_rsp_frame));
  447. +      mac802_16_rng_rsp_frame *frame = (mac802_16_rng_rsp_frame*) rep->accessdata();
  448. +      frame->type = MAC_RNG_RSP;
  449. +      frame->uc_id = ulsubframe->getChannelID();
  450. +      frame->rng_status = RNG_SUCCESS;
  451. +      frame->ss_mac_address = req->ss_mac_address;
  452. +      frame->basic_cid = basic->get_cid();
  453. +      frame->primary_cid = primary->get_cid();
  454. +      ch->size() = RNG_RSP_SIZE;
  455. +      //compute transmission time
  456. +      Burst *b = map_->getDlSubframe()->getPdu ()->getBurst (0);
  457. +      double txtime = mac_->getPhy()->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding());
  458. +      ch->txtime() = txtime;
  459. +      //enqueue packet
  460. +      mac_->getCManager()->get_connection (BROADCAST_CID, false)->enqueue (rep);
  461. +
  462. +      if (cl_head_==NULL) {
  463. + cl_head_ = (new_client_t*)malloc (sizeof (new_client_t));
  464. + cl_tail_ = cl_head_;
  465. +      } else {
  466. + cl_tail_->next = (new_client_t*)malloc (sizeof (new_client_t));
  467. + cl_tail_=cl_tail_->next;
  468. +      }
  469. +      cl_tail_->cid = primary->get_cid();
  470. +      cl_tail_->next = NULL;
  471. +
  472. +#ifdef USE_802_21
  473. +      mac_->send_link_detected (mac_->addr(), peer->getPeerNode(), 1);
  474. +#endif
  475. +
  476. +    } else {
  477. +      mac_->debug ("Received ranging for known station (%d)n", req->ss_mac_address);
  478. +      //reset invited ranging retries for SS
  479. +      //create packet for answers
  480. +      Connection *basic = peer->getBasic();
  481. +      Connection *primary = peer->getPrimary();
  482. +      Packet *rep = mac_->getPacket ();
  483. +      struct hdr_cmn *ch = HDR_CMN(rep);
  484. +      rep->allocdata (sizeof (struct mac802_16_rng_rsp_frame));
  485. +      mac802_16_rng_rsp_frame *frame = (mac802_16_rng_rsp_frame*) rep->accessdata();
  486. +      frame->type = MAC_RNG_RSP;
  487. +      frame->uc_id = ulsubframe->getChannelID();
  488. +      frame->rng_status = RNG_SUCCESS;
  489. +      frame->ss_mac_address = req->ss_mac_address;
  490. +      frame->basic_cid = basic->get_cid();
  491. +      frame->primary_cid = primary->get_cid();
  492. +      ch->size() = RNG_RSP_SIZE;
  493. +      //compute transmission time
  494. +      Burst *b = map_->getDlSubframe()->getPdu ()->getBurst (0);
  495. +      double txtime = mac_->getPhy()->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding());
  496. +      ch->txtime() = txtime;
  497. +      //enqueue packet
  498. +      mac_->getCManager()->get_connection (BROADCAST_CID, false)->enqueue (rep);
  499. +    }
  500. +  }
  501. +}
  502. +
  503. +/**
  504. + * Add a new timer17 in the list. It also performs cleaning of the list
  505. + * @param index The client address
  506. + */
  507. +void BSScheduler::addtimer17 (int index)
  508. +{
  509. +  //clean expired timers
  510. +  T17Element *entry;
  511. +  for (entry = t17_head_.lh_first; entry ; ) {
  512. +    if (entry->paused ()) {
  513. +      T17Element *tmp = entry;
  514. +      entry = entry->next_entry();
  515. +      tmp->remove_entry();
  516. +      free (tmp);
  517. +    }
  518. +    entry = entry->next_entry();
  519. +  }
  520. +
  521. +  entry = new T17Element (mac_, index);
  522. +  entry->insert_entry (&t17_head_);
  523. +}
  524. +/**
  525. + * Cancel and remove the timer17 associated with the node
  526. + * @param index The client address
  527. + */
  528. +void BSScheduler::removetimer17 (int index)
  529. +{
  530. +  //clean expired timers
  531. +  T17Element *entry;
  532. +  for (entry = t17_head_.lh_first; entry ; entry = entry->next_entry()) {
  533. +    if (entry->index ()==index) {
  534. +      entry->cancel();
  535. +      entry->remove_entry();
  536. +      delete (entry);
  537. +      break;
  538. +    }
  539. +  }
  540. +}
  541. +
  542. +/**
  543. + * Process bandwidth request
  544. + * @param p The request
  545. + */
  546. +void BSScheduler::process_bw_req (Packet *p)
  547. +{ 
  548. +  hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(p);
  549. +  gen_mac_header_t header = wimaxHdr->header;
  550. +
  551. +  bw_req_header_t *req;
  552. +  req = (bw_req_header_t *)&header;
  553. +
  554. +  mac_->debug ("received bandwidth request of %d bytes from %dn", req->br, req->cid); 
  555. +  
  556. +}
  557. +
  558. +/**
  559. + * Process registration request
  560. + * @param p The request
  561. + */
  562. +void BSScheduler::process_reg_req (Packet *req)
  563. +{ 
  564. +  hdr_mac802_16 *wimaxHdr_req = HDR_MAC802_16(req);
  565. +  gen_mac_header_t header_req = wimaxHdr_req->header;
  566. +  
  567. +  mac_->debug ("received registration request from %dn", header_req.cid);
  568. +
  569. +  Packet *p;
  570. +  struct hdr_cmn *ch;
  571. +  hdr_mac802_16 *wimaxHdr;
  572. +  mac802_16_reg_rsp_frame *reg_frame;
  573. +  PeerNode *peer;
  574. +
  575. +  //create packet for request
  576. +  p = mac_->getPacket ();
  577. +  ch = HDR_CMN(p);
  578. +  wimaxHdr = HDR_MAC802_16(p);
  579. +  p->allocdata (sizeof (struct mac802_16_reg_rsp_frame));
  580. +  reg_frame = (mac802_16_reg_rsp_frame*) p->accessdata();
  581. +  reg_frame->type = MAC_REG_RSP;
  582. +  reg_frame->response = 0; //OK
  583. +  peer = mac_->getCManager()->get_connection (header_req.cid, false)->getPeerNode();
  584. +  Connection *secondary = peer->getSecondary ();
  585. +  if (secondary==NULL) {
  586. +    //first time 
  587. +    secondary = new Connection (CONN_SECONDARY);
  588. +    Connection *upsecondary = new Connection (CONN_SECONDARY, secondary->get_cid());
  589. +    mac_->getCManager()->add_connection (upsecondary, true);
  590. +    mac_->getCManager()->add_connection (secondary, false);
  591. +    peer->setSecondary (secondary);
  592. +    upsecondary->setPeerNode (peer);
  593. +  }
  594. +  reg_frame->sec_mngmt_cid = secondary->get_cid();
  595. +  wimaxHdr->header.cid = header_req.cid;
  596. +  ch->size() = REG_RSP_SIZE;
  597. +  
  598. +  //compute transmission time
  599. +  Burst *b = map_->getDlSubframe()->getPdu ()->getBurst (0);
  600. +  double txtime = mac_->getPhy()->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding());
  601. +  ch->txtime() = txtime;
  602. +  //enqueue packet
  603. +  mac_->getCManager()->get_connection (BROADCAST_CID, false)->enqueue (p);
  604. +  //clear t17 timer for this node
  605. +  removetimer17 (peer->getPeerNode());
  606. +
  607. +#ifdef USE_802_21
  608. +  mac_->debug ("At %f in Mac %d, send link upn", NOW, mac_->addr());
  609. +  mac_->send_link_up (peer->getPeerNode(),mac_->addr());
  610. +#endif
  611. +}
  612. +
  613. +/**
  614. + * Send a neighbor advertisement message
  615. + */
  616. +void BSScheduler::send_nbr_adv ()
  617. +{
  618. +  mac_->debug ("At %f in BS %d send_nbr_adv (nb_neighbor=%d)n", NOW, mac_->addr(), nbr_db_->getNbNeighbor());
  619. +  Packet *p;
  620. +  struct hdr_cmn *ch;
  621. +  hdr_mac802_16 *wimaxHdr;
  622. +  mac802_16_mob_nbr_adv_frame *frame;
  623. +  //PeerNode *peer;
  624. +
  625. +  //create packet for request
  626. +  p = mac_->getPacket ();
  627. +  ch = HDR_CMN(p);
  628. +  wimaxHdr = HDR_MAC802_16(p);
  629. +  p->allocdata (sizeof (struct mac802_16_mob_nbr_adv_frame));
  630. +  frame = (mac802_16_mob_nbr_adv_frame*) p->accessdata();
  631. +  frame->type = MAC_MOB_NBR_ADV;
  632. +  frame->n_neighbors = nbr_db_->getNbNeighbor();
  633. +  frame->skip_opt_field = 0;
  634. +  for (int i = 0 ; i < frame->n_neighbors ; i++) {
  635. +    frame->nbr_info[i].phy_profile_id.FAindex = 0;
  636. +    frame->nbr_info[i].phy_profile_id.bs_eirp = 0;
  637. +    frame->nbr_info[i].nbr_bsid= nbr_db_->getNeighbors()[i]->getID();
  638. +    frame->nbr_info[i].dcd_included = true;
  639. +    memcpy (&(frame->nbr_info[i].dcd_settings), nbr_db_->getNeighbors ()[i]->getDCD(), sizeof(mac802_16_dcd_frame));
  640. +    frame->nbr_info[i].ucd_included = true;
  641. +    memcpy (&(frame->nbr_info[i].ucd_settings), nbr_db_->getNeighbors ()[i]->getUCD(), sizeof(mac802_16_ucd_frame));
  642. +    frame->nbr_info[i].phy_included = false;
  643. +  }
  644. +  ch->size() = Mac802_16pkt::getMOB_NBR_ADV_size(frame);
  645. +  mac_->getCManager()->get_connection (BROADCAST_CID, false)->enqueue (p);
  646. +  
  647. +}
  648. +
  649. +/** 
  650. + * Finds out if the given station is currently scanning
  651. + * @param nodeid The MS id
  652. + */
  653. +bool BSScheduler::isPeerScanning (int nodeid)
  654. +{
  655. +  ScanningStation *sta;
  656. +  for (sta = scan_stations_.lh_first; sta ; sta = sta->next_entry()) {
  657. +    if (sta->getNodeId()==nodeid && sta->isScanning(mac_->frame_number_)) {
  658. +      //printf ("station %d scanningn", nodeid);
  659. +      return true;
  660. +    }
  661. +  }
  662. +  return false;
  663. +}
  664. +
  665. +/**
  666. + * Process handover request
  667. + * @param p The request
  668. + */
  669. +void BSScheduler::process_msho_req (Packet *req)
  670. +{
  671. +  hdr_mac802_16 *wimaxHdr_req = HDR_MAC802_16(req);
  672. +  gen_mac_header_t header_req = wimaxHdr_req->header;
  673. +  mac802_16_mob_msho_req_frame *req_frame = 
  674. +    (mac802_16_mob_msho_req_frame*) req->accessdata();
  675. +  
  676. +  mac_->debug ("At %f in Mac %d received handover request from %dn", NOW, mac_->addr(), header_req.cid);
  677. +
  678. +  //check the BS that has stronger power
  679. +  int maxIndex = 0;
  680. +  int maxRssi = 0; //max value
  681. +  for (int i = 0; i < req_frame->n_new_bs_full ; i++) {
  682. +    if (req_frame->bs_full[i].bs_rssi_mean >= maxRssi) {
  683. +      maxIndex = i;
  684. +      maxRssi = req_frame->bs_full[i].bs_rssi_mean;
  685. +    }
  686. +  }
  687. +  //reply with one recommended BS
  688. +  Packet *p;
  689. +  struct hdr_cmn *ch;
  690. +  hdr_mac802_16 *wimaxHdr;
  691. +  mac802_16_mob_bsho_rsp_frame *rsp_frame;
  692. +
  693. +  send_nbr_adv (); //to force update with latest information
  694. +
  695. +  //create packet for request
  696. +  p = mac_->getPacket ();
  697. +  ch = HDR_CMN(p);
  698. +  wimaxHdr = HDR_MAC802_16(p);
  699. +  p->allocdata (sizeof (struct mac802_16_mob_bsho_rsp_frame)+sizeof (mac802_16_mob_bsho_rsp_rec));
  700. +  rsp_frame = (mac802_16_mob_bsho_rsp_frame*) p->accessdata();
  701. +  rsp_frame->type = MAC_MOB_BSHO_RSP;
  702. +  
  703. +  rsp_frame->mode = 0; //HO request
  704. +  rsp_frame->ho_operation_mode = 1; //mandatory handover response
  705. +  rsp_frame->n_recommended = 1;
  706. +  rsp_frame->resource_retain_flag = 0; //release connection information
  707. +  rsp_frame->n_rec[0].neighbor_bsid = req_frame->bs_full[maxIndex].neighbor_bs_index;
  708. +  rsp_frame->n_rec[0].ho_process_optimization=0; //no optimization
  709. +
  710. +  ch->size() += Mac802_16pkt::getMOB_BSHO_RSP_size(rsp_frame);
  711. +  wimaxHdr->header.cid = header_req.cid;
  712. +  mac_->getCManager()->get_connection (BROADCAST_CID, false)->enqueue (p);
  713. +}
  714. +/**
  715. + * Process handover indication
  716. + * @param p The indication
  717. + */
  718. +void BSScheduler::process_ho_ind (Packet *p)
  719. +{
  720. +  hdr_mac802_16 *wimaxHdr_req = HDR_MAC802_16(p);
  721. +  gen_mac_header_t header_req = wimaxHdr_req->header;
  722. +  //mac802_16_mob_ho_ind_frame *req_frame = 
  723. +  //  (mac802_16_mob_ho_ind_frame*) p->accessdata();
  724. +  
  725. +  mac_->debug ("At %f in Mac %d received handover indication from %dn", NOW, mac_->addr(), header_req.cid);
  726. +  
  727. +
  728. +}
  729. +/**
  730. + * Send a scan response to the MN
  731. + * @param rsp The response from the control
  732. + */
  733. +void BSScheduler::send_scan_response (mac802_16_mob_scn_rsp_frame *rsp, int cid)
  734. +{
  735. +  //create packet for request
  736. +  Packet *p = mac_->getPacket ();
  737. +  struct hdr_cmn *ch = HDR_CMN(p);
  738. +  hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(p);
  739. +  p->allocdata (sizeof (struct mac802_16_mob_scn_rsp_frame));
  740. +  mac802_16_mob_scn_rsp_frame* rsp_frame = (mac802_16_mob_scn_rsp_frame*) p->accessdata();
  741. +  memcpy (rsp_frame, rsp, sizeof (mac802_16_mob_scn_rsp_frame));
  742. +  rsp_frame->type = MAC_MOB_SCN_RSP;
  743. +  
  744. +  wimaxHdr->header.cid = cid;
  745. +  ch->size() += Mac802_16pkt::getMOB_SCN_RSP_size(rsp_frame);
  746. +  
  747. +  //add scanning station to the list
  748. +  PeerNode *peer = mac_->getCManager()->get_connection (cid, false)->getPeerNode();
  749. +
  750. +  /* The request is received in frame i, the reply is sent in frame i+1
  751. +   * so the frame at which the scanning start is start_frame+2
  752. +   */
  753. +  ScanningStation *sta = new ScanningStation (peer->getPeerNode(), rsp_frame->scan_duration & 0xFF, 
  754. +      rsp_frame->start_frame+mac_->frame_number_+2, 
  755. +      rsp_frame->interleaving_interval & 0xFF,
  756. +      rsp_frame->scan_iteration & 0xFF);
  757. +  sta->insert_entry_head (&scan_stations_);
  758. +
  759. +  //compute transmission time
  760. +  Burst *b = map_->getDlSubframe()->getPdu ()->getBurst (0);
  761. +  double txtime = mac_->getPhy()->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding());
  762. +  ch->txtime() = txtime;
  763. +  //enqueue packet
  764. +  mac_->getCManager()->get_connection (BROADCAST_CID, false)->enqueue (p);
  765. +}
  766. diff -Naur ns-2.29-org/wimax/scheduling/bsscheduler.h ns-2.29/wimax/scheduling/bsscheduler.h
  767. --- ns-2.29-org/wimax/scheduling/bsscheduler.h 1969-12-31 19:00:00.000000000 -0500
  768. +++ ns-2.29/wimax/scheduling/bsscheduler.h 2006-09-22 17:27:47.000000000 -0400
  769. @@ -0,0 +1,322 @@
  770. +/* This software was developed at the National Institute of Standards and
  771. + * Technology by employees of the Federal Government in the course of
  772. + * their official duties. Pursuant to title 17 Section 105 of the United
  773. + * States Code this software is not subject to copyright protection and
  774. + * is in the public domain.
  775. + * NIST assumes no responsibility whatsoever for its use by other parties,
  776. + * and makes no guarantees, expressed or implied, about its quality,
  777. + * reliability, or any other characteristic.
  778. + * <BR>
  779. + * We would appreciate acknowledgement if the software is used.
  780. + * <BR>
  781. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  782. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  783. + * FROM THE USE OF THIS SOFTWARE.
  784. + * </PRE></P>
  785. + * @author  rouil
  786. + */
  787. +
  788. +#ifndef BSSCHEDULER_H
  789. +#define BSSCHEDULER_H
  790. +
  791. +#include "wimaxscheduler.h"
  792. +#include "scanningstation.h"
  793. +
  794. +#define INIT_DL_DURATION 20 //enough for DL_MAP, UL_MAP, DCD, UCD and some RNG-RSP
  795. +#define MIN_CONTENTION_SIZE 5 //minimum number of opportunity for allocation
  796. +
  797. +/** Information about a new client */
  798. +struct new_client_t {
  799. +  int cid; //primary cid of new client
  800. +  new_client_t *next;
  801. +};
  802. +
  803. +class T17Element;
  804. +LIST_HEAD (t17element, T17Element);
  805. +/** Object to handle timer t17 */
  806. +class T17Element {
  807. + public:
  808. +  T17Element (Mac802_16 *mac, int index) {
  809. +    index_ = index;
  810. +    timer = new WimaxT17Timer (mac, index);
  811. +    timer->start (mac->macmib_.t17_timeout);
  812. +  }
  813. +
  814. +  ~T17Element () { delete (timer); }
  815. +
  816. +  int index () { return index_; }
  817. +  int paused () { return timer->paused(); }
  818. +  void cancel () { timer->stop(); }
  819. +
  820. +  // Chain element to the list
  821. +  inline void insert_entry(struct t17element *head) {
  822. +    LIST_INSERT_HEAD(head, this, link);
  823. +  }
  824. +  
  825. +  // Return next element in the chained list
  826. +  T17Element* next_entry(void) const { return link.le_next; }
  827. +
  828. +  // Remove the entry from the list
  829. +  inline void remove_entry() { 
  830. +    LIST_REMOVE(this, link); 
  831. +  }
  832. + protected:
  833. +  
  834. +  /*
  835. +   * Pointer to next in the list
  836. +   */
  837. +  LIST_ENTRY(T17Element) link;
  838. +  //LIST_ENTRY(T17Element); //for magic draw
  839. +
  840. + private:
  841. +  int index_;
  842. +  WimaxT17Timer *timer;
  843. +};
  844. +
  845. +class FastRangingInfo;
  846. +LIST_HEAD (fastRangingInfo, FastRangingInfo);
  847. +/** Store information about a fast ranging request to send */
  848. +class FastRangingInfo {
  849. + public:
  850. +  FastRangingInfo (int frame, int macAddr) {
  851. +    frame_ = frame;
  852. +    macAddr_ = macAddr;
  853. +  }
  854. +
  855. +  int frame () { return frame_; }
  856. +  int macAddr () { return macAddr_; }
  857. +
  858. +  // Chain element to the list
  859. +  inline void insert_entry(struct fastRangingInfo *head) {
  860. +    LIST_INSERT_HEAD(head, this, link);
  861. +  }
  862. +  
  863. +  // Return next element in the chained list
  864. +  FastRangingInfo* next_entry(void) const { return link.le_next; }
  865. +
  866. +  // Remove the entry from the list
  867. +  inline void remove_entry() { 
  868. +    LIST_REMOVE(this, link); 
  869. +  }
  870. + protected:
  871. +  
  872. +  /*
  873. +   * Pointer to next in the list
  874. +   */
  875. +  LIST_ENTRY(FastRangingInfo) link;
  876. +  //LIST_ENTRY(FastRangingInfo); //for magic draw
  877. +
  878. + private:
  879. +  int frame_;
  880. +  int macAddr_;
  881. +};
  882. +
  883. +class WimaxCtrlAgent;
  884. +/**
  885. + * Class BSScheduler
  886. + * Implement the packet scheduler on the BS side
  887. + */ 
  888. +class BSScheduler : public WimaxScheduler {
  889. +  //friend class SendTimer;
  890. + public:
  891. +  /*
  892. +   * Create a scheduler
  893. +   */
  894. +  BSScheduler ();
  895. +
  896. +  /*
  897. +   * Interface with the TCL script
  898. +   * @param argc The number of parameter
  899. +   * @param argv The list of parameters
  900. +   */
  901. +  int command(int argc, const char*const* argv);
  902. +    
  903. +  /**
  904. +   * Process a packet received by the Mac. Only scheduling related packets should be sent here (BW request, UL_MAP...)
  905. +   * @param p The packet to process
  906. +   */
  907. +  void  process (Packet * p);
  908. +
  909. +  /**
  910. +   * Return the type of STA this scheduler is good for
  911. +   */
  912. +  virtual station_type_t getNodeType ();
  913. +
  914. +  /**
  915. +   * Initializes the scheduler
  916. +   */
  917. +  virtual void init ();
  918. +  /**
  919. +   * Called when a timer expires
  920. +   * @param The timer ID
  921. +   */
  922. +  virtual void expire (timer_id id);
  923. +
  924. +  /**
  925. +   * Start a new DL subframe
  926. +   */
  927. +  virtual void start_dlsubframe ();
  928. +
  929. +  /**
  930. +   * Start a new UL subframe
  931. +   */
  932. +  virtual void start_ulsubframe ();
  933. +
  934. +  /** 
  935. +   * Finds out if the given station is currently scanning
  936. +   * @param nodeid The MS id
  937. +   */
  938. +  bool isPeerScanning (int nodeid);
  939. +
  940. +  /**
  941. +   * Set the control agent
  942. +   * @param agent The control agent
  943. +   */
  944. +  void setCtrlAgent (WimaxCtrlAgent *agent);
  945. +
  946. +  /** Add a new Fast Ranging allocation
  947. +   * @param time The time when to allocate data
  948. +   * @param macAddr The MN address
  949. +   */
  950. +  void addNewFastRanging (double time, int macAddr);
  951. +
  952. +  /**
  953. +   * Send a scan response to the MN
  954. +   * @param rsp The response from the control
  955. +   * @cid The CID for the MN
  956. +   */
  957. +  void send_scan_response (mac802_16_mob_scn_rsp_frame *rsp, int cid);
  958. +
  959. + protected:
  960. +
  961. +  /**
  962. +   * Default modulation 
  963. +   */
  964. +  Ofdm_mod_rate default_mod_;
  965. +
  966. +  /**
  967. +   * Number of transmission opportunity for initial ranging
  968. +   * and bw request (i.e contention slots)
  969. +   */
  970. +  int contention_size_; 
  971. +
  972. +  /**
  973. +   * Compute and return the bandwidth request opportunity size
  974. +   * @return The bandwidth request opportunity size
  975. +   */
  976. +  int getBWopportunity ();
  977. +
  978. +  /**
  979. +   * Compute and return the initial ranging opportunity size
  980. +   * @return The initial ranging opportunity size
  981. +   */
  982. +  int getInitRangingopportunity ();  
  983. +
  984. + private:
  985. +
  986. +  /**
  987. +   * Process a RNG-REQ message
  988. +   * @param frame The ranging request information
  989. +   */
  990. +  void process_ranging_req (Packet *p);
  991. +
  992. +  /**
  993. +   * Process bandwidth request
  994. +   * @param p The request
  995. +   */
  996. +  void process_bw_req (Packet *p);
  997. +
  998. +  /**
  999. +   * Process bandwidth request
  1000. +   * @param p The request
  1001. +   */
  1002. +  void process_reg_req (Packet *p);
  1003. +
  1004. +  /**
  1005. +   * Process handover request
  1006. +   * @param req The request
  1007. +   */
  1008. +  void process_msho_req (Packet *req);
  1009. +  /**
  1010. +   * Process handover indication
  1011. +   * @param p The indication
  1012. +   */
  1013. +  void process_ho_ind (Packet *p);
  1014. +  /**
  1015. +   * Send a neighbor advertisement message
  1016. +   */
  1017. +  void send_nbr_adv ();
  1018. +
  1019. +
  1020. +  /**
  1021. +   * Add a new timer 17 for client
  1022. +   * @param index The client address
  1023. +   */
  1024. +  void addtimer17 (int index);
  1025. +  
  1026. +  /**
  1027. +   * Cancel and remove the timer17 associated with the node
  1028. +   * @param index The client address
  1029. +   */
  1030. +  void removetimer17 (int index);
  1031. +
  1032. +  struct new_client_t *cl_head_;
  1033. +  struct new_client_t *cl_tail_;
  1034. +
  1035. +  struct t17element t17_head_;
  1036. +
  1037. +  /**
  1038. +   * The index of the last SS that had bandwidth allocation
  1039. +   */
  1040. +  int bw_node_index_;
  1041. +  
  1042. +  /**
  1043. +   * The node that had the last bandwidth allocation
  1044. +   */
  1045. +  PeerNode *bw_peer_; 
  1046. +
  1047. +  /**
  1048. +   * Timer for DCD
  1049. +   */
  1050. +  WimaxDCDTimer *dcdtimer_; 
  1051. +
  1052. +  /**
  1053. +   * Timer for UCD
  1054. +   */
  1055. +  WimaxUCDTimer *ucdtimer_;
  1056. +
  1057. +  /**
  1058. +   * Timer for MOB-NBR_ADV messages
  1059. +   */
  1060. +  WimaxMobNbrAdvTimer *nbradvtimer_;
  1061. +
  1062. +  /**
  1063. +   * Indicates if it is time to send a DCD message
  1064. +   */
  1065. +  bool sendDCD;
  1066. +  int dlccc_;
  1067. +  bool sendUCD;
  1068. +  int ulccc_;
  1069. +  
  1070. +  /** 
  1071. +   * List of station in scanning 
  1072. +   */
  1073. +  struct scanningStation scan_stations_;
  1074. +
  1075. +  /**
  1076. +   * The Wimax control for BS synchronization
  1077. +   */
  1078. +  WimaxCtrlAgent *ctrlagent_;
  1079. +
  1080. +  /**
  1081. +   * List of the upcoming Fast Ranging allocation 
  1082. +   */
  1083. +  struct fastRangingInfo fast_ranging_head_;
  1084. +
  1085. +};
  1086. +
  1087. +#endif //BSSCHEDULER_H
  1088. +
  1089. diff -Naur ns-2.29-org/wimax/scheduling/burst.cc ns-2.29/wimax/scheduling/burst.cc
  1090. --- ns-2.29-org/wimax/scheduling/burst.cc 1969-12-31 19:00:00.000000000 -0500
  1091. +++ ns-2.29/wimax/scheduling/burst.cc 2006-09-22 17:27:47.000000000 -0400
  1092. @@ -0,0 +1,155 @@
  1093. +/* This software was developed at the National Institute of Standards and
  1094. + * Technology by employees of the Federal Government in the course of
  1095. + * their official duties. Pursuant to title 17 Section 105 of the United
  1096. + * States Code this software is not subject to copyright protection and
  1097. + * is in the public domain.
  1098. + * NIST assumes no responsibility whatsoever for its use by other parties,
  1099. + * and makes no guarantees, expressed or implied, about its quality,
  1100. + * reliability, or any other characteristic.
  1101. + * <BR>
  1102. + * We would appreciate acknowledgement if the software is used.
  1103. + * <BR>
  1104. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  1105. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  1106. + * FROM THE USE OF THIS SOFTWARE.
  1107. + * </PRE></P>
  1108. + * @author  rouil
  1109. + */
  1110. +
  1111. +#include "burst.h"
  1112. +
  1113. +
  1114. +/**
  1115. + * Creates a burst
  1116. + * @param phypdu The PhyPdu where it is located
  1117. + */
  1118. +Burst::Burst (PhyPdu *phypdu) : cid_(-1), duration_(0), 
  1119. + starttime_(0),iuc_(-1)
  1120. +{
  1121. +  assert (phypdu);
  1122. +  phypdu_ = phypdu;
  1123. +  queue_ = NULL;
  1124. +}
  1125. +
  1126. +/*
  1127. + * Delete the object
  1128. + */
  1129. +Burst::~Burst () 
  1130. +{
  1131. +  //delete packets in queue
  1132. +  if (queue_!=NULL) {
  1133. +    for (Packet *p = dequeue(); p ; p=dequeue()) {
  1134. +      Packet::free (p);
  1135. +    }
  1136. +    delete (queue_);
  1137. +  }
  1138. +} 
  1139. +
  1140. +/**
  1141. + * Set burst CID
  1142. + * @param cid The burst CID
  1143. + */
  1144. +void Burst::setCid( int cid )
  1145. +{
  1146. +  cid_ = cid;
  1147. +}
  1148. +
  1149. +/**
  1150. + * Return the CID for this burst
  1151. + * @return the CID for this burst
  1152. + */
  1153. +int Burst::getCid( )
  1154. +{
  1155. +  return cid_;
  1156. +}
  1157. +
  1158. +/**
  1159. + * Return the burst duration in units of OFDM symbols
  1160. + * @return the burst duration 
  1161. + */
  1162. +int Burst::getDuration( )
  1163. +{
  1164. +  return duration_;
  1165. +}
  1166. +
  1167. +/**
  1168. + * Set the duration of the burst in units of OFDM symbols
  1169. + * @param duration The burst duration
  1170. + */
  1171. +void Burst::setDuration (int duration)
  1172. +{
  1173. +  duration_=duration;
  1174. +}
  1175. +
  1176. +/**
  1177. + * Set burst IUC
  1178. + * @param iuc The burst IUC
  1179. + */
  1180. +void Burst::setIUC( int iuc )
  1181. +{
  1182. +  iuc_ = iuc;
  1183. +}
  1184. +
  1185. +/**
  1186. + * Return the Interval Usage Code
  1187. + * @return the burst start time
  1188. + */
  1189. +int Burst::getIUC( )
  1190. +{
  1191. +  return iuc_;
  1192. +}
  1193. +
  1194. +/**
  1195. + * Set burst start time in units of symbol duration
  1196. + * @param starttime the burst start time
  1197. + */
  1198. +void Burst::setStarttime( int starttime )
  1199. +{
  1200. +  assert (starttime >= 0);
  1201. +  starttime_ = starttime;
  1202. +}
  1203. +
  1204. +/**
  1205. + * Return the burst start time in units of symbol duration
  1206. + * @return the burst start time
  1207. + */
  1208. +int Burst::getStarttime( )
  1209. +{
  1210. +  return starttime_;
  1211. +}
  1212. +
  1213. +/**
  1214. + * Enqueue the given packet
  1215. + * @param p The packet to enqueue
  1216. + */
  1217. +void Burst::enqueue (Packet * p) 
  1218. +{
  1219. +  if (queue_ == NULL) {
  1220. +    //this is the first packet we enqueue, create queue
  1221. +    queue_ = new PacketQueue();
  1222. +  }
  1223. +  queue_->enque (p);
  1224. +}
  1225. +
  1226. +/**
  1227. + * Dequeue a packet from the queue
  1228. + * @param p The packet to enqueue
  1229. + */
  1230. +Packet * Burst::dequeue () 
  1231. +{
  1232. +  if (queue_==NULL) //in case there was never an enqueue
  1233. +    return NULL;
  1234. +  return queue_->deque ();
  1235. +}
  1236. +
  1237. +/**
  1238. + * Trigger the timer to send packets for this burst
  1239. + * @param time The time the trigger expires
  1240. + */
  1241. +/*
  1242. +void Burst::trigger_timer (double time)
  1243. +{
  1244. +  //assert (NOW < time);
  1245. +  timer_.resched (time);
  1246. +}
  1247. +*/
  1248. diff -Naur ns-2.29-org/wimax/scheduling/burst.h ns-2.29/wimax/scheduling/burst.h
  1249. --- ns-2.29-org/wimax/scheduling/burst.h 1969-12-31 19:00:00.000000000 -0500
  1250. +++ ns-2.29/wimax/scheduling/burst.h 2006-09-22 17:27:47.000000000 -0400
  1251. @@ -0,0 +1,189 @@
  1252. +/* This software was developed at the National Institute of Standards and
  1253. + * Technology by employees of the Federal Government in the course of
  1254. + * their official duties. Pursuant to title 17 Section 105 of the United
  1255. + * States Code this software is not subject to copyright protection and
  1256. + * is in the public domain.
  1257. + * NIST assumes no responsibility whatsoever for its use by other parties,
  1258. + * and makes no guarantees, expressed or implied, about its quality,
  1259. + * reliability, or any other characteristic.
  1260. + * <BR>
  1261. + * We would appreciate acknowledgement if the software is used.
  1262. + * <BR>
  1263. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  1264. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  1265. + * FROM THE USE OF THIS SOFTWARE.
  1266. + * </PRE></P>
  1267. + * @author  rouil
  1268. + */
  1269. +
  1270. +#ifndef BURST_H
  1271. +#define BURST_H
  1272. +
  1273. +#include "queue.h"
  1274. +#include "packet.h"
  1275. +
  1276. +class PhyPdu;
  1277. +
  1278. +class Burst;
  1279. +LIST_HEAD (burst, Burst);
  1280. +
  1281. +/**
  1282. + * This class describe a burst
  1283. + */
  1284. +class Burst
  1285. +{
  1286. +  friend class WimaxBurstTimer;
  1287. +
  1288. + public:
  1289. +  /**
  1290. +   * Creates a burst
  1291. +   * @param phypdu The PhyPdu where it is located
  1292. +   */
  1293. +  Burst (PhyPdu *phypdu);
  1294. +
  1295. +  /**
  1296. +   * Delete the object
  1297. +   */
  1298. +  ~Burst ();
  1299. +
  1300. +  /**
  1301. +   * Return the CID for this burst
  1302. +   * @return the CID for this burst
  1303. +   */
  1304. +  int getCid( );
  1305. +
  1306. +  /**
  1307. +   * Return the burst duration in units of OFDM symbols
  1308. +   * @return the burst duration 
  1309. +   */
  1310. +  int getDuration( );
  1311. +
  1312. +  /**
  1313. +   * Set the duration of the burst in units of OFDM symbols
  1314. +   * @param duration The burst duration
  1315. +   */
  1316. +  void setDuration (int duration);
  1317. +  
  1318. +  /**
  1319. +   * Return the burst start time in units of symbol duration
  1320. +   * @return the burst start time
  1321. +   */
  1322. +  int getStarttime( );
  1323. +
  1324. +  /**
  1325. +   * Return the Interval Usage Code
  1326. +   * @return the burst start time
  1327. +   */
  1328. +  int getIUC( );
  1329. +
  1330. +  /**
  1331. +   * Set burst CID
  1332. +   * @param cid The burst CID
  1333. +   */
  1334. +  void setCid( int cid );
  1335. +
  1336. +  /**
  1337. +   * Set burst start time in units of symbol duration
  1338. +   * @param starttime the burst start time
  1339. +   */
  1340. +  void setStarttime( int starttime );
  1341. +
  1342. +  /**
  1343. +   * Set burst IUC
  1344. +   * @param iuc The burst IUC
  1345. +   */
  1346. +  void setIUC( int iuc );
  1347. +
  1348. +  /**
  1349. +   * Enqueue a packet to be schedule in this burst
  1350. +   * @param p The packet to queue
  1351. +   */
  1352. +  void enqueue (Packet *p);
  1353. +
  1354. +  /**
  1355. +   * Dequeue a packet from the queue
  1356. +   * @param p The packet to enqueue
  1357. +   */
  1358. +  Packet * dequeue ();
  1359. +
  1360. +  /**
  1361. +   * Return the queue size in bytes
  1362. +   */
  1363. +  int getQueueLength() { return queue_->byteLength();}
  1364. +
  1365. +  /**
  1366. +   * Schedule the timer for this burst
  1367. +   * @param time The time the trigger expires
  1368. +   */
  1369. +  //void trigger_timer (double time);
  1370. +
  1371. +  // Chain element to the list
  1372. +  inline void insert_entry_head(struct burst *head) {
  1373. +    LIST_INSERT_HEAD(head, this, link);
  1374. +  }
  1375. +  
  1376. +  // Chain element to the list
  1377. +  inline void insert_entry(Burst *elem) {
  1378. +    LIST_INSERT_AFTER(elem, this, link);
  1379. +  }
  1380. +
  1381. +  // Return next element in the chained list
  1382. +  Burst* next_entry(void) const { return link.le_next; }
  1383. +
  1384. +  // Remove the entry from the list
  1385. +  inline void remove_entry() { 
  1386. +    LIST_REMOVE(this, link); 
  1387. +  }
  1388. +
  1389. +protected:
  1390. +  /**
  1391. +   * A timer use to transmit the burst
  1392. +   */
  1393. +  //WimaxBurstTimer timer_;
  1394. +
  1395. +  /**
  1396. +   * Packets to be sent during this burst
  1397. +   */
  1398. +  PacketQueue* queue_;
  1399. +
  1400. +  /** 
  1401. +   * Return the PhyPdu 
  1402. +   * @return the PhyPdu 
  1403. +   */
  1404. +  inline PhyPdu *getPhyPdu () { return phypdu_; }
  1405. +
  1406. +  /*
  1407. +   * Pointer to next in the list
  1408. +   */
  1409. +  LIST_ENTRY(Burst) link;
  1410. +  //LIST_ENTRY(Burst); //for magic draw
  1411. +
  1412. + private:
  1413. +  /**
  1414. +   * The CID for the burst. If a broadcast or multicast is used, then Mac SDUs for different SSs can be included in the burst.
  1415. +   */
  1416. +  int cid_;
  1417. +  
  1418. +  /**
  1419. +   * The burst duration in units of OFDM Symbols
  1420. +   */
  1421. +  int duration_;
  1422. +  
  1423. +  /**
  1424. +   * The start time of the burst in units of Symbol Duration
  1425. +   */
  1426. +  int starttime_;
  1427. +  
  1428. +  /**
  1429. +   * The profile ID
  1430. +   */
  1431. +  int iuc_;
  1432. +
  1433. +  /**
  1434. +   * The PhyPdu where it is located
  1435. +   */
  1436. +  PhyPdu *phypdu_;
  1437. +
  1438. +};
  1439. +
  1440. +#endif
  1441. diff -Naur ns-2.29-org/wimax/scheduling/contentionrequest.cc ns-2.29/wimax/scheduling/contentionrequest.cc
  1442. --- ns-2.29-org/wimax/scheduling/contentionrequest.cc 1969-12-31 19:00:00.000000000 -0500
  1443. +++ ns-2.29/wimax/scheduling/contentionrequest.cc 2006-09-22 17:27:47.000000000 -0400
  1444. @@ -0,0 +1,217 @@
  1445. +/* This software was developed at the National Institute of Standards and
  1446. + * Technology by employees of the Federal Government in the course of
  1447. + * their official duties. Pursuant to title 17 Section 105 of the United
  1448. + * States Code this software is not subject to copyright protection and
  1449. + * is in the public domain.
  1450. + * NIST assumes no responsibility whatsoever for its use by other parties,
  1451. + * and makes no guarantees, expressed or implied, about its quality,
  1452. + * reliability, or any other characteristic.
  1453. + * <BR>
  1454. + * We would appreciate acknowledgement if the software is used.
  1455. + * <BR>
  1456. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  1457. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  1458. + * FROM THE USE OF THIS SOFTWARE.
  1459. + * </PRE></P>
  1460. + * @author  rouil
  1461. + */
  1462. +
  1463. +#include "contentionrequest.h"
  1464. +#include "contentionslot.h"
  1465. +#include "framemap.h"
  1466. +#include "wimaxscheduler.h"
  1467. +#include "random.h"
  1468. +
  1469. +/*
  1470. + * Handling function for WimaxFrameTimer
  1471. + * @param e The event that occured
  1472. + */
  1473. +void WimaxBackoffTimer::handle(Event *e)
  1474. +{
  1475. +  busy_ = 0;
  1476. +  paused_ = 0;
  1477. +  stime = 0.0;
  1478. +  rtime = 0.0;
  1479. +
  1480. +  mac->transmit (c_->p_->copy());
  1481. +
  1482. +  //start timeout trigger
  1483. +  c_->starttimeout ();
  1484. +}
  1485. +
  1486. +void WimaxBackoffTimer::pause()
  1487. +{
  1488. + Scheduler &s = Scheduler::instance();
  1489. +
  1490. + //the caculation below make validation pass for linux though it
  1491. + // looks dummy
  1492. +
  1493. + double st = s.clock();
  1494. + double rt = stime;
  1495. + double sr = st - rt;
  1496. +
  1497. + assert(busy_ && ! paused_);
  1498. +
  1499. + paused_ = 1;
  1500. + rtime -= sr;
  1501. +
  1502. + assert(rtime >= 0.0);
  1503. +
  1504. + s.cancel(&intr);
  1505. +}
  1506. +
  1507. +
  1508. +void WimaxBackoffTimer::resume()
  1509. +{
  1510. + Scheduler &s = Scheduler::instance();
  1511. +
  1512. + assert(busy_ && paused_);
  1513. +
  1514. + paused_ = 0;
  1515. + stime = s.clock();
  1516. +
  1517. + assert(rtime >= 0.0);
  1518. +        s.schedule(this, &intr, rtime);
  1519. +}
  1520. +
  1521. +/*
  1522. + * Creates a contention slot for the given frame
  1523. + * @param s The contention slot 
  1524. + * @param p The packet to send
  1525. + */
  1526. +ContentionRequest::ContentionRequest (ContentionSlot *s, Packet *p)
  1527. +{
  1528. +  assert (s);
  1529. +  assert (p);
  1530. +  s_=s;
  1531. +  mac_ = s_->map_->getMac();
  1532. +  window_ = s_->getBackoff_start();
  1533. +  nb_retry_ = 0;
  1534. +  p_=p;
  1535. +  backoff_timer_ = new WimaxBackoffTimer (this, mac_);
  1536. +  timeout_timer_ = new ContentionTimer (this);
  1537. +  int result = Random::random() % ((int)(pow (2, window_)+1));
  1538. +  mac_->debug ("At %f in Mac %d Start contention in %f(backoff=%d, size=%d, ps=%f)n", NOW, mac_->addr(), result*s_->getSize()*mac_->getPhy()->getPS(),result,s_->getSize(),mac_->getPhy()->getPS());
  1539. +  backoff_timer_->start (result*s_->getSize()*mac_->getPhy()->getPS());
  1540. +  backoff_timer_->pause();
  1541. +}
  1542. +
  1543. +ContentionRequest::~ContentionRequest ()
  1544. +{
  1545. +  //printf ("canceling timeoutn");
  1546. +  //the timeout timer need not be triggered 
  1547. +  //this can happen when the STA received bw allocation
  1548. +  //when it is not waiting for one (or it's still in backoff)
  1549. +  if (timeout_timer_->status()!=TIMER_IDLE)
  1550. +    timeout_timer_->cancel();
  1551. +  if (backoff_timer_->busy())
  1552. +    backoff_timer_->stop();
  1553. +  delete backoff_timer_;
  1554. +  delete timeout_timer_;
  1555. +  assert (p_);
  1556. +  Packet:: free (p_);
  1557. +}
  1558. +
  1559. +/*
  1560. + * Called when timeout expired
  1561. + */
  1562. +void ContentionRequest::expire ()
  1563. +{
  1564. +
  1565. +}
  1566. +
  1567. +/*
  1568. + * Called when timeout expired
  1569. + */
  1570. +void ContentionRequest::starttimeout ()
  1571. +{
  1572. +  timeout_timer_->sched (timeout_);
  1573. +}
  1574. +
  1575. +/* 
  1576. + * Pause the backoff timer
  1577. + */
  1578. +void ContentionRequest::pause () 
  1579. +{
  1580. +  if (backoff_timer_->busy() && !backoff_timer_->paused())
  1581. +    backoff_timer_->pause(); 
  1582. +}
  1583. +
  1584. +/*
  1585. + * Resume the backoff timer
  1586. + */
  1587. +void ContentionRequest::resume () 
  1588. +{ 
  1589. +  if (backoff_timer_->paused() && timeout_timer_->status()==TIMER_IDLE)
  1590. +    backoff_timer_->resume(); 
  1591. +}
  1592. +
  1593. +/*
  1594. + * Creates a contention slot for the given frame
  1595. + * @param frame The frame map 
  1596. + */
  1597. +RangingRequest::RangingRequest (ContentionSlot *s, Packet *p) : ContentionRequest (s,p)
  1598. +{
  1599. +  type_ = WimaxT3TimerID;
  1600. +  timeout_ = mac_->macmib_.t3_timeout;
  1601. +}
  1602. +
  1603. +/*
  1604. + * Called when timeout expired
  1605. + */
  1606. +void RangingRequest::expire ()
  1607. +{
  1608. +  mac_->debug ("Ranging request expiresn");
  1609. +  if (nb_retry_ == (int)mac_->macmib_.contention_rng_retry) {
  1610. +    //max retries reached, inform the scheduler
  1611. +    mac_->getScheduler ()->expire (type_);
  1612. +  } else {
  1613. +    if (window_ < s_->getBackoff_stop())
  1614. +      window_++;
  1615. +    nb_retry_++;
  1616. +    int result = Random::random() % ((int)(pow (2, window_)+1));
  1617. +    mac_->debug ("Start Ranging contention in %f(backoff=%d, size=%d, ps=%f)n", result*s_->getSize()*mac_->getPhy()->getPS(),result,s_->getSize(),mac_->getPhy()->getPS());
  1618. +    backoff_timer_->start (result*s_->getSize()*mac_->getPhy()->getPS());
  1619. +    backoff_timer_->pause();
  1620. +  }
  1621. +}
  1622. +
  1623. +/*
  1624. + * Creates a contention slot for the given frame
  1625. + * @param frame The frame map 
  1626. + */
  1627. +BwRequest::BwRequest (ContentionSlot *s, Packet *p, int cid, int len) : ContentionRequest (s,p)
  1628. +{
  1629. +  type_ = WimaxT16TimerID;
  1630. +  timeout_ = mac_->macmib_.t16_timeout;
  1631. +  cid_ = cid;
  1632. +  size_ = len;
  1633. +}
  1634. +
  1635. +/*
  1636. + * Called when timeout expired
  1637. + */ 
  1638. +void BwRequest::expire ()
  1639. +{
  1640. +  printf ("Bw request expiresn");
  1641. +  if (nb_retry_ == (int)mac_->macmib_.request_retry) {
  1642. +    //max retries reached, delete the pdu that were waiting
  1643. +    Connection *c = mac_->getCManager()->get_connection (cid_, true);
  1644. +    int len = 0;
  1645. +    printf ("Dropping packet because bw req exceededn");
  1646. +    while (len < size_) {
  1647. +      Packet *p = c->dequeue();
  1648. +      assert (p);
  1649. +      len += HDR_CMN(p)->size();
  1650. +      Packet::free (p);
  1651. +    }
  1652. +  } else {
  1653. +    if (window_ < s_->getBackoff_stop())
  1654. +      window_++;
  1655. +    nb_retry_++;
  1656. +    int result = Random::random() % ((int)(pow (2, window_)+1));
  1657. +    printf ("Start BW contention in %f(backoff=%d, size=%d, ps=%f)n", result*s_->getSize()*mac_->getPhy()->getPS(),result,s_->getSize(),mac_->getPhy()->getPS());
  1658. +    backoff_timer_->start (result*s_->getSize()*mac_->getPhy()->getPS());
  1659. +    backoff_timer_->pause();
  1660. +  }
  1661. +}
  1662. diff -Naur ns-2.29-org/wimax/scheduling/contentionrequest.h ns-2.29/wimax/scheduling/contentionrequest.h
  1663. --- ns-2.29-org/wimax/scheduling/contentionrequest.h 1969-12-31 19:00:00.000000000 -0500
  1664. +++ ns-2.29/wimax/scheduling/contentionrequest.h 2006-09-22 17:27:47.000000000 -0400
  1665. @@ -0,0 +1,211 @@
  1666. +/* This software was developed at the National Institute of Standards and
  1667. + * Technology by employees of the Federal Government in the course of
  1668. + * their official duties. Pursuant to title 17 Section 105 of the United
  1669. + * States Code this software is not subject to copyright protection and
  1670. + * is in the public domain.
  1671. + * NIST assumes no responsibility whatsoever for its use by other parties,
  1672. + * and makes no guarantees, expressed or implied, about its quality,
  1673. + * reliability, or any other characteristic.
  1674. + * <BR>
  1675. + * We would appreciate acknowledgement if the software is used.
  1676. + * <BR>
  1677. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  1678. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  1679. + * FROM THE USE OF THIS SOFTWARE.
  1680. + * </PRE></P>
  1681. + * @author  rouil
  1682. + */
  1683. +
  1684. +#ifndef CONTENTIONREQUEST_H
  1685. +#define CONTENTIONREQUEST_H
  1686. +
  1687. +#include "mac802_16.h"
  1688. +#include "mac802_16timer.h"
  1689. +
  1690. +class ContentionSlot;
  1691. +class ContentionTimer;
  1692. +class Mac802_16;
  1693. +
  1694. +class ContentionRequest;
  1695. +/** Timer for backoff */
  1696. +class WimaxBackoffTimer : public WimaxTimer {
  1697. + public:
  1698. +  WimaxBackoffTimer(ContentionRequest *c, Mac802_16 *m) : WimaxTimer(m) {c_=c;}
  1699. +  
  1700. +  void handle(Event *e);
  1701. +  void pause(void);
  1702. +  void resume(void);
  1703. + private:
  1704. +  ContentionRequest *c_;
  1705. +}; 
  1706. +
  1707. +
  1708. +class ContentionRequest;
  1709. +LIST_HEAD (contentionRequest, ContentionRequest);
  1710. +
  1711. +/**
  1712. + * This class is used to manage contention opportunities
  1713. + * supports list
  1714. + */
  1715. +class ContentionRequest
  1716. +{
  1717. +  friend class WimaxBackoffTimer;
  1718. + public:
  1719. +  /**
  1720. +   * Creates a contention slot for the given frame
  1721. +   * @param s The contention slot 
  1722. +   * @param p The packet to send
  1723. +   */
  1724. +  ContentionRequest (ContentionSlot *s, Packet *p);
  1725. +  virtual ~ContentionRequest ();
  1726. +  /**
  1727. +   * Called when timeout expired
  1728. +   */
  1729. +  virtual void expire ();
  1730. +
  1731. +  /**
  1732. +   * Start the timeout timer
  1733. +   */
  1734. +  void starttimeout();
  1735. +
  1736. +  /** 
  1737. +   * Pause the backoff timer
  1738. +   */
  1739. +  void pause ();
  1740. +  
  1741. +  /**
  1742. +   * Resume the backoff timer
  1743. +   */
  1744. +  void resume ();
  1745. +
  1746. +  /// Chain element to the list
  1747. +  inline void insert_entry_head(struct contentionRequest *head) {
  1748. +    LIST_INSERT_HEAD(head, this, link);
  1749. +  }
  1750. +  
  1751. +  /// Chain element to the list
  1752. +  inline void insert_entry(ContentionRequest *elem) {
  1753. +    LIST_INSERT_AFTER(elem, this, link);
  1754. +  }
  1755. +
  1756. +  /// Return next element in the chained list
  1757. +  ContentionRequest* next_entry(void) const { return link.le_next; }
  1758. +
  1759. +  /// Remove the entry from the list
  1760. +  inline void remove_entry() { 
  1761. +    LIST_REMOVE(this, link); 
  1762. +  }
  1763. +
  1764. + protected:
  1765. +
  1766. +  /**
  1767. +   * The contention slot information
  1768. +   */
  1769. +  ContentionSlot *s_;
  1770. +
  1771. +  /**
  1772. +   * The backoff timer
  1773. +   */
  1774. +  WimaxBackoffTimer *backoff_timer_;
  1775. +
  1776. +  /**
  1777. +   * The timeout timer
  1778. +   */
  1779. +  ContentionTimer *timeout_timer_;
  1780. +
  1781. +  /**
  1782. +   * Type of timer
  1783. +   */
  1784. +  timer_id type_; 
  1785. +
  1786. +  /**
  1787. +   * Value for timeout
  1788. +   */
  1789. +  double timeout_;
  1790. +
  1791. +  /**
  1792. +   * The current window size
  1793. +   */
  1794. +  int window_;
  1795. +
  1796. +  /**
  1797. +   * Number of retry
  1798. +   */
  1799. +  int nb_retry_;
  1800. +
  1801. +  /** 
  1802. +   * The scheduler to inform about timeout
  1803. +   */
  1804. +  Mac802_16 *mac_;
  1805. +
  1806. +  /**
  1807. +   * The packet to send when the backoff expires
  1808. +   */
  1809. +  Packet *p_;
  1810. +
  1811. +  /**
  1812. +   * Pointer to next in the list
  1813. +   */
  1814. +  LIST_ENTRY(ContentionRequest) link;
  1815. +  //LIST_ENTRY(ContentionRequest); //for magic draw
  1816. +};
  1817. +
  1818. +/**
  1819. + * Class to handle ranging opportunities
  1820. + */
  1821. +class RangingRequest: public ContentionRequest 
  1822. +{
  1823. + public:
  1824. +
  1825. +  /**
  1826. +   * Creates a contention slot for the given frame
  1827. +   * @param frame The frame map 
  1828. +   */
  1829. +  RangingRequest (ContentionSlot *s, Packet *p);
  1830. +
  1831. +  /**
  1832. +   * Called when timeout expired
  1833. +   */
  1834. +  void expire ();
  1835. +
  1836. + private:
  1837. +};
  1838. +
  1839. +
  1840. +/**
  1841. + * Class to handle bandwidth request opportunities
  1842. + */
  1843. +class BwRequest: public ContentionRequest 
  1844. +{
  1845. + public:
  1846. +
  1847. +  /**
  1848. +   * Creates a contention slot for the given frame
  1849. +   * @param frame The frame map 
  1850. +   */
  1851. +  BwRequest (ContentionSlot *s, Packet *p, int cid, int length);
  1852. +
  1853. +  /**
  1854. +   * Called when timeout expired
  1855. +   */
  1856. +  void expire ();
  1857. +
  1858. +  /**
  1859. +   * Return the CID for this request
  1860. +   * @return the CID for this request
  1861. +   */
  1862. +  inline int getCID () { return cid_; }
  1863. +
  1864. + private:
  1865. +  /**
  1866. +   * The CID for the request
  1867. +   */
  1868. +  int cid_;
  1869. +
  1870. +  /**
  1871. +   * The size in bytes of the bandwidth requested
  1872. +   */
  1873. +  int size_;
  1874. +};
  1875. +
  1876. +#endif
  1877. diff -Naur ns-2.29-org/wimax/scheduling/contentionslot.cc ns-2.29/wimax/scheduling/contentionslot.cc
  1878. --- ns-2.29-org/wimax/scheduling/contentionslot.cc 1969-12-31 19:00:00.000000000 -0500
  1879. +++ ns-2.29/wimax/scheduling/contentionslot.cc 2006-09-22 17:27:47.000000000 -0400
  1880. @@ -0,0 +1,211 @@
  1881. +/* This software was developed at the National Institute of Standards and
  1882. + * Technology by employees of the Federal Government in the course of
  1883. + * their official duties. Pursuant to title 17 Section 105 of the United
  1884. + * States Code this software is not subject to copyright protection and
  1885. + * is in the public domain.
  1886. + * NIST assumes no responsibility whatsoever for its use by other parties,
  1887. + * and makes no guarantees, expressed or implied, about its quality,
  1888. + * reliability, or any other characteristic.
  1889. + * <BR>
  1890. + * We would appreciate acknowledgement if the software is used.
  1891. + * <BR>
  1892. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  1893. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  1894. + * FROM THE USE OF THIS SOFTWARE.
  1895. + * </PRE></P>
  1896. + * @author  rouil
  1897. + */
  1898. +
  1899. +#include "contentionslot.h"
  1900. +#include <random.h>
  1901. +#include <math.h>
  1902. +
  1903. +/*
  1904. + * Creates a contention slot for the given frame
  1905. + * @param frame The frame map 
  1906. + */
  1907. +ContentionSlot::ContentionSlot (FrameMap *map) 
  1908. +{
  1909. +  assert (map);
  1910. +  map_ = map;
  1911. +}
  1912. +
  1913. +/**
  1914. + * Destructor
  1915. + */
  1916. +ContentionSlot::~ContentionSlot() {}
  1917. +
  1918. +/*
  1919. + * Set the initial contention slot window size
  1920. + * @param backoff_start the initial contention slot window size
  1921. + */
  1922. +void ContentionSlot::setBackoff_start( int backoff_start ) 
  1923. +{ 
  1924. +  backoff_start_ = backoff_start;
  1925. +}
  1926. +
  1927. +/*
  1928. + * Set the final contention slot window size
  1929. + * @param backoff_stop the final contention slot window size 
  1930. + */
  1931. +void ContentionSlot::setBackoff_stop( int backoff_stop ) 
  1932. +{ 
  1933. +  backoff_stop_ = backoff_stop;
  1934. +}
  1935. +
  1936. +/**
  1937. + * Resume the timers for the requests
  1938. + */
  1939. +void ContentionSlot::resumeTimers () {}
  1940. +
  1941. +/**
  1942. + * Pause the timers for the requests
  1943. + */
  1944. +void ContentionSlot::pauseTimers () {}
  1945. +
  1946. +/**** Methods for Ranging Contention slot ****/
  1947. +
  1948. +/*
  1949. + * Creates a contention slot for the given frame
  1950. + * @param frame The frame map 
  1951. + */
  1952. +RngContentionSlot::RngContentionSlot (FrameMap *map) : ContentionSlot (map)
  1953. +{
  1954. +  request_ = NULL;
  1955. +}
  1956. +
  1957. +/**
  1958. + * Destructor
  1959. + */
  1960. +RngContentionSlot::~RngContentionSlot() 
  1961. +{
  1962. +  if (request_)
  1963. +    delete request_;
  1964. +}
  1965. +
  1966. +
  1967. +/*
  1968. + * Add a ranging request
  1969. + * @param p The packet to be sent during the ranging opportunity
  1970. + */
  1971. +void RngContentionSlot::addRequest (Packet *p)
  1972. +{
  1973. +  assert (request_ == NULL);
  1974. +  request_ = new RangingRequest (this, p);
  1975. +}
  1976. +
  1977. +/*
  1978. + * Remove the pending request
  1979. + */
  1980. +void RngContentionSlot::removeRequest ()
  1981. +{
  1982. +  //assert (request_);
  1983. +  if (request_) {
  1984. +    delete request_;
  1985. +    request_ = NULL;
  1986. +  }
  1987. +}
  1988. +
  1989. +/**
  1990. + * Resume the timers for the requests
  1991. + */
  1992. +void RngContentionSlot::resumeTimers ()
  1993. +{
  1994. +  if (request_)
  1995. +    request_->resume();
  1996. +}
  1997. +
  1998. +/**
  1999. + * Pause the timers for the requests
  2000. + */
  2001. +void RngContentionSlot::pauseTimers ()
  2002. +{
  2003. +  if (request_)
  2004. +    request_->pause();
  2005. +}
  2006. +
  2007. +/**** Methods for Bandwidth Contention slot ****/
  2008. +
  2009. +/*
  2010. + * Creates a contention slot for the given frame
  2011. + * @param frame The frame map 
  2012. + */
  2013. +BwContentionSlot::BwContentionSlot (FrameMap *map) : ContentionSlot (map)
  2014. +{
  2015. +  LIST_INIT (&request_list_);
  2016. +}
  2017. +
  2018. +/**
  2019. + * Destructor
  2020. + */
  2021. +BwContentionSlot::~BwContentionSlot() {}
  2022. +
  2023. +/*
  2024. + * Add a bandwidth request
  2025. + * @param p The packet to be sent during the ranging opportunity
  2026. + * @param cid The CID of the bandwidth request
  2027. + * @param len The size in bytes of the bandwidth request
  2028. + */
  2029. +void BwContentionSlot::addRequest (Packet *p, int cid, int len)
  2030. +{
  2031. +  assert (getRequest (cid)==NULL);
  2032. +  BwRequest *b = new BwRequest (this, p, cid, len);
  2033. +  b->insert_entry_head (&request_list_);
  2034. +}
  2035. +
  2036. +/*
  2037. + * Remove the pending request
  2038. + */
  2039. +void BwContentionSlot::removeRequest (int cid)
  2040. +{
  2041. +  BwRequest *b = getRequest (cid);
  2042. +  if (b!=NULL) {
  2043. +    b->remove_entry ();
  2044. +    delete b;
  2045. +  }
  2046. +}
  2047. +
  2048. +/*
  2049. + * Remove all pending reuquest
  2050. + */
  2051. +void BwContentionSlot::removeRequests ()
  2052. +{
  2053. +  for (BwRequest *c = (BwRequest *)request_list_.lh_first; c ; c=(BwRequest *)request_list_.lh_first) {
  2054. +    c->remove_entry();
  2055. +    delete c;
  2056. +  }
  2057. +}
  2058. +
  2059. +
  2060. +/*
  2061. + * Get the request for the given CID
  2062. + * @param cid The CID for the request
  2063. + */
  2064. +BwRequest* BwContentionSlot::getRequest (int cid)
  2065. +{
  2066. +  for (BwRequest *c = (BwRequest *)request_list_.lh_first; c ; c=(BwRequest *)(c->next_entry())) {
  2067. +    if (c->getCID()==cid)
  2068. +      return c;
  2069. +  }
  2070. +  return NULL;
  2071. +}
  2072. +
  2073. +/**
  2074. + * Resume the timers for the requests
  2075. + */
  2076. +void BwContentionSlot::resumeTimers ()
  2077. +{
  2078. +  for (BwRequest *c = (BwRequest *)request_list_.lh_first; c ; c=(BwRequest *)(c->next_entry())) {
  2079. +      c->resume();
  2080. +  }
  2081. +}
  2082. +
  2083. +/**
  2084. + * Pause the timers for the requests
  2085. + */
  2086. +void BwContentionSlot::pauseTimers ()
  2087. +{
  2088. +  for (BwRequest *c = (BwRequest *)request_list_.lh_first; c ; c=(BwRequest *)(c->next_entry())) {
  2089. +      c->pause();
  2090. +  }
  2091. +}
  2092. diff -Naur ns-2.29-org/wimax/scheduling/contentionslot.h ns-2.29/wimax/scheduling/contentionslot.h
  2093. --- ns-2.29-org/wimax/scheduling/contentionslot.h 1969-12-31 19:00:00.000000000 -0500
  2094. +++ ns-2.29/wimax/scheduling/contentionslot.h 2006-09-22 17:27:47.000000000 -0400
  2095. @@ -0,0 +1,214 @@
  2096. +/* This software was developed at the National Institute of Standards and
  2097. + * Technology by employees of the Federal Government in the course of
  2098. + * their official duties. Pursuant to title 17 Section 105 of the United
  2099. + * States Code this software is not subject to copyright protection and
  2100. + * is in the public domain.
  2101. + * NIST assumes no responsibility whatsoever for its use by other parties,
  2102. + * and makes no guarantees, expressed or implied, about its quality,
  2103. + * reliability, or any other characteristic.
  2104. + * <BR>
  2105. + * We would appreciate acknowledgement if the software is used.
  2106. + * <BR>
  2107. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  2108. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  2109. + * FROM THE USE OF THIS SOFTWARE.
  2110. + * </PRE></P>
  2111. + * @author  rouil
  2112. + */
  2113. +
  2114. +#ifndef CONTENTIONSLOT_H
  2115. +#define CONTENTIONSLOT_H
  2116. +
  2117. +#include "packet.h"
  2118. +#include "queue.h"
  2119. +#include "contentiontimer.h"
  2120. +
  2121. +class FrameMap;
  2122. +
  2123. +/**
  2124. + * This class contains information about a contention slot
  2125. + */
  2126. +class ContentionSlot
  2127. +{
  2128. +  friend class ContentionRequest;
  2129. +
  2130. + public:
  2131. +  /*
  2132. +   * Creates a contention slot for the given frame
  2133. +   * @param frame The frame map 
  2134. +   */
  2135. +  ContentionSlot (FrameMap *map);
  2136. +  
  2137. +  /**
  2138. +   * Destructor
  2139. +   */
  2140. +  virtual ~ContentionSlot();
  2141. +
  2142. +  /*
  2143. +   * Return the initial contention slot window size
  2144. +   * @return the initial contention slot window size
  2145. +   */
  2146. +  inline int getBackoff_start( ) { return backoff_start_; }
  2147. +
  2148. +  /*
  2149. +   * Return the final contention slot window size
  2150. +   * @return the final contention slot window size 
  2151. +   */
  2152. +  inline int getBackoff_stop( ) { return backoff_stop_; }
  2153. +
  2154. +  /*
  2155. +   * Return the opportunity size
  2156. +   * @return the opportunity size
  2157. +   */
  2158. +  inline int getSize( ) { return size_; }
  2159. +
  2160. +  /*
  2161. +   * Set the initial contention slot window size
  2162. +   * @param backoff_start the initial contention slot window size
  2163. +   */
  2164. +  void setBackoff_start( int backoff_start );
  2165. +
  2166. +  /*
  2167. +   * Set the final contention slot window size
  2168. +   * @param backoff_stop the final contention slot window size 
  2169. +   */
  2170. +  void setBackoff_stop( int backoff_stop );
  2171. +
  2172. +  /*
  2173. +   * Set the opportunity size
  2174. +   * @param size The opportunity size
  2175. +   */
  2176. +  inline void setSize( int size ) { size_ = size; }
  2177. +  
  2178. +  /**
  2179. +   * Resume the timers for the requests
  2180. +   */
  2181. +  virtual void resumeTimers ();
  2182. +  
  2183. +  /**
  2184. +   * Pause the timers for the requests
  2185. +   */
  2186. +  virtual void pauseTimers ();
  2187. +
  2188. + protected:
  2189. +    /**
  2190. +   * The frame map where this contention slot is located
  2191. +   */
  2192. +  FrameMap *map_;
  2193. +
  2194. +  /**
  2195. +   * Initial backoff window size. Must be power of 2
  2196. +   */
  2197. +  int backoff_start_;
  2198. +  
  2199. +  /**
  2200. +   * Final backoff window size
  2201. +   */
  2202. +  int backoff_stop_;
  2203. +  
  2204. +  /**
  2205. +   * The duration in PS of the contention slot
  2206. +   */
  2207. +  int size_;
  2208. + private:
  2209. +  
  2210. +};
  2211. +
  2212. +/**
  2213. + * Subclass used for ranging contention slot
  2214. + */
  2215. +class RngContentionSlot: public ContentionSlot {
  2216. +  friend class RngContentionTimer;
  2217. + public:
  2218. +
  2219. +  /*
  2220. +   * Creates a contention slot for the given frame
  2221. +   * @param frame The frame map 
  2222. +   */
  2223. +  RngContentionSlot (FrameMap *map);
  2224. +
  2225. +  /**
  2226. +   * Destructor
  2227. +   */
  2228. +  virtual ~RngContentionSlot();
  2229. +
  2230. +  /*
  2231. +   * Add a ranging request
  2232. +   * @param p The packet to be sent during the ranging opportunity
  2233. +   */
  2234. +  void addRequest (Packet *p);
  2235. +
  2236. +  /*
  2237. +   * Remove the pending request
  2238. +   */
  2239. +  void removeRequest ();
  2240. +  
  2241. +  /**
  2242. +   * Resume the timers for the requests
  2243. +   */
  2244. +  void resumeTimers ();
  2245. +
  2246. +  /**
  2247. +   * Pause the timers for the requests
  2248. +   */
  2249. +  void pauseTimers ();
  2250. +
  2251. + private:
  2252. +  RangingRequest *request_;
  2253. +};
  2254. +
  2255. +/**
  2256. + * Subclass used for ranging contention slot
  2257. + */
  2258. +class BwContentionSlot: public ContentionSlot {
  2259. + public:
  2260. +  /*
  2261. +   * Creates a contention slot for the given frame
  2262. +   * @param frame The frame map 
  2263. +   */
  2264. +  BwContentionSlot (FrameMap *map);
  2265. +
  2266. +  /**
  2267. +   * Destructor
  2268. +   */
  2269. +  virtual ~BwContentionSlot();
  2270. +
  2271. +  /*
  2272. +   * Add a bandwidth request
  2273. +   * @param p The packet to be sent during the ranging opportunity
  2274. +   * @param cid The CID of the bandwidth request
  2275. +   * @param len The size in bytes of the bandwidth request
  2276. +   */
  2277. +  void addRequest (Packet *p, int cid, int len);
  2278. +
  2279. +  /*
  2280. +   * Remove the pending request
  2281. +   */
  2282. +  void removeRequest (int cid);  
  2283. +
  2284. +  /*
  2285. +   * Remove all pending reuquest
  2286. +   */
  2287. +  void removeRequests ();
  2288. +
  2289. +  /*
  2290. +   * Get the request for the given CID
  2291. +   * @param cid The CID for the request
  2292. +   */
  2293. +  BwRequest * getRequest (int cid);
  2294. +
  2295. +  /**
  2296. +   * Resume the timers for the requests
  2297. +   */
  2298. +  void resumeTimers ();
  2299. +
  2300. +  /**
  2301. +   * Pause the timers for the requests
  2302. +   */
  2303. +  void pauseTimers ();
  2304. +
  2305. + private:
  2306. +  struct contentionRequest request_list_;
  2307. +};
  2308. +
  2309. +#endif
  2310. diff -Naur ns-2.29-org/wimax/scheduling/contentiontimer.cc ns-2.29/wimax/scheduling/contentiontimer.cc
  2311. --- ns-2.29-org/wimax/scheduling/contentiontimer.cc 1969-12-31 19:00:00.000000000 -0500
  2312. +++ ns-2.29/wimax/scheduling/contentiontimer.cc 2006-09-22 17:27:47.000000000 -0400
  2313. @@ -0,0 +1,40 @@
  2314. +/* This software was developed at the National Institute of Standards and
  2315. + * Technology by employees of the Federal Government in the course of
  2316. + * their official duties. Pursuant to title 17 Section 105 of the United
  2317. + * States Code this software is not subject to copyright protection and
  2318. + * is in the public domain.
  2319. + * NIST assumes no responsibility whatsoever for its use by other parties,
  2320. + * and makes no guarantees, expressed or implied, about its quality,
  2321. + * reliability, or any other characteristic.
  2322. + * <BR>
  2323. + * We would appreciate acknowledgement if the software is used.
  2324. + * <BR>
  2325. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  2326. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  2327. + * FROM THE USE OF THIS SOFTWARE.
  2328. + * </PRE></P>
  2329. + * @author  rouil
  2330. + */
  2331. +
  2332. +#include "contentiontimer.h"
  2333. +
  2334. +/**
  2335. + * Creates a timer to handle the burst's transmission
  2336. + * @param c The contention slot
  2337. + */
  2338. +ContentionTimer::ContentionTimer( ContentionRequest* c ) : TimerHandler()
  2339. +{
  2340. +  assert (c);
  2341. +  c_ = c;
  2342. +}
  2343. +
  2344. +/**
  2345. + * When it expires, the timer will handle the next packet to send
  2346. + * @param e not used
  2347. + */
  2348. +void ContentionTimer::expire( Event* e )
  2349. +{
  2350. +  c_->expire();
  2351. +}
  2352. +
  2353. +
  2354. diff -Naur ns-2.29-org/wimax/scheduling/contentiontimer.h ns-2.29/wimax/scheduling/contentiontimer.h
  2355. --- ns-2.29-org/wimax/scheduling/contentiontimer.h 1969-12-31 19:00:00.000000000 -0500
  2356. +++ ns-2.29/wimax/scheduling/contentiontimer.h 2006-09-22 17:27:47.000000000 -0400
  2357. @@ -0,0 +1,51 @@
  2358. +/* This software was developed at the National Institute of Standards and
  2359. + * Technology by employees of the Federal Government in the course of
  2360. + * their official duties. Pursuant to title 17 Section 105 of the United
  2361. + * States Code this software is not subject to copyright protection and
  2362. + * is in the public domain.
  2363. + * NIST assumes no responsibility whatsoever for its use by other parties,
  2364. + * and makes no guarantees, expressed or implied, about its quality,
  2365. + * reliability, or any other characteristic.
  2366. + * <BR>
  2367. + * We would appreciate acknowledgement if the software is used.
  2368. + * <BR>
  2369. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  2370. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  2371. + * FROM THE USE OF THIS SOFTWARE.
  2372. + * </PRE></P>
  2373. + * @author  rouil
  2374. + */
  2375. +
  2376. +#ifndef CONTENTIONTIMER_H
  2377. +#define CONTENTIONTIMER_H
  2378. +
  2379. +#include "timer-handler.h"
  2380. +#include "contentionrequest.h"
  2381. +
  2382. +/**
  2383. + * Timer for contention window
  2384. + */
  2385. +class ContentionTimer: public TimerHandler
  2386. +{
  2387. + public:
  2388. +  /**
  2389. +   * Creates a timer to handle the burst's transmission
  2390. +   * @param c The contention slot
  2391. +   */
  2392. +  ContentionTimer( ContentionRequest* c );
  2393. +  
  2394. +  /**
  2395. +   * When it expires, the timer will handle the next packet to send
  2396. +   * @param e not used
  2397. +   */
  2398. +  void expire( Event* e );
  2399. +
  2400. + private:
  2401. +
  2402. +  /**
  2403. +   * The contention slot containing the packets to send
  2404. +   */
  2405. +  ContentionRequest* c_;
  2406. +};
  2407. +
  2408. +#endif
  2409. diff -Naur ns-2.29-org/wimax/scheduling/dlburst.cc ns-2.29/wimax/scheduling/dlburst.cc
  2410. --- ns-2.29-org/wimax/scheduling/dlburst.cc 1969-12-31 19:00:00.000000000 -0500
  2411. +++ ns-2.29/wimax/scheduling/dlburst.cc 2006-09-22 17:27:47.000000000 -0400
  2412. @@ -0,0 +1,28 @@
  2413. +/* This software was developed at the National Institute of Standards and
  2414. + * Technology by employees of the Federal Government in the course of
  2415. + * their official duties. Pursuant to title 17 Section 105 of the United
  2416. + * States Code this software is not subject to copyright protection and
  2417. + * is in the public domain.
  2418. + * NIST assumes no responsibility whatsoever for its use by other parties,
  2419. + * and makes no guarantees, expressed or implied, about its quality,
  2420. + * reliability, or any other characteristic.
  2421. + * <BR>
  2422. + * We would appreciate acknowledgement if the software is used.
  2423. + * <BR>
  2424. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  2425. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  2426. + * FROM THE USE OF THIS SOFTWARE.
  2427. + * </PRE></P>
  2428. + * @author  rouil
  2429. + */
  2430. +
  2431. +#include "dlburst.h"
  2432. +
  2433. +/**
  2434. + * Creates a downlink burst
  2435. + * @param phypdu The PhyPdu where it is located
  2436. + */
  2437. +DlBurst::DlBurst (PhyPdu *phypdu) : Burst (phypdu)
  2438. +{
  2439. +
  2440. +}
  2441. diff -Naur ns-2.29-org/wimax/scheduling/dlburst.h ns-2.29/wimax/scheduling/dlburst.h
  2442. --- ns-2.29-org/wimax/scheduling/dlburst.h 1969-12-31 19:00:00.000000000 -0500
  2443. +++ ns-2.29/wimax/scheduling/dlburst.h 2006-09-22 17:27:47.000000000 -0400
  2444. @@ -0,0 +1,78 @@
  2445. +/* This software was developed at the National Institute of Standards and
  2446. + * Technology by employees of the Federal Government in the course of
  2447. + * their official duties. Pursuant to title 17 Section 105 of the United
  2448. + * States Code this software is not subject to copyright protection and
  2449. + * is in the public domain.
  2450. + * NIST assumes no responsibility whatsoever for its use by other parties,
  2451. + * and makes no guarantees, expressed or implied, about its quality,
  2452. + * reliability, or any other characteristic.
  2453. + * <BR>
  2454. + * We would appreciate acknowledgement if the software is used.
  2455. + * <BR>
  2456. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  2457. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  2458. + * FROM THE USE OF THIS SOFTWARE.
  2459. + * </PRE></P>
  2460. + * @author  rouil
  2461. + */
  2462. +
  2463. +#ifndef DLBURST_H
  2464. +#define DLBURST_H
  2465. +
  2466. +#include "burst.h"
  2467. +
  2468. +/* Defines the OFDM DIUC values */
  2469. +enum diuc_t {
  2470. +  DIUC_STC_ZONE=0,
  2471. +  //1-11 reserved for burst profiles
  2472. +  DIUC_PROFILE_1,
  2473. +  DIUC_PROFILE_2,
  2474. +  DIUC_PROFILE_3,
  2475. +  DIUC_PROFILE_4,
  2476. +  DIUC_PROFILE_5,
  2477. +  DIUC_PROFILE_6,
  2478. +  DIUC_PROFILE_7,
  2479. +  DIUC_PROFILE_8,
  2480. +  DIUC_PROFILE_9,
  2481. +  DIUC_PROFILE_10,
  2482. +  DIUC_PROFILE_11,
  2483. +  //12 is reserved
  2484. +  DIUC_GAP=13,
  2485. +  DIUC_END_OF_MAP,
  2486. +  DIUC_EXT_DIUC
  2487. +};
  2488. +
  2489. +/**
  2490. + * Downlink Burst Description
  2491. + */
  2492. +class DlBurst : public Burst
  2493. +{
  2494. + public:
  2495. +
  2496. +  /**
  2497. +   * Default contructor
  2498. +   * @param phypdu The PhyPdu where it is located
  2499. +   */
  2500. +  DlBurst (PhyPdu *phypdu);
  2501. +
  2502. +  /**
  2503. +   * Return true if preamble is present in the burst
  2504. +   * @return true if preamble is present in the burst
  2505. +   */
  2506. +  inline bool isPreamble( ) { return preamble_; }
  2507. +
  2508. +  /**
  2509. +   * Set the preamble flag for the burst
  2510. +   * @param preamble The flag
  2511. +   */
  2512. +  inline void setPreamble( bool preamble ) { preamble_ = preamble; }
  2513. +  
  2514. + private:
  2515. +  /**
  2516. +   * Indicate if a preamble is included in the burst of not
  2517. +   */
  2518. +  bool preamble_;
  2519. +
  2520. +};
  2521. +
  2522. +#endif
  2523. diff -Naur ns-2.29-org/wimax/scheduling/dlsubframetimer.cc ns-2.29/wimax/scheduling/dlsubframetimer.cc
  2524. --- ns-2.29-org/wimax/scheduling/dlsubframetimer.cc 1969-12-31 19:00:00.000000000 -0500
  2525. +++ ns-2.29/wimax/scheduling/dlsubframetimer.cc 2006-09-22 17:27:47.000000000 -0400
  2526. @@ -0,0 +1,101 @@
  2527. +/* This software was developed at the National Institute of Standards and
  2528. + * Technology by employees of the Federal Government in the course of
  2529. + * their official duties. Pursuant to title 17 Section 105 of the United
  2530. + * States Code this software is not subject to copyright protection and
  2531. + * is in the public domain.
  2532. + * NIST assumes no responsibility whatsoever for its use by other parties,
  2533. + * and makes no guarantees, expressed or implied, about its quality,
  2534. + * reliability, or any other characteristic.
  2535. + * <BR>
  2536. + * We would appreciate acknowledgement if the software is used.
  2537. + * <BR>
  2538. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  2539. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  2540. + * FROM THE USE OF THIS SOFTWARE.
  2541. + * </PRE></P>
  2542. + * @author  rouil
  2543. + */
  2544. +
  2545. +#include "dlsubframetimer.h"
  2546. +#include "framemap.h"
  2547. +#include "subframe.h"
  2548. +#include "wimaxscheduler.h"
  2549. +#include "contentionslot.h"
  2550. +
  2551. +/**
  2552. + * Creates a timer to handle the subframe transmission
  2553. + * @param subframe The DlSubframe
  2554. + */
  2555. +DlSubFrameTimer::DlSubFrameTimer (DlSubFrame *subframe): burstIndex_(0), newburst_(true), mac_(0)
  2556. +{
  2557. +  assert (subframe);
  2558. +  subframe_ = subframe;
  2559. +}
  2560. +
  2561. +/**
  2562. + * Reset the timer
  2563. + */
  2564. +void DlSubFrameTimer::reset ()
  2565. +{
  2566. +  burstIndex_ = 0;
  2567. +  newburst_ = true;
  2568. +  if (status()==TIMER_PENDING)
  2569. +    cancel();
  2570. +}
  2571. +
  2572. +/**
  2573. + * When it expires, the timer will handle the next packet to send
  2574. + * @param e not used
  2575. + */
  2576. +void DlSubFrameTimer::expire( Event* e )
  2577. +{
  2578. +  if (!mac_) {
  2579. +    mac_= subframe_->map_->getMac();
  2580. +  }
  2581. +  
  2582. +  //printf ("At %f in Mac %d DlsubFrameTimer expiresn", NOW, mac_->addr());
  2583. +  int iuc;
  2584. +  Burst *b = subframe_->getPdu()->getBurst(burstIndex_);
  2585. +  if (newburst_) {
  2586. +    //printf ("tburst=%x type=%dn", b,b->getIUC());
  2587. +    if (b->getIUC()==DIUC_END_OF_MAP) {
  2588. +      //printf ("tend of subframen");
  2589. +      burstIndex_=0;//reset for next frame
  2590. +      if (mac_->getScheduler()->getNodeType()==STA_MN) {
  2591. + mac_->getPhy()->setMode (OFDM_SEND);
  2592. +      } else {
  2593. + mac_->getPhy()->setMode (OFDM_RECV);
  2594. +      }
  2595. +      return; //end of subframe
  2596. +    }
  2597. +    //change modulation
  2598. +    iuc = b->getIUC();
  2599. +    Ofdm_mod_rate rate = subframe_->getProfile (iuc)->getEncoding();
  2600. +    mac_->getPhy()->setModulation (rate);
  2601. +  }
  2602. +  //check if packet to send
  2603. +  Packet *p = b->dequeue();
  2604. +  if (p) {
  2605. +    newburst_ = false;
  2606. +    double txtime = HDR_CMN(p)->txtime();
  2607. +    //schedule for next packet
  2608. +    mac_->transmit (p);
  2609. +    //printf ("tNext packet at %f(in %f)n", NOW+txtime, txtime);
  2610. +    if (b->getQueueLength()!=0) {
  2611. +      resched (txtime); //wait transmition time 
  2612. +      return;
  2613. +    }
  2614. +  }
  2615. +  
  2616. +  //no packet to send...schedule for next phypdu
  2617. +  newburst_= true;
  2618. +  burstIndex_++;
  2619. +  double stime=0.0;
  2620. +  assert (b->next_entry());
  2621. +  
  2622. +  stime = subframe_->map_->getStarttime();
  2623. +  stime += b->next_entry()->getStarttime()*mac_->getPhy()->getSymbolTime();
  2624. +  //printf ("tNext burst at %fn", stime);
  2625. +  resched (stime-NOW);
  2626. +  
  2627. +}
  2628. diff -Naur ns-2.29-org/wimax/scheduling/dlsubframetimer.h ns-2.29/wimax/scheduling/dlsubframetimer.h
  2629. --- ns-2.29-org/wimax/scheduling/dlsubframetimer.h 1969-12-31 19:00:00.000000000 -0500
  2630. +++ ns-2.29/wimax/scheduling/dlsubframetimer.h 2006-09-22 17:27:47.000000000 -0400
  2631. @@ -0,0 +1,73 @@
  2632. +/* This software was developed at the National Institute of Standards and
  2633. + * Technology by employees of the Federal Government in the course of
  2634. + * their official duties. Pursuant to title 17 Section 105 of the United
  2635. + * States Code this software is not subject to copyright protection and
  2636. + * is in the public domain.
  2637. + * NIST assumes no responsibility whatsoever for its use by other parties,
  2638. + * and makes no guarantees, expressed or implied, about its quality,
  2639. + * reliability, or any other characteristic.
  2640. + * <BR>
  2641. + * We would appreciate acknowledgement if the software is used.
  2642. + * <BR>
  2643. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  2644. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  2645. + * FROM THE USE OF THIS SOFTWARE.
  2646. + * </PRE></P>
  2647. + * @author  rouil
  2648. + */
  2649. +
  2650. +#ifndef DLSUBFRAME_H
  2651. +#define DLSUBFRAME_H
  2652. +
  2653. +#include "mac802_16.h"
  2654. +#include "phypdu.h"
  2655. +
  2656. +class DlSubFrame;
  2657. +/**
  2658. + * This timer is used to handle the transmission of 
  2659. + * a UlSubframe.
  2660. + */
  2661. +class DlSubFrameTimer: public TimerHandler
  2662. +{
  2663. + public:
  2664. +  /**
  2665. +   * Creates a timer to handle the subframe transmission
  2666. +   * @param subframe The UlSubframe
  2667. +   */
  2668. +  DlSubFrameTimer (DlSubFrame *subframe);
  2669. +
  2670. +  /**
  2671. +   * When it expires, the timer will handle the next packet to send
  2672. +   * @param e not used
  2673. +   */
  2674. +  void expire( Event* e );
  2675. +
  2676. +  /**
  2677. +   * Reset the timer
  2678. +   */
  2679. +  void reset ();
  2680. +
  2681. + private:
  2682. +  /**
  2683. +   * The subframe
  2684. +   */
  2685. +  DlSubFrame *subframe_;
  2686. +
  2687. +  /**
  2688. +   * The current Burst being handled
  2689. +   */
  2690. +  int burstIndex_;
  2691. +
  2692. +  /**
  2693. +   * Tag to know if we are changing PhyPdu
  2694. +   */
  2695. +  bool newburst_;
  2696. +
  2697. +  /** 
  2698. +   * Store local variables for faster access
  2699. +   */
  2700. +  Mac802_16 *mac_;
  2701. +
  2702. +};
  2703. +
  2704. +#endif
  2705. diff -Naur ns-2.29-org/wimax/scheduling/framemap.cc ns-2.29/wimax/scheduling/framemap.cc
  2706. --- ns-2.29-org/wimax/scheduling/framemap.cc 1969-12-31 19:00:00.000000000 -0500
  2707. +++ ns-2.29/wimax/scheduling/framemap.cc 2006-09-22 17:27:47.000000000 -0400
  2708. @@ -0,0 +1,323 @@
  2709. +/* This software was developed at the National Institute of Standards and
  2710. + * Technology by employees of the Federal Government in the course of
  2711. + * their official duties. Pursuant to title 17 Section 105 of the United
  2712. + * States Code this software is not subject to copyright protection and
  2713. + * is in the public domain.
  2714. + * NIST assumes no responsibility whatsoever for its use by other parties,
  2715. + File * and makes no guarantees, expressed or implied, about its quality,
  2716. + * reliability, or any other characteristic.
  2717. + * <BR>
  2718. + * We would appreciate acknowledgement if the software is used.
  2719. + * <BR>
  2720. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  2721. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  2722. + * FROM THE USE OF THIS SOFTWARE.
  2723. + * </PRE></P>
  2724. + * @author  rouil
  2725. + */
  2726. +
  2727. +
  2728. +#include "framemap.h"
  2729. +#include "wimaxscheduler.h"
  2730. +#include "ulburst.h"
  2731. +#include "dlburst.h"
  2732. +
  2733. +/*
  2734. + * Creates a map of the frame
  2735. + * @param mac Pointer to the mac layer
  2736. + */
  2737. +FrameMap::FrameMap (Mac802_16 *mac): dlsubframe_(this), ulsubframe_(this)
  2738. +{
  2739. +  assert (mac);
  2740. +  mac_ = mac; 
  2741. +
  2742. +  //retreive information from mac
  2743. +  rtg_ = mac_->phymib_.rtg;
  2744. +  ttg_ = mac_->phymib_.ttg;
  2745. +  duration_ = mac_->getFrameDuration();
  2746. +}
  2747. +
  2748. +/**
  2749. + * Compute the DL_MAP packet based on the information contained in the structure
  2750. + */
  2751. +Packet* FrameMap::getDL_MAP( )
  2752. +{
  2753. +  Packet *p = mac_->getPacket();
  2754. +  hdr_cmn* ch = HDR_CMN(p);
  2755. +
  2756. +  //printf ("Creating DL_MAP:");
  2757. +  int nbies = dlsubframe_.getPdu()->getNbBurst();
  2758. +  //printf ("nbies=%dn",nbies);
  2759. +
  2760. +  //allocate data for DL_MAP
  2761. +  p->allocdata (sizeof (struct mac802_16_dl_map_frame));
  2762. +  mac802_16_dl_map_frame *frame = (mac802_16_dl_map_frame*) p->accessdata();
  2763. +
  2764. +  frame->type = MAC_DL_MAP;
  2765. +  frame->bsid = mac_->addr();
  2766. +  frame->nb_ies = nbies;
  2767. +  
  2768. +  //allocate IEs
  2769. +  mac802_16_dlmap_ie *ies = frame->ies;
  2770. +
  2771. +  for (int i = 0 ; i < nbies ; i++) {
  2772. +    Burst *b = dlsubframe_.getPdu()->getBurst(i);
  2773. +    ies[i].diuc = b->getIUC();
  2774. +    ies[i].start_time = b->getStarttime();
  2775. +    if (b->getIUC()!=DIUC_END_OF_MAP) {
  2776. +      ies[i].cid =  b->getCid();
  2777. +      if (i==0)
  2778. + ies[i].preamble = dlsubframe_.getPdu()->getPreamble();
  2779. +      else
  2780. + ies[i].preamble = 0;
  2781. +    }
  2782. +  }
  2783. +  
  2784. +  ch->size() += GET_DL_MAP_SIZE(nbies);
  2785. +
  2786. +  return p;
  2787. +}
  2788. +
  2789. +/**
  2790. + * Compute and return the DCD frame
  2791. + */
  2792. +Packet* FrameMap::getDCD( )
  2793. +{
  2794. +  Packet *p = mac_->getPacket ();
  2795. +  hdr_cmn* ch = HDR_CMN(p);
  2796. +
  2797. +  //allocate data for DL_MAP
  2798. +  //printf ("getDCD...nbprofile=%dn", dlsubframe_.getNbProfile());
  2799. +  p->allocdata (sizeof (struct mac802_16_dcd_frame));
  2800. +  mac802_16_dcd_frame *frame = (mac802_16_dcd_frame*) p->accessdata();
  2801. +
  2802. +  frame->type = MAC_DCD;
  2803. +  frame->dcid = mac_->addr(); //to check if needs to be different from ucid
  2804. +  frame->config_change_count = dlsubframe_.getCCC(); 
  2805. +  frame->frame_duration_code = mac_->getFrameDurationCode ();
  2806. +  frame->frame_number = mac_->frame_number_;
  2807. +  frame->nb_prof = dlsubframe_.getNbProfile();
  2808. +  frame->ttg = mac_->phymib_.ttg;
  2809. +  frame->rtg = mac_->phymib_.rtg;
  2810. +  frame->frequency = (int) (mac_->getPhy()->getFreq()/1000); 
  2811. +
  2812. +  //allocate IEs
  2813. +  mac802_16_dcd_profile *profiles = frame->profiles;
  2814. +
  2815. +  int i=0;
  2816. +  for (Profile *p = dlsubframe_.getFirstProfile() ; p ; p=p->next_entry()) {
  2817. +    //set data for first burst
  2818. +    profiles[i].diuc = p->getIUC(); 
  2819. +    profiles[i].frequency = p->getFrequency();
  2820. +    profiles[i].fec = p->getEncoding(); 
  2821. +    i++;
  2822. +  }
  2823. +  //the end of map is already included in the frame length
  2824. +  
  2825. +  ch->size() += GET_DCD_SIZE(dlsubframe_.getNbProfile());
  2826. +  return p;
  2827. +}
  2828. +
  2829. +/**
  2830. + * Compute and return the UL_MAP frame
  2831. + */
  2832. +Packet* FrameMap::getUL_MAP( )
  2833. +{
  2834. +  Packet *p = mac_->getPacket ();
  2835. +  hdr_cmn* ch = HDR_CMN(p);
  2836. +
  2837. +  int nbies = ulsubframe_.getNbPdu(); //there is one burst per UL phy PDU
  2838. +  //printf ("getUL_MAP, nbies=%dn", nbies);
  2839. +  //allocate data for DL_MAP
  2840. +  p->allocdata (sizeof (struct mac802_16_ul_map_frame));
  2841. +  mac802_16_ul_map_frame *frame = (mac802_16_ul_map_frame*) p->accessdata();
  2842. +
  2843. +  frame->type = MAC_UL_MAP;
  2844. +  frame->ucid = mac_->addr();  //set channel ID to index_ to be unique
  2845. +  frame->ucd_count = ulsubframe_.getCCC(); 
  2846. +  frame->allocation_start = ulsubframe_.getStarttime(); //the subframe starts with the contention slot
  2847. +  frame->nb_ies = nbies; 
  2848. +  
  2849. +  //allocate IEs
  2850. +  mac802_16_ulmap_ie *ies = frame->ies;
  2851. +
  2852. +  int i=0;
  2853. +  for (PhyPdu *p = ulsubframe_.getFirstPdu(); p ; p= p ->next_entry()) {
  2854. +    UlBurst *b = (UlBurst*) p->getBurst(0);
  2855. +    ies[i].uiuc = b->getIUC(); //end of map
  2856. +    ies[i].start_time = b->getStarttime();
  2857. +    if (b->getIUC()!=UIUC_END_OF_MAP) {
  2858. +      ies[i].cid =  b->getCid();
  2859. +      ies[i].midamble_rep = b->getMidamble();
  2860. +      ies[i].duration = b->getDuration();
  2861. +      if (b->getIUC() == UIUC_EXT_UIUC) {
  2862. + ies[i].extended_uiuc = b->getExtendedUIUC();
  2863. + if (b->getExtendedUIUC ()== UIUC_FAST_RANGING) {
  2864. +   ies[i].fast_ranging.mac_addr = b->getFastRangingMacAddr ();
  2865. +   ies[i].fast_ranging.uiuc = b->getFastRangingUIUC ();
  2866. + }
  2867. +      }
  2868. +    }
  2869. +    i++;
  2870. +  }
  2871. +
  2872. +  ch->size() += GET_UL_MAP_SIZE(nbies);
  2873. +  return p;
  2874. +}
  2875. +
  2876. +/**
  2877. + * Compute and return the UCD frame
  2878. + */
  2879. +Packet* FrameMap::getUCD( )
  2880. +{
  2881. +  Packet *p = mac_->getPacket ();
  2882. +  hdr_cmn* ch = HDR_CMN(p);
  2883. +
  2884. +  //allocate data for DL_MAP
  2885. +  p->allocdata (sizeof (struct mac802_16_ucd_frame));
  2886. +  mac802_16_ucd_frame *frame = (mac802_16_ucd_frame*) p->accessdata();
  2887. +
  2888. +  frame->type = MAC_UCD;
  2889. +  frame->config_change_count = 0; //changed by scheduler
  2890. +  frame->rng_backoff_start = ulsubframe_.getRanging()->getBackoff_start();
  2891. +  frame->rng_backoff_end = ulsubframe_.getRanging()->getBackoff_stop();
  2892. +  frame->rng_req_size = ulsubframe_.getRanging()->getSize();
  2893. +  frame->req_backoff_start = ulsubframe_.getBw_req()->getBackoff_start();
  2894. +  frame->req_backoff_end = ulsubframe_.getBw_req()->getBackoff_stop()+1;
  2895. +  frame->bw_req_size = ulsubframe_.getBw_req()->getSize();
  2896. +
  2897. +  frame->nb_prof = ulsubframe_.getNbProfile();
  2898. +  //allocate IEs
  2899. +  mac802_16_ucd_profile *profiles = frame->profiles;
  2900. +
  2901. +  int i=0;
  2902. +  for (Profile *p = ulsubframe_.getFirstProfile() ; p ; p=p->next_entry()) {
  2903. +    //set data for first burst
  2904. +    profiles[i].uiuc = p->getIUC(); 
  2905. +    profiles[i].fec = p->getEncoding(); 
  2906. +    i++;
  2907. +  }
  2908. +
  2909. +  //the end of map is already included in the frame length
  2910. +  ch->size() += GET_UCD_SIZE(ulsubframe_.getNbProfile());
  2911. +  return p;
  2912. +}
  2913. +
  2914. +/**
  2915. + * Parse a DL_MAP message and create the data structure
  2916. + * @param frame The DL frame information
  2917. + */
  2918. +void FrameMap::parseDLMAPframe (mac802_16_dl_map_frame *frame)
  2919. +{
  2920. +  //printf ("parse DL-MAP in %dn", mac_->addr());
  2921. +  // Clear previous information  
  2922. +  while (dlsubframe_.getPdu()->getNbBurst()>0) {
  2923. +    Burst *b = dlsubframe_.getPdu()->getBurst (0);
  2924. +    dlsubframe_.getPdu()->removeBurst (b);
  2925. +    delete b;
  2926. +  }
  2927. +
  2928. +  int nbies = frame->nb_ies;
  2929. +  mac802_16_dlmap_ie *ies = frame->ies;
  2930. +
  2931. +  for (int i = 0 ; i < nbies ; i++) {
  2932. +    Burst *b = dlsubframe_.getPdu()->addBurst(i);
  2933. +    b->setIUC(ies[i].diuc);
  2934. +    b->setStarttime(ies[i].start_time);
  2935. +    if (b->getIUC()!=DIUC_END_OF_MAP) {
  2936. +      b->setCid(ies[i].cid);
  2937. +      if (i==0) //first burst contains preamble
  2938. + dlsubframe_.getPdu()->setPreamble(ies[i].preamble);
  2939. +    }
  2940. +    //printf ("t Adding burst %d: cid=%d, iuc=%d start=%dn", i, b->getCid(), b->getIUC(),b->getStarttime());
  2941. +  }
  2942. +  //should we parse end of map too?
  2943. +}
  2944. +
  2945. +/**
  2946. + * Parse a DCD message and create the data structure
  2947. + * @param frame The DL frame information
  2948. + */
  2949. +void FrameMap::parseDCDframe (mac802_16_dcd_frame *frame)
  2950. +{
  2951. +  //clear previous profiles
  2952. +  dlsubframe_.removeProfiles();
  2953. +
  2954. +  int nb_prof = frame->nb_prof;
  2955. +  mac_->frame_number_ = frame->frame_number;
  2956. +  mac802_16_dcd_profile *profiles = frame->profiles;
  2957. +  mac_->setFrameDurationCode (frame->frame_duration_code);
  2958. +
  2959. +  for (int i = 0 ; i < nb_prof ; i++) {
  2960. +    Profile *p = dlsubframe_.addProfile (profiles[i].frequency, (Ofdm_mod_rate)profiles[i].fec);
  2961. +    p->setIUC (profiles[i].diuc);
  2962. +    //printf ("t Adding dl profile %i: f=%d, rate=%d, iuc=%dn", i, p->getFrequency(), p->getEncoding(), p->getIUC());
  2963. +  }
  2964. +}
  2965. +
  2966. +/**
  2967. + * Parse a UL_MAP message and create the data structure
  2968. + * @param frame The UL frame information
  2969. + */
  2970. +void FrameMap::parseULMAPframe (mac802_16_ul_map_frame *frame)
  2971. +{
  2972. +  //printf ("parse UL-MAPn");
  2973. +  // Clear previous information
  2974. +  for (PhyPdu *p = ulsubframe_.getFirstPdu(); p ; p = ulsubframe_.getFirstPdu()) {
  2975. +    ulsubframe_.removePhyPdu(p);
  2976. +    delete (p);
  2977. +  }
  2978. +  
  2979. +  int nbies = frame->nb_ies;
  2980. +  mac802_16_ulmap_ie *ies = frame->ies;
  2981. +
  2982. +  ulsubframe_.setStarttime(frame->allocation_start);
  2983. +  //mac_->debug ("tul start time = %d %fn", frame->allocation_start, frame->allocation_start*mac_->getPhy()->getPS());
  2984. +
  2985. +  for (int i = 0 ; i < nbies ; i++) {
  2986. +    UlBurst *b = (UlBurst*)(ulsubframe_.addPhyPdu(i,0))->addBurst(0);
  2987. +    b->setIUC(ies[i].uiuc);
  2988. +    b->setStarttime(ies[i].start_time);
  2989. +    if (b->getIUC()!=UIUC_END_OF_MAP) {
  2990. +      b->setCid(ies[i].cid);
  2991. +      b->setMidamble(ies[i].midamble_rep);
  2992. +      b->setDuration(ies[i].duration);
  2993. +      if (b->getIUC() == UIUC_EXT_UIUC) {
  2994. + if(ies[i].extended_uiuc== UIUC_FAST_RANGING) {
  2995. +   b->setFastRangingParam (ies[i].fast_ranging.mac_addr, ies[i].fast_ranging.uiuc);
  2996. + }
  2997. +      }
  2998. +    }
  2999. +    /*mac_->debug ("t Adding burst %d: cid=%d, iuc=%d start=%d (%f) duration=%dn", 
  3000. +      i, b->getCid(), b->getIUC(),b->getStarttime(), starttime_+frame->allocation_start*mac_->getPhy()->getPS()+b->getStarttime()*mac_->getPhy()->getSymbolTime(), b->getDuration());*/
  3001. +  }
  3002. +}
  3003. +
  3004. +/**
  3005. + * Parse a UCD message and create the data structure
  3006. + * @param frame The DL frame information
  3007. + */
  3008. +void FrameMap::parseUCDframe (mac802_16_ucd_frame *frame)
  3009. +{
  3010. +  assert (frame);
  3011. +  //clear previous profiles
  3012. +  ulsubframe_.removeProfiles();
  3013. +  
  3014. +  /*printf ("parse UCD..rng_start=%d, rng_stop=%d, req_start=%d, req_stop=%dn",
  3015. +    frame->rng_backoff_start, frame->rng_backoff_end, frame->req_backoff_start,
  3016. +    frame->req_backoff_end);*/
  3017. +  ulsubframe_.getRanging()->setBackoff_start(frame->rng_backoff_start);
  3018. +  ulsubframe_.getRanging()->setBackoff_stop(frame->rng_backoff_end);
  3019. +  ulsubframe_.getRanging()->setSize(frame->rng_req_size);
  3020. +  ulsubframe_.getBw_req()->setBackoff_start(frame->req_backoff_start);
  3021. +  ulsubframe_.getBw_req()->setBackoff_stop(frame->req_backoff_end);  
  3022. +  ulsubframe_.getBw_req()->setSize(frame->bw_req_size);
  3023. +
  3024. +  int nb_prof = frame->nb_prof;
  3025. +  mac802_16_ucd_profile *profiles = frame->profiles;
  3026. +  for (int i = 0 ; i < nb_prof ; i++) {
  3027. +    Profile *p = ulsubframe_.addProfile (0, (Ofdm_mod_rate)(profiles[i].fec));
  3028. +    p->setIUC (profiles[i].uiuc);
  3029. +    //printf ("t Adding ul profile %i: f=%d, rate=%d, iuc=%dn", i, p->getFrequency(), p->getEncoding(), p->getIUC());
  3030. +  }
  3031. +}
  3032. diff -Naur ns-2.29-org/wimax/scheduling/framemap.h ns-2.29/wimax/scheduling/framemap.h
  3033. --- ns-2.29-org/wimax/scheduling/framemap.h 1969-12-31 19:00:00.000000000 -0500
  3034. +++ ns-2.29/wimax/scheduling/framemap.h 2006-09-22 17:27:47.000000000 -0400
  3035. @@ -0,0 +1,148 @@
  3036. +/* This software was developed at the National Institute of Standards and
  3037. + * Technology by employees of the Federal Government in the course of
  3038. + * their official duties. Pursuant to title 17 Section 105 of the United
  3039. + * States Code this software is not subject to copyright protection and
  3040. + * is in the public domain.
  3041. + * NIST assumes no responsibility whatsoever for its use by other parties,
  3042. + * and makes no guarantees, expressed or implied, about its quality,
  3043. + * reliability, or any other characteristic.
  3044. + * <BR>
  3045. + * We would appreciate acknowledgement if the software is used.
  3046. + * <BR>
  3047. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  3048. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  3049. + * FROM THE USE OF THIS SOFTWARE.
  3050. + * </PRE></P>
  3051. + * @author  rouil
  3052. + */
  3053. +
  3054. +#ifndef FRAMEMAP_H
  3055. +#define FRAMEMAP_H
  3056. +
  3057. +#include "subframe.h"
  3058. +#include "mac802_16.h"
  3059. +
  3060. +/**
  3061. + * This class contains the datastructure to describe a frame
  3062. + */
  3063. +class FrameMap
  3064. +{
  3065. + public:
  3066. +  /*
  3067. +   * Creates a map of the frame
  3068. +   * @param mac Pointer to the mac layer
  3069. +   */
  3070. +  FrameMap (Mac802_16 *mac);
  3071. +
  3072. +  /**
  3073. +   * Compute and return the DCD frame
  3074. +   */
  3075. +  Packet* getDCD( );
  3076. +  /**
  3077. +   * Compute the DL_MAP packet based on the information contained in the structure
  3078. +   */
  3079. +  Packet* getDL_MAP( );
  3080. +
  3081. +  /**
  3082. +   * Compute and return the UCD frame
  3083. +   */
  3084. +  Packet* getUCD( );
  3085. +
  3086. +  /**
  3087. +   * Compute and return the UL_MAP frame
  3088. +   */
  3089. +  Packet* getUL_MAP( );
  3090. +
  3091. +  /**
  3092. +   * Return the attached mac
  3093. +   * @return the mac
  3094. +   */
  3095. +  inline Mac802_16 * getMac () { return mac_; }
  3096. +
  3097. +  /**
  3098. +   * Return the DL subframe
  3099. +   * @return the DL subframe
  3100. +   */
  3101. +  inline DlSubFrame * getDlSubframe () { return &dlsubframe_; }
  3102. +
  3103. +
  3104. +  /**
  3105. +   * Return the UL subframe
  3106. +   * @return the UL subframe
  3107. +   */
  3108. +  inline UlSubFrame * getUlSubframe () { return &ulsubframe_; }
  3109. +
  3110. +
  3111. +  /**
  3112. +   * Parse a DL_MAP message and create the data structure
  3113. +   * @param frame The DL frame information
  3114. +   */
  3115. +  void parseDLMAPframe (mac802_16_dl_map_frame *frame);
  3116. +
  3117. +  /**
  3118. +   * Parse a DCD message and create the data structure
  3119. +   * @param frame The DL frame information
  3120. +   */
  3121. +  void parseDCDframe (mac802_16_dcd_frame *frame);
  3122. +
  3123. +  /**
  3124. +   * Parse a UL_MAP message and create the data structure
  3125. +   * @param frame The UL frame information
  3126. +   */
  3127. +  void parseULMAPframe (mac802_16_ul_map_frame *frame);
  3128. +
  3129. +  /**
  3130. +   * Parse a UCD message and create the data structure
  3131. +   * @param frame The DL frame information
  3132. +   */
  3133. +  void parseUCDframe (mac802_16_ucd_frame *frame);
  3134. +
  3135. +  /**
  3136. +   * Set the start time of the frame
  3137. +   */
  3138. +  inline void setStarttime (double time) { starttime_ = time; }
  3139. +
  3140. +  /**
  3141. +   * Return the time the frame started
  3142. +   * @return The time the frame started
  3143. +   */
  3144. +  inline double getStarttime () { return starttime_; }
  3145. +
  3146. +private:
  3147. +  /**
  3148. +   * The mac layer
  3149. +   */
  3150. +  Mac802_16 *mac_;
  3151. +
  3152. +  /**
  3153. +   * The frame duration
  3154. +   */
  3155. +  double duration_;
  3156. +  
  3157. +  /**
  3158. +   * Time the frame started. Used for synchronization
  3159. +   */
  3160. +  double starttime_;
  3161. +
  3162. +  /**
  3163. +   * The number of PS required to switch from receiver to transmitter
  3164. +   */
  3165. +  int rtg_;
  3166. +  
  3167. +  /**
  3168. +   * The number of PS required to switch from sender to receiver
  3169. +   */
  3170. +  int ttg_;
  3171. +  
  3172. +  /**
  3173. +   * The downlink subframe
  3174. +   */
  3175. +  DlSubFrame dlsubframe_;
  3176. +
  3177. +  /**
  3178. +   * The uplink subframe
  3179. +   */
  3180. +  UlSubFrame ulsubframe_;
  3181. +};
  3182. +
  3183. +#endif
  3184. diff -Naur ns-2.29-org/wimax/scheduling/phypdu.cc ns-2.29/wimax/scheduling/phypdu.cc
  3185. --- ns-2.29-org/wimax/scheduling/phypdu.cc 1969-12-31 19:00:00.000000000 -0500
  3186. +++ ns-2.29/wimax/scheduling/phypdu.cc 2006-09-22 17:27:47.000000000 -0400
  3187. @@ -0,0 +1,174 @@
  3188. +/* This software was developed at the National Institute of Standards and
  3189. + * Technology by employees of the Federal Government in the course of
  3190. + * their official duties. Pursuant to title 17 Section 105 of the United
  3191. + * States Code this software is not subject to copyright protection and
  3192. + * is in the public domain.
  3193. + * NIST assumes no responsibility whatsoever for its use by other parties,
  3194. + * and makes no guarantees, expressed or implied, about its quality,
  3195. + * reliability, or any other characteristic.
  3196. + * <BR>
  3197. + * We would appreciate acknowledgement if the software is used.
  3198. + * <BR>
  3199. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  3200. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  3201. + * FROM THE USE OF THIS SOFTWARE.
  3202. + * </PRE></P>
  3203. + * @author  rouil
  3204. + */
  3205. +
  3206. +#include "phypdu.h"
  3207. +
  3208. +/**
  3209. + * Create a phy pdu with the given preamble size
  3210. + * @param preamble The preamble size in OFDM symbols
  3211. + */
  3212. +PhyPdu::PhyPdu (FrameMap *map, int preamble)
  3213. +{
  3214. +  assert (preamble >=0 && map);
  3215. +  preamble_ = preamble;
  3216. +  map_ = map;
  3217. +  nb_burst_=0;
  3218. +  LIST_INIT(&burst_list_);
  3219. +}
  3220. +
  3221. +/*
  3222. + * Delete the object
  3223. + */
  3224. +PhyPdu::~PhyPdu ()
  3225. +{
  3226. +  for (Burst *b = burst_list_.lh_first; b ; b=burst_list_.lh_first) {
  3227. +    b->remove_entry ();
  3228. +    delete (b);
  3229. +  }
  3230. +}
  3231. +
  3232. +
  3233. +/**
  3234. + * Set the preamble size for the PDU in unit of OFDM symbols
  3235. + * @param preamble the preamble size for the PDU
  3236. + */
  3237. +void PhyPdu::setPreamble( int preamble )
  3238. +{
  3239. +  assert (preamble>=0);
  3240. +  preamble_ = preamble;
  3241. +}
  3242. +
  3243. +/**
  3244. + * Return the preamble size for the PDU in unit of OFDM symbols
  3245. + * @return the preamble size for the PDU
  3246. + */
  3247. +int PhyPdu::getPreamble( )
  3248. +{
  3249. +  return preamble_;
  3250. +}
  3251. +
  3252. +/**
  3253. + * Add a burst in the PDU
  3254. + * @param pos The position of the burst 
  3255. + */
  3256. +Burst* PhyPdu::addBurst(int pos)
  3257. +{
  3258. +  assert (pos >= 0 && pos <= nb_burst_ );
  3259. +  Burst *b = new Burst (this);
  3260. +  if (pos==0)
  3261. +    b->insert_entry_head (&burst_list_);
  3262. +  else {
  3263. +    Burst *prev = burst_list_.lh_first ;
  3264. +    Burst *b2 = prev->next_entry();
  3265. +    int index = 1;
  3266. +    while (index < pos) {
  3267. +      prev=b2;
  3268. +      b2=b2->next_entry();
  3269. +      index++;
  3270. +    }
  3271. +    b->insert_entry (prev);
  3272. +  }
  3273. +  nb_burst_++;
  3274. +  return b;
  3275. +}
  3276. +
  3277. +/**
  3278. + * Remove a burst in the PDU
  3279. + * @param burst The burst to remove
  3280. + */
  3281. +void PhyPdu::removeBurst(Burst *b)
  3282. +{
  3283. +  b->remove_entry();
  3284. +  nb_burst_--;
  3285. +}
  3286. +
  3287. +/**
  3288. + * Return the burst located at the given index
  3289. + * @param pos The position of the burst
  3290. + */
  3291. +Burst* PhyPdu::getBurst(int pos)
  3292. +{
  3293. +  assert (pos >= 0 && pos < nb_burst_ );
  3294. +  Burst *b = burst_list_.lh_first ;
  3295. +  for (int i = 0 ; i < pos ; i++) {
  3296. +    b=b->next_entry();
  3297. +  }
  3298. +  return b;
  3299. +}
  3300. +
  3301. +/** Methods for class DlPhyPdu **/
  3302. +
  3303. +/**
  3304. + * Create a phy pdu with the given preamble size
  3305. + * @param preamble The preamble size in OFDM symbols
  3306. + */
  3307. +DlPhyPdu::DlPhyPdu (FrameMap *map, int preamble) : PhyPdu(map, preamble)
  3308. +{
  3309. +
  3310. +}
  3311. +
  3312. +/**
  3313. + * Add a burst in the PDU
  3314. + * @param pos The position of the burst 
  3315. + */
  3316. +Burst* DlPhyPdu::addBurst(int pos)
  3317. +{
  3318. +  assert (pos >= 0 && pos <= nb_burst_ );
  3319. +  DlBurst *b = new DlBurst (this);
  3320. +  if (pos==0 || nb_burst_==0)
  3321. +    b->insert_entry_head (&burst_list_);
  3322. +  else {
  3323. +    Burst *prev = burst_list_.lh_first ;
  3324. +    Burst *b2 = prev->next_entry();
  3325. +    int index = 1;
  3326. +    while (b2 && index < pos) {
  3327. +      prev=b2;
  3328. +      b2=b2->next_entry();
  3329. +      index++;
  3330. +    }
  3331. +    b->insert_entry (prev);
  3332. +  }
  3333. +  nb_burst_++;
  3334. +  return b;
  3335. +}
  3336. +
  3337. +
  3338. +/** Methods for class UlPhyPdu **/
  3339. +
  3340. +/**
  3341. + * Create a phy pdu with the given preamble size
  3342. + * @param preamble The preamble size in OFDM symbols
  3343. + */
  3344. +UlPhyPdu::UlPhyPdu (FrameMap *map, int preamble) : PhyPdu(map, preamble)
  3345. +{
  3346. +
  3347. +}
  3348. +
  3349. +/**
  3350. + * Add a burst in the PDU
  3351. + * @param pos The position of the burst 
  3352. + */
  3353. +Burst* UlPhyPdu::addBurst(int pos)
  3354. +{
  3355. +  //UlPhyPdu only have one burst
  3356. +  assert (pos == 0 && nb_burst_==0 );
  3357. +  UlBurst *b = new UlBurst (this);
  3358. +  b->insert_entry_head (&burst_list_);
  3359. +  nb_burst_++;
  3360. +  return b;
  3361. +}
  3362. diff -Naur ns-2.29-org/wimax/scheduling/phypdu.h ns-2.29/wimax/scheduling/phypdu.h
  3363. --- ns-2.29-org/wimax/scheduling/phypdu.h 1969-12-31 19:00:00.000000000 -0500
  3364. +++ ns-2.29/wimax/scheduling/phypdu.h 2006-09-22 17:27:47.000000000 -0400
  3365. @@ -0,0 +1,175 @@
  3366. +/* This software was developed at the National Institute of Standards and
  3367. + * Technology by employees of the Federal Government in the course of
  3368. + * their official duties. Pursuant to title 17 Section 105 of the United
  3369. + * States Code this software is not subject to copyright protection and
  3370. + * is in the public domain.
  3371. + * NIST assumes no responsibility whatsoever for its use by other parties,
  3372. + * and makes no guarantees, expressed or implied, about its quality,
  3373. + * reliability, or any other characteristic.
  3374. + * <BR>
  3375. + * We would appreciate acknowledgement if the software is used.
  3376. + * <BR>
  3377. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  3378. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  3379. + * FROM THE USE OF THIS SOFTWARE.
  3380. + * </PRE></P>
  3381. + * @author  rouil
  3382. + */
  3383. +
  3384. +#ifndef PHYPDU_H
  3385. +#define PHYPDU_H
  3386. +
  3387. +#include "burst.h"
  3388. +#include "dlburst.h"
  3389. +#include "ulburst.h"
  3390. +
  3391. +class FrameMap;
  3392. +class PhyPdu;
  3393. +LIST_HEAD (phyPdu, PhyPdu);
  3394. +/**
  3395. + * This class describte the content of a Phy PDU
  3396. + */
  3397. +class PhyPdu
  3398. +{
  3399. + public:
  3400. +  /**
  3401. +   * Create a phy pdu with the given preamble size
  3402. +   * @param preamble The preamble size in OFDM symbols
  3403. +   */
  3404. +  PhyPdu (FrameMap *map, int preamble);
  3405. +
  3406. +  /**
  3407. +   * Delete the object
  3408. +   */
  3409. +  virtual ~PhyPdu ();
  3410. +
  3411. +  /**
  3412. +   * Return the preamble size for the PDU in unit of OFDM symbols
  3413. +   * @return the preamble size for the PDU
  3414. +   */
  3415. +  int getPreamble( );
  3416. +
  3417. +  /**
  3418. +   * Set the preamble size for the PDU in unit of OFDM symbols
  3419. +   * @param preamble the preamble size for the PDU
  3420. +   */
  3421. +  void setPreamble( int preamble );
  3422. +  
  3423. +  /**
  3424. +   * Create and return a burst in the PDU
  3425. +   * @param pos The position of the burst
  3426. +   * @return The burst created
  3427. +   */
  3428. +  virtual Burst * addBurst(int pos);
  3429. +
  3430. +  /**
  3431. +   * Remove a burst in the PDU
  3432. +   * @param burst The burst to remove
  3433. +   */
  3434. +  void removeBurst(Burst *b);
  3435. +
  3436. +  /**
  3437. +   * Return the burst located at the given index
  3438. +   * @param pos The position of the burst
  3439. +   */
  3440. +  Burst* getBurst(int pos);
  3441. +
  3442. +  /**
  3443. +   * Return the number of burst in the PhyPDU
  3444. +   */
  3445. +  inline int getNbBurst () { return nb_burst_; }
  3446. +
  3447. +  /**
  3448. +   * Return the FrameMap 
  3449. +   */
  3450. +  inline FrameMap * getMap() { return map_; }
  3451. +
  3452. +  // Chain element to the list
  3453. +  inline void insert_entry_head(struct phyPdu *head) {
  3454. +    LIST_INSERT_HEAD(head, this, link);
  3455. +  }
  3456. +  
  3457. +  // Chain element to the list
  3458. +  inline void insert_entry(PhyPdu *elem) {
  3459. +    LIST_INSERT_AFTER(elem, this, link);
  3460. +  }
  3461. +  
  3462. +  // Return next element in the chained list
  3463. +  PhyPdu* next_entry(void) const { return link.le_next; }
  3464. +
  3465. +  // Remove the entry from the list
  3466. +  inline void remove_entry() { 
  3467. +    LIST_REMOVE(this, link); 
  3468. +  }
  3469. + protected:
  3470. +  /*
  3471. +   * Pointer to next in the list
  3472. +   */
  3473. +  LIST_ENTRY(PhyPdu) link;
  3474. +  //LIST_ENTRY(PhyPdu); //for magic draw
  3475. +
  3476. +  /**
  3477. +   * Curent number of bursts
  3478. +   */
  3479. +  int nb_burst_;
  3480. +
  3481. +  /**
  3482. +   * The list of burst contained in this PDU.
  3483. +   * For uplink Phy PDU, only one burst is allowed
  3484. +   */
  3485. +  struct burst burst_list_;
  3486. +
  3487. + private:
  3488. +  /**
  3489. +   * Size of the preamble in units of OFDM symbols
  3490. +   */
  3491. +  int preamble_;
  3492. +  
  3493. +  /**
  3494. +   * The frame map
  3495. +   */
  3496. +  FrameMap *map_;
  3497. +
  3498. +};
  3499. +
  3500. +/**
  3501. + * Define subclass for downlink phy pdu
  3502. + */
  3503. +class DlPhyPdu: public PhyPdu
  3504. +{
  3505. + public:
  3506. +  /**
  3507. +   * Create a phy pdu with the given preamble size
  3508. +   * @param preamble The preamble size in OFDM symbols
  3509. +   */
  3510. +  DlPhyPdu (FrameMap *map, int preamble);
  3511. +
  3512. +  /**
  3513. +   * Create and return a burst in the PDU
  3514. +   * @param pos The position of the burst
  3515. +   * @return The burst created
  3516. +   */
  3517. +  virtual Burst * addBurst(int pos);
  3518. +};
  3519. +
  3520. +/**
  3521. + * Define subclass for uplink phy pdu
  3522. + */
  3523. +class UlPhyPdu: public PhyPdu
  3524. +{
  3525. + public:
  3526. +  /**
  3527. +   * Create a phy pdu with the given preamble size
  3528. +   * @param preamble The preamble size in OFDM symbols
  3529. +   */
  3530. +  UlPhyPdu (FrameMap *map, int preamble);
  3531. +
  3532. +  /**
  3533. +   * Create and return a burst in the PDU
  3534. +   * @param pos The position of the burst
  3535. +   * @return The burst created
  3536. +   */
  3537. +  virtual Burst * addBurst(int pos);
  3538. +};
  3539. +
  3540. +#endif
  3541. diff -Naur ns-2.29-org/wimax/scheduling/profile.cc ns-2.29/wimax/scheduling/profile.cc
  3542. --- ns-2.29-org/wimax/scheduling/profile.cc 1969-12-31 19:00:00.000000000 -0500
  3543. +++ ns-2.29/wimax/scheduling/profile.cc 2006-09-22 17:27:47.000000000 -0400
  3544. @@ -0,0 +1,95 @@
  3545. +/* This software was developed at the National Institute of Standards and
  3546. + * Technology by employees of the Federal Government in the course of
  3547. + * their official duties. Pursuant to title 17 Section 105 of the United
  3548. + * States Code this software is not subject to copyright protection and
  3549. + * is in the public domain.
  3550. + * NIST assumes no responsibility whatsoever for its use by other parties,
  3551. + * and makes no guarantees, expressed or implied, about its quality,
  3552. + * reliability, or any other characteristic.
  3553. + * <BR>
  3554. + * We would appreciate acknowledgement if the software is used.
  3555. + * <BR>
  3556. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  3557. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  3558. + * FROM THE USE OF THIS SOFTWARE.
  3559. + * </PRE></P>
  3560. + * @author  rouil
  3561. + */
  3562. +
  3563. +#include "profile.h"
  3564. +#include "subframe.h"
  3565. +
  3566. +/**
  3567. + * Creates a profile with the given frequency and encoding
  3568. + * @param f The frequency information for the profile
  3569. + * @param enc The encoding type
  3570. + */
  3571. +Profile::Profile (SubFrame *subframe, int f, Ofdm_mod_rate enc) : iuc_(0)
  3572. +{
  3573. +  assert (subframe);
  3574. +  subframe_ = subframe;
  3575. +  frequency_ = f;
  3576. +  encoding_ = enc;
  3577. +}
  3578. +
  3579. +/**
  3580. + * Return the encoding type
  3581. + * @return the encoding type
  3582. + */
  3583. +Ofdm_mod_rate Profile::getEncoding( ) 
  3584. +{ 
  3585. +  return encoding_; 
  3586. +}
  3587. +
  3588. +/**
  3589. + * Set the encoding type
  3590. + * @param enc the encoding type
  3591. + */
  3592. +void Profile::setEncoding( Ofdm_mod_rate enc ) 
  3593. +{
  3594. +  if (encoding_ != enc)
  3595. +    subframe_->incrCCC();
  3596. +  encoding_ = enc; 
  3597. +}
  3598. +
  3599. +/**
  3600. + * Return the frequency in unit of kHz
  3601. + * @return the frequency
  3602. + */
  3603. +int Profile::getFrequency( ) 
  3604. +{ 
  3605. +  return frequency_; 
  3606. +}
  3607. +
  3608. +/**
  3609. + * Set the frequency in unit of kHz
  3610. + * @param f the frequency
  3611. + */
  3612. +void Profile::setFrequency( int f ) 
  3613. +{ 
  3614. +  if (frequency_ != f)
  3615. +    subframe_->incrCCC();
  3616. +  frequency_ = f; 
  3617. +}
  3618. +
  3619. +/**
  3620. + * Return the frequency in unit of kHz
  3621. + * @return the frequency
  3622. + */
  3623. +int Profile::getIUC( ) 
  3624. +{ 
  3625. +  return iuc_; 
  3626. +}
  3627. +
  3628. +/**
  3629. + * Set the IUC number for this profile
  3630. + * @param iuc The IUC number for this profile
  3631. + */
  3632. +void Profile::setIUC( int iuc ) 
  3633. +{ 
  3634. +  if (iuc_!=0 && iuc_!= iuc)
  3635. +    subframe_->incrCCC();
  3636. +  iuc_ = iuc; 
  3637. +}
  3638. +
  3639. +
  3640. diff -Naur ns-2.29-org/wimax/scheduling/profile.h ns-2.29/wimax/scheduling/profile.h
  3641. --- ns-2.29-org/wimax/scheduling/profile.h 1969-12-31 19:00:00.000000000 -0500
  3642. +++ ns-2.29/wimax/scheduling/profile.h 2006-09-22 17:27:47.000000000 -0400
  3643. @@ -0,0 +1,121 @@
  3644. +/* This software was developed at the National Institute of Standards and
  3645. + * Technology by employees of the Federal Government in the course of
  3646. + * their official duties. Pursuant to title 17 Section 105 of the United
  3647. + * States Code this software is not subject to copyright protection and
  3648. + * is in the public domain.
  3649. + * NIST assumes no responsibility whatsoever for its use by other parties,
  3650. + * and makes no guarantees, expressed or implied, about its quality,
  3651. + * reliability, or any other characteristic.
  3652. + * <BR>
  3653. + * We would appreciate acknowledgement if the software is used.
  3654. + * <BR>
  3655. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  3656. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  3657. + * FROM THE USE OF THIS SOFTWARE.
  3658. + * </PRE></P>
  3659. + * @author  rouil
  3660. + */
  3661. +
  3662. +#ifndef PROFILE_H
  3663. +#define PROFILE_H
  3664. +
  3665. +#include "ofdmphy.h"
  3666. +
  3667. +class SubFrame;
  3668. +
  3669. +class Profile;
  3670. +LIST_HEAD (profile, Profile);
  3671. +
  3672. +/**
  3673. + * This class contains information about burst such as modulation, frequency...
  3674. + */
  3675. +class Profile
  3676. +{
  3677. + public:
  3678. +  /**
  3679. +   * Creates a profile with the given frequency and encoding
  3680. +   * @param f The frequency information for the profile
  3681. +   * @param enc The encoding type
  3682. +   */
  3683. +  Profile (SubFrame *subframe, int f, Ofdm_mod_rate enc);
  3684. +
  3685. +  /**
  3686. +   * Set the IUC number for this profile
  3687. +   * @param iuc The IUC number for this profile
  3688. +   */
  3689. +  void setIUC( int iuc );
  3690. +
  3691. +  /**
  3692. +   * Return the frequency in unit of kHz
  3693. +   * @return the frequency
  3694. +   */
  3695. +  int getIUC();
  3696. +
  3697. +  /**
  3698. +   * Return the encoding type
  3699. +   * @return the encoding type
  3700. +   */
  3701. +  Ofdm_mod_rate getEncoding( );
  3702. +
  3703. +  /**
  3704. +   * Return the frequency in unit of kHz
  3705. +   * @return the frequency
  3706. +   */
  3707. +  int getFrequency( );
  3708. +
  3709. +  /**
  3710. +   * Set the encoding type
  3711. +   * @param enc the encoding type
  3712. +   */
  3713. +  void setEncoding( Ofdm_mod_rate enc );
  3714. +
  3715. +  /**
  3716. +   * Set the frequency in unit of kHz
  3717. +   * @param f the frequency
  3718. +   */
  3719. +  void setFrequency( int f );
  3720. +
  3721. +  // Chain element to the list
  3722. +  inline void insert_entry(struct profile *head) {
  3723. +    LIST_INSERT_HEAD(head, this, link);
  3724. +  }
  3725. +  
  3726. +  // Return next element in the chained list
  3727. +  Profile* next_entry(void) const { return link.le_next; }
  3728. +
  3729. +  // Remove the entry from the list
  3730. +  inline void remove_entry() { 
  3731. +    LIST_REMOVE(this, link); 
  3732. +  }
  3733. +
  3734. + private:
  3735. +  /**
  3736. +   * The type of modulation used by the burst
  3737. +   */
  3738. +  Ofdm_mod_rate encoding_;
  3739. +  
  3740. +  /**
  3741. +   * The downlink frequency in kHz
  3742. +   */
  3743. +  int frequency_;
  3744. +  
  3745. +  /**
  3746. +   * The Interval Usage Code for the profile
  3747. +   */
  3748. +  int iuc_;
  3749. +
  3750. +  /**
  3751. +   * The subframe containing this profile
  3752. +   * Used to inform configuration change
  3753. +   */
  3754. +  SubFrame *subframe_;
  3755. +  
  3756. +  /*
  3757. +   * Pointer to next in the list
  3758. +   */
  3759. +  LIST_ENTRY(Profile) link;
  3760. +  //LIST_ENTRY(Profile); //for magic draw
  3761. +  
  3762. +};
  3763. +
  3764. +#endif
  3765. diff -Naur ns-2.29-org/wimax/scheduling/scanningstation.cc ns-2.29/wimax/scheduling/scanningstation.cc
  3766. --- ns-2.29-org/wimax/scheduling/scanningstation.cc 1969-12-31 19:00:00.000000000 -0500
  3767. +++ ns-2.29/wimax/scheduling/scanningstation.cc 2006-09-22 17:27:47.000000000 -0400
  3768. @@ -0,0 +1,50 @@
  3769. +/* This software was developed at the National Institute of Standards and
  3770. + * Technology by employees of the Federal Government in the course of
  3771. + * their official duties. Pursuant to title 17 Section 105 of the United
  3772. + * States Code this software is not subject to copyright protection and
  3773. + * is in the public domain.
  3774. + * NIST assumes no responsibility whatsoever for its use by other parties,
  3775. + * and makes no guarantees, expressed or implied, about its quality,
  3776. + * reliability, or any other characteristic.
  3777. + * <BR>
  3778. + * We would appreciate acknowledgement if the software is used.
  3779. + * <BR>
  3780. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  3781. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  3782. + * FROM THE USE OF THIS SOFTWARE.
  3783. + * </PRE></P>
  3784. + * @author  rouil
  3785. + */
  3786. +
  3787. +#include "scanningstation.h"
  3788. +
  3789. +/**
  3790. + * Create an data object with the given attributes
  3791. + * @param nodeid The node 
  3792. + * @param duration The scanning duration
  3793. + * @param start The frame at which the scanning start
  3794. + * @param interleaving The interleaving interval
  3795. + * @param iteration The number of iterations
  3796. + */
  3797. +ScanningStation::ScanningStation (int nodeid, int duration, int start, int interleaving, int iteration)
  3798. +{
  3799. +  nodeid_ = nodeid;
  3800. +  duration_ = duration;
  3801. +  start_frame_ = start;
  3802. +  interleaving_ = interleaving;
  3803. +  iteration_ = iteration;
  3804. +}
  3805. +
  3806. +/**
  3807. + * Determines if the node is currently scanning
  3808. + * @param frame The current frame
  3809. + */
  3810. +bool ScanningStation::isScanning (int frame)
  3811. +{
  3812. +  //printf ("isScanning %d frame=%d, start_frame=%d, duration=%d, interleaving=%d iteration %dn", nodeid_, frame, start_frame_, duration_, interleaving_, iteration_);
  3813. +  if ((frame < start_frame_)||(frame > (start_frame_ + (duration_+interleaving_)*iteration_)))
  3814. +    return false;
  3815. +  else {
  3816. +    return (((frame-start_frame_)%(duration_+interleaving_))-duration_)<0;
  3817. +  }
  3818. +}
  3819. diff -Naur ns-2.29-org/wimax/scheduling/scanningstation.h ns-2.29/wimax/scheduling/scanningstation.h
  3820. --- ns-2.29-org/wimax/scheduling/scanningstation.h 1969-12-31 19:00:00.000000000 -0500
  3821. +++ ns-2.29/wimax/scheduling/scanningstation.h 2006-09-22 17:27:47.000000000 -0400
  3822. @@ -0,0 +1,112 @@
  3823. +/* This software was developed at the National Institute of Standards and
  3824. + * Technology by employees of the Federal Government in the course of
  3825. + * their official duties. Pursuant to title 17 Section 105 of the United
  3826. + * States Code this software is not subject to copyright protection and
  3827. + * is in the public domain.
  3828. + * NIST assumes no responsibility whatsoever for its use by other parties,
  3829. + * and makes no guarantees, expressed or implied, about its quality,
  3830. + * reliability, or any other characteristic.
  3831. + * <BR>
  3832. + * We would appreciate acknowledgement if the software is used.
  3833. + * <BR>
  3834. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  3835. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  3836. + * FROM THE USE OF THIS SOFTWARE.
  3837. + * </PRE></P>
  3838. + * @author  rouil
  3839. + */
  3840. +
  3841. +#ifndef SCANNINGSTATION_H
  3842. +#define SCANNINGSTATION_H
  3843. +
  3844. +#include "packet.h"
  3845. +
  3846. +class ScanningStation;
  3847. +LIST_HEAD (scanningStation, ScanningStation);
  3848. +
  3849. +/**
  3850. + * Contains information about a scanning station and 
  3851. + * helps to determine if it is in a scanning or interleaving
  3852. + * time.
  3853. + */
  3854. +class ScanningStation
  3855. +{
  3856. + public:
  3857. +  /**
  3858. +   * Create an data object with the given attributes
  3859. +   * @param nodeid The node 
  3860. +   * @param duration The scanning duration
  3861. +   * @param start The frame at which the scanning start
  3862. +   * @param interleaving The interleaving interval
  3863. +   * @param iteration The number of iterations
  3864. +   */
  3865. +  ScanningStation (int nodeid, int duration, int start, int interleaving, int iteration);
  3866. +
  3867. +  /**
  3868. +   * Determines if the node is currently scanning
  3869. +   * @param frame The current frame
  3870. +   */
  3871. +  bool isScanning (int frame);
  3872. +
  3873. +  /**
  3874. +   * Return the node id 
  3875. +   */
  3876. +  int getNodeId () { return nodeid_; }
  3877. +
  3878. +  // Chain element to the list
  3879. +  inline void insert_entry_head(struct scanningStation *head) {
  3880. +    LIST_INSERT_HEAD(head, this, link);
  3881. +  }
  3882. +  
  3883. +  // Chain element to the list
  3884. +  inline void insert_entry(ScanningStation *elem) {
  3885. +    LIST_INSERT_AFTER(elem, this, link);
  3886. +  }
  3887. +
  3888. +  // Return next element in the chained list
  3889. +  ScanningStation* next_entry(void) const { return link.le_next; }
  3890. +
  3891. +  // Remove the entry from the list
  3892. +  inline void remove_entry() { 
  3893. +    LIST_REMOVE(this, link); 
  3894. +  }
  3895. +
  3896. + protected:
  3897. +
  3898. +  /**
  3899. +   * Pointer to next in the list
  3900. +   */
  3901. +  LIST_ENTRY(ScanningStation) link;
  3902. +  //LIST_ENTRY(ScanningStation); //for magic draw
  3903. +
  3904. +
  3905. + private:
  3906. +  /**
  3907. +   * Duration of scanning allocation in frames
  3908. +   */
  3909. +  int duration_;
  3910. +  
  3911. +  /**
  3912. +   * Start frame (absolute)
  3913. +   */
  3914. +  int start_frame_;
  3915. +
  3916. +  /**
  3917. +   * interleaving in frames
  3918. +   */
  3919. +  int interleaving_;
  3920. +
  3921. +  /**
  3922. +   * number of iterations
  3923. +   */
  3924. +  int iteration_;
  3925. +
  3926. +  /**
  3927. +   * The node that is scanning
  3928. +   */
  3929. +  int nodeid_;
  3930. +};
  3931. +
  3932. +
  3933. +
  3934. +#endif
  3935. diff -Naur ns-2.29-org/wimax/scheduling/ssscheduler.cc ns-2.29/wimax/scheduling/ssscheduler.cc
  3936. --- ns-2.29-org/wimax/scheduling/ssscheduler.cc 1969-12-31 19:00:00.000000000 -0500
  3937. +++ ns-2.29/wimax/scheduling/ssscheduler.cc 2006-09-22 17:27:47.000000000 -0400
  3938. @@ -0,0 +1,1436 @@
  3939. +/* This software was developed at the National Institute of Standards and
  3940. + * Technology by employees of the Federal Government in the course of
  3941. + * their official duties. Pursuant to title 17 Section 105 of the United
  3942. + * States Code this software is not subject to copyright protection and
  3943. + * is in the public domain.
  3944. + * NIST assumes no responsibility whatsoever for its use by other parties,
  3945. + * and makes no guarantees, expressed or implied, about its quality,
  3946. + * reliability, or any other characteristic.
  3947. + * <BR>
  3948. + * We would appreciate acknowledgement if the software is used.
  3949. + * <BR>
  3950. + * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  3951. + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  3952. + * FROM THE USE OF THIS SOFTWARE.
  3953. + * </PRE></P>
  3954. + * @author  rouil
  3955. + */
  3956. +
  3957. +#include "ssscheduler.h"
  3958. +#include "burst.h"
  3959. +
  3960. +/**
  3961. + * Tcl hook for creating SS scheduler 
  3962. + */
  3963. +static class SSschedulerClass : public TclClass {
  3964. +public:
  3965. +  SSschedulerClass() : TclClass("WimaxScheduler/SS") {}
  3966. +  TclObject* create(int, const char*const*) {
  3967. +    return (new SSscheduler());
  3968. +    
  3969. +  }
  3970. +} class_ssscheduler;
  3971. +
  3972. +/*
  3973. + * Create a scheduler
  3974. + */
  3975. +SSscheduler::SSscheduler (): t1timer_(0),t2timer_(0),t6timer_(0), t12timer_(0),
  3976. +      t21timer_(0), lostDLMAPtimer_(0), lostULMAPtimer_(0),
  3977. +      t44timer_(0), scan_info_(0)
  3978. +{
  3979. +  debug2 ("SSscheduler createdn");
  3980. +}
  3981. +
  3982. +/**
  3983. + * Initializes the scheduler
  3984. + */
  3985. +void SSscheduler::init ()
  3986. +{
  3987. +  WimaxScheduler::init();
  3988. +  
  3989. +  //At initialization, the SS is looking for synchronization
  3990. +  mac_->setMacState (MAC802_16_WAIT_DL_SYNCH);
  3991. +  mac_->getPhy()->setMode (OFDM_RECV);
  3992. +  //start timer for expiration
  3993. +  t21timer_ = new WimaxT21Timer (mac_);
  3994. +  t21timer_->start (mac_->macmib_.t21_timeout);
  3995. +
  3996. +  //creates other timers
  3997. +  t1timer_ = new WimaxT1Timer (mac_);
  3998. +  t12timer_ = new WimaxT12Timer (mac_);
  3999. +  t2timer_ = new WimaxT2Timer (mac_);
  4000. +  lostDLMAPtimer_ = new WimaxLostDLMAPTimer (mac_);
  4001. +  lostULMAPtimer_ = new WimaxLostULMAPTimer (mac_);
  4002. +
  4003. +  nb_scan_req_ = 0;
  4004. +
  4005. +  scan_info_ = (struct scanning_structure *) malloc (sizeof (struct scanning_structure));
  4006. +  memset (scan_info_, 0, sizeof (struct scanning_structure));
  4007. +  scan_info_->nbr = NULL;
  4008. +  scan_info_->substate = NORMAL;
  4009. +}
  4010. +
  4011. +/**
  4012. + * Interface with the TCL script
  4013. + * @param argc The number of parameter
  4014. + * @param argv The list of parameters
  4015. + */
  4016. +int SSscheduler::command(int argc, const char*const* argv)
  4017. +{
  4018. +  if (argc == 2) {
  4019. +    if (strcmp(argv[1], "send-scan") == 0) {
  4020. +      send_scan_request();
  4021. +      return TCL_OK;
  4022. +    }
  4023. +  }
  4024. +  
  4025. +  return TCL_ERROR;
  4026. +}
  4027. +
  4028. +/**
  4029. + * Start a new frame
  4030. + */
  4031. +void SSscheduler::start_dlsubframe ()
  4032. +{
  4033. +  //mac_->debug ("At %f in Mac %d SS scheduler dlsubframe expires %dn", NOW, mac_->addr(), scan_info_->substate);
  4034. +
  4035. +  mac_->frame_number_++;
  4036. +
  4037. +  switch (scan_info_->substate) {
  4038. +  case SCAN_PENDING: 
  4039. +    if (scan_info_->count == 0) {
  4040. +      resume_scanning();
  4041. +      return;
  4042. +    } 
  4043. +    scan_info_->count--;
  4044. +    break;
  4045. +  case HANDOVER_PENDING:
  4046. +    if (scan_info_->handoff_timeout == 0) {
  4047. +      assert (scan_info_->nbr);
  4048. +#ifdef USE_802_21
  4049. +      mac_->debug ("At %f in Mac %d link handoff proceedingn", NOW, mac_->addr());
  4050. +      mac_->send_link_handoff_proceeding (mac_->addr(), mac_->getPeerNode_head()->getPeerNode(), scan_info_->nbr->getID());
  4051. +#endif 
  4052. +      scan_info_->substate = HANDOVER;
  4053. +      //restore previous state 
  4054. +      //mac_->restore_state (scan_info_->nbr->getState()->state_info);
  4055. +      mac_->setChannel (scan_info_->nbr->getState()->state_info->channel);
  4056. +      lost_synch ();
  4057. +      //add target as peer
  4058. +      mac_->addPeerNode (new PeerNode(scan_info_->nbr->getID()));
  4059. +      return;
  4060. +    }
  4061. +    scan_info_->handoff_timeout--;
  4062. +    break;
  4063. +  default:
  4064. +    break;
  4065. +  }
  4066. +    
  4067. +  //change state of PHY
  4068. +  //mac_->getPhy()->setMode (OFDM_RECV);
  4069. +  
  4070. +  //this is the begining of new frame
  4071. +  map_->setStarttime (NOW);
  4072. +
  4073. +  //start handler of dlsubframe
  4074. +  map_->getDlSubframe()->getTimer()->sched (0);
  4075. +
  4076. +  //reschedule for next frame
  4077. +  dl_timer_->resched (mac_->getFrameDuration());
  4078. +}
  4079. +
  4080. +/**
  4081. + * Start a new frame
  4082. + */
  4083. +void SSscheduler::start_ulsubframe ()
  4084. +{
  4085. +  //mac_->debug ("At %f in Mac %d SS scheduler ulsubframe expiresn", NOW, mac_->addr());
  4086. +  
  4087. +  //change state of PHY: even though it should have been done before
  4088. +  //there are some cases where it does not (during scanning)
  4089. +  mac_->getPhy()->setMode (OFDM_SEND);
  4090. +
  4091. +  //1-Transfert the packets from the queues in Connections to burst queues
  4092. +  Burst *b;
  4093. +  OFDMPhy *phy = mac_->getPhy();
  4094. +  //printf ("SS has %d ul burstsn", map_->getUlSubframe()->getNbPdu ());
  4095. +
  4096. +  PeerNode *peer = mac_->getPeerNode_head(); //this is the BS
  4097. +  assert (peer!=NULL);
  4098. +
  4099. +  for (int index = 0 ; index < map_->getUlSubframe()->getNbPdu (); index++) {
  4100. +    b = map_->getUlSubframe()->getPhyPdu (index)->getBurst (0);
  4101. +
  4102. +    if (b->getIUC()==UIUC_END_OF_MAP) {
  4103. +      //consistency check..
  4104. +      assert (index == map_->getUlSubframe()->getNbPdu ()-1);
  4105. +      break;
  4106. +    }    
  4107. +    
  4108. +    if (b->getIUC()==UIUC_INITIAL_RANGING || b->getIUC()==UIUC_REQ_REGION_FULL)
  4109. +      continue;
  4110. +    int duration = 0; 
  4111. +    //get the packets from the connection with the same CID
  4112. +    //printf ("tBurst CID=%dn", b->getCid());
  4113. +    Connection *c=mac_->getCManager ()->get_connection (b->getCid(), true);
  4114. +    //assert (c);
  4115. +    if (!c)
  4116. +      continue; //I do not have this CID. Must be for another node
  4117. +    //transfert the packets until it reaches burst duration or no more packets
  4118. +    assert (c->getType()==CONN_PRIMARY);
  4119. +    if (peer->getBasic()!= NULL) 
  4120. +      duration = transfer_packets (peer->getBasic(), b, duration);
  4121. +    if (peer->getPrimary()!= NULL)
  4122. +      duration = transfer_packets (peer->getPrimary(), b, duration);
  4123. +    if (peer->getSecondary()!= NULL)
  4124. +      duration = transfer_packets (peer->getSecondary(), b, duration);
  4125. +    if (peer->getOutData()!=NULL)
  4126. +      duration = transfer_packets (peer->getOutData(), b, duration);
  4127. +  }
  4128. +
  4129. +  //2-compute size of data left to create bandwidth requests
  4130. +  if (peer->getBasic()!= NULL) 
  4131. +    create_request (peer->getBasic());
  4132. +  if (peer->getPrimary()!= NULL)
  4133. +    create_request (peer->getPrimary());
  4134. +  if (peer->getSecondary()!= NULL)
  4135. +    create_request (peer->getSecondary());
  4136. +  if (peer->getOutData()!=NULL)
  4137. +    create_request (peer->getOutData());
  4138. +
  4139. +  //start handler for ulsubframe
  4140. +  b = map_->getUlSubframe()->getPhyPdu (0)->getBurst (0);
  4141. +  map_->getUlSubframe()->getTimer()->sched (b->getStarttime()*phy->getSymbolTime());
  4142. +
  4143. +  //reschedule for next frame
  4144. +  ul_timer_->resched (mac_->getFrameDuration());      
  4145. +}
  4146. +
  4147. +/**
  4148. + * Create a request for the given connection
  4149. + * @param con The connection to check
  4150. + */
  4151. +void SSscheduler::create_request (Connection *con)
  4152. +{
  4153. +  if (con->queueLength()==0)
  4154. +    return; //queue is empty
  4155. +  else if (map_->getUlSubframe()->getBw_req()->getRequest (con->get_cid())!=NULL) {
  4156. +    debug2 ("At %f in Mac %d already pending requests for cid=%dn", NOW, mac_->addr(), con->get_cid());
  4157. +    return; //there is already a pending request
  4158. +  }
  4159. +
  4160. +  Packet *p= mac_->getPacket();
  4161. +  hdr_cmn* ch = HDR_CMN(p);
  4162. +  bw_req_header_t *header = (bw_req_header_t *)&(HDR_MAC802_16(p)->header);
  4163. +  header->ht=1;
  4164. +  header->ec=1;
  4165. +  header->type = 0; //incremental..to check meaning
  4166. +  header->br = con->queueByteLength();
  4167. +  header->cid = con->get_cid();
  4168. +
  4169. +  double txtime = mac_->getPhy()->getTrxTime (ch->size(), map_->getUlSubframe()->getProfile (UIUC_REQ_REGION_FULL)->getEncoding());
  4170. +  ch->txtime() = txtime;
  4171. +  map_->getUlSubframe()->getBw_req()->addRequest (p, con->get_cid(), con->queueByteLength());
  4172. +  debug2 ("SSscheduler enqueued request for cid=%d len=%dn", con->get_cid(), con->queueByteLength());
  4173. +  //start timeout for request
  4174. +}
  4175. +
  4176. +/**
  4177. + * Process a packet received by the Mac. Only scheduling related packets should be sent here (BW request, UL_MAP...)
  4178. + * @param p The packet to process
  4179. + */
  4180. +void SSscheduler::process (Packet * p)
  4181. +{
  4182. +  assert (mac_ && HDR_CMN(p)->ptype()==PT_MAC);
  4183. +  debug2 ("SSScheduler received packet to processn");
  4184. +  
  4185. +  hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(p);
  4186. +  gen_mac_header_t header = wimaxHdr->header;
  4187. +
  4188. +  //we cast to this frame because all management frame start with
  4189. +  //a type 
  4190. +  mac802_16_dl_map_frame *frame = (mac802_16_dl_map_frame*) p->accessdata();
  4191. +
  4192. +  switch (frame->type) {
  4193. +  case MAC_DL_MAP: 
  4194. +    map_->setStarttime (NOW-HDR_CMN(p)->txtime());
  4195. +    //printf ("At %f frame start at %fn", NOW, map_->getStarttime());
  4196. +    process_dl_map (frame);
  4197. +    break;
  4198. +  case MAC_DCD: 
  4199. +    process_dcd ((mac802_16_dcd_frame*)frame);
  4200. +    break;
  4201. +  case MAC_UL_MAP: 
  4202. +    process_ul_map ((mac802_16_ul_map_frame*)frame);
  4203. +    break;
  4204. +  case MAC_UCD: 
  4205. +    process_ucd ((mac802_16_ucd_frame*)frame);
  4206. +    break;
  4207. +  case MAC_RNG_RSP:
  4208. +    process_ranging_rsp ((mac802_16_rng_rsp_frame*) frame);
  4209. +    break;
  4210. +  case MAC_REG_RSP:
  4211. +    process_reg_rsp ((mac802_16_reg_rsp_frame*) frame);
  4212. +    break;    
  4213. +  case MAC_MOB_SCN_RSP:
  4214. +    process_scan_rsp ((mac802_16_mob_scn_rsp_frame *) frame);
  4215. +    break;
  4216. +  case MAC_MOB_BSHO_RSP:
  4217. +    process_bsho_rsp ((mac802_16_mob_bsho_rsp_frame *) frame);
  4218. +    break;
  4219. +  case MAC_MOB_NBR_ADV:
  4220. +    process_nbr_adv ((mac802_16_mob_nbr_adv_frame *) frame);
  4221. +    break;
  4222. +  default:
  4223. +    mac_->debug ("unknown packet in SS %dn", mac_->addr());
  4224. +    //exit (0);
  4225. +  }
  4226. +  Packet::free (p);
  4227. +}
  4228. +
  4229. +/**
  4230. + * Return the type of STA this scheduler is good for
  4231. + * @return STA_SS
  4232. + */
  4233. +station_type_t SSscheduler::getNodeType ()
  4234. +{
  4235. +  return STA_MN;
  4236. +}
  4237. +
  4238. +/**
  4239. + * Called when lost synchronization
  4240. + */
  4241. +void SSscheduler::lost_synch ()
  4242. +{
  4243. +  //reset timers
  4244. +  if (t1timer_->busy()!=0)
  4245. +    t1timer_->stop();
  4246. +  if (t12timer_->busy()!=0)
  4247. +    t12timer_->stop();
  4248. +  if (t21timer_->busy()!=0)
  4249. +    t21timer_->stop();
  4250. +  if (lostDLMAPtimer_->busy()!=0)
  4251. +    lostDLMAPtimer_->stop(); 
  4252. +  if (lostULMAPtimer_->busy()!=0)
  4253. +    lostULMAPtimer_->stop(); 
  4254. +  if (t2timer_->busy()!=0)
  4255. +    t2timer_->stop(); 
  4256. +  if (t44timer_ && t44timer_->busy()!=0)
  4257. +    t44timer_->stop();
  4258. +  //we need to go to receiving mode
  4259. +  //printf ("Set phy to recv %xn", mac_->getPhy());
  4260. +  mac_->getPhy()->setMode (OFDM_RECV);
  4261. +  if (mac_->getMacState()==MAC802_16_CONNECTED) {
  4262. +    //remove possible pending requests
  4263. +    map_->getUlSubframe()->getBw_req()->removeRequests(); 
  4264. +
  4265. +#ifdef USE_802_21
  4266. +    mac_->debug ("At %f in Mac %d, send link downn", NOW, mac_->addr());
  4267. +    mac_->send_link_down (mac_->addr(), RC_FAIL_NORESOURCE);
  4268. +#endif
  4269. +  }
  4270. +
  4271. +  //remove information about peer node
  4272. +  if (mac_->getPeerNode_head())
  4273. +    mac_->removePeerNode (mac_->getPeerNode_head());
  4274. +
  4275. +  //start waiting for DL synch
  4276. +  mac_->setMacState (MAC802_16_WAIT_DL_SYNCH);
  4277. +  t21timer_->start (mac_->macmib_.t21_timeout);
  4278. +  if (dl_timer_->status()==TIMER_PENDING)
  4279. +    dl_timer_->cancel();