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

网络

开发平台:

C/C++

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