A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
hwmp-protocol.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008,2009 IITP RAS
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  * Authors: Kirill Andreev <andreev@iitp.ru>
19  */
20 
21 #include "hwmp-protocol.h"
22 #include "hwmp-protocol-mac.h"
23 #include "hwmp-tag.h"
24 #include "hwmp-rtable.h"
25 #include "ns3/log.h"
26 #include "ns3/simulator.h"
27 #include "ns3/packet.h"
28 #include "ns3/mesh-point-device.h"
29 #include "ns3/wifi-net-device.h"
30 #include "ns3/mesh-point-device.h"
31 #include "ns3/mesh-wifi-interface-mac.h"
32 #include "ns3/random-variable-stream.h"
33 #include "airtime-metric.h"
34 #include "ie-dot11s-preq.h"
35 #include "ie-dot11s-prep.h"
36 #include "ns3/trace-source-accessor.h"
37 #include "ie-dot11s-perr.h"
38 
39 NS_LOG_COMPONENT_DEFINE ("HwmpProtocol");
40 
41 namespace ns3 {
42 namespace dot11s {
43 
44 NS_OBJECT_ENSURE_REGISTERED (HwmpProtocol);
45 TypeId
46 HwmpProtocol::GetTypeId ()
47 {
48  static TypeId tid = TypeId ("ns3::dot11s::HwmpProtocol")
49  .SetParent<MeshL2RoutingProtocol> ()
50  .AddConstructor<HwmpProtocol> ()
51  .AddAttribute ( "RandomStart",
52  "Random delay at first proactive PREQ",
53  TimeValue (Seconds (0.1)),
54  MakeTimeAccessor (
56  MakeTimeChecker ()
57  )
58  .AddAttribute ( "MaxQueueSize",
59  "Maximum number of packets we can store when resolving route",
60  UintegerValue (255),
61  MakeUintegerAccessor (
62  &HwmpProtocol::m_maxQueueSize),
63  MakeUintegerChecker<uint16_t> (1)
64  )
65  .AddAttribute ( "Dot11MeshHWMPmaxPREQretries",
66  "Maximum number of retries before we suppose the destination to be unreachable",
67  UintegerValue (3),
68  MakeUintegerAccessor (
69  &HwmpProtocol::m_dot11MeshHWMPmaxPREQretries),
70  MakeUintegerChecker<uint8_t> (1)
71  )
72  .AddAttribute ( "Dot11MeshHWMPnetDiameterTraversalTime",
73  "Time we suppose the packet to go from one edge of the network to another",
74  TimeValue (MicroSeconds (1024*100)),
75  MakeTimeAccessor (
76  &HwmpProtocol::m_dot11MeshHWMPnetDiameterTraversalTime),
77  MakeTimeChecker ()
78  )
79  .AddAttribute ( "Dot11MeshHWMPpreqMinInterval",
80  "Minimal interval between to successive PREQs",
81  TimeValue (MicroSeconds (1024*100)),
82  MakeTimeAccessor (
83  &HwmpProtocol::m_dot11MeshHWMPpreqMinInterval),
84  MakeTimeChecker ()
85  )
86  .AddAttribute ( "Dot11MeshHWMPperrMinInterval",
87  "Minimal interval between to successive PREQs",
88  TimeValue (MicroSeconds (1024*100)),
89  MakeTimeAccessor (&HwmpProtocol::m_dot11MeshHWMPperrMinInterval),
90  MakeTimeChecker ()
91  )
92  .AddAttribute ( "Dot11MeshHWMPactiveRootTimeout",
93  "Lifetime of poractive routing information",
94  TimeValue (MicroSeconds (1024*5000)),
95  MakeTimeAccessor (
96  &HwmpProtocol::m_dot11MeshHWMPactiveRootTimeout),
97  MakeTimeChecker ()
98  )
99  .AddAttribute ( "Dot11MeshHWMPactivePathTimeout",
100  "Lifetime of reactive routing information",
101  TimeValue (MicroSeconds (1024*5000)),
102  MakeTimeAccessor (
103  &HwmpProtocol::m_dot11MeshHWMPactivePathTimeout),
104  MakeTimeChecker ()
105  )
106  .AddAttribute ( "Dot11MeshHWMPpathToRootInterval",
107  "Interval between two successive proactive PREQs",
108  TimeValue (MicroSeconds (1024*2000)),
109  MakeTimeAccessor (
110  &HwmpProtocol::m_dot11MeshHWMPpathToRootInterval),
111  MakeTimeChecker ()
112  )
113  .AddAttribute ( "Dot11MeshHWMPrannInterval",
114  "Lifetime of poractive routing information",
115  TimeValue (MicroSeconds (1024*5000)),
116  MakeTimeAccessor (
117  &HwmpProtocol::m_dot11MeshHWMPrannInterval),
118  MakeTimeChecker ()
119  )
120  .AddAttribute ( "MaxTtl",
121  "Initial value of Time To Live field",
122  UintegerValue (32),
123  MakeUintegerAccessor (
124  &HwmpProtocol::m_maxTtl),
125  MakeUintegerChecker<uint8_t> (2)
126  )
127  .AddAttribute ( "UnicastPerrThreshold",
128  "Maximum number of PERR receivers, when we send a PERR as a chain of unicasts",
129  UintegerValue (32),
130  MakeUintegerAccessor (
131  &HwmpProtocol::m_unicastPerrThreshold),
132  MakeUintegerChecker<uint8_t> (1)
133  )
134  .AddAttribute ( "UnicastPreqThreshold",
135  "Maximum number of PREQ receivers, when we send a PREQ as a chain of unicasts",
136  UintegerValue (1),
137  MakeUintegerAccessor (
138  &HwmpProtocol::m_unicastPreqThreshold),
139  MakeUintegerChecker<uint8_t> (1)
140  )
141  .AddAttribute ( "UnicastDataThreshold",
142  "Maximum number ofbroadcast receivers, when we send a broadcast as a chain of unicasts",
143  UintegerValue (1),
144  MakeUintegerAccessor (
145  &HwmpProtocol::m_unicastDataThreshold),
146  MakeUintegerChecker<uint8_t> (1)
147  )
148  .AddAttribute ( "DoFlag",
149  "Destination only HWMP flag",
150  BooleanValue (false),
151  MakeBooleanAccessor (
152  &HwmpProtocol::m_doFlag),
153  MakeBooleanChecker ()
154  )
155  .AddAttribute ( "RfFlag",
156  "Reply and forward flag",
157  BooleanValue (true),
158  MakeBooleanAccessor (
159  &HwmpProtocol::m_rfFlag),
160  MakeBooleanChecker ()
161  )
162  .AddTraceSource ( "RouteDiscoveryTime",
163  "The time of route discovery procedure",
166  )
167  ;
168  return tid;
169 }
170 
171 HwmpProtocol::HwmpProtocol () :
172  m_dataSeqno (1),
173  m_hwmpSeqno (1),
174  m_preqId (0),
175  m_rtable (CreateObject<HwmpRtable> ()),
176  m_randomStart (Seconds (0.1)),
177  m_maxQueueSize (255),
178  m_dot11MeshHWMPmaxPREQretries (3),
179  m_dot11MeshHWMPnetDiameterTraversalTime (MicroSeconds (1024*100)),
180  m_dot11MeshHWMPpreqMinInterval (MicroSeconds (1024*100)),
181  m_dot11MeshHWMPperrMinInterval (MicroSeconds (1024*100)),
182  m_dot11MeshHWMPactiveRootTimeout (MicroSeconds (1024*5000)),
183  m_dot11MeshHWMPactivePathTimeout (MicroSeconds (1024*5000)),
184  m_dot11MeshHWMPpathToRootInterval (MicroSeconds (1024*2000)),
185  m_dot11MeshHWMPrannInterval (MicroSeconds (1024*5000)),
186  m_isRoot (false),
187  m_maxTtl (32),
188  m_unicastPerrThreshold (32),
189  m_unicastPreqThreshold (1),
190  m_unicastDataThreshold (1),
191  m_doFlag (false),
192  m_rfFlag (false)
193 {
195  m_coefficient = CreateObject<UniformRandomVariable> ();
196 }
197 
198 HwmpProtocol::~HwmpProtocol ()
199 {
201 }
202 
203 void
205 {
206  m_coefficient->SetAttribute ("Max", DoubleValue (m_randomStart.GetSeconds ()));
207  if (m_isRoot)
208  {
209  SetRoot ();
210  }
211 }
212 
213 void
215 {
217  for (std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.begin (); i != m_preqTimeouts.end (); i++)
218  {
219  i->second.preqTimeout.Cancel ();
220  }
221  m_proactivePreqTimer.Cancel ();
222  m_preqTimeouts.clear ();
223  m_lastDataSeqno.clear ();
224  m_hwmpSeqnoMetricDatabase.clear ();
225  m_interfaces.clear ();
226  m_rqueue.clear ();
227  m_rtable = 0;
228  m_mp = 0;
229 }
230 
231 bool
233  uint32_t sourceIface,
234  const Mac48Address source,
235  const Mac48Address destination,
236  Ptr<const Packet> constPacket,
237  uint16_t protocolType, //ethrnet 'Protocol' field
239  )
240 {
241  Ptr <Packet> packet = constPacket->Copy ();
242  HwmpTag tag;
243  if (sourceIface == GetMeshPoint ()->GetIfIndex ())
244  {
245  // packet from level 3
246  if (packet->PeekPacketTag (tag))
247  {
248  NS_FATAL_ERROR ("HWMP tag has come with a packet from upper layer. This must not occur...");
249  }
250  //Filling TAG:
251  if (destination == Mac48Address::GetBroadcast ())
252  {
253  tag.SetSeqno (m_dataSeqno++);
254  }
255  tag.SetTtl (m_maxTtl);
256  }
257  else
258  {
259  if (!packet->RemovePacketTag (tag))
260  {
261  NS_FATAL_ERROR ("HWMP tag is supposed to be here at this point.");
262  }
263  tag.DecrementTtl ();
264  if (tag.GetTtl () == 0)
265  {
266  m_stats.droppedTtl++;
267  return false;
268  }
269  }
270  if (destination == Mac48Address::GetBroadcast ())
271  {
272  m_stats.txBroadcast++;
273  m_stats.txBytes += packet->GetSize ();
274  //channel IDs where we have already sent broadcast:
275  std::vector<uint16_t> channels;
276  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
277  {
278  bool shouldSend = true;
279  for (std::vector<uint16_t>::const_iterator chan = channels.begin (); chan != channels.end (); chan++)
280  {
281  if ((*chan) == plugin->second->GetChannelId ())
282  {
283  shouldSend = false;
284  }
285  }
286  if (!shouldSend)
287  {
288  continue;
289  }
290  channels.push_back (plugin->second->GetChannelId ());
291  std::vector<Mac48Address> receivers = GetBroadcastReceivers (plugin->first);
292  for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i++)
293  {
294  Ptr<Packet> packetCopy = packet->Copy ();
295  //
296  // 64-bit Intel valgrind complains about tag.SetAddress (*i). It
297  // likes this just fine.
298  //
299  Mac48Address address = *i;
300  tag.SetAddress (address);
301  packetCopy->AddPacketTag (tag);
302  routeReply (true, packetCopy, source, destination, protocolType, plugin->first);
303  }
304  }
305  }
306  else
307  {
308  return ForwardUnicast (sourceIface, source, destination, packet, protocolType, routeReply, tag.GetTtl ());
309  }
310  return true;
311 }
312 bool
313 HwmpProtocol::RemoveRoutingStuff (uint32_t fromIface, const Mac48Address source,
314  const Mac48Address destination, Ptr<Packet> packet, uint16_t& protocolType)
315 {
316  HwmpTag tag;
317  if (!packet->RemovePacketTag (tag))
318  {
319  NS_FATAL_ERROR ("HWMP tag must exist when packet received from the network");
320  }
321  return true;
322 }
323 bool
324 HwmpProtocol::ForwardUnicast (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination,
325  Ptr<Packet> packet, uint16_t protocolType, RouteReplyCallback routeReply, uint32_t ttl)
326 {
327  NS_ASSERT (destination != Mac48Address::GetBroadcast ());
328  HwmpRtable::LookupResult result = m_rtable->LookupReactive (destination);
329  NS_LOG_DEBUG ("Requested src = "<<source<<", dst = "<<destination<<", I am "<<GetAddress ()<<", RA = "<<result.retransmitter);
330  if (result.retransmitter == Mac48Address::GetBroadcast ())
331  {
332  result = m_rtable->LookupProactive ();
333  }
334  HwmpTag tag;
335  tag.SetAddress (result.retransmitter);
336  tag.SetTtl (ttl);
337  //seqno and metric is not used;
338  packet->AddPacketTag (tag);
339  if (result.retransmitter != Mac48Address::GetBroadcast ())
340  {
341  //reply immediately:
342  routeReply (true, packet, source, destination, protocolType, result.ifIndex);
343  m_stats.txUnicast++;
344  m_stats.txBytes += packet->GetSize ();
345  return true;
346  }
347  if (sourceIface != GetMeshPoint ()->GetIfIndex ())
348  {
349  //Start path error procedure:
350  NS_LOG_DEBUG ("Must Send PERR");
351  result = m_rtable->LookupReactiveExpired (destination);
352  //1. Lookup expired reactive path. If exists - start path error
353  // procedure towards a next hop of this path
354  //2. If there was no reactive path, we lookup expired proactive
355  // path. If exist - start path error procedure towards path to
356  // root
357  if (result.retransmitter == Mac48Address::GetBroadcast ())
358  {
359  result = m_rtable->LookupProactiveExpired ();
360  }
361  if (result.retransmitter != Mac48Address::GetBroadcast ())
362  {
363  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (result.retransmitter);
364  InitiatePathError (MakePathError (destinations));
365  }
366  m_stats.totalDropped++;
367  return false;
368  }
369  //Request a destination:
370  result = m_rtable->LookupReactiveExpired (destination);
371  if (ShouldSendPreq (destination))
372  {
373  uint32_t originator_seqno = GetNextHwmpSeqno ();
374  uint32_t dst_seqno = 0;
375  if (result.retransmitter != Mac48Address::GetBroadcast ())
376  {
377  dst_seqno = result.seqnum;
378  }
379  m_stats.initiatedPreq++;
380  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
381  {
382  i->second->RequestDestination (destination, originator_seqno, dst_seqno);
383  }
384  }
385  QueuedPacket pkt;
386  pkt.pkt = packet;
387  pkt.dst = destination;
388  pkt.src = source;
389  pkt.protocol = protocolType;
390  pkt.reply = routeReply;
391  pkt.inInterface = sourceIface;
392  if (QueuePacket (pkt))
393  {
394  m_stats.totalQueued++;
395  return true;
396  }
397  else
398  {
399  m_stats.totalDropped++;
400  return false;
401  }
402 }
403 void
404 HwmpProtocol::ReceivePreq (IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
405 {
406  preq.IncrementMetric (metric);
407  //acceptance cretirea:
408  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
409  preq.GetOriginatorAddress ());
410  bool freshInfo (true);
411  if (i != m_hwmpSeqnoMetricDatabase.end ())
412  {
413  if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber ()) > 0)
414  {
415  return;
416  }
417  if (i->second.first == preq.GetOriginatorSeqNumber ())
418  {
419  freshInfo = false;
420  if (i->second.second <= preq.GetMetric ())
421  {
422  return;
423  }
424  }
425  }
426  m_hwmpSeqnoMetricDatabase[preq.GetOriginatorAddress ()] =
427  std::make_pair (preq.GetOriginatorSeqNumber (), preq.GetMetric ());
428  NS_LOG_DEBUG ("I am " << GetAddress () << "Accepted preq from address" << from << ", preq:" << preq);
429  std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
430  //Add reactive path to originator:
431  if (
432  (freshInfo) ||
433  (
434  (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).retransmitter == Mac48Address::GetBroadcast ()) ||
435  (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).metric > preq.GetMetric ())
436  )
437  )
438  {
439  m_rtable->AddReactivePath (
440  preq.GetOriginatorAddress (),
441  from,
442  interface,
443  preq.GetMetric (),
444  MicroSeconds (preq.GetLifetime () * 1024),
445  preq.GetOriginatorSeqNumber ()
446  );
447  ReactivePathResolved (preq.GetOriginatorAddress ());
448  }
449  if (
450  (m_rtable->LookupReactive (fromMp).retransmitter == Mac48Address::GetBroadcast ()) ||
451  (m_rtable->LookupReactive (fromMp).metric > metric)
452  )
453  {
454  m_rtable->AddReactivePath (
455  fromMp,
456  from,
457  interface,
458  metric,
459  MicroSeconds (preq.GetLifetime () * 1024),
460  preq.GetOriginatorSeqNumber ()
461  );
462  ReactivePathResolved (fromMp);
463  }
464  for (std::vector<Ptr<DestinationAddressUnit> >::const_iterator i = destinations.begin (); i != destinations.end (); i++)
465  {
466  if ((*i)->GetDestinationAddress () == Mac48Address::GetBroadcast ())
467  {
468  //only proactive PREQ contains destination
469  //address as broadcast! Proactive preq MUST
470  //have destination count equal to 1 and
471  //per destination flags DO and RF
472  NS_ASSERT (preq.GetDestCount () == 1);
473  NS_ASSERT (((*i)->IsDo ()) && ((*i)->IsRf ()));
474  //Add proactive path only if it is the better then existed
475  //before
476  if (
477  ((m_rtable->LookupProactive ()).retransmitter == Mac48Address::GetBroadcast ()) ||
478  ((m_rtable->LookupProactive ()).metric > preq.GetMetric ())
479  )
480  {
481  m_rtable->AddProactivePath (
482  preq.GetMetric (),
483  preq.GetOriginatorAddress (),
484  from,
485  interface,
486  MicroSeconds (preq.GetLifetime () * 1024),
487  preq.GetOriginatorSeqNumber ()
488  );
489  ProactivePathResolved ();
490  }
491  if (!preq.IsNeedNotPrep ())
492  {
493  SendPrep (
494  GetAddress (),
495  preq.GetOriginatorAddress (),
496  from,
497  (uint32_t)0,
498  preq.GetOriginatorSeqNumber (),
499  GetNextHwmpSeqno (),
500  preq.GetLifetime (),
501  interface
502  );
503  }
504  break;
505  }
506  if ((*i)->GetDestinationAddress () == GetAddress ())
507  {
508  SendPrep (
509  GetAddress (),
510  preq.GetOriginatorAddress (),
511  from,
512  (uint32_t)0,
513  preq.GetOriginatorSeqNumber (),
514  GetNextHwmpSeqno (),
515  preq.GetLifetime (),
516  interface
517  );
518  NS_ASSERT (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).retransmitter != Mac48Address::GetBroadcast ());
519  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
520  continue;
521  }
522  //check if can answer:
523  HwmpRtable::LookupResult result = m_rtable->LookupReactive ((*i)->GetDestinationAddress ());
524  if ((!((*i)->IsDo ())) && (result.retransmitter != Mac48Address::GetBroadcast ()))
525  {
526  //have a valid information and can answer
527  uint32_t lifetime = result.lifetime.GetMicroSeconds () / 1024;
528  if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber ()) >= 0))
529  {
530  SendPrep (
531  (*i)->GetDestinationAddress (),
532  preq.GetOriginatorAddress (),
533  from,
534  result.metric,
535  preq.GetOriginatorSeqNumber (),
536  result.seqnum,
537  lifetime,
538  interface
539  );
540  m_rtable->AddPrecursor ((*i)->GetDestinationAddress (), interface, from,
541  MicroSeconds (preq.GetLifetime () * 1024));
542  if ((*i)->IsRf ())
543  {
544  (*i)->SetFlags (true, false, (*i)->IsUsn ()); //DO = 1, RF = 0
545  }
546  else
547  {
548  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
549  continue;
550  }
551  }
552  }
553  }
554  //check if must retransmit:
555  if (preq.GetDestCount () == 0)
556  {
557  return;
558  }
559  //Forward PREQ to all interfaces:
560  NS_LOG_DEBUG ("I am " << GetAddress () << "retransmitting PREQ:" << preq);
561  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
562  {
563  i->second->SendPreq (preq);
564  }
565 }
566 void
567 HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
568 {
569  prep.IncrementMetric (metric);
570  //acceptance cretirea:
571  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
572  prep.GetOriginatorAddress ());
573  bool freshInfo (true);
574  uint32_t sequence = prep.GetDestinationSeqNumber ();
575  if (i != m_hwmpSeqnoMetricDatabase.end ())
576  {
577  if ((int32_t)(i->second.first - sequence) > 0)
578  {
579  return;
580  }
581  if (i->second.first == sequence)
582  {
583  freshInfo = false;
584  }
585  }
586  m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (sequence, prep.GetMetric ());
587  //update routing info
588  //Now add a path to destination and add precursor to source
589  NS_LOG_DEBUG ("I am " << GetAddress () << ", received prep from " << prep.GetOriginatorAddress () << ", receiver was:" << from);
590  HwmpRtable::LookupResult result = m_rtable->LookupReactive (prep.GetDestinationAddress ());
591  //Add a reactive path only if seqno is fresher or it improves the
592  //metric
593  if (
594  (freshInfo) ||
595  (
596  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).retransmitter == Mac48Address::GetBroadcast ()) ||
597  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).metric > prep.GetMetric ())
598  )
599  )
600  {
601  m_rtable->AddReactivePath (
602  prep.GetOriginatorAddress (),
603  from,
604  interface,
605  prep.GetMetric (),
606  MicroSeconds (prep.GetLifetime () * 1024),
607  sequence);
608  m_rtable->AddPrecursor (prep.GetDestinationAddress (), interface, from,
609  MicroSeconds (prep.GetLifetime () * 1024));
610  if (result.retransmitter != Mac48Address::GetBroadcast ())
611  {
612  m_rtable->AddPrecursor (prep.GetOriginatorAddress (), interface, result.retransmitter,
613  result.lifetime);
614  }
615  ReactivePathResolved (prep.GetOriginatorAddress ());
616  }
617  if (
618  ((m_rtable->LookupReactive (fromMp)).retransmitter == Mac48Address::GetBroadcast ()) ||
619  ((m_rtable->LookupReactive (fromMp)).metric > metric)
620  )
621  {
622  m_rtable->AddReactivePath (
623  fromMp,
624  from,
625  interface,
626  metric,
627  MicroSeconds (prep.GetLifetime () * 1024),
628  sequence);
629  ReactivePathResolved (fromMp);
630  }
631  if (prep.GetDestinationAddress () == GetAddress ())
632  {
633  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", resolved "<<prep.GetOriginatorAddress ());
634  return;
635  }
636  if (result.retransmitter == Mac48Address::GetBroadcast ())
637  {
638  return;
639  }
640  //Forward PREP
641  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (result.ifIndex);
642  NS_ASSERT (prep_sender != m_interfaces.end ());
643  prep_sender->second->SendPrep (prep, result.retransmitter);
644 }
645 void
646 HwmpProtocol::ReceivePerr (std::vector<FailedDestination> destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
647 {
648  //Acceptance cretirea:
649  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", received PERR from "<<from);
650  std::vector<FailedDestination> retval;
651  HwmpRtable::LookupResult result;
652  for (unsigned int i = 0; i < destinations.size (); i++)
653  {
654  result = m_rtable->LookupReactiveExpired (destinations[i].destination);
655  if (!(
656  (result.retransmitter != from) ||
657  (result.ifIndex != interface) ||
658  ((int32_t)(result.seqnum - destinations[i].seqnum) > 0)
659  ))
660  {
661  retval.push_back (destinations[i]);
662  }
663  }
664  if (retval.size () == 0)
665  {
666  return;
667  }
668  ForwardPathError (MakePathError (retval));
669 }
670 void
671 HwmpProtocol::SendPrep (
672  Mac48Address src,
673  Mac48Address dst,
674  Mac48Address retransmitter,
675  uint32_t initMetric,
676  uint32_t originatorDsn,
677  uint32_t destinationSN,
678  uint32_t lifetime,
679  uint32_t interface)
680 {
681  IePrep prep;
682  prep.SetHopcount (0);
683  prep.SetTtl (m_maxTtl);
684  prep.SetDestinationAddress (dst);
685  prep.SetDestinationSeqNumber (destinationSN);
686  prep.SetLifetime (lifetime);
687  prep.SetMetric (initMetric);
688  prep.SetOriginatorAddress (src);
689  prep.SetOriginatorSeqNumber (originatorDsn);
690  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (interface);
691  NS_ASSERT (prep_sender != m_interfaces.end ());
692  prep_sender->second->SendPrep (prep, retransmitter);
693  m_stats.initiatedPrep++;
694 }
695 bool
697 {
698  m_mp = mp;
699  std::vector<Ptr<NetDevice> > interfaces = mp->GetInterfaces ();
700  for (std::vector<Ptr<NetDevice> >::const_iterator i = interfaces.begin (); i != interfaces.end (); i++)
701  {
702  // Checking for compatible net device
703  Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice> ();
704  if (wifiNetDev == 0)
705  {
706  return false;
707  }
708  Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
709  if (mac == 0)
710  {
711  return false;
712  }
713  // Installing plugins:
714  Ptr<HwmpProtocolMac> hwmpMac = Create<HwmpProtocolMac> (wifiNetDev->GetIfIndex (), this);
715  m_interfaces[wifiNetDev->GetIfIndex ()] = hwmpMac;
716  mac->InstallPlugin (hwmpMac);
717  //Installing airtime link metric:
718  Ptr<AirtimeLinkMetricCalculator> metric = CreateObject <AirtimeLinkMetricCalculator> ();
719  mac->SetLinkMetricCallback (MakeCallback (&AirtimeLinkMetricCalculator::CalculateMetric, metric));
720  }
721  mp->SetRoutingProtocol (this);
722  // Mesh point aggregates all installed protocols
723  mp->AggregateObject (this);
724  m_address = Mac48Address::ConvertFrom (mp->GetAddress ()); // address;
725  return true;
726 }
727 void
728 HwmpProtocol::PeerLinkStatus (Mac48Address meshPointAddress, Mac48Address peerAddress, uint32_t interface, bool status)
729 {
730  if (status)
731  {
732  return;
733  }
734  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (peerAddress);
735  InitiatePathError (MakePathError (destinations));
736 }
737 void
738 HwmpProtocol::SetNeighboursCallback (Callback<std::vector<Mac48Address>, uint32_t> cb)
739 {
740  m_neighboursCallback = cb;
741 }
742 bool
744 {
745  if (source == GetAddress ())
746  {
747  return true;
748  }
749  std::map<Mac48Address, uint32_t,std::less<Mac48Address> >::const_iterator i = m_lastDataSeqno.find (source);
750  if (i == m_lastDataSeqno.end ())
751  {
752  m_lastDataSeqno[source] = seqno;
753  }
754  else
755  {
756  if ((int32_t)(i->second - seqno) >= 0)
757  {
758  return true;
759  }
760  m_lastDataSeqno[source] = seqno;
761  }
762  return false;
763 }
765 HwmpProtocol::MakePathError (std::vector<FailedDestination> destinations)
766 {
767  PathError retval;
768  //HwmpRtable increments a sequence number as written in 11B.9.7.2
769  retval.receivers = GetPerrReceivers (destinations);
770  if (retval.receivers.size () == 0)
771  {
772  return retval;
773  }
774  m_stats.initiatedPerr++;
775  for (unsigned int i = 0; i < destinations.size (); i++)
776  {
777  retval.destinations.push_back (destinations[i]);
778  m_rtable->DeleteReactivePath (destinations[i].destination);
779  }
780  return retval;
781 }
782 void
784 {
785  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
786  {
787  std::vector<Mac48Address> receivers_for_interface;
788  for (unsigned int j = 0; j < perr.receivers.size (); j++)
789  {
790  if (i->first == perr.receivers[j].first)
791  {
792  receivers_for_interface.push_back (perr.receivers[j].second);
793  }
794  }
795  i->second->InitiatePerr (perr.destinations, receivers_for_interface);
796  }
797 }
798 void
800 {
801  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
802  {
803  std::vector<Mac48Address> receivers_for_interface;
804  for (unsigned int j = 0; j < perr.receivers.size (); j++)
805  {
806  if (i->first == perr.receivers[j].first)
807  {
808  receivers_for_interface.push_back (perr.receivers[j].second);
809  }
810  }
811  i->second->ForwardPerr (perr.destinations, receivers_for_interface);
812  }
813 }
814 
815 std::vector<std::pair<uint32_t, Mac48Address> >
816 HwmpProtocol::GetPerrReceivers (std::vector<FailedDestination> failedDest)
817 {
819  for (unsigned int i = 0; i < failedDest.size (); i++)
820  {
821  HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors (failedDest[i].destination);
822  m_rtable->DeleteReactivePath (failedDest[i].destination);
823  m_rtable->DeleteProactivePath (failedDest[i].destination);
824  for (unsigned int j = 0; j < precursors.size (); j++)
825  {
826  retval.push_back (precursors[j]);
827  }
828  }
829  //Check if we have dublicates in retval and precursors:
830  for (unsigned int i = 0; i < retval.size (); i++)
831  {
832  for (unsigned int j = i+1; j < retval.size (); j++)
833  {
834  if (retval[i].second == retval[j].second)
835  {
836  retval.erase (retval.begin () + j);
837  }
838  }
839  }
840  return retval;
841 }
842 std::vector<Mac48Address>
843 HwmpProtocol::GetPreqReceivers (uint32_t interface)
844 {
845  std::vector<Mac48Address> retval;
846  if (!m_neighboursCallback.IsNull ())
847  {
848  retval = m_neighboursCallback (interface);
849  }
850  if ((retval.size () >= m_unicastPreqThreshold) || (retval.size () == 0))
851  {
852  retval.clear ();
853  retval.push_back (Mac48Address::GetBroadcast ());
854  }
855  return retval;
856 }
857 std::vector<Mac48Address>
859 {
860  std::vector<Mac48Address> retval;
861  if (!m_neighboursCallback.IsNull ())
862  {
863  retval = m_neighboursCallback (interface);
864  }
865  if ((retval.size () >= m_unicastDataThreshold) || (retval.size () == 0))
866  {
867  retval.clear ();
868  retval.push_back (Mac48Address::GetBroadcast ());
869  }
870  return retval;
871 }
872 
873 bool
874 HwmpProtocol::QueuePacket (QueuedPacket packet)
875 {
876  if (m_rqueue.size () > m_maxQueueSize)
877  {
878  return false;
879  }
880  m_rqueue.push_back (packet);
881  return true;
882 }
883 
884 HwmpProtocol::QueuedPacket
885 HwmpProtocol::DequeueFirstPacketByDst (Mac48Address dst)
886 {
887  QueuedPacket retval;
888  retval.pkt = 0;
889  for (std::vector<QueuedPacket>::iterator i = m_rqueue.begin (); i != m_rqueue.end (); i++)
890  {
891  if ((*i).dst == dst)
892  {
893  retval = (*i);
894  m_rqueue.erase (i);
895  break;
896  }
897  }
898  return retval;
899 }
900 
901 HwmpProtocol::QueuedPacket
902 HwmpProtocol::DequeueFirstPacket ()
903 {
904  QueuedPacket retval;
905  retval.pkt = 0;
906  if (m_rqueue.size () != 0)
907  {
908  retval = m_rqueue[0];
909  m_rqueue.erase (m_rqueue.begin ());
910  }
911  return retval;
912 }
913 
914 void
915 HwmpProtocol::ReactivePathResolved (Mac48Address dst)
916 {
917  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
918  if (i != m_preqTimeouts.end ())
919  {
920  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
921  }
922 
923  HwmpRtable::LookupResult result = m_rtable->LookupReactive (dst);
924  NS_ASSERT (result.retransmitter != Mac48Address::GetBroadcast ());
925  //Send all packets stored for this destination
926  QueuedPacket packet = DequeueFirstPacketByDst (dst);
927  while (packet.pkt != 0)
928  {
929  //set RA tag for retransmitter:
930  HwmpTag tag;
931  packet.pkt->RemovePacketTag (tag);
932  tag.SetAddress (result.retransmitter);
933  packet.pkt->AddPacketTag (tag);
934  m_stats.txUnicast++;
935  m_stats.txBytes += packet.pkt->GetSize ();
936  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
937 
938  packet = DequeueFirstPacketByDst (dst);
939  }
940 }
941 void
942 HwmpProtocol::ProactivePathResolved ()
943 {
944  //send all packets to root
945  HwmpRtable::LookupResult result = m_rtable->LookupProactive ();
946  NS_ASSERT (result.retransmitter != Mac48Address::GetBroadcast ());
947  QueuedPacket packet = DequeueFirstPacket ();
948  while (packet.pkt != 0)
949  {
950  //set RA tag for retransmitter:
951  HwmpTag tag;
952  if (!packet.pkt->RemovePacketTag (tag))
953  {
954  NS_FATAL_ERROR ("HWMP tag must be present at this point");
955  }
956  tag.SetAddress (result.retransmitter);
957  packet.pkt->AddPacketTag (tag);
958  m_stats.txUnicast++;
959  m_stats.txBytes += packet.pkt->GetSize ();
960  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
961 
962  packet = DequeueFirstPacket ();
963  }
964 }
965 
966 bool
968 {
969  std::map<Mac48Address, PreqEvent>::const_iterator i = m_preqTimeouts.find (dst);
970  if (i == m_preqTimeouts.end ())
971  {
972  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
973  Time (m_dot11MeshHWMPnetDiameterTraversalTime * 2),
974  &HwmpProtocol::RetryPathDiscovery, this, dst, 1);
975  m_preqTimeouts[dst].whenScheduled = Simulator::Now ();
976  return true;
977  }
978  return false;
979 }
980 void
982 {
983  HwmpRtable::LookupResult result = m_rtable->LookupReactive (dst);
984  if (result.retransmitter == Mac48Address::GetBroadcast ())
985  {
986  result = m_rtable->LookupProactive ();
987  }
988  if (result.retransmitter != Mac48Address::GetBroadcast ())
989  {
990  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
991  NS_ASSERT (i != m_preqTimeouts.end ());
992  m_preqTimeouts.erase (i);
993  return;
994  }
995  if (numOfRetry > m_dot11MeshHWMPmaxPREQretries)
996  {
997  QueuedPacket packet = DequeueFirstPacketByDst (dst);
998  //purge queue and delete entry from retryDatabase
999  while (packet.pkt != 0)
1000  {
1001  m_stats.totalDropped++;
1002  packet.reply (false, packet.pkt, packet.src, packet.dst, packet.protocol, HwmpRtable::MAX_METRIC);
1003  packet = DequeueFirstPacketByDst (dst);
1004  }
1005  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1006  NS_ASSERT (i != m_preqTimeouts.end ());
1007  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
1008  m_preqTimeouts.erase (i);
1009  return;
1010  }
1011  numOfRetry++;
1012  uint32_t originator_seqno = GetNextHwmpSeqno ();
1013  uint32_t dst_seqno = m_rtable->LookupReactiveExpired (dst).seqnum;
1014  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1015  {
1016  i->second->RequestDestination (dst, originator_seqno, dst_seqno);
1017  }
1018  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
1019  Time ((2 * (numOfRetry + 1)) * m_dot11MeshHWMPnetDiameterTraversalTime),
1020  &HwmpProtocol::RetryPathDiscovery, this, dst, numOfRetry);
1021 }
1022 //Proactive PREQ routines:
1023 void
1024 HwmpProtocol::SetRoot ()
1025 {
1026  Time randomStart = Seconds (m_coefficient->GetValue ());
1027  m_proactivePreqTimer = Simulator::Schedule (randomStart, &HwmpProtocol::SendProactivePreq, this);
1028  NS_LOG_DEBUG ("ROOT IS: " << m_address);
1029  m_isRoot = true;
1030 }
1031 void
1032 HwmpProtocol::UnsetRoot ()
1033 {
1034  m_proactivePreqTimer.Cancel ();
1035 }
1036 void
1038 {
1039  IePreq preq;
1040  //By default: must answer
1041  preq.SetHopcount (0);
1042  preq.SetTTL (m_maxTtl);
1043  preq.SetLifetime (m_dot11MeshHWMPactiveRootTimeout.GetMicroSeconds () /1024);
1044  //\attention: do not forget to set originator address, sequence
1045  //number and preq ID in HWMP-MAC plugin
1047  preq.SetOriginatorAddress (GetAddress ());
1048  preq.SetPreqID (GetNextPreqId ());
1049  preq.SetOriginatorSeqNumber (GetNextHwmpSeqno ());
1050  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1051  {
1052  i->second->SendPreq (preq);
1053  }
1054  m_proactivePreqTimer = Simulator::Schedule (m_dot11MeshHWMPpathToRootInterval, &HwmpProtocol::SendProactivePreq, this);
1055 }
1056 bool
1057 HwmpProtocol::GetDoFlag ()
1058 {
1059  return m_doFlag;
1060 }
1061 bool
1062 HwmpProtocol::GetRfFlag ()
1063 {
1064  return m_rfFlag;
1065 }
1066 Time
1067 HwmpProtocol::GetPreqMinInterval ()
1068 {
1069  return m_dot11MeshHWMPpreqMinInterval;
1070 }
1071 Time
1072 HwmpProtocol::GetPerrMinInterval ()
1073 {
1074  return m_dot11MeshHWMPperrMinInterval;
1075 }
1076 uint8_t
1077 HwmpProtocol::GetMaxTtl ()
1078 {
1079  return m_maxTtl;
1080 }
1081 uint32_t
1082 HwmpProtocol::GetNextPreqId ()
1083 {
1084  m_preqId++;
1085  return m_preqId;
1086 }
1087 uint32_t
1088 HwmpProtocol::GetNextHwmpSeqno ()
1089 {
1090  m_hwmpSeqno++;
1091  return m_hwmpSeqno;
1092 }
1093 uint32_t
1094 HwmpProtocol::GetActivePathLifetime ()
1095 {
1096  return m_dot11MeshHWMPactivePathTimeout.GetMicroSeconds () / 1024;
1097 }
1098 uint8_t
1099 HwmpProtocol::GetUnicastPerrThreshold ()
1100 {
1101  return m_unicastPerrThreshold;
1102 }
1103 Mac48Address
1105 {
1106  return m_address;
1107 }
1108 //Statistics:
1109 HwmpProtocol::Statistics::Statistics () :
1110  txUnicast (0),
1111  txBroadcast (0),
1112  txBytes (0),
1113  droppedTtl (0),
1114  totalQueued (0),
1115  totalDropped (0),
1116  initiatedPreq (0),
1117  initiatedPrep (0),
1118  initiatedPerr (0)
1119 {
1120 }
1121 void HwmpProtocol::Statistics::Print (std::ostream & os) const
1122 {
1123  os << "<Statistics "
1124  "txUnicast=\"" << txUnicast << "\" "
1125  "txBroadcast=\"" << txBroadcast << "\" "
1126  "txBytes=\"" << txBytes << "\" "
1127  "droppedTtl=\"" << droppedTtl << "\" "
1128  "totalQueued=\"" << totalQueued << "\" "
1129  "totalDropped=\"" << totalDropped << "\" "
1130  "initiatedPreq=\"" << initiatedPreq << "\" "
1131  "initiatedPrep=\"" << initiatedPrep << "\" "
1132  "initiatedPerr=\"" << initiatedPerr << "\"/>" << std::endl;
1133 }
1134 void
1135 HwmpProtocol::Report (std::ostream & os) const
1136 {
1137  os << "<Hwmp "
1138  "address=\"" << m_address << "\"" << std::endl <<
1139  "maxQueueSize=\"" << m_maxQueueSize << "\"" << std::endl <<
1140  "Dot11MeshHWMPmaxPREQretries=\"" << (uint16_t)m_dot11MeshHWMPmaxPREQretries << "\"" << std::endl <<
1141  "Dot11MeshHWMPnetDiameterTraversalTime=\"" << m_dot11MeshHWMPnetDiameterTraversalTime.GetSeconds () << "\"" << std::endl <<
1142  "Dot11MeshHWMPpreqMinInterval=\"" << m_dot11MeshHWMPpreqMinInterval.GetSeconds () << "\"" << std::endl <<
1143  "Dot11MeshHWMPperrMinInterval=\"" << m_dot11MeshHWMPperrMinInterval.GetSeconds () << "\"" << std::endl <<
1144  "Dot11MeshHWMPactiveRootTimeout=\"" << m_dot11MeshHWMPactiveRootTimeout.GetSeconds () << "\"" << std::endl <<
1145  "Dot11MeshHWMPactivePathTimeout=\"" << m_dot11MeshHWMPactivePathTimeout.GetSeconds () << "\"" << std::endl <<
1146  "Dot11MeshHWMPpathToRootInterval=\"" << m_dot11MeshHWMPpathToRootInterval.GetSeconds () << "\"" << std::endl <<
1147  "Dot11MeshHWMPrannInterval=\"" << m_dot11MeshHWMPrannInterval.GetSeconds () << "\"" << std::endl <<
1148  "isRoot=\"" << m_isRoot << "\"" << std::endl <<
1149  "maxTtl=\"" << (uint16_t)m_maxTtl << "\"" << std::endl <<
1150  "unicastPerrThreshold=\"" << (uint16_t)m_unicastPerrThreshold << "\"" << std::endl <<
1151  "unicastPreqThreshold=\"" << (uint16_t)m_unicastPreqThreshold << "\"" << std::endl <<
1152  "unicastDataThreshold=\"" << (uint16_t)m_unicastDataThreshold << "\"" << std::endl <<
1153  "doFlag=\"" << m_doFlag << "\"" << std::endl <<
1154  "rfFlag=\"" << m_rfFlag << "\">" << std::endl;
1155  m_stats.Print (os);
1156  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
1157  {
1158  plugin->second->Report (os);
1159  }
1160  os << "</Hwmp>" << std::endl;
1161 }
1162 void
1163 HwmpProtocol::ResetStats ()
1164 {
1165  m_stats = Statistics ();
1166  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
1167  {
1168  plugin->second->ResetStats ();
1169  }
1170 }
1171 
1172 int64_t
1174 {
1175  NS_LOG_FUNCTION (this << stream);
1176  m_coefficient->SetStream (stream);
1177  return 1;
1178 }
1179 
1180 HwmpProtocol::QueuedPacket::QueuedPacket () :
1181  pkt (0),
1182  protocol (0),
1183  inInterface (0)
1184 {
1185 }
1186 } // namespace dot11s
1187 } // namespace ns3
Structure of path error: IePerr and list of receivers: interfaces and MAC address.
bool RequestRoute(uint32_t sourceIface, const Mac48Address source, const Mac48Address destination, Ptr< const Packet > packet, uint16_t protocolType, RouteReplyCallback routeReply)
Route request, inherited from MeshL2RoutingProtocol.
keep track of time unit.
Definition: nstime.h:149
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
Callback template class.
Definition: callback.h:369
Hwmp tag implements interaction between HWMP protocol and MeshWifiMac.
Definition: hwmp-tag.h:48
static const uint32_t MAX_METRIC
Maximum (the best?) path metric.
Definition: hwmp-rtable.h:41
Route lookup result, return type of LookupXXX methods.
Definition: hwmp-rtable.h:44
void AddPacketTag(const Tag &tag) const
Definition: packet.cc:868
#define NS_ASSERT(condition)
Definition: assert.h:64
void ForwardPathError(PathError perr)
Forwards a received path error.
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
uint32_t GetSize(void) const
Definition: packet.h:620
bool Install(Ptr< MeshPointDevice >)
Install HWMP on given mesh point.
void InitiatePathError(PathError perr)
Passes a self-generated PERR to interface-plugin.
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
TracedCallback< Time > m_routeDiscoveryTimeCallback
Route discovery time:
void SendProactivePreq()
Proactive Preq routines:
bool DropDataFrame(uint32_t seqno, Mac48Address source)
MAC-plugin asks whether the frame can be dropped. Protocol automatically updates seqno.
std::vector< std::pair< uint32_t, Mac48Address > > PrecursorList
Path precursor = {MAC, interface ID}.
Definition: hwmp-rtable.h:62
std::vector< Mac48Address > GetPreqReceivers(uint32_t interface)
double GetSeconds(void) const
Definition: nstime.h:262
bool RemoveRoutingStuff(uint32_t fromIface, const Mac48Address source, const Mac48Address destination, Ptr< Packet > packet, uint16_t &protocolType)
Cleanup packet from all tags.
bool PeekPacketTag(Tag &tag) const
Definition: packet.cc:881
std::vector< std::pair< uint32_t, Mac48Address > > GetPerrReceivers(std::vector< FailedDestination > failedDest)
void RetryPathDiscovery(Mac48Address dst, uint8_t numOfRetry)
Generates PREQ retry when retry timeout has expired and route is still unresolved.
See 7.3.2.96 of 802.11s draft 2.07.
bool ForwardUnicast(uint32_t sourceIface, const Mac48Address source, const Mac48Address destination, Ptr< Packet > packet, uint16_t protocolType, RouteReplyCallback routeReply, uint32_t ttl)
Like RequestRoute, but for unicast packets.
Packet waiting its routing information.
Hold together all Wifi-related objects.This class holds together ns3::WifiChannel, ns3::WifiPhy, ns3::WifiMac, and, ns3::WifiRemoteStationManager.
static Mac48Address GetBroadcast(void)
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
Time m_randomStart
Random start in Proactive PREQ propagation.
static Mac48Address ConvertFrom(const Address &address)
Ptr< Packet > Copy(void) const
Definition: packet.cc:131
void AddDestinationAddressElement(bool doFlag, bool rfFlag, Mac48Address dest_address, uint32_t dest_seq_number)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
void DelDestinationAddressElement(Mac48Address dest_address)
Delete a destination address unit by destination.
PathError MakePathError(std::vector< FailedDestination > destinations)
forms a path error information element when list of destination fails on a given interface ...
std::vector< std::pair< uint32_t, Mac48Address > > receivers
list of PathError receivers (in case of unicast PERR)
an EUI-48 address
Definition: mac48-address.h:41
static Time Now(void)
Definition: simulator.cc:179
std::vector< Ptr< DestinationAddressUnit > > GetDestinationList()
Get all destinations, which are stored in PREQ:
RouteReplyCallback reply
how to reply
void Report(std::ostream &) const
Statistics:
Ptr< UniformRandomVariable > m_coefficient
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
std::vector< Mac48Address > GetBroadcastReceivers(uint32_t interface)
std::vector< FailedDestination > destinations
destination list: Mac48Address and sequence number
bool RemovePacketTag(Tag &tag)
Definition: packet.cc:874
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
uint32_t inInterface
incoming device interface ID. (if packet has come from upper layers, this is Mesh point ID) ...
bool ShouldSendPreq(Mac48Address dst)
checks when the last path discovery procedure was started for a given destination.
Hold an floating point type.
Definition: double.h:41
Basic MAC of mesh point Wi-Fi interface. Its function is extendable through plugins mechanism...
Time MicroSeconds(uint64_t us)
create ns3::Time instances in units of microseconds.
Definition: nstime.h:615
int64_t AssignStreams(int64_t stream)
void SetNeighboursCallback(Callback< std::vector< Mac48Address >, uint32_t > cb)
This callback is used to obtain active neighbours on a given interface.