A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
uan-mac-rc.cc
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 
21 #include "uan-mac-rc.h"
22 #include "uan-header-rc.h"
23 #include "uan-tx-mode.h"
24 #include "uan-phy.h"
25 #include "uan-header-common.h"
26 #include "uan-phy-dual.h"
27 
28 #include "ns3/log.h"
29 #include "ns3/nstime.h"
30 #include "ns3/simulator.h"
31 #include "ns3/assert.h"
32 #include "ns3/double.h"
33 #include "ns3/uinteger.h"
34 
35 #include <list>
36 #include <utility>
37 
38 
39 
40 NS_LOG_COMPONENT_DEFINE ("UanMacRc");
41 namespace ns3 {
42 
43 NS_OBJECT_ENSURE_REGISTERED (UanMacRc);
44 
46  : m_length (0),
47  m_frameNo (0),
48  m_retryNo (0),
49  m_transmitted (false)
50 {
51 
52 }
53 
54 Reservation::Reservation (std::list<std::pair <Ptr<Packet>, UanAddress > > &list, uint8_t frameNo, uint32_t maxPkts)
55  : m_frameNo (frameNo),
56  m_retryNo (0),
57  m_transmitted (false)
58 {
59  uint32_t numPkts = (maxPkts) ? maxPkts : list.size ();
60  uint32_t length = 0;
61  UanHeaderRcData dh;
62  UanHeaderCommon ch;
63 
64  for (uint32_t i = 0; i < numPkts; i++)
65  {
66  length += list.front ().first->GetSize () +
67  ch.GetSerializedSize () +
68  dh.GetSerializedSize ();
69  m_pktList.push_back (list.front ());
70  list.pop_front ();
71  }
72  m_length = length;
73 }
74 
75 Reservation::~Reservation ()
76 {
77  std::list<std::pair <Ptr<Packet>, UanAddress > >::iterator it;
78  for (it = m_pktList.begin (); it != m_pktList.end (); it++)
79  {
80  it->first = Ptr<Packet> ((Packet *) 0);
81  }
82  m_pktList.clear ();
83  m_timestamp.clear ();
84 }
85 uint32_t
87 {
88  return m_pktList.size ();
89 }
90 
91 uint32_t
93 {
94  return m_length;
95 }
96 
97 const std::list<std::pair <Ptr<Packet>, UanAddress > > &
99 {
100  return m_pktList;
101 }
102 
103 uint8_t
105 {
106  return m_frameNo;
107 }
108 
109 uint8_t
111 {
112  return m_retryNo;
113 }
114 
115 Time
116 Reservation::GetTimestamp (uint8_t n) const
117 {
118  return m_timestamp[n];
119 }
120 
121 bool
123 {
124  return m_transmitted;
125 }
126 
127 void
129 {
130  m_frameNo = fn;
131 }
132 
133 void
135 {
136  m_timestamp.push_back (t);
137 }
138 
139 void
141 {
142  m_retryNo++;
143 }
144 
145 void
147 {
148  m_transmitted = true;
149 }
150 
151 uint32_t UanMacRc::m_cntrlSends = 0;
152 
153 UanMacRc::UanMacRc ()
154  : UanMac (),
155  m_state (UNASSOCIATED),
156  m_rtsBlocked (false),
157  m_currentRate (10),
158  m_frameNo (0),
159  m_cleared (false)
160 {
161  m_ev = CreateObject<ExponentialRandomVariable> ();
162 
163  UanHeaderCommon ch;
164  UanHeaderRcCts ctsh;
166 
167  m_ctsSizeN = ctsh.GetSerializedSize ();
168  m_ctsSizeG = ch.GetSerializedSize () + ctsg.GetSerializedSize ();
169 }
170 
171 UanMacRc::~UanMacRc ()
172 {
173 }
174 
175 void
177 {
178  if (m_cleared)
179  {
180  return;
181  }
182  m_cleared = true;
183  if (m_phy)
184  {
185  m_phy->Clear ();
186  m_phy = 0;
187  }
188  std::list<std::pair <Ptr<Packet>, UanAddress > >::iterator it;
189  for (it = m_pktQueue.begin (); it != m_pktQueue.end (); it++)
190  {
191  it->first = 0;
192  }
193  m_pktQueue.clear ();
194  m_resList.clear ();
195  m_startAgain.Cancel ();
196  m_rtsEvent.Cancel ();
197 }
198 
199 void
201 {
202  Clear ();
204 }
205 
206 TypeId
207 UanMacRc::GetTypeId (void)
208 {
209  static TypeId tid = TypeId ("ns3::UanMacRc")
210  .SetParent<UanMac> ()
211  .AddConstructor<UanMacRc> ()
212  .AddAttribute ("RetryRate",
213  "Number of retry attempts per second (of RTS/GWPING)",
214  DoubleValue (1 / 5.0),
215  MakeDoubleAccessor (&UanMacRc::m_retryRate),
216  MakeDoubleChecker<double> ())
217  .AddAttribute ("MaxFrames",
218  "Maximum number of frames to include in a single RTS",
219  UintegerValue (1),
220  MakeUintegerAccessor (&UanMacRc::m_maxFrames),
221  MakeUintegerChecker<uint32_t> ())
222  .AddAttribute ("QueueLimit",
223  "Maximum packets to queue at MAC",
224  UintegerValue (10),
225  MakeUintegerAccessor (&UanMacRc::m_queueLimit),
226  MakeUintegerChecker<uint32_t> ())
227  .AddAttribute ("SIFS",
228  "Spacing to give between frames (this should match gateway)",
229  TimeValue (Seconds (0.2)),
230  MakeTimeAccessor (&UanMacRc::m_sifs),
231  MakeTimeChecker ())
232  .AddAttribute ("NumberOfRates",
233  "Number of rate divisions supported by each PHY",
234  UintegerValue (0),
235  MakeUintegerAccessor (&UanMacRc::m_numRates),
236  MakeUintegerChecker<uint32_t> ())
237  .AddAttribute ("MinRetryRate",
238  "Smallest allowed RTS retry rate",
239  DoubleValue (0.01),
240  MakeDoubleAccessor (&UanMacRc::m_minRetryRate),
241  MakeDoubleChecker<double> ())
242  .AddAttribute ("RetryStep",
243  "Retry rate increment",
244  DoubleValue (0.01),
245  MakeDoubleAccessor (&UanMacRc::m_retryStep),
246  MakeDoubleChecker<double> ())
247  .AddAttribute ("NumberOfRetryRates",
248  "Number of retry rates",
249  UintegerValue (100),
250  MakeUintegerAccessor (&UanMacRc::m_numRetryRates),
251  MakeUintegerChecker<uint16_t> ())
252  .AddAttribute ("MaxPropDelay",
253  "Maximum possible propagation delay to gateway",
254  TimeValue (Seconds (2)),
255  MakeTimeAccessor (&UanMacRc::m_learnedProp),
256  MakeTimeChecker ())
257  .AddTraceSource ("Enqueue",
258  "A (data) packet arrived at MAC for transmission",
259  MakeTraceSourceAccessor (&UanMacRc::m_enqueueLogger))
260  .AddTraceSource ("Dequeue",
261  "A (data) packet was passed down to PHY from MAC",
262  MakeTraceSourceAccessor (&UanMacRc::m_dequeueLogger))
263  .AddTraceSource ("RX",
264  "A packet was destined for and received at this MAC layer",
265  MakeTraceSourceAccessor (&UanMacRc::m_rxLogger))
266  ;
267  return tid;
268 }
269 
270 int64_t
271 UanMacRc::AssignStreams (int64_t stream)
272 {
273  NS_LOG_FUNCTION (this << stream);
274  m_ev->SetStream (stream);
275  return 1;
276 }
277 
278 Address
280 {
281  return m_address;
282 }
283 
284 void
286 {
287  m_address = addr;
288 }
289 
290 bool
291 UanMacRc::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
292 {
293  if (protocolNumber > 0)
294  {
295  NS_LOG_WARN ("Warning: UanMacRc does not support multiple protocols. protocolNumber argument to Enqueue is being ignored");
296  }
297 
298 
299  if (m_pktQueue.size () >= m_queueLimit)
300  {
301  return false;
302  }
303 
304  m_pktQueue.push_back (std::make_pair (packet, UanAddress::ConvertFrom (dest)));
305 
306  switch (m_state)
307  {
308  case UNASSOCIATED:
309  Associate ();
310  return true;
311  case IDLE:
312  if (!m_rtsEvent.IsRunning ())
313  {
314  SendRts ();
315  }
316  return true;
317  case GWPSENT:
318  case RTSSENT:
319  case DATATX:
320  return true;
321  }
322 
323  return true;
324 }
325 
326 void
328 {
329  m_forwardUpCb = cb;
330 }
331 
332 void
334 {
335  m_phy = phy;
336  m_phy->SetReceiveOkCallback (MakeCallback (&UanMacRc::ReceiveOkFromPhy, this));
337 }
338 
339 Address
341 {
342  return UanAddress::GetBroadcast ();
343 }
344 
345 void
346 UanMacRc::ReceiveOkFromPhy (Ptr<Packet> pkt, double sinr, UanTxMode mode)
347 {
348 
349  UanHeaderCommon ch;
350  pkt->RemoveHeader (ch);
351  if (ch.GetDest () == m_address || ch.GetDest () == UanAddress::GetBroadcast ())
352  {
353  m_rxLogger (pkt, mode);
354  }
355 
356  switch (ch.GetType ())
357  {
358  case TYPE_DATA:
359 
360  if (ch.GetDest () == m_address)
361  {
362  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " UanMacRc Receiving DATA packet from PHY");
363  UanHeaderRcData dh;
364  pkt->RemoveHeader (dh);
365  m_forwardUpCb (pkt, ch.GetSrc ());
366  }
367  break;
368  case TYPE_RTS:
369  // Currently don't respond to RTS packets at non-gateway nodes
370  // (Code assumes single network neighberhood)
371  break;
372  case TYPE_CTS:
373  {
374  uint32_t ctsBytes = ch.GetSerializedSize () + pkt->GetSize ();
375  m_assocAddr = ch.GetSrc ();
376  UanHeaderRcCtsGlobal ctsg;
377  pkt->RemoveHeader (ctsg);
378  m_currentRate = ctsg.GetRateNum ();
379  m_retryRate = m_minRetryRate + m_retryStep*ctsg.GetRetryRate ();
380 
381  UanHeaderRcRts rhtmp;
382 
383  Time winDelay = ctsg.GetWindowTime ();
384 
385  if (winDelay.GetSeconds () > 0)
386  {
387  m_rtsBlocked = false;
388  Simulator::Schedule (winDelay, &UanMacRc::BlockRtsing, this);
389  }
390  else
391  {
392  NS_FATAL_ERROR (Simulator::Now ().GetSeconds () << " Node " << m_address << " Received window period < 0");
393  }
394 
395  UanHeaderRcCts ctsh;
397  while (pkt->GetSize () > 0)
398  {
399  pkt->RemoveHeader (ctsh);
400  if (ctsh.GetAddress () == m_address)
401  {
402  if (m_state == GWPSENT)
403  {
404  m_assocAddr = ch.GetSrc ();
405  ScheduleData (ctsh, ctsg, ctsBytes);
406  }
407  else if (m_state == RTSSENT)
408  {
409  ScheduleData (ctsh, ctsg, ctsBytes);
410  }
411  else
412  {
413  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS while state != RTSSENT or GWPING");
414  }
415  }
416  }
417  }
418  break;
419  case TYPE_GWPING:
420  // Do not respond to GWPINGS at non-gateway nodes
421  break;
422  case TYPE_ACK:
423  m_rtsBlocked = true;
424  if (ch.GetDest () != m_address)
425  {
426  return;
427  }
428  ProcessAck (pkt);
429  break;
430  default:
431  NS_FATAL_ERROR ("Unknown packet type " << ch.GetType () << " received at node " << GetAddress ());
432  }
433 
434 }
435 
436 void
437 UanMacRc::ScheduleData (const UanHeaderRcCts &ctsh, const UanHeaderRcCtsGlobal &ctsg, uint32_t ctsBytes)
438 {
439  NS_ASSERT (m_state == RTSSENT || m_state == GWPSENT);
440 
441 
442 
443  std::list<Reservation>::iterator it = m_resList.begin ();
444  for (; it != m_resList.end (); it++)
445  {
446  if (it->GetFrameNo () == ctsh.GetFrameNo ())
447  {
448  break;
449  }
450  }
451  if (it == m_resList.end ())
452  {
453  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS packet with no corresponding reservation!");
454  return;
455  }
456  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS packet. Scheduling data");
457  it->SetTransmitted ();
458 
459  double currentBps = m_phy->GetMode (m_currentRate).GetDataRateBps ();
460 
461  m_learnedProp = Simulator::Now () - ctsg.GetTxTimeStamp () - Seconds (ctsBytes * 8.0 / currentBps);
462 
463 
464  Time arrTime = ctsg.GetTxTimeStamp () + ctsh.GetDelayToTx ();
465  Time txTime = arrTime - m_learnedProp;
466 
467  Time startDelay = txTime - Simulator::Now ();
468 
469  Time frameDelay = Seconds (0);
470 
471  const std::list<std::pair <Ptr<Packet>, UanAddress > > l = it->GetPktList ();
472  std::list<std::pair <Ptr<Packet>, UanAddress > >::const_iterator pit;
473  pit = l.begin ();
474 
475 
476 
477  for (uint32_t i = 0; i < it->GetNoFrames (); i++, pit++)
478  {
479  Ptr<Packet> pkt = (*pit).first->Copy ();
480 
481  UanHeaderRcData dh;
482  dh.SetFrameNo (i);
483  dh.SetPropDelay (m_learnedProp);
484  pkt->AddHeader (dh);
485 
486  UanHeaderCommon ch;
487  ch.SetType (TYPE_DATA);
488  ch.SetDest (m_assocAddr);
489  ch.SetSrc (m_address);
490 
491  pkt->AddHeader (ch);
492  Time eventTime = startDelay + frameDelay;
493  if (eventTime.GetSeconds () < 0)
494  {
495  if (eventTime.GetSeconds () > -0.001)
496  {
497  eventTime = Seconds (0);
498  }
499  else
500  {
501  NS_FATAL_ERROR ("Scheduling error resulted in very negative data transmission time! eventTime = " << eventTime.GetSeconds ());
502  }
503  }
504  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 ());
505  Simulator::Schedule (eventTime, &UanMacRc::SendPacket, this, pkt, m_currentRate);
506  frameDelay = frameDelay + m_sifs + Seconds (pkt->GetSize () / currentBps);
507  }
508 
509  m_state = IDLE;
510  if (!m_pktQueue.empty ())
511  {
512 
513  if (m_rtsEvent.IsRunning ())
514  {
515  m_rtsEvent.Cancel ();
516  }
517 
518  m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
519  double timeout = m_ev->GetValue ();
520  m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::SendRts, this);
521  }
522 
523 }
524 
525 void
526 UanMacRc::SendPacket (Ptr<Packet> pkt, uint32_t rate)
527 {
528  UanHeaderCommon ch;
529  pkt->PeekHeader (ch);
530  std::string type;
531  switch (ch.GetType ())
532  {
533  case TYPE_DATA:
534  type = "DATA";
535  break;
536  case TYPE_RTS:
537  type = "RTS";
538  break;
539  case TYPE_CTS:
540  type = "CTS";
541  break;
542  case TYPE_ACK:
543  type = "ACK";
544  break;
545  case TYPE_GWPING:
546  type = "GWPING";
547  break;
548  default:
549  type = "UNKNOWN";
550  break;
551  }
552  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 ());
553  m_dequeueLogger (pkt, rate);
554  m_phy->SendPacket (pkt, rate);
555 }
556 
557 void
558 UanMacRc::ProcessAck (Ptr<Packet> ack)
559 {
560  UanHeaderRcAck ah;
561  ack->RemoveHeader (ah);
562 
563  std::list<Reservation>::iterator it = m_resList.begin ();
564  for (; it != m_resList.end (); it++)
565  {
566  if (it->GetFrameNo () == ah.GetFrameNo ())
567  {
568  break;
569  }
570  }
571  if (it == m_resList.end ())
572  {
573  NS_LOG_DEBUG ("In " << __func__ << " could not find reservation corresponding to received ACK");
574  return;
575  }
576  if (!it->IsTransmitted ())
577  {
578  return;
579  }
580  if (ah.GetNoNacks () > 0)
581  {
582  const std::list<std::pair <Ptr<Packet>, UanAddress > > l = it->GetPktList ();
583  std::list<std::pair <Ptr<Packet>, UanAddress > >::const_iterator pit;
584  pit = l.begin ();
585 
586  const std::set<uint8_t> &nacks = ah.GetNackedFrames ();
587  std::set<uint8_t>::iterator nit = nacks.begin ();
588  uint8_t pnum = 0;
589  for (; nit != nacks.end (); nit++)
590  {
591  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " Received NACK for " << (uint32_t) *nit);
592  while (pnum < *nit)
593  {
594  pit++;
595  pnum++;
596  }
597  UanHeaderRcData dh;
598  UanHeaderCommon ch;
599  m_pktQueue.push_front (*pit);
600  }
601  }
602  else
603  {
604  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received ACK for all frames");
605  }
606  m_resList.erase (it);
607 }
608 
609 UanHeaderRcRts
610 UanMacRc::CreateRtsHeader (const Reservation &res)
611 {
612  UanHeaderRcRts rh = UanHeaderRcRts ();
613 
614  rh.SetLength (res.GetLength ());
615  rh.SetNoFrames (res.GetNoFrames ());
616  rh.SetTimeStamp (res.GetTimestamp (res.GetRetryNo ()));
617  rh.SetFrameNo (res.GetFrameNo ());
618  rh.SetRetryNo (res.GetRetryNo ());
619  return rh;
620 }
621 
622 void
623 UanMacRc::Associate (void)
624 {
625  m_cntrlSends++;
626 
627  Reservation res (m_pktQueue, m_frameNo, m_maxFrames);
628  res.AddTimestamp (Simulator::Now ());
629  m_frameNo++;
630  m_resList.push_back (res);
631  Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
632  bool phy1ok = IsPhy1Ok ();
633  if (phy1ok && !phyDual->IsPhy2Tx () & !m_rtsBlocked)
634  {
635  Ptr<Packet> pkt = Create<Packet> (0);
636  pkt->AddHeader (CreateRtsHeader (res));
637  pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_GWPING));
638  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Sending first GWPING " << *pkt);
639  SendPacket (pkt,m_currentRate + m_numRates);
640  }
641  m_state = GWPSENT;
642  NS_ASSERT (!m_rtsEvent.IsRunning ());
643  m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
644  double timeout = m_ev->GetValue ();
645  m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::AssociateTimeout, this);
646 }
647 
648 void
649 UanMacRc::AssociateTimeout ()
650 {
651  m_cntrlSends++;
652  if (m_state != GWPSENT)
653  {
654  return;
655  }
656  Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
657  bool phy1ok = IsPhy1Ok ();
658  if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked)
659  {
660  Ptr<Packet> pkt = Create<Packet> ();
661 
662  Reservation res = m_resList.back ();
663  m_resList.pop_back ();
664  res.AddTimestamp (Simulator::Now ());
665  res.IncrementRetry ();
666 
667  pkt->AddHeader (CreateRtsHeader (res));
668  pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_GWPING));
669 
670  SendPacket (pkt,m_currentRate + m_numRates);
671  m_resList.push_back (res);
672  }
673  NS_ASSERT (!m_rtsEvent.IsRunning ());
674  m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
675  double timeout = m_ev->GetValue ();
676  m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::AssociateTimeout, this);
677 }
678 
679 
680 void
681 UanMacRc::SendRts (void)
682 {
683  m_cntrlSends++;
684  if (m_state == RTSSENT)
685  {
686  return;
687  }
688 
689  NS_ASSERT (!m_pktQueue.empty ());
690 
691  Reservation res (m_pktQueue, m_frameNo, m_maxFrames);
692  res.AddTimestamp (Simulator::Now ());
693  m_frameNo++;
694  m_resList.push_back (res);
695  Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
696  bool phy1ok = IsPhy1Ok ();
697  if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked )
698  {
699  Ptr<Packet> pkt = Create<Packet> (0);
700  pkt->AddHeader (CreateRtsHeader (res));
701  pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_RTS));
702  SendPacket (pkt,m_currentRate + m_numRates);
703  }
704  m_state = RTSSENT;
705  NS_ASSERT (!m_rtsEvent.IsRunning ());
706  m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
707  double timeout = m_ev->GetValue ();
708  m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::RtsTimeout, this);
709 
710 }
711 
712 // We assume here that packet types are known at detection.
713 bool
714 UanMacRc::IsPhy1Ok ()
715 {
716  Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
717 
718  bool phy1ok = true;
719  if (phyDual->IsPhy1Rx ())
720  {
721  Ptr<Packet> pkt = phyDual->GetPhy1PacketRx ();
722  UanHeaderCommon ch;
723  pkt->PeekHeader (ch);
724  if (ch.GetType () == TYPE_CTS || ch.GetType () == TYPE_ACK)
725  {
726  phy1ok = false;
727  }
728  else if (ch.GetDest () == m_address)
729  {
730  phy1ok = false;
731  }
732  }
733  return phy1ok;
734 }
735 
736 void
737 UanMacRc::RtsTimeout (void)
738 {
739  m_cntrlSends++;
740 
741  if (m_state != RTSSENT)
742  {
743  return;
744  }
745  Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
746 
747  bool phy1ok = IsPhy1Ok ();
748  if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked)
749  {
750 
751  if (m_resList.empty ())
752  {
753  NS_FATAL_ERROR (Simulator::Now ().GetSeconds () << " Node " << m_address << " tried to retry RTS with empty reservation list");
754  }
755  Ptr<Packet> pkt = Create<Packet> (0);
756 
757  Reservation res = m_resList.back ();
758  NS_ASSERT (!res.IsTransmitted ());
759  m_resList.pop_back ();
760  res.AddTimestamp (Simulator::Now ());
761  res.IncrementRetry ();
762  m_resList.push_back (res);
763  pkt->AddHeader (CreateRtsHeader (res));
764  pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_RTS));
765  SendPacket (pkt,m_currentRate + m_numRates);
766 
767  }
768  m_state = RTSSENT;
769  NS_ASSERT (!m_rtsEvent.IsRunning ());
770  m_ev->SetAttribute ("Mean", DoubleValue (1 / m_retryRate));
771  double timeout = m_ev->GetValue ();
772  m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::RtsTimeout, this);
773 }
774 
775 void
776 UanMacRc::BlockRtsing (void)
777 {
778  m_rtsBlocked = true;
779 }
780 
781 } // namespace ns3
uint32_t RemoveHeader(Header &header)
Definition: packet.cc:285
keep track of time unit.
Definition: nstime.h:149
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
Cycle broadcast information for.
Callback template class.
Definition: callback.h:369
void DoDispose()
Definition: uan-mac-rc.cc:200
void AddTimestamp(Time t)
Definition: uan-mac-rc.cc:134
void SetAddress(UanAddress addr)
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
uint32_t GetSize(void) const
Definition: packet.h:620
virtual void DoDispose(void)
Definition: object.cc:335
bool IsRunning(void) const
Definition: event-id.cc:59
virtual Address GetAddress(void)
Definition: uan-mac-rc.cc:279
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
network packets
Definition: packet.h:203
uint8_t GetType(void) const
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
a polymophic address class
Definition: address.h:86
virtual Address GetBroadcast(void) const
Definition: uan-mac-rc.cc:340
uint32_t GetNoFrames() const
Definition: uan-mac-rc.cc:86
void SetTransmitted(bool t=true)
Sets reservation transmitted state.
Definition: uan-mac-rc.cc:146
double GetSeconds(void) const
Definition: nstime.h:262
Virtual base class for all UAN MAC protocols.
Definition: uan-mac.h:47
Reservation()
Create empty object with default values.
Definition: uan-mac-rc.cc:45
uint8_t GetRetryNo() const
Definition: uan-mac-rc.cc:110
hold objects of type ns3::Time
Definition: nstime.h:700
virtual void SetForwardUpCb(Callback< void, Ptr< Packet >, const UanAddress & > cb)
Definition: uan-mac-rc.cc:327
virtual uint32_t GetSerializedSize(void) const
static UanAddress ConvertFrom(const Address &address)
Definition: uan-address.cc:54
virtual void Clear(void)
Definition: uan-mac-rc.cc:176
Hold an unsigned integer type.
Definition: uinteger.h:46
Abstraction of packet modulation information.
Definition: uan-tx-mode.h:36
bool IsTransmitted() const
Definition: uan-mac-rc.cc:122
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
Ptr< ExponentialRandomVariable > m_ev
Provides exponential random variables.
Definition: uan-mac-rc.h:223
static UanAddress GetBroadcast(void)
Definition: uan-address.cc:92
void SetFrameNo(uint8_t fn)
Definition: uan-mac-rc.cc:128
Ptr< Packet > Copy(void) const
Definition: packet.cc:131
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
const std::list< std::pair< Ptr< Packet >, UanAddress > > & GetPktList(void) const
Definition: uan-mac-rc.cc:98
UanAddress GetDest(void) const
static Time Now(void)
Definition: simulator.cc:179
int64_t AssignStreams(int64_t stream)
Definition: uan-mac-rc.cc:271
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
virtual void SetAddress(UanAddress addr)
Definition: uan-mac-rc.cc:285
#define NS_LOG_WARN(msg)
Definition: log.h:246
virtual void AttachPhy(Ptr< UanPhy > phy)
Definition: uan-mac-rc.cc:333
uint32_t GetLength() const
Definition: uan-mac-rc.cc:92
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
uint8_t GetFrameNo() const
Definition: uan-mac-rc.cc:104
void Cancel(void)
Definition: event-id.cc:47
virtual uint32_t GetSerializedSize(void) const
void SetType(uint8_t type)
UanAddress GetSrc(void) const
Hold an floating point type.
Definition: double.h:41
virtual uint32_t GetSerializedSize(void) const
a unique identifier for an interface.
Definition: type-id.h:44
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
void IncrementRetry()
Increments retry count by 1.
Definition: uan-mac-rc.cc:140
void AddHeader(const Header &header)
Definition: packet.cc:270
Time GetTimestamp(uint8_t n) const
Definition: uan-mac-rc.cc:116
Extra data header information.
Definition: uan-header-rc.h:41
virtual bool Enqueue(Ptr< Packet > pkt, const Address &dest, uint16_t protocolNumber)
Definition: uan-mac-rc.cc:291
virtual uint32_t GetSerializedSize(void) const