PageRenderTime 23ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/uan/model/uan-mac-rc.cc

https://bitbucket.org/cttc-lena/ns-3-lena-dev
C++ | 776 lines | 654 code | 99 blank | 23 comment | 81 complexity | 267b6e69d946e4df22715ae999ed4e0f MD5 | raw file
Possible License(s): GPL-2.0
  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/assert.h"
  30. #include "ns3/double.h"
  31. #include "ns3/uinteger.h"
  32. #include <list>
  33. #include <utility>
  34. NS_LOG_COMPONENT_DEFINE ("UanMacRc");
  35. namespace ns3 {
  36. NS_OBJECT_ENSURE_REGISTERED (UanMacRc);
  37. Reservation::Reservation ()
  38. : m_length (0),
  39. m_frameNo (0),
  40. m_retryNo (0),
  41. m_transmitted (false)
  42. {
  43. }
  44. Reservation::Reservation (std::list<std::pair <Ptr<Packet>, UanAddress > > &list, uint8_t frameNo, uint32_t maxPkts)
  45. : m_frameNo (frameNo),
  46. m_retryNo (0),
  47. m_transmitted (false)
  48. {
  49. uint32_t numPkts = (maxPkts) ? maxPkts : list.size ();
  50. uint32_t length = 0;
  51. UanHeaderRcData dh;
  52. UanHeaderCommon ch;
  53. for (uint32_t i = 0; i < numPkts; i++)
  54. {
  55. length += list.front ().first->GetSize () +
  56. ch.GetSerializedSize () +
  57. dh.GetSerializedSize ();
  58. m_pktList.push_back (list.front ());
  59. list.pop_front ();
  60. }
  61. m_length = length;
  62. }
  63. Reservation::~Reservation ()
  64. {
  65. std::list<std::pair <Ptr<Packet>, UanAddress > >::iterator it;
  66. for (it = m_pktList.begin (); it != m_pktList.end (); it++)
  67. {
  68. it->first = Ptr<Packet> ((Packet *) 0);
  69. }
  70. m_pktList.clear ();
  71. m_timestamp.clear ();
  72. }
  73. uint32_t
  74. Reservation::GetNoFrames () const
  75. {
  76. return m_pktList.size ();
  77. }
  78. uint32_t
  79. Reservation::GetLength () const
  80. {
  81. return m_length;
  82. }
  83. const std::list<std::pair <Ptr<Packet>, UanAddress > > &
  84. Reservation::GetPktList (void) const
  85. {
  86. return m_pktList;
  87. }
  88. uint8_t
  89. Reservation::GetFrameNo () const
  90. {
  91. return m_frameNo;
  92. }
  93. uint8_t
  94. Reservation::GetRetryNo () const
  95. {
  96. return m_retryNo;
  97. }
  98. Time
  99. Reservation::GetTimestamp (uint8_t n) const
  100. {
  101. return m_timestamp[n];
  102. }
  103. bool
  104. Reservation::IsTransmitted () const
  105. {
  106. return m_transmitted;
  107. }
  108. void
  109. Reservation::SetFrameNo (uint8_t fn)
  110. {
  111. m_frameNo = fn;
  112. }
  113. void
  114. Reservation::AddTimestamp (Time t)
  115. {
  116. m_timestamp.push_back (t);
  117. }
  118. void
  119. Reservation::IncrementRetry ()
  120. {
  121. m_retryNo++;
  122. }
  123. void
  124. Reservation::SetTransmitted (bool t)
  125. {
  126. m_transmitted = true;
  127. }
  128. uint32_t UanMacRc::m_cntrlSends = 0;
  129. UanMacRc::UanMacRc ()
  130. : UanMac (),
  131. m_state (UNASSOCIATED),
  132. m_rtsBlocked (false),
  133. m_currentRate (10),
  134. m_frameNo (0),
  135. m_cleared (false)
  136. {
  137. m_ev = CreateObject<ExponentialRandomVariable> ();
  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 ("MaxPropDelay",
  218. "Maximum possible propagation delay to gateway.",
  219. TimeValue (Seconds (2)),
  220. MakeTimeAccessor (&UanMacRc::m_learnedProp),
  221. MakeTimeChecker ())
  222. .AddTraceSource ("Enqueue",
  223. "A (data) packet arrived at MAC for transmission.",
  224. MakeTraceSourceAccessor (&UanMacRc::m_enqueueLogger))
  225. .AddTraceSource ("Dequeue",
  226. "A (data) packet was passed down to PHY from MAC.",
  227. MakeTraceSourceAccessor (&UanMacRc::m_dequeueLogger))
  228. .AddTraceSource ("RX",
  229. "A packet was destined for and received at this MAC layer.",
  230. MakeTraceSourceAccessor (&UanMacRc::m_rxLogger))
  231. ;
  232. return tid;
  233. }
  234. int64_t
  235. UanMacRc::AssignStreams (int64_t stream)
  236. {
  237. NS_LOG_FUNCTION (this << stream);
  238. m_ev->SetStream (stream);
  239. return 1;
  240. }
  241. Address
  242. UanMacRc::GetAddress (void)
  243. {
  244. return m_address;
  245. }
  246. void
  247. UanMacRc::SetAddress (UanAddress addr)
  248. {
  249. m_address = addr;
  250. }
  251. bool
  252. UanMacRc::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
  253. {
  254. if (protocolNumber > 0)
  255. {
  256. NS_LOG_WARN ("Warning: UanMacRc does not support multiple protocols. protocolNumber argument to Enqueue is being ignored");
  257. }
  258. if (m_pktQueue.size () >= m_queueLimit)
  259. {
  260. return false;
  261. }
  262. m_pktQueue.push_back (std::make_pair (packet, UanAddress::ConvertFrom (dest)));
  263. switch (m_state)
  264. {
  265. case UNASSOCIATED:
  266. Associate ();
  267. return true;
  268. case IDLE:
  269. if (!m_rtsEvent.IsRunning ())
  270. {
  271. SendRts ();
  272. }
  273. return true;
  274. case GWPSENT:
  275. case RTSSENT:
  276. case DATATX:
  277. return true;
  278. }
  279. return true;
  280. }
  281. void
  282. UanMacRc::SetForwardUpCb (Callback<void, Ptr<Packet>, const UanAddress&> cb)
  283. {
  284. m_forwardUpCb = cb;
  285. }
  286. void
  287. UanMacRc::AttachPhy (Ptr<UanPhy> phy)
  288. {
  289. m_phy = phy;
  290. m_phy->SetReceiveOkCallback (MakeCallback (&UanMacRc::ReceiveOkFromPhy, this));
  291. }
  292. Address
  293. UanMacRc::GetBroadcast (void) const
  294. {
  295. return UanAddress::GetBroadcast ();
  296. }
  297. void
  298. UanMacRc::ReceiveOkFromPhy (Ptr<Packet> pkt, double sinr, UanTxMode mode)
  299. {
  300. UanHeaderCommon ch;
  301. pkt->RemoveHeader (ch);
  302. if (ch.GetDest () == m_address || ch.GetDest () == UanAddress::GetBroadcast ())
  303. {
  304. m_rxLogger (pkt, mode);
  305. }
  306. switch (ch.GetType ())
  307. {
  308. case TYPE_DATA:
  309. if (ch.GetDest () == m_address)
  310. {
  311. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " UanMacRc Receiving DATA packet from PHY");
  312. UanHeaderRcData dh;
  313. pkt->RemoveHeader (dh);
  314. m_forwardUpCb (pkt, ch.GetSrc ());
  315. }
  316. break;
  317. case TYPE_RTS:
  318. // Currently don't respond to RTS packets at non-gateway nodes
  319. // (Code assumes single network neighberhood)
  320. break;
  321. case TYPE_CTS:
  322. {
  323. uint32_t ctsBytes = ch.GetSerializedSize () + pkt->GetSize ();
  324. m_assocAddr = ch.GetSrc ();
  325. UanHeaderRcCtsGlobal ctsg;
  326. pkt->RemoveHeader (ctsg);
  327. m_currentRate = ctsg.GetRateNum ();
  328. m_retryRate = m_minRetryRate + m_retryStep*ctsg.GetRetryRate ();
  329. UanHeaderRcRts rhtmp;
  330. Time winDelay = ctsg.GetWindowTime ();
  331. if (winDelay.GetSeconds () > 0)
  332. {
  333. m_rtsBlocked = false;
  334. Simulator::Schedule (winDelay, &UanMacRc::BlockRtsing, this);
  335. }
  336. else
  337. {
  338. NS_FATAL_ERROR (Simulator::Now ().GetSeconds () << " Node " << m_address << " Received window period < 0");
  339. }
  340. UanHeaderRcCts ctsh;
  341. ctsh.SetAddress (UanAddress::GetBroadcast ());
  342. while (pkt->GetSize () > 0)
  343. {
  344. pkt->RemoveHeader (ctsh);
  345. if (ctsh.GetAddress () == m_address)
  346. {
  347. if (m_state == GWPSENT)
  348. {
  349. m_assocAddr = ch.GetSrc ();
  350. ScheduleData (ctsh, ctsg, ctsBytes);
  351. }
  352. else if (m_state == RTSSENT)
  353. {
  354. ScheduleData (ctsh, ctsg, ctsBytes);
  355. }
  356. else
  357. {
  358. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS while state != RTSSENT or GWPING");
  359. }
  360. }
  361. }
  362. }
  363. break;
  364. case TYPE_GWPING:
  365. // Do not respond to GWPINGS at non-gateway nodes
  366. break;
  367. case TYPE_ACK:
  368. m_rtsBlocked = true;
  369. if (ch.GetDest () != m_address)
  370. {
  371. return;
  372. }
  373. ProcessAck (pkt);
  374. break;
  375. default:
  376. NS_FATAL_ERROR ("Unknown packet type " << ch.GetType () << " received at node " << GetAddress ());
  377. }
  378. }
  379. void
  380. UanMacRc::ScheduleData (const UanHeaderRcCts &ctsh, const UanHeaderRcCtsGlobal &ctsg, uint32_t ctsBytes)
  381. {
  382. NS_ASSERT (m_state == RTSSENT || m_state == GWPSENT);
  383. std::list<Reservation>::iterator it = m_resList.begin ();
  384. for (; it != m_resList.end (); it++)
  385. {
  386. if (it->GetFrameNo () == ctsh.GetFrameNo ())
  387. {
  388. break;
  389. }
  390. }
  391. if (it == m_resList.end ())
  392. {
  393. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS packet with no corresponding reservation!");
  394. return;
  395. }
  396. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS packet. Scheduling data");
  397. it->SetTransmitted ();
  398. double currentBps = m_phy->GetMode (m_currentRate).GetDataRateBps ();
  399. m_learnedProp = Simulator::Now () - ctsg.GetTxTimeStamp () - Seconds (ctsBytes * 8.0 / currentBps);
  400. Time arrTime = ctsg.GetTxTimeStamp () + ctsh.GetDelayToTx ();
  401. Time txTime = arrTime - m_learnedProp;
  402. Time startDelay = txTime - Simulator::Now ();
  403. Time frameDelay = Seconds (0);
  404. const std::list<std::pair <Ptr<Packet>, UanAddress > > l = it->GetPktList ();
  405. std::list<std::pair <Ptr<Packet>, UanAddress > >::const_iterator pit;
  406. pit = l.begin ();
  407. for (uint32_t i = 0; i < it->GetNoFrames (); i++, pit++)
  408. {
  409. Ptr<Packet> pkt = (*pit).first->Copy ();
  410. UanHeaderRcData dh;
  411. dh.SetFrameNo (i);
  412. dh.SetPropDelay (m_learnedProp);
  413. pkt->AddHeader (dh);
  414. UanHeaderCommon ch;
  415. ch.SetType (TYPE_DATA);
  416. ch.SetDest (m_assocAddr);
  417. ch.SetSrc (m_address);
  418. pkt->AddHeader (ch);
  419. Time eventTime = startDelay + frameDelay;
  420. if (eventTime.GetSeconds () < 0)
  421. {
  422. if (eventTime.GetSeconds () > -0.001)
  423. {
  424. eventTime = Seconds (0);
  425. }
  426. else
  427. {
  428. NS_FATAL_ERROR ("Scheduling error resulted in very negative data transmission time! eventTime = " << eventTime.GetSeconds ());
  429. }
  430. }
  431. 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 ());
  432. Simulator::Schedule (eventTime, &UanMacRc::SendPacket, this, pkt, m_currentRate);
  433. frameDelay = frameDelay + m_sifs + Seconds (pkt->GetSize () / currentBps);
  434. }
  435. m_state = IDLE;
  436. if (!m_pktQueue.empty ())
  437. {
  438. if (m_rtsEvent.IsRunning ())
  439. {
  440. m_rtsEvent.Cancel ();
  441. }
  442. m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
  443. double timeout = m_ev->GetValue ();
  444. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::SendRts, this);
  445. }
  446. }
  447. void
  448. UanMacRc::SendPacket (Ptr<Packet> pkt, uint32_t rate)
  449. {
  450. UanHeaderCommon ch;
  451. pkt->PeekHeader (ch);
  452. std::string type;
  453. switch (ch.GetType ())
  454. {
  455. case TYPE_DATA:
  456. type = "DATA";
  457. break;
  458. case TYPE_RTS:
  459. type = "RTS";
  460. break;
  461. case TYPE_CTS:
  462. type = "CTS";
  463. break;
  464. case TYPE_ACK:
  465. type = "ACK";
  466. break;
  467. case TYPE_GWPING:
  468. type = "GWPING";
  469. break;
  470. default:
  471. type = "UNKNOWN";
  472. break;
  473. }
  474. 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 ());
  475. m_dequeueLogger (pkt, rate);
  476. m_phy->SendPacket (pkt, rate);
  477. }
  478. void
  479. UanMacRc::ProcessAck (Ptr<Packet> ack)
  480. {
  481. UanHeaderRcAck ah;
  482. ack->RemoveHeader (ah);
  483. std::list<Reservation>::iterator it = m_resList.begin ();
  484. for (; it != m_resList.end (); it++)
  485. {
  486. if (it->GetFrameNo () == ah.GetFrameNo ())
  487. {
  488. break;
  489. }
  490. }
  491. if (it == m_resList.end ())
  492. {
  493. NS_LOG_DEBUG ("In " << __func__ << " could not find reservation corresponding to received ACK");
  494. return;
  495. }
  496. if (!it->IsTransmitted ())
  497. {
  498. return;
  499. }
  500. if (ah.GetNoNacks () > 0)
  501. {
  502. const std::list<std::pair <Ptr<Packet>, UanAddress > > l = it->GetPktList ();
  503. std::list<std::pair <Ptr<Packet>, UanAddress > >::const_iterator pit;
  504. pit = l.begin ();
  505. const std::set<uint8_t> &nacks = ah.GetNackedFrames ();
  506. std::set<uint8_t>::iterator nit = nacks.begin ();
  507. uint8_t pnum = 0;
  508. for (; nit != nacks.end (); nit++)
  509. {
  510. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " Received NACK for " << (uint32_t) *nit);
  511. while (pnum < *nit)
  512. {
  513. pit++;
  514. pnum++;
  515. }
  516. UanHeaderRcData dh;
  517. UanHeaderCommon ch;
  518. m_pktQueue.push_front (*pit);
  519. }
  520. }
  521. else
  522. {
  523. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received ACK for all frames");
  524. }
  525. m_resList.erase (it);
  526. }
  527. UanHeaderRcRts
  528. UanMacRc::CreateRtsHeader (const Reservation &res)
  529. {
  530. UanHeaderRcRts rh = UanHeaderRcRts ();
  531. rh.SetLength (res.GetLength ());
  532. rh.SetNoFrames (res.GetNoFrames ());
  533. rh.SetTimeStamp (res.GetTimestamp (res.GetRetryNo ()));
  534. rh.SetFrameNo (res.GetFrameNo ());
  535. rh.SetRetryNo (res.GetRetryNo ());
  536. return rh;
  537. }
  538. void
  539. UanMacRc::Associate (void)
  540. {
  541. m_cntrlSends++;
  542. Reservation res (m_pktQueue, m_frameNo, m_maxFrames);
  543. res.AddTimestamp (Simulator::Now ());
  544. m_frameNo++;
  545. m_resList.push_back (res);
  546. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  547. bool phy1ok = IsPhy1Ok ();
  548. if (phy1ok && !phyDual->IsPhy2Tx () & !m_rtsBlocked)
  549. {
  550. Ptr<Packet> pkt = Create<Packet> (0);
  551. pkt->AddHeader (CreateRtsHeader (res));
  552. pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_GWPING));
  553. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Sending first GWPING " << *pkt);
  554. SendPacket (pkt,m_currentRate + m_numRates);
  555. }
  556. m_state = GWPSENT;
  557. NS_ASSERT (!m_rtsEvent.IsRunning ());
  558. m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
  559. double timeout = m_ev->GetValue ();
  560. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::AssociateTimeout, this);
  561. }
  562. void
  563. UanMacRc::AssociateTimeout ()
  564. {
  565. m_cntrlSends++;
  566. if (m_state != GWPSENT)
  567. {
  568. return;
  569. }
  570. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  571. bool phy1ok = IsPhy1Ok ();
  572. if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked)
  573. {
  574. Ptr<Packet> pkt = Create<Packet> ();
  575. Reservation res = m_resList.back ();
  576. m_resList.pop_back ();
  577. res.AddTimestamp (Simulator::Now ());
  578. res.IncrementRetry ();
  579. pkt->AddHeader (CreateRtsHeader (res));
  580. pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_GWPING));
  581. SendPacket (pkt,m_currentRate + m_numRates);
  582. m_resList.push_back (res);
  583. }
  584. NS_ASSERT (!m_rtsEvent.IsRunning ());
  585. m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
  586. double timeout = m_ev->GetValue ();
  587. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::AssociateTimeout, this);
  588. }
  589. void
  590. UanMacRc::SendRts (void)
  591. {
  592. m_cntrlSends++;
  593. if (m_state == RTSSENT)
  594. {
  595. return;
  596. }
  597. NS_ASSERT (!m_pktQueue.empty ());
  598. Reservation res (m_pktQueue, m_frameNo, m_maxFrames);
  599. res.AddTimestamp (Simulator::Now ());
  600. m_frameNo++;
  601. m_resList.push_back (res);
  602. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  603. bool phy1ok = IsPhy1Ok ();
  604. if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked )
  605. {
  606. Ptr<Packet> pkt = Create<Packet> (0);
  607. pkt->AddHeader (CreateRtsHeader (res));
  608. pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_RTS));
  609. SendPacket (pkt,m_currentRate + m_numRates);
  610. }
  611. m_state = RTSSENT;
  612. NS_ASSERT (!m_rtsEvent.IsRunning ());
  613. m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
  614. double timeout = m_ev->GetValue ();
  615. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::RtsTimeout, this);
  616. }
  617. // We assume here that packet types are known at detection.
  618. bool
  619. UanMacRc::IsPhy1Ok ()
  620. {
  621. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  622. bool phy1ok = true;
  623. if (phyDual->IsPhy1Rx ())
  624. {
  625. Ptr<Packet> pkt = phyDual->GetPhy1PacketRx ();
  626. UanHeaderCommon ch;
  627. pkt->PeekHeader (ch);
  628. if (ch.GetType () == TYPE_CTS || ch.GetType () == TYPE_ACK)
  629. {
  630. phy1ok = false;
  631. }
  632. else if (ch.GetDest () == m_address)
  633. {
  634. phy1ok = false;
  635. }
  636. }
  637. return phy1ok;
  638. }
  639. void
  640. UanMacRc::RtsTimeout (void)
  641. {
  642. m_cntrlSends++;
  643. if (m_state != RTSSENT)
  644. {
  645. return;
  646. }
  647. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  648. bool phy1ok = IsPhy1Ok ();
  649. if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked)
  650. {
  651. if (m_resList.empty ())
  652. {
  653. NS_FATAL_ERROR (Simulator::Now ().GetSeconds () << " Node " << m_address << " tried to retry RTS with empty reservation list");
  654. }
  655. Ptr<Packet> pkt = Create<Packet> (0);
  656. Reservation res = m_resList.back ();
  657. NS_ASSERT (!res.IsTransmitted ());
  658. m_resList.pop_back ();
  659. res.AddTimestamp (Simulator::Now ());
  660. res.IncrementRetry ();
  661. m_resList.push_back (res);
  662. pkt->AddHeader (CreateRtsHeader (res));
  663. pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_RTS));
  664. SendPacket (pkt,m_currentRate + m_numRates);
  665. }
  666. m_state = RTSSENT;
  667. NS_ASSERT (!m_rtsEvent.IsRunning ());
  668. m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
  669. double timeout = m_ev->GetValue ();
  670. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::RtsTimeout, this);
  671. }
  672. void
  673. UanMacRc::BlockRtsing (void)
  674. {
  675. m_rtsBlocked = true;
  676. }
  677. } // namespace ns3