PageRenderTime 53ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/klenkovic/ns-3-dev-logging-fixes
C++ | 781 lines | 659 code | 99 blank | 23 comment | 81 complexity | 8b49f163bf59510e1ee4617caca15d60 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 ("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. int64_t
  240. UanMacRc::AssignStreams (int64_t stream)
  241. {
  242. NS_LOG_FUNCTION (this << stream);
  243. m_ev->SetStream (stream);
  244. return 1;
  245. }
  246. Address
  247. UanMacRc::GetAddress (void)
  248. {
  249. return m_address;
  250. }
  251. void
  252. UanMacRc::SetAddress (UanAddress addr)
  253. {
  254. m_address = addr;
  255. }
  256. bool
  257. UanMacRc::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
  258. {
  259. if (protocolNumber > 0)
  260. {
  261. NS_LOG_WARN ("Warning: UanMacRc does not support multiple protocols. protocolNumber argument to Enqueue is being ignored");
  262. }
  263. if (m_pktQueue.size () >= m_queueLimit)
  264. {
  265. return false;
  266. }
  267. m_pktQueue.push_back (std::make_pair (packet, UanAddress::ConvertFrom (dest)));
  268. switch (m_state)
  269. {
  270. case UNASSOCIATED:
  271. Associate ();
  272. return true;
  273. case IDLE:
  274. if (!m_rtsEvent.IsRunning ())
  275. {
  276. SendRts ();
  277. }
  278. return true;
  279. case GWPSENT:
  280. case RTSSENT:
  281. case DATATX:
  282. return true;
  283. }
  284. return true;
  285. }
  286. void
  287. UanMacRc::SetForwardUpCb (Callback<void, Ptr<Packet>, const UanAddress&> cb)
  288. {
  289. m_forwardUpCb = cb;
  290. }
  291. void
  292. UanMacRc::AttachPhy (Ptr<UanPhy> phy)
  293. {
  294. m_phy = phy;
  295. m_phy->SetReceiveOkCallback (MakeCallback (&UanMacRc::ReceiveOkFromPhy, this));
  296. }
  297. Address
  298. UanMacRc::GetBroadcast (void) const
  299. {
  300. return UanAddress::GetBroadcast ();
  301. }
  302. void
  303. UanMacRc::ReceiveOkFromPhy (Ptr<Packet> pkt, double sinr, UanTxMode mode)
  304. {
  305. UanHeaderCommon ch;
  306. pkt->RemoveHeader (ch);
  307. if (ch.GetDest () == m_address || ch.GetDest () == UanAddress::GetBroadcast ())
  308. {
  309. m_rxLogger (pkt, mode);
  310. }
  311. switch (ch.GetType ())
  312. {
  313. case TYPE_DATA:
  314. if (ch.GetDest () == m_address)
  315. {
  316. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " UanMacRc Receiving DATA packet from PHY");
  317. UanHeaderRcData dh;
  318. pkt->RemoveHeader (dh);
  319. m_forwardUpCb (pkt, ch.GetSrc ());
  320. }
  321. break;
  322. case TYPE_RTS:
  323. // Currently don't respond to RTS packets at non-gateway nodes
  324. // (Code assumes single network neighberhood)
  325. break;
  326. case TYPE_CTS:
  327. {
  328. uint32_t ctsBytes = ch.GetSerializedSize () + pkt->GetSize ();
  329. m_assocAddr = ch.GetSrc ();
  330. UanHeaderRcCtsGlobal ctsg;
  331. pkt->RemoveHeader (ctsg);
  332. m_currentRate = ctsg.GetRateNum ();
  333. m_retryRate = m_minRetryRate + m_retryStep*ctsg.GetRetryRate ();
  334. UanHeaderRcRts rhtmp;
  335. Time winDelay = ctsg.GetWindowTime ();
  336. if (winDelay.GetSeconds () > 0)
  337. {
  338. m_rtsBlocked = false;
  339. Simulator::Schedule (winDelay, &UanMacRc::BlockRtsing, this);
  340. }
  341. else
  342. {
  343. NS_FATAL_ERROR (Simulator::Now ().GetSeconds () << " Node " << m_address << " Received window period < 0");
  344. }
  345. UanHeaderRcCts ctsh;
  346. ctsh.SetAddress (UanAddress::GetBroadcast ());
  347. while (pkt->GetSize () > 0)
  348. {
  349. pkt->RemoveHeader (ctsh);
  350. if (ctsh.GetAddress () == m_address)
  351. {
  352. if (m_state == GWPSENT)
  353. {
  354. m_assocAddr = ch.GetSrc ();
  355. ScheduleData (ctsh, ctsg, ctsBytes);
  356. }
  357. else if (m_state == RTSSENT)
  358. {
  359. ScheduleData (ctsh, ctsg, ctsBytes);
  360. }
  361. else
  362. {
  363. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS while state != RTSSENT or GWPING");
  364. }
  365. }
  366. }
  367. }
  368. break;
  369. case TYPE_GWPING:
  370. // Do not respond to GWPINGS at non-gateway nodes
  371. break;
  372. case TYPE_ACK:
  373. m_rtsBlocked = true;
  374. if (ch.GetDest () != m_address)
  375. {
  376. return;
  377. }
  378. ProcessAck (pkt);
  379. break;
  380. default:
  381. NS_FATAL_ERROR ("Unknown packet type " << ch.GetType () << " received at node " << GetAddress ());
  382. }
  383. }
  384. void
  385. UanMacRc::ScheduleData (const UanHeaderRcCts &ctsh, const UanHeaderRcCtsGlobal &ctsg, uint32_t ctsBytes)
  386. {
  387. NS_ASSERT (m_state == RTSSENT || m_state == GWPSENT);
  388. std::list<Reservation>::iterator it = m_resList.begin ();
  389. for (; it != m_resList.end (); it++)
  390. {
  391. if (it->GetFrameNo () == ctsh.GetFrameNo ())
  392. {
  393. break;
  394. }
  395. }
  396. if (it == m_resList.end ())
  397. {
  398. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS packet with no corresponding reservation!");
  399. return;
  400. }
  401. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS packet. Scheduling data");
  402. it->SetTransmitted ();
  403. double currentBps = m_phy->GetMode (m_currentRate).GetDataRateBps ();
  404. m_learnedProp = Simulator::Now () - ctsg.GetTxTimeStamp () - Seconds (ctsBytes * 8.0 / currentBps);
  405. Time arrTime = ctsg.GetTxTimeStamp () + ctsh.GetDelayToTx ();
  406. Time txTime = arrTime - m_learnedProp;
  407. Time startDelay = txTime - Simulator::Now ();
  408. Time frameDelay = Seconds (0);
  409. const std::list<std::pair <Ptr<Packet>, UanAddress > > l = it->GetPktList ();
  410. std::list<std::pair <Ptr<Packet>, UanAddress > >::const_iterator pit;
  411. pit = l.begin ();
  412. for (uint32_t i = 0; i < it->GetNoFrames (); i++, pit++)
  413. {
  414. Ptr<Packet> pkt = (*pit).first->Copy ();
  415. UanHeaderRcData dh;
  416. dh.SetFrameNo (i);
  417. dh.SetPropDelay (m_learnedProp);
  418. pkt->AddHeader (dh);
  419. UanHeaderCommon ch;
  420. ch.SetType (TYPE_DATA);
  421. ch.SetDest (m_assocAddr);
  422. ch.SetSrc (m_address);
  423. pkt->AddHeader (ch);
  424. Time eventTime = startDelay + frameDelay;
  425. if (eventTime.GetSeconds () < 0)
  426. {
  427. if (eventTime.GetSeconds () > -0.001)
  428. {
  429. eventTime = Seconds (0);
  430. }
  431. else
  432. {
  433. NS_FATAL_ERROR ("Scheduling error resulted in very negative data transmission time! eventTime = " << eventTime.GetSeconds ());
  434. }
  435. }
  436. 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 ());
  437. Simulator::Schedule (eventTime, &UanMacRc::SendPacket, this, pkt, m_currentRate);
  438. frameDelay = frameDelay + m_sifs + Seconds (pkt->GetSize () / currentBps);
  439. }
  440. m_state = IDLE;
  441. if (!m_pktQueue.empty ())
  442. {
  443. if (m_rtsEvent.IsRunning ())
  444. {
  445. m_rtsEvent.Cancel ();
  446. }
  447. m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
  448. double timeout = m_ev->GetValue ();
  449. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::SendRts, this);
  450. }
  451. }
  452. void
  453. UanMacRc::SendPacket (Ptr<Packet> pkt, uint32_t rate)
  454. {
  455. UanHeaderCommon ch;
  456. pkt->PeekHeader (ch);
  457. std::string type;
  458. switch (ch.GetType ())
  459. {
  460. case TYPE_DATA:
  461. type = "DATA";
  462. break;
  463. case TYPE_RTS:
  464. type = "RTS";
  465. break;
  466. case TYPE_CTS:
  467. type = "CTS";
  468. break;
  469. case TYPE_ACK:
  470. type = "ACK";
  471. break;
  472. case TYPE_GWPING:
  473. type = "GWPING";
  474. break;
  475. default:
  476. type = "UNKNOWN";
  477. break;
  478. }
  479. 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 ());
  480. m_dequeueLogger (pkt, rate);
  481. m_phy->SendPacket (pkt, rate);
  482. }
  483. void
  484. UanMacRc::ProcessAck (Ptr<Packet> ack)
  485. {
  486. UanHeaderRcAck ah;
  487. ack->RemoveHeader (ah);
  488. std::list<Reservation>::iterator it = m_resList.begin ();
  489. for (; it != m_resList.end (); it++)
  490. {
  491. if (it->GetFrameNo () == ah.GetFrameNo ())
  492. {
  493. break;
  494. }
  495. }
  496. if (it == m_resList.end ())
  497. {
  498. NS_LOG_DEBUG ("In " << __func__ << " could not find reservation corresponding to received ACK");
  499. return;
  500. }
  501. if (!it->IsTransmitted ())
  502. {
  503. return;
  504. }
  505. if (ah.GetNoNacks () > 0)
  506. {
  507. const std::list<std::pair <Ptr<Packet>, UanAddress > > l = it->GetPktList ();
  508. std::list<std::pair <Ptr<Packet>, UanAddress > >::const_iterator pit;
  509. pit = l.begin ();
  510. const std::set<uint8_t> &nacks = ah.GetNackedFrames ();
  511. std::set<uint8_t>::iterator nit = nacks.begin ();
  512. uint8_t pnum = 0;
  513. for (; nit != nacks.end (); nit++)
  514. {
  515. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " Received NACK for " << (uint32_t) *nit);
  516. while (pnum < *nit)
  517. {
  518. pit++;
  519. pnum++;
  520. }
  521. UanHeaderRcData dh;
  522. UanHeaderCommon ch;
  523. m_pktQueue.push_front (*pit);
  524. }
  525. }
  526. else
  527. {
  528. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received ACK for all frames");
  529. }
  530. m_resList.erase (it);
  531. }
  532. UanHeaderRcRts
  533. UanMacRc::CreateRtsHeader (const Reservation &res)
  534. {
  535. UanHeaderRcRts rh = UanHeaderRcRts ();
  536. rh.SetLength (res.GetLength ());
  537. rh.SetNoFrames (res.GetNoFrames ());
  538. rh.SetTimeStamp (res.GetTimestamp (res.GetRetryNo ()));
  539. rh.SetFrameNo (res.GetFrameNo ());
  540. rh.SetRetryNo (res.GetRetryNo ());
  541. return rh;
  542. }
  543. void
  544. UanMacRc::Associate (void)
  545. {
  546. m_cntrlSends++;
  547. Reservation res (m_pktQueue, m_frameNo, m_maxFrames);
  548. res.AddTimestamp (Simulator::Now ());
  549. m_frameNo++;
  550. m_resList.push_back (res);
  551. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  552. bool phy1ok = IsPhy1Ok ();
  553. if (phy1ok && !phyDual->IsPhy2Tx () & !m_rtsBlocked)
  554. {
  555. Ptr<Packet> pkt = Create<Packet> (0);
  556. pkt->AddHeader (CreateRtsHeader (res));
  557. pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_GWPING));
  558. NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Sending first GWPING " << *pkt);
  559. SendPacket (pkt,m_currentRate + m_numRates);
  560. }
  561. m_state = GWPSENT;
  562. NS_ASSERT (!m_rtsEvent.IsRunning ());
  563. m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
  564. double timeout = m_ev->GetValue ();
  565. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::AssociateTimeout, this);
  566. }
  567. void
  568. UanMacRc::AssociateTimeout ()
  569. {
  570. m_cntrlSends++;
  571. if (m_state != GWPSENT)
  572. {
  573. return;
  574. }
  575. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  576. bool phy1ok = IsPhy1Ok ();
  577. if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked)
  578. {
  579. Ptr<Packet> pkt = Create<Packet> ();
  580. Reservation res = m_resList.back ();
  581. m_resList.pop_back ();
  582. res.AddTimestamp (Simulator::Now ());
  583. res.IncrementRetry ();
  584. pkt->AddHeader (CreateRtsHeader (res));
  585. pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_GWPING));
  586. SendPacket (pkt,m_currentRate + m_numRates);
  587. m_resList.push_back (res);
  588. }
  589. NS_ASSERT (!m_rtsEvent.IsRunning ());
  590. m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
  591. double timeout = m_ev->GetValue ();
  592. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::AssociateTimeout, this);
  593. }
  594. void
  595. UanMacRc::SendRts (void)
  596. {
  597. m_cntrlSends++;
  598. if (m_state == RTSSENT)
  599. {
  600. return;
  601. }
  602. NS_ASSERT (!m_pktQueue.empty ());
  603. Reservation res (m_pktQueue, m_frameNo, m_maxFrames);
  604. res.AddTimestamp (Simulator::Now ());
  605. m_frameNo++;
  606. m_resList.push_back (res);
  607. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  608. bool phy1ok = IsPhy1Ok ();
  609. if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked )
  610. {
  611. Ptr<Packet> pkt = Create<Packet> (0);
  612. pkt->AddHeader (CreateRtsHeader (res));
  613. pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_RTS));
  614. SendPacket (pkt,m_currentRate + m_numRates);
  615. }
  616. m_state = RTSSENT;
  617. NS_ASSERT (!m_rtsEvent.IsRunning ());
  618. m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
  619. double timeout = m_ev->GetValue ();
  620. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::RtsTimeout, this);
  621. }
  622. // We assume here that packet types are known at detection.
  623. bool
  624. UanMacRc::IsPhy1Ok ()
  625. {
  626. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  627. bool phy1ok = true;
  628. if (phyDual->IsPhy1Rx ())
  629. {
  630. Ptr<Packet> pkt = phyDual->GetPhy1PacketRx ();
  631. UanHeaderCommon ch;
  632. pkt->PeekHeader (ch);
  633. if (ch.GetType () == TYPE_CTS || ch.GetType () == TYPE_ACK)
  634. {
  635. phy1ok = false;
  636. }
  637. else if (ch.GetDest () == m_address)
  638. {
  639. phy1ok = false;
  640. }
  641. }
  642. return phy1ok;
  643. }
  644. void
  645. UanMacRc::RtsTimeout (void)
  646. {
  647. m_cntrlSends++;
  648. if (m_state != RTSSENT)
  649. {
  650. return;
  651. }
  652. Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
  653. bool phy1ok = IsPhy1Ok ();
  654. if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked)
  655. {
  656. if (m_resList.empty ())
  657. {
  658. NS_FATAL_ERROR (Simulator::Now ().GetSeconds () << " Node " << m_address << " tried to retry RTS with empty reservation list");
  659. }
  660. Ptr<Packet> pkt = Create<Packet> (0);
  661. Reservation res = m_resList.back ();
  662. NS_ASSERT (!res.IsTransmitted ());
  663. m_resList.pop_back ();
  664. res.AddTimestamp (Simulator::Now ());
  665. res.IncrementRetry ();
  666. m_resList.push_back (res);
  667. pkt->AddHeader (CreateRtsHeader (res));
  668. pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_RTS));
  669. SendPacket (pkt,m_currentRate + m_numRates);
  670. }
  671. m_state = RTSSENT;
  672. NS_ASSERT (!m_rtsEvent.IsRunning ());
  673. m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
  674. double timeout = m_ev->GetValue ();
  675. m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::RtsTimeout, this);
  676. }
  677. void
  678. UanMacRc::BlockRtsing (void)
  679. {
  680. m_rtsBlocked = true;
  681. }
  682. } // namespace ns3