p802_15_4csmaca.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:16k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /********************************************/
  2. /*     NS2 Simulator for IEEE 802.15.4      */
  3. /*           (per P802.15.4/D18)            */
  4. /*------------------------------------------*/
  5. /* by:        Jianliang Zheng               */
  6. /*        (zheng@ee.ccny.cuny.edu)          */
  7. /*              Myung J. Lee                */
  8. /*          (lee@ccny.cuny.edu)             */
  9. /*        ~~~~~~~~~~~~~~~~~~~~~~~~~         */
  10. /*           SAIT-CUNY Joint Lab            */
  11. /********************************************/
  12. // File:  p802_15_4csmaca.cc
  13. // Mode:  C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t
  14. // $Header: /cvsroot/nsnam/ns-2/wpan/p802_15_4csmaca.cc,v 1.4 2007/01/30 15:54:40 tom_henderson Exp $
  15. /*
  16.  * Copyright (c) 2003-2004 Samsung Advanced Institute of Technology and
  17.  * The City University of New York. All rights reserved.
  18.  *
  19.  * Redistribution and use in source and binary forms, with or without
  20.  * modification, are permitted provided that the following conditions
  21.  * are met:
  22.  * 1. Redistributions of source code must retain the above copyright
  23.  *    notice, this list of conditions and the following disclaimer.
  24.  * 2. Redistributions in binary form must reproduce the above copyright
  25.  *    notice, this list of conditions and the following disclaimer in the
  26.  *    documentation and/or other materials provided with the distribution.
  27.  * 3. All advertising materials mentioning features or use of this software
  28.  *    must display the following acknowledgement:
  29.  * This product includes software developed by the Joint Lab of Samsung 
  30.  *      Advanced Institute of Technology and The City University of New York.
  31.  * 4. Neither the name of Samsung Advanced Institute of Technology nor of 
  32.  *    The City University of New York may be used to endorse or promote 
  33.  *    products derived from this software without specific prior written 
  34.  *    permission.
  35.  *
  36.  * THIS SOFTWARE IS PROVIDED BY THE JOINT LAB OF SAMSUNG ADVANCED INSTITUTE
  37.  * OF TECHNOLOGY AND THE CITY UNIVERSITY OF NEW YORK ``AS IS'' AND ANY EXPRESS 
  38.  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
  39.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 
  40.  * NO EVENT SHALL SAMSUNG ADVANCED INSTITUTE OR THE CITY UNIVERSITY OF NEW YORK 
  41.  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
  42.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
  43.  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  44.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  45.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
  46.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47.  */
  48. #include "p802_15_4csmaca.h"
  49. #include "p802_15_4const.h"
  50. #include "p802_15_4trace.h"
  51. #ifndef MAX
  52. #define MAX(x,y)        (((x)>(y))?(x):(y))
  53. #endif
  54. #ifndef MIN
  55. #define MIN(x,y)        (((x)<(y))?(x):(y))
  56. #endif
  57. CsmaCA802_15_4::CsmaCA802_15_4(Phy802_15_4 *p, Mac802_15_4 *m)
  58. {
  59. phy = p;
  60. mac = m;
  61. txPkt = 0;
  62. waitNextBeacon = false;
  63. backoffT = new macBackoffTimer(this);
  64. assert(backoffT);
  65. bcnOtherT = new macBeaconOtherTimer(this);
  66. assert(bcnOtherT);
  67. deferCCAT = new macDeferCCATimer(this);
  68. assert(deferCCAT);
  69. }
  70. CsmaCA802_15_4::~CsmaCA802_15_4()
  71. {
  72. delete backoffT;
  73. delete bcnOtherT;
  74. delete deferCCAT;
  75. }
  76. void CsmaCA802_15_4::reset(void)
  77. {
  78. if (beaconEnabled)
  79. {
  80. NB = 0;
  81. CW = 2;
  82. BE = mac->mpib.macMinBE;
  83. if ((mac->mpib.macBattLifeExt)&&(BE > 2))
  84. BE = 2;
  85. }
  86. else
  87. {
  88. NB = 0;
  89. BE = mac->mpib.macMinBE;
  90. }
  91. }
  92. double CsmaCA802_15_4::adjustTime(double wtime)
  93. {
  94. //find the beginning point of CAP and adjust the scheduled time
  95. //if it comes before CAP
  96. double neg;
  97. double tmpf;
  98. assert(txPkt);
  99. if (!mac->toParent(txPkt))
  100. {
  101. if (mac->mpib.macBeaconOrder != 15)
  102. {
  103. /* Linux floating number compatibility
  104. neg = (CURRENT_TIME + wtime - bcnTxTime) - mac->beaconPeriods * bPeriod;
  105. */
  106. {
  107. tmpf = mac->beaconPeriods * bPeriod;
  108. tmpf = CURRENT_TIME - tmpf;
  109. tmpf += wtime;
  110. neg = tmpf - bcnTxTime;
  111. }
  112. if (neg < 0.0)
  113. wtime -= neg;
  114. return wtime;
  115. }
  116. else
  117. return wtime;
  118. }
  119. else
  120. {
  121. if (mac->macBeaconOrder2 != 15)
  122. {
  123. /* Linux floating number compatibility
  124. neg = (CURRENT_TIME + wtime - bcnRxTime) - mac->beaconPeriods2 * bPeriod;
  125. */
  126. {
  127. tmpf = mac->beaconPeriods2 * bPeriod;
  128. tmpf = CURRENT_TIME - tmpf;
  129. tmpf += wtime;
  130. neg = tmpf - bcnRxTime;
  131. }
  132. if (neg < 0.0)
  133. wtime -= neg;
  134. return wtime;
  135. }
  136. else
  137. return wtime;
  138. }
  139. }
  140. bool CsmaCA802_15_4::canProceed(double wtime, bool afterCCA)
  141. {
  142. //check if can proceed within the current superframe
  143. //(in the case the node acts as both a coordinator and a device, both the superframes from and to this node should be taken into account)
  144. bool ok;
  145. UINT_16 t_bPeriods,t_CAP;
  146. double t_fCAP,t_CCATime,t_IFS,t_transacTime,bcnOtherTime,BI2;
  147. waitNextBeacon = false;
  148. wtime = mac->locateBoundary(mac->toParent(txPkt),wtime);
  149. if (!mac->toParent(txPkt))
  150. {
  151. if (mac->mpib.macBeaconOrder != 15)
  152. {
  153. if (mac->sfSpec.BLE)
  154. t_CAP = mac->getBattLifeExtSlotNum();
  155. else
  156. t_CAP = (mac->sfSpec.FinCAP + 1) * (mac->sfSpec.sd / aUnitBackoffPeriod) - mac->beaconPeriods; //(mac->sfSpec.sd % aUnitBackoffPeriod) = 0
  157. /* Linux floating number compatibility
  158. t_bPeriods = (UINT_16)(((CURRENT_TIME + wtime - bcnTxTime) / bPeriod) - mac->beaconPeriods);
  159. */
  160. {
  161. double tmpf;
  162. tmpf = CURRENT_TIME + wtime;
  163. tmpf -= bcnTxTime;
  164. tmpf /= bPeriod;
  165. t_bPeriods = (UINT_16)(tmpf - mac->beaconPeriods);
  166. }
  167. /* Linux floating number compatibility
  168. if (fmod(CURRENT_TIME + wtime - bcnTxTime, bPeriod) > 0.0)
  169. */
  170. double tmpf;
  171. tmpf = CURRENT_TIME + wtime;
  172. tmpf -= bcnTxTime;
  173. if (fmod(tmpf, bPeriod) > 0.0)
  174. t_bPeriods++;
  175. bPeriodsLeft = t_bPeriods - t_CAP;
  176. }
  177. else
  178. bPeriodsLeft = -1;
  179. }
  180. else
  181. {
  182. if (mac->macBeaconOrder2 != 15)
  183. {
  184. BI2 = mac->sfSpec2.BI / phy->getRate('s');
  185. /* Linux floating number compatibility
  186. t_CAP = (UINT_16)((mac->macBcnRxTime + (mac->sfSpec2.FinCAP + 1) * mac->sfSpec2.sd ) / phy->getRate('s'));
  187. */
  188. {
  189. double tmpf;
  190. tmpf = (mac->sfSpec2.FinCAP + 1) * mac->sfSpec2.sd;
  191. tmpf += mac->macBcnRxTime;
  192. t_CAP = (UINT_16)(tmpf / phy->getRate('s'));
  193. }
  194. /* Linux floating number compatibility
  195. if (t_CAP + aMaxLostBeacons * BI2 < CURRENT_TIME)
  196. */
  197. double tmpf;
  198. tmpf = aMaxLostBeacons * BI2;
  199. if (t_CAP + tmpf < CURRENT_TIME)
  200. bPeriodsLeft = -1;
  201. else
  202. {
  203. if (mac->sfSpec2.BLE)
  204. t_CAP = mac->getBattLifeExtSlotNum();
  205. else
  206. t_CAP = (mac->sfSpec2.FinCAP + 1) * (mac->sfSpec2.sd / aUnitBackoffPeriod) - mac->beaconPeriods2;
  207. /* Linux floating number compatibility
  208. t_bPeriods = (UINT_16)(((CURRENT_TIME + wtime - bcnRxTime) / bPeriod) - mac->beaconPeriods2);
  209. */
  210. {
  211. double tmpf;
  212. tmpf = CURRENT_TIME + wtime;
  213. tmpf -= bcnRxTime;
  214. tmpf /= bPeriod;
  215. t_bPeriods = (UINT_16)(tmpf - mac->beaconPeriods2);
  216. }
  217. /* Linux floating number compatibility
  218. if (fmod(CURRENT_TIME + wtime - bcnRxTime, bPeriod) > 0.0)
  219. */
  220. double tmpf;
  221. tmpf = CURRENT_TIME + wtime;
  222. tmpf -= bcnRxTime;
  223. if (fmod(tmpf, bPeriod) > 0.0)
  224. t_bPeriods++;
  225. bPeriodsLeft = t_bPeriods - t_CAP;
  226. }
  227. }
  228. else
  229. bPeriodsLeft = -1;
  230. }
  231. ok = true;
  232. if (bPeriodsLeft > 0)
  233. ok = false;
  234. else if (bPeriodsLeft == 0)
  235. {
  236. if ((!mac->toParent(txPkt))
  237. &&  (!mac->sfSpec.BLE))
  238. ok = false;
  239. else if ((mac->toParent(txPkt))
  240. &&  (!mac->sfSpec2.BLE))
  241. ok = false;
  242. }
  243. if (!ok)
  244. {
  245. #ifdef DEBUG802_15_4
  246. fprintf(stdout,"[%s::%s][%f](node %d) cannot proceed: bPeriodsLeft = %d, orders = %d/%d/%d, type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %dn",__FILE__,__FUNCTION__,CURRENT_TIME,mac->index_,bPeriodsLeft,mac->mpib.macBeaconOrder,mac->macBeaconOrder2,mac->macBeaconOrder3,wpan_pName(txPkt),p802_15_4macSA(txPkt),p802_15_4macDA(txPkt),ch->uid(),HDR_LRWPAN(txPkt)->uid,ch->size());
  247. #endif
  248. if (mac->macBeaconOrder2 != 15)
  249. if (!mac->bcnRxT->busy())
  250. mac->bcnRxT->start();
  251. waitNextBeacon = true;
  252. return false;
  253. }
  254. //calculate the time needed to finish the transaction
  255. t_CCATime = 8 / phy->getRate('s');
  256. if (HDR_CMN(txPkt)->size() <= aMaxSIFSFrameSize)
  257. t_IFS = aMinSIFSPeriod;
  258. else
  259. t_IFS = aMinLIFSPeriod;
  260. t_IFS /= phy->getRate('s');
  261. t_transacTime  = mac->locateBoundary(mac->toParent(txPkt),wtime) - wtime; //boundary location time -- should be 0 here, since we have already located the boundary
  262. if (!afterCCA)
  263. {
  264. t_transacTime += t_CCATime; //first CCA time
  265. t_transacTime += mac->locateBoundary(mac->toParent(txPkt),t_transacTime) - (t_transacTime); //boundary location time for second CCA
  266. t_transacTime += t_CCATime; //second CCA time
  267. }
  268. t_transacTime += mac->locateBoundary(mac->toParent(txPkt),t_transacTime) - (t_transacTime); //boundary location time for transmission
  269. t_transacTime += phy->trxTime(txPkt); //packet transmission time
  270. if (ackReq)
  271. {
  272. t_transacTime += mac->mpib.macAckWaitDuration/phy->getRate('s'); //ack. waiting time (this value does not include round trip propagation delay)
  273. t_transacTime += 2*max_pDelay; //round trip propagation delay (802.15.4 ignores this, but it should be there even though it is very small)
  274. t_transacTime += t_IFS; //IFS time -- not only ensure that the sender can finish the transaction, but also the receiver
  275. t_fCAP = mac->getCAP(true);
  276. /* Linux floating number compatibility
  277. if (CURRENT_TIME + wtime + t_transacTime > t_fCAP)
  278. */
  279. double tmpf;
  280. tmpf = CURRENT_TIME + wtime;
  281. tmpf += t_transacTime;
  282. if (tmpf > t_fCAP)
  283. ok = false;
  284. else
  285. ok= true;
  286. }
  287. else
  288. {
  289. //in this case, we need to handle individual CAP 
  290. ok = true;
  291. t_fCAP = mac->getCAPbyType(1);
  292. /* Linux floating number compatibility
  293. if (CURRENT_TIME + wtime + t_transacTime > t_fCAP)
  294. */
  295. double tmpf;
  296. tmpf = CURRENT_TIME + wtime;
  297. tmpf += t_transacTime;
  298. if (tmpf > t_fCAP)
  299. ok = false;
  300. if (ok)
  301. {
  302. t_fCAP = mac->getCAPbyType(2);
  303. t_transacTime += max_pDelay; //one-way trip propagation delay (802.15.4 ignores this, but it should be there even though it is very small)
  304. t_transacTime += 12/phy->getRate('s'); //transceiver turn-around time (receiver may need to do this to transmit next beacon)
  305. t_transacTime += t_IFS; //IFS time -- not only ensure that the sender can finish the transaction, but also the receiver
  306. /* Linux floating number compatibility
  307. if (CURRENT_TIME + wtime + t_transacTime > t_fCAP)
  308. */
  309. double tmpf;
  310. tmpf = CURRENT_TIME + wtime;
  311. tmpf += t_transacTime;
  312. if (tmpf > t_fCAP)
  313. ok = false;
  314. }
  315. if (ok)
  316. {
  317. t_fCAP = mac->getCAPbyType(3);
  318. t_transacTime -= t_IFS; //the third node does not need to handle the transaction
  319. /* Linux floating number compatibility
  320. if (CURRENT_TIME + wtime + t_transacTime > t_fCAP)
  321. */
  322. double tmpf;
  323. tmpf = CURRENT_TIME + wtime;
  324. tmpf += t_transacTime;
  325. if (tmpf > t_fCAP)
  326. ok = false;
  327. }
  328. }
  329. //check if have enough CAP to finish the transaction
  330. if (!ok)
  331. {
  332. bPeriodsLeft = 0;
  333. if ((mac->mpib.macBeaconOrder == 15)
  334. &&  (mac->macBeaconOrder2 == 15)
  335. &&  (mac->macBeaconOrder3 != 15))
  336. {
  337. /* Linux floating number compatibility
  338. bcnOtherTime = (mac->macBcnOtherRxTime + mac->sfSpec3.BI) / phy->getRate('s');
  339. */
  340. {
  341. double tmpf;
  342. tmpf = (mac->macBcnOtherRxTime + mac->sfSpec3.BI);
  343. bcnOtherTime = tmpf / phy->getRate('s');
  344. }
  345. while (bcnOtherTime < CURRENT_TIME)
  346. bcnOtherTime += (mac->sfSpec3.BI / phy->getRate('s'));
  347. bcnOtherT->start(bcnOtherTime - CURRENT_TIME);
  348. }
  349. #ifdef DEBUG802_15_4
  350. fprintf(stdout,"[%s::%s][%f](node %d) cannot proceed: orders = %d/%d/%d, type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %dn",__FILE__,__FUNCTION__,CURRENT_TIME,mac->index_,mac->mpib.macBeaconOrder,mac->macBeaconOrder2,mac->macBeaconOrder3,wpan_pName(txPkt),p802_15_4macSA(txPkt),p802_15_4macDA(txPkt),ch->uid(),HDR_LRWPAN(txPkt)->uid,ch->size());
  351. #endif
  352. if (mac->macBeaconOrder2 != 15)
  353. if (!mac->bcnRxT->busy())
  354. mac->bcnRxT->start();
  355. waitNextBeacon = true;
  356. return false;
  357. }
  358. else
  359. {
  360. bPeriodsLeft = -1;
  361. return true;
  362. }
  363. }
  364. void CsmaCA802_15_4::newBeacon(char trx)
  365. {
  366. //this function will be called by MAC each time a new beacon received or sent within the current PAN
  367. double rate,wtime;
  368. if (!mac->txAck)
  369. mac->plme_set_trx_state_request(p_RX_ON);
  370. if (bcnOtherT->busy())
  371. bcnOtherT->stop();
  372. //update values
  373. beaconEnabled = ((mac->mpib.macBeaconOrder != 15)||(mac->macBeaconOrder2 != 15));
  374. beaconOther = (mac->macBeaconOrder3 != 15);
  375. reset();
  376. rate = phy->getRate('s');
  377. bcnTxTime = mac->macBcnTxTime / rate;
  378. bcnRxTime = mac->macBcnRxTime / rate;
  379. bPeriod = aUnitBackoffPeriod / rate;
  380. if (waitNextBeacon)
  381. if ((txPkt)
  382.         && (!backoffT->busy()))
  383. {
  384. assert(bPeriodsLeft >= 0);
  385. if (bPeriodsLeft == 0)
  386. {
  387. wtime = adjustTime(0.0);
  388. if (canProceed(wtime));
  389. backoffHandler(); //no need to resume backoff
  390. }
  391. else
  392. {
  393. wtime = adjustTime(0.0);
  394. wtime += bPeriodsLeft * bPeriod;
  395. if (canProceed(wtime));
  396. backoffT->start(wtime);
  397. }
  398. }
  399. waitNextBeacon = false;
  400. }
  401. void CsmaCA802_15_4::start(bool firsttime,Packet *pkt,bool ackreq)
  402. {
  403. bool backoff;
  404. double rate,wtime,BI2;
  405. if (mac->txAck)
  406. {
  407. mac->backoffStatus = 0;
  408. txPkt = 0;
  409. return;
  410. }
  411. assert(backoffT->busy() == 0);
  412. if (firsttime)
  413. {
  414. beaconEnabled = ((mac->mpib.macBeaconOrder != 15)||(mac->macBeaconOrder2 != 15));
  415. beaconOther = (mac->macBeaconOrder3 != 15);
  416. reset();
  417. assert(txPkt == 0);
  418. txPkt = pkt;
  419. ackReq = ackreq;
  420. rate = phy->getRate('s');
  421. bPeriod = aUnitBackoffPeriod / rate;
  422. if (beaconEnabled)
  423. {
  424. bcnTxTime = mac->macBcnTxTime / rate;
  425. bcnRxTime = mac->macBcnRxTime / rate;
  426. //it's possible we missed some beacons
  427. BI2 = (mac->sfSpec2.BI / phy->getRate('s'));
  428. if (mac->macBeaconOrder2 != 15)
  429. while (bcnRxTime + BI2 < CURRENT_TIME)
  430. bcnRxTime += BI2;
  431. }
  432. }
  433. wtime = (Random::random() % (1<<BE)) * bPeriod;
  434. #ifdef SHUTDOWN
  435. if (BE == mac->mpib.macMinBE)
  436. wtime=MAX(wtime,ceil(phy->T_transition_local_/bPeriod)*bPeriod); // 2.31 change: added this to take care of sleep-idle ramp-up
  437. #endif
  438. wtime = adjustTime(wtime);
  439. backoff = true;
  440. if (beaconEnabled||beaconOther)
  441. {
  442. if (beaconEnabled)
  443. if (firsttime)
  444. wtime = mac->locateBoundary(mac->toParent(txPkt),wtime);
  445. if (!canProceed(wtime))
  446. backoff = false;
  447. }
  448. if (backoff)
  449. backoffT->start(wtime);
  450. }
  451. void CsmaCA802_15_4::cancel(void)
  452. {
  453. if (bcnOtherT->busy())
  454. bcnOtherT->stop();
  455. else if (backoffT->busy())
  456. backoffT->stop();
  457. else if (deferCCAT->busy())
  458. deferCCAT->stop();
  459. else
  460. mac->taskP.taskStatus(TP_CCA_csmaca) = false;
  461. txPkt = 0;
  462. }
  463. void CsmaCA802_15_4::backoffHandler(void)
  464. {
  465. mac->taskP.taskStatus(TP_RX_ON_csmaca) = true;
  466. mac->plme_set_trx_state_request(p_RX_ON);
  467. }
  468. void CsmaCA802_15_4::RX_ON_confirm(PHYenum status)
  469. {
  470. double now,wtime;
  471. if (status != p_RX_ON)
  472. {
  473. if (status == p_BUSY_TX)
  474. mac->taskP.taskStatus(TP_RX_ON_csmaca) = true;
  475. else
  476. backoffHandler();
  477. return;
  478. }
  479. //locate backoff boundary if needed
  480. now = CURRENT_TIME;
  481. if (beaconEnabled)
  482. wtime = mac->locateBoundary(mac->toParent(txPkt),0.0);
  483. else
  484. wtime = 0.0;
  485. if (wtime == 0.0)
  486. {
  487. mac->taskP.taskStatus(TP_CCA_csmaca) = true;
  488. phy->PLME_CCA_request();
  489. }
  490. else
  491. deferCCAT->start(wtime);
  492. }
  493. void CsmaCA802_15_4::bcnOtherHandler(void)
  494. {
  495. newBeacon('R');
  496. }
  497. void CsmaCA802_15_4::deferCCAHandler(void)
  498. {
  499. mac->taskP.taskStatus(TP_CCA_csmaca) = true;
  500. phy->PLME_CCA_request();
  501. }
  502. void CsmaCA802_15_4::CCA_confirm(PHYenum status)
  503. {
  504. //This function should be called when mac receiving CCA_confirm.
  505. bool idle;
  506. idle = (status == p_IDLE)?1:0;
  507. if (idle)
  508. {
  509. if ((!beaconEnabled)&&(!beaconOther))
  510. {
  511. txPkt = 0;
  512. mac->csmacaCallBack(p_IDLE);
  513. }
  514. else
  515. {
  516. if (beaconEnabled)
  517. CW--;
  518. else
  519. CW = 0;
  520. if (CW == 0)
  521. {
  522. //timing condition may not still hold -- check again
  523. if (canProceed(0.0, true))
  524. {
  525. txPkt = 0;
  526. mac->csmacaCallBack(p_IDLE);
  527. }
  528. else //postpone until next beacon sent or received
  529. {
  530. if (beaconEnabled) CW = 2;
  531. bPeriodsLeft = 0;
  532. }
  533. }
  534. else //perform CCA again
  535. backoffHandler();
  536. }
  537. }
  538. else //busy
  539. {
  540. if (beaconEnabled) CW = 2;
  541. NB++;
  542. if (NB > mac->mpib.macMaxCSMABackoffs)
  543. {
  544. txPkt = 0;
  545. mac->csmacaCallBack(p_BUSY);
  546. }
  547. else //backoff again
  548. {
  549. BE++;
  550. if (BE > aMaxBE)
  551. BE = aMaxBE;
  552. start(false);
  553. }
  554. }
  555. }
  556. // End of file: p802_15_4csmaca.cc