PageRenderTime 54ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/ns-allinone-3.14.1/ns-3.14.1/src/uan/model/uan-mac-rc.cc

https://bitbucket.org/hbhzwj/imalse
C++ | 772 lines | 652 code | 97 blank | 23 comment | 81 complexity | 2aa2ff9872bea6ae86204904193ccd61 MD5 | raw file
Possible License(s): GPL-3.0, BSD-2-Clause, GPL-2.0, LGPL-2.1, 0BSD
  1. /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
  2. /*
  3. * Copyright (c) 2009 University of Washington
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation;
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. *
  18. * Author: Leonard Tracy <lentracy@gmail.com>
  19. */
  20. #include "uan-mac-rc.h"
  21. #include "uan-header-rc.h"
  22. #include "uan-tx-mode.h"
  23. #include "uan-phy.h"
  24. #include "uan-header-common.h"
  25. #include "uan-phy-dual.h"
  26. #include "ns3/log.h"
  27. #include "ns3/nstime.h"
  28. #include "ns3/simulator.h"
  29. #include "ns3/random-variable.h"
  30. #include "ns3/assert.h"
  31. #include "ns3/double.h"
  32. #include "ns3/uinteger.h"
  33. #include <list>
  34. #include <utility>
  35. NS_LOG_COMPONENT_DEFINE ("UanMacRc");
  36. namespace ns3 {
  37. NS_OBJECT_ENSURE_REGISTERED (UanMacRc);
  38. Reservation::Reservation ()
  39. : m_length (0),
  40. m_frameNo (0),
  41. m_retryNo (0),
  42. m_transmitted (false)
  43. {
  44. }
  45. Reservation::Reservation (std::list<std::pair <Ptr<Packet>, UanAddress > > &list, uint8_t frameNo, uint32_t maxPkts)
  46. : m_frameNo (frameNo),
  47. m_retryNo (0),
  48. m_transmitted (false)
  49. {
  50. uint32_t numPkts = (maxPkts) ? maxPkts : list.size ();
  51. uint32_t length = 0;
  52. UanHeaderRcData dh;
  53. UanHeaderCommon ch;
  54. for (uint32_t i = 0; i < numPkts; i++)
  55. {
  56. length += list.front ().first->GetSize () +
  57. ch.GetSerializedSize () +
  58. dh.GetSerializedSize ();
  59. m_pktList.push_back (list.front ());
  60. list.pop_front ();
  61. }
  62. m_length = length;
  63. }
  64. Reservation::~Reservation ()
  65. {
  66. std::list<std::pair <Ptr<Packet>, UanAddress > >::iterator it;
  67. for (it = m_pktList.begin (); it != m_pktList.end (); it++)
  68. {
  69. it->first = Ptr<Packet> ((Packet *) 0);
  70. }
  71. m_pktList.clear ();
  72. m_timestamp.clear ();
  73. }
  74. uint32_t
  75. Reservation::GetNoFrames () const
  76. {
  77. return m_pktList.size ();
  78. }
  79. uint32_t
  80. Reservation::GetLength () const
  81. {
  82. return m_length;
  83. }
  84. const std::list<std::pair <Ptr<Packet>, UanAddress > > &
  85. Reservation::GetPktList (void) const
  86. {
  87. return m_pktList;
  88. }
  89. uint8_t
  90. Reservation::GetFrameNo () const
  91. {
  92. return m_frameNo;
  93. }
  94. uint8_t
  95. Reservation::GetRetryNo () const
  96. {
  97. return m_retryNo;
  98. }
  99. Time
  100. Reservation::GetTimestamp (uint8_t n) const
  101. {
  102. return m_timestamp[n];
  103. }
  104. bool
  105. Reservation::IsTransmitted () const
  106. {
  107. return m_transmitted;
  108. }
  109. void
  110. Reservation::SetFrameNo (uint8_t fn)
  111. {
  112. m_frameNo = fn;
  113. }
  114. void
  115. Reservation::AddTimestamp (Time t)
  116. {
  117. m_timestamp.push_back (t);
  118. }
  119. void
  120. Reservation::IncrementRetry ()
  121. {
  122. m_retryNo++;
  123. }
  124. void
  125. Reservation::SetTransmitted (bool t)
  126. {
  127. m_transmitted = true;
  128. }
  129. uint32_t UanMacRc::m_cntrlSends = 0;
  130. UanMacRc::UanMacRc ()
  131. : UanMac (),
  132. m_state (UNASSOCIATED),
  133. m_rtsBlocked (false),
  134. m_currentRate (10),
  135. m_frameNo (0),
  136. m_cleared (false)
  137. {
  138. UanHeaderCommon ch;
  139. UanHeaderRcCts ctsh;
  140. UanHeaderRcCtsGlobal ctsg;
  141. m_ctsSizeN = ctsh.GetSerializedSize ();
  142. m_ctsSizeG = ch.GetSerializedSize () + ctsg.GetSerializedSize ();
  143. }
  144. UanMacRc::~UanMacRc ()
  145. {
  146. }
  147. void
  148. UanMacRc::Clear ()
  149. {
  150. if (m_cleared)
  151. {
  152. return;
  153. }
  154. m_cleared = true;
  155. if (m_phy)
  156. {
  157. m_phy->Clear ();
  158. m_phy = 0;
  159. }
  160. std::list<std::pair <Ptr<Packet>, UanAddress > >::iterator it;
  161. for (it = m_pktQueue.begin (); it != m_pktQueue.end (); it++)
  162. {
  163. it->first = 0;
  164. }
  165. m_pktQueue.clear ();
  166. m_resList.clear ();
  167. m_startAgain.Cancel ();
  168. m_rtsEvent.Cancel ();
  169. }
  170. void
  171. UanMacRc::DoDispose ()
  172. {
  173. Clear ();
  174. UanMac::DoDispose ();
  175. }
  176. TypeId
  177. UanMacRc::GetTypeId (void)
  178. {
  179. static TypeId tid = TypeId ("ns3::UanMacRc")
  180. .SetParent<UanMac> ()
  181. .AddConstructor<UanMacRc> ()
  182. .AddAttribute ("RetryRate",
  183. "Number of retry attempts per second (of RTS/GWPING)",
  184. DoubleValue (1 / 5.0),
  185. MakeDoubleAccessor (&UanMacRc::m_retryRate),
  186. MakeDoubleChecker<double> ())
  187. .AddAttribute ("MaxFrames",
  188. "Maximum number of frames to include in a single RTS",
  189. UintegerValue (1),
  190. MakeUintegerAccessor (&UanMacRc::m_maxFrames),
  191. MakeUintegerChecker<uint32_t> ())
  192. .AddAttribute ("QueueLimit",
  193. "Maximum packets to queue at MAC",
  194. UintegerValue (10),
  195. MakeUintegerAccessor (&UanMacRc::m_queueLimit),
  196. MakeUintegerChecker<uint32_t> ())
  197. .AddAttribute ("SIFS",
  198. "Spacing to give between frames (this should match gateway)",
  199. TimeValue (Seconds (0.2)),
  200. MakeTimeAccessor (&UanMacRc::m_sifs),
  201. MakeTimeChecker ())
  202. .AddAttribute ("NumberOfRates",
  203. "Number of rate divisions supported by each PHY",
  204. UintegerValue (0),
  205. MakeUintegerAccessor (&UanMacRc::m_numRates),
  206. MakeUintegerChecker<uint32_t> ())
  207. .AddAttribute ("MinRetryRate",
  208. "Smallest allowed RTS retry rate",
  209. DoubleValue (0.01),
  210. MakeDoubleAccessor (&UanMacRc::m_minRetryRate),
  211. MakeDoubleChecker<double> ())
  212. .AddAttribute ("RetryStep",
  213. "Retry rate increment",
  214. DoubleValue (0.01),
  215. MakeDoubleAccessor (&UanMacRc::m_retryStep),
  216. MakeDoubleChecker<double> ())
  217. .AddAttribute ("NumberOfRetryRates",
  218. "Number of retry rates",
  219. UintegerValue (100),
  220. MakeUintegerAccessor (&UanMacRc::m_numRetryRates),
  221. MakeUintegerChecker<uint16_t> ())
  222. .AddAttribute ("MaxPropDelay",
  223. "Maximum possible propagation delay to gateway",
  224. TimeValue (Seconds (2)),
  225. MakeTimeAccessor (&UanMacRc::m_learnedProp),
  226. MakeTimeChecker ())
  227. .AddTraceSource ("Enqueue",
  228. "A (data) packet arrived at MAC for transmission",
  229. MakeTraceSourceAccessor (&UanMacRc::m_enqueueLogger))
  230. .AddTraceSource ("Dequeue",
  231. "A (data) packet was passed down to PHY from MAC",
  232. MakeTraceSourceAccessor (&UanMacRc::m_dequeueLogger))
  233. .AddTraceSource ("RX",
  234. "A packet was destined for and received at this MAC layer",
  235. MakeTraceSourceAccessor (&UanMacRc::m_rxLogger))
  236. ;
  237. return tid;
  238. }
  239. Address
  240. UanMacRc::GetAddress (void)
  241. {
  242. return m_address;
  243. }
  244. void
  245. UanMacRc::SetAddress (UanAddress addr)
  246. {
  247. m_address = addr;
  248. }
  249. bool
  250. UanMacRc::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
  251. {
  252. if (protocolNumber > 0)
  253. {
  254. NS_LOG_WARN ("Warning: UanMacRc does not support multiple protocols. protocolNumber argument to Enqueue is being ignored");
  255. }
  256. if (m_pktQueue.size () >= m_queueLimit)
  257. {
  258. return false;
  259. }
  260. m_pktQueue.push_back (std::make_pair (packet, UanAddress::ConvertFrom (dest)));
  261. switch (m_state)
  262. {
  263. case UNASSOCIATED:
  264. Associate ();
  265. return true;
  266. case IDLE:
  267. if (!m_rtsEvent.IsRunning ())
  268. {
  269. SendRts ();
  270. }
  271. return true;
  272. case GWPSENT:
  273. case RTSSENT:
  274. case DATATX:
  275. return true;
  276. }
  277. return true;
  278. }
  279. void
  280. UanMacRc::SetForwardUpCb (Callback<void, Ptr<Packet>, const UanAddress&> cb)
  281. {
  282. m_forwardUpCb = cb;
  283. }
  284. void
  285. UanMacRc::AttachPhy (Ptr<UanPhy> phy)
  286. {
  287. m_phy = phy;
  288. m_phy->SetReceiveOkCallback (MakeCallback (&UanMacRc::ReceiveOkFromPhy, this));
  289. }
  290. Address
  291. UanMacRc::GetBroadcast (void) const
  292. {
  293. return UanAddress::GetBroadcast ();
  294. }
  295. void
  296. UanMacRc::ReceiveOkFromPhy (Ptr<Packet> pkt, double sinr, UanTxMode mode)
  297. {
  298. UanHeaderCommon ch;
  299. pkt->RemoveHeader (ch);
  300. if (ch.GetDest () == m_address || ch.GetDest () == UanAddress::GetBroadcast ())
  301. {
  302. m_rxLogger (pkt, mode);
  303. }
  304. switch (ch.GetType ())
  305. {
  306. case TYPE_DATA:
  307. if (ch.GetDest () == m_address)
  308. {
  309. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " UanMacRc Receiving DATA packet from PHY");
  310. UanHeaderRcData dh;
  311. pkt->RemoveHeader (dh);
  312. m_forwardUpCb (pkt, ch.GetSrc ());
  313. }
  314. break;
  315. case TYPE_RTS:
  316. // Currently don't respond to RTS packets at non-gateway nodes
  317. // (Code assumes single network neighberhood)
  318. break;
  319. case TYPE_CTS:
  320. {
  321. uint32_t ctsBytes = ch.GetSerializedSize () + pkt->GetSize ();
  322. m_assocAddr = ch.GetSrc ();
  323. UanHeaderRcCtsGlobal ctsg;
  324. pkt->RemoveHeader (ctsg);
  325. m_currentRate = ctsg.GetRateNum ();
  326. m_retryRate = m_minRetryRate + m_retryStep*ctsg.GetRetryRate ();
  327. UanHeaderRcRts rhtmp;
  328. Time winDelay = ctsg.GetWindowTime ();
  329. if (winDelay.GetSeconds () > 0)
  330. {
  331. m_rtsBlocked = false;
  332. Simulator::Schedule (winDelay, &UanMacRc::BlockRtsing, this);
  333. }
  334. else
  335. {
  336. NS_FATAL_ERROR (Simulator::Now ().GetSeconds () << " Node " << m_address << " Received window period < 0");
  337. }
  338. UanHeaderRcCts ctsh;
  339. ctsh.SetAddress (UanAddress::GetBroadcast ());
  340. while (pkt->GetSize () > 0)
  341. {
  342. pkt->RemoveHeader (ctsh);
  343. if (ctsh.GetAddress () == m_address)
  344. {
  345. if (m_state == GWPSENT)
  346. {
  347. m_assocAddr = ch.GetSrc ();
  348. ScheduleData (ctsh, ctsg, ctsBytes);
  349. }
  350. else if (m_state == RTSSENT)
  351. {
  352. ScheduleData (ctsh, ctsg, ctsBytes);
  353. }
  354. else
  355. {
  356. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS while state != RTSSENT or GWPING");
  357. }
  358. }
  359. }
  360. }
  361. break;
  362. case TYPE_GWPING:
  363. // Do not respond to GWPINGS at non-gateway nodes
  364. break;
  365. case TYPE_ACK:
  366. m_rtsBlocked = true;
  367. if (ch.GetDest () != m_address)
  368. {
  369. return;
  370. }
  371. ProcessAck (pkt);
  372. break;
  373. default:
  374. NS_FATAL_ERROR ("Unknown packet type " << ch.GetType () << " received at node " << GetAddress ());
  375. }
  376. }
  377. void
  378. UanMacRc::ScheduleData (const UanHeaderRcCts &ctsh, const UanHeaderRcCtsGlobal &ctsg, uint32_t ctsBytes)
  379. {
  380. NS_ASSERT (m_state == RTSSENT || m_state == GWPSENT);
  381. std::list<Reservation>::iterator it = m_resList.begin ();
  382. for (; it != m_resList.end (); it++)
  383. {
  384. if (it->GetFrameNo () == ctsh.GetFrameNo ())
  385. {
  386. break;
  387. }
  388. }
  389. if (it == m_resList.end ())
  390. {
  391. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS packet with no corresponding reservation!");
  392. return;
  393. }
  394. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS packet. Scheduling data");
  395. it->SetTransmitted ();
  396. double currentBps = m_phy->GetMode (m_currentRate).GetDataRateBps ();
  397. m_learnedProp = Simulator::Now () - ctsg.GetTxTimeStamp () - Seconds (ctsBytes * 8.0 / currentBps);
  398. Time arrTime = ctsg.GetTxTimeStamp () + ctsh.GetDelayToTx ();
  399. Time txTime = arrTime - m_learnedProp;
  400. Time startDelay = txTime - Simulator::Now ();
  401. Time frameDelay = Seconds (0);
  402. const std::list<std::pair <Ptr<Packet>, UanAddress > > l = it->GetPktList ();
  403. std::list<std::pair <Ptr<Packet>, UanAddress > >::const_iterator pit;
  404. pit = l.begin ();
  405. for (uint32_t i = 0; i < it->GetNoFrames (); i++, pit++)
  406. {
  407. Ptr<Packet> pkt = (*pit).first->Copy ();
  408. UanHeaderRcData dh;
  409. dh.SetFrameNo (i);
  410. dh.SetPropDelay (m_learnedProp);
  411. pkt->AddHeader (dh);
  412. UanHeaderCommon ch;
  413. ch.SetType (TYPE_DATA);
  414. ch.SetDest (m_assocAddr);
  415. ch.SetSrc (m_address);
  416. pkt->AddHeader (ch);
  417. Time eventTime = startDelay + frameDelay;
  418. if (eventTime.GetSeconds () < 0)
  419. {
  420. if (eventTime.GetSeconds () > -0.001)
  421. {
  422. eventTime = Seconds (0);
  423. }
  424. else
  425. {
  426. NS_FATAL_ERROR ("Scheduling error resulted in very negative data transmission time! eventTime = " << eventTime.GetSeconds ());
  427. }
  428. }
  429. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " scheduling with delay " << eventTime.GetSeconds () << " propDelay " << m_learnedProp.GetSeconds () << " start delay " << startDelay.GetSeconds () << " arrival time " << arrTime.GetSeconds ());
  430. Simulator::Schedule (eventTime, &UanMacRc::SendPacket, this, pkt, m_currentRate);
  431. frameDelay = frameDelay + m_sifs + Seconds (pkt->GetSize () / currentBps);
  432. }
  433. m_state = IDLE;
  434. if (!m_pktQueue.empty ())
  435. {
  436. if (m_rtsEvent.IsRunning ())
  437. {
  438. m_rtsEvent.Cancel ();
  439. }
  440. ExponentialVariable ev (1 / m_retryRate);
  441. double timeout = ev.GetValue ();
  442. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::SendRts, this);
  443. }
  444. }
  445. void
  446. UanMacRc::SendPacket (Ptr<Packet> pkt, uint32_t rate)
  447. {
  448. UanHeaderCommon ch;
  449. pkt->PeekHeader (ch);
  450. std::string type;
  451. switch (ch.GetType ())
  452. {
  453. case TYPE_DATA:
  454. type = "DATA";
  455. break;
  456. case TYPE_RTS:
  457. type = "RTS";
  458. break;
  459. case TYPE_CTS:
  460. type = "CTS";
  461. break;
  462. case TYPE_ACK:
  463. type = "ACK";
  464. break;
  465. case TYPE_GWPING:
  466. type = "GWPING";
  467. break;
  468. default:
  469. type = "UNKNOWN";
  470. break;
  471. }
  472. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " transmitting " << pkt->GetSize () << " byte packet of type " << type << " with rate " << rate << "(" << m_phy->GetMode (rate).GetDataRateBps () << ") to " << ch.GetDest ());
  473. m_dequeueLogger (pkt, rate);
  474. m_phy->SendPacket (pkt, rate);
  475. }
  476. void
  477. UanMacRc::ProcessAck (Ptr<Packet> ack)
  478. {
  479. UanHeaderRcAck ah;
  480. ack->RemoveHeader (ah);
  481. std::list<Reservation>::iterator it = m_resList.begin ();
  482. for (; it != m_resList.end (); it++)
  483. {
  484. if (it->GetFrameNo () == ah.GetFrameNo ())
  485. {
  486. break;
  487. }
  488. }
  489. if (it == m_resList.end ())
  490. {
  491. NS_LOG_DEBUG ("In " << __func__ << " could not find reservation corresponding to received ACK");
  492. return;
  493. }
  494. if (!it->IsTransmitted ())
  495. {
  496. return;
  497. }
  498. if (ah.GetNoNacks () > 0)
  499. {
  500. const std::list<std::pair <Ptr<Packet>, UanAddress > > l = it->GetPktList ();
  501. std::list<std::pair <Ptr<Packet>, UanAddress > >::const_iterator pit;
  502. pit = l.begin ();
  503. const std::set<uint8_t> &nacks = ah.GetNackedFrames ();
  504. std::set<uint8_t>::iterator nit = nacks.begin ();
  505. uint8_t pnum = 0;
  506. for (; nit != nacks.end (); nit++)
  507. {
  508. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " Received NACK for " << (uint32_t) *nit);
  509. while (pnum < *nit)
  510. {
  511. pit++;
  512. pnum++;
  513. }
  514. UanHeaderRcData dh;
  515. UanHeaderCommon ch;
  516. m_pktQueue.push_front (*pit);
  517. }
  518. }
  519. else
  520. {
  521. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received ACK for all frames");
  522. }
  523. m_resList.erase (it);
  524. }
  525. UanHeaderRcRts
  526. UanMacRc::CreateRtsHeader (const Reservation &res)
  527. {
  528. UanHeaderRcRts rh = UanHeaderRcRts ();
  529. rh.SetLength (res.GetLength ());
  530. rh.SetNoFrames (res.GetNoFrames ());
  531. rh.SetTimeStamp (res.GetTimestamp (res.GetRetryNo ()));
  532. rh.SetFrameNo (res.GetFrameNo ());
  533. rh.SetRetryNo (res.GetRetryNo ());
  534. return rh;
  535. }
  536. void
  537. UanMacRc::Associate (void)
  538. {
  539. m_cntrlSends++;
  540. Reservation res (m_pktQueue, m_frameNo, m_maxFrames);
  541. res.AddTimestamp (Simulator::Now ());
  542. m_frameNo++;
  543. m_resList.push_back (res);
  544. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  545. bool phy1ok = IsPhy1Ok ();
  546. if (phy1ok && !phyDual->IsPhy2Tx () & !m_rtsBlocked)
  547. {
  548. Ptr<Packet> pkt = Create<Packet> (0);
  549. pkt->AddHeader (CreateRtsHeader (res));
  550. pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_GWPING));
  551. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Sending first GWPING " << *pkt);
  552. SendPacket (pkt,m_currentRate + m_numRates);
  553. }
  554. m_state = GWPSENT;
  555. NS_ASSERT (!m_rtsEvent.IsRunning ());
  556. ExponentialVariable ev (1.0 / m_retryRate);
  557. double timeout = ev.GetValue ();
  558. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::AssociateTimeout, this);
  559. }
  560. void
  561. UanMacRc::AssociateTimeout ()
  562. {
  563. m_cntrlSends++;
  564. if (m_state != GWPSENT)
  565. {
  566. return;
  567. }
  568. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  569. bool phy1ok = IsPhy1Ok ();
  570. if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked)
  571. {
  572. Ptr<Packet> pkt = Create<Packet> ();
  573. Reservation res = m_resList.back ();
  574. m_resList.pop_back ();
  575. res.AddTimestamp (Simulator::Now ());
  576. res.IncrementRetry ();
  577. pkt->AddHeader (CreateRtsHeader (res));
  578. pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_GWPING));
  579. SendPacket (pkt,m_currentRate + m_numRates);
  580. m_resList.push_back (res);
  581. }
  582. NS_ASSERT (!m_rtsEvent.IsRunning ());
  583. ExponentialVariable ev (1.0 / m_retryRate);
  584. double timeout = ev.GetValue ();
  585. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::AssociateTimeout, this);
  586. }
  587. void
  588. UanMacRc::SendRts (void)
  589. {
  590. m_cntrlSends++;
  591. if (m_state == RTSSENT)
  592. {
  593. return;
  594. }
  595. NS_ASSERT (!m_pktQueue.empty ());
  596. Reservation res (m_pktQueue, m_frameNo, m_maxFrames);
  597. res.AddTimestamp (Simulator::Now ());
  598. m_frameNo++;
  599. m_resList.push_back (res);
  600. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  601. bool phy1ok = IsPhy1Ok ();
  602. if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked )
  603. {
  604. Ptr<Packet> pkt = Create<Packet> (0);
  605. pkt->AddHeader (CreateRtsHeader (res));
  606. pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_RTS));
  607. SendPacket (pkt,m_currentRate + m_numRates);
  608. }
  609. m_state = RTSSENT;
  610. NS_ASSERT (!m_rtsEvent.IsRunning ());
  611. ExponentialVariable ev (1.0 / m_retryRate);
  612. double timeout = ev.GetValue ();
  613. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::RtsTimeout, this);
  614. }
  615. // We assume here that packet types are known at detection.
  616. bool
  617. UanMacRc::IsPhy1Ok ()
  618. {
  619. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  620. bool phy1ok = true;
  621. if (phyDual->IsPhy1Rx ())
  622. {
  623. Ptr<Packet> pkt = phyDual->GetPhy1PacketRx ();
  624. UanHeaderCommon ch;
  625. pkt->PeekHeader (ch);
  626. if (ch.GetType () == TYPE_CTS || ch.GetType () == TYPE_ACK)
  627. {
  628. phy1ok = false;
  629. }
  630. else if (ch.GetDest () == m_address)
  631. {
  632. phy1ok = false;
  633. }
  634. }
  635. return phy1ok;
  636. }
  637. void
  638. UanMacRc::RtsTimeout (void)
  639. {
  640. m_cntrlSends++;
  641. if (m_state != RTSSENT)
  642. {
  643. return;
  644. }
  645. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  646. bool phy1ok = IsPhy1Ok ();
  647. if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked)
  648. {
  649. if (m_resList.empty ())
  650. {
  651. NS_FATAL_ERROR (Simulator::Now ().GetSeconds () << " Node " << m_address << " tried to retry RTS with empty reservation list");
  652. }
  653. Ptr<Packet> pkt = Create<Packet> (0);
  654. Reservation res = m_resList.back ();
  655. NS_ASSERT (!res.IsTransmitted ());
  656. m_resList.pop_back ();
  657. res.AddTimestamp (Simulator::Now ());
  658. res.IncrementRetry ();
  659. m_resList.push_back (res);
  660. pkt->AddHeader (CreateRtsHeader (res));
  661. pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_RTS));
  662. SendPacket (pkt,m_currentRate + m_numRates);
  663. }
  664. m_state = RTSSENT;
  665. NS_ASSERT (!m_rtsEvent.IsRunning ());
  666. ExponentialVariable ev (1.0 / m_retryRate);
  667. double timeout = ev.GetValue ();
  668. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::RtsTimeout, this);
  669. }
  670. void
  671. UanMacRc::BlockRtsing (void)
  672. {
  673. m_rtsBlocked = true;
  674. }
  675. } // namespace ns3