A Discrete-Event Network Simulator
API
hwmp-protocol.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008,2009 IITP RAS
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Authors: Kirill Andreev <andreev@iitp.ru>
18  */
19 
20 #include "hwmp-protocol.h"
21 
22 #include "airtime-metric.h"
23 #include "hwmp-protocol-mac.h"
24 #include "hwmp-rtable.h"
25 #include "hwmp-tag.h"
26 #include "ie-dot11s-perr.h"
27 #include "ie-dot11s-prep.h"
28 #include "ie-dot11s-preq.h"
29 
30 #include "ns3/log.h"
31 #include "ns3/mesh-point-device.h"
32 #include "ns3/mesh-wifi-interface-mac.h"
33 #include "ns3/packet.h"
34 #include "ns3/pointer.h"
35 #include "ns3/random-variable-stream.h"
36 #include "ns3/simulator.h"
37 #include "ns3/string.h"
38 #include "ns3/trace-source-accessor.h"
39 #include "ns3/wifi-net-device.h"
40 
41 namespace ns3
42 {
43 
44 NS_LOG_COMPONENT_DEFINE("HwmpProtocol");
45 
46 namespace dot11s
47 {
48 
49 NS_OBJECT_ENSURE_REGISTERED(HwmpProtocol);
50 
51 TypeId
53 {
54  static TypeId tid =
55  TypeId("ns3::dot11s::HwmpProtocol")
57  .SetGroupName("Mesh")
58  .AddConstructor<HwmpProtocol>()
59  .AddAttribute("RandomStart",
60  "Random delay at first proactive PREQ",
61  TimeValue(Seconds(0.1)),
64  .AddAttribute("MaxQueueSize",
65  "Maximum number of packets we can store when resolving route",
66  UintegerValue(255),
68  MakeUintegerChecker<uint16_t>(1))
69  .AddAttribute(
70  "Dot11MeshHWMPmaxPREQretries",
71  "Maximum number of retries before we suppose the destination to be unreachable",
72  UintegerValue(3),
74  MakeUintegerChecker<uint8_t>(1))
75  .AddAttribute(
76  "Dot11MeshHWMPnetDiameterTraversalTime",
77  "Time we suppose the packet to go from one edge of the network to another",
78  TimeValue(MicroSeconds(1024 * 100)),
81  .AddAttribute("Dot11MeshHWMPpreqMinInterval",
82  "Minimal interval between to successive PREQs",
83  TimeValue(MicroSeconds(1024 * 100)),
86  .AddAttribute("Dot11MeshHWMPperrMinInterval",
87  "Minimal interval between to successive PREQs",
88  TimeValue(MicroSeconds(1024 * 100)),
91  .AddAttribute("Dot11MeshHWMPactiveRootTimeout",
92  "Lifetime of proactive routing information",
93  TimeValue(MicroSeconds(1024 * 5000)),
96  .AddAttribute("Dot11MeshHWMPactivePathTimeout",
97  "Lifetime of reactive routing information",
98  TimeValue(MicroSeconds(1024 * 5000)),
100  MakeTimeChecker())
101  .AddAttribute("Dot11MeshHWMPpathToRootInterval",
102  "Interval between two successive proactive PREQs",
103  TimeValue(MicroSeconds(1024 * 2000)),
105  MakeTimeChecker())
106  .AddAttribute("Dot11MeshHWMPrannInterval",
107  "Lifetime of proactive routing information",
108  TimeValue(MicroSeconds(1024 * 5000)),
110  MakeTimeChecker())
111  .AddAttribute("MaxTtl",
112  "Initial value of Time To Live field",
113  UintegerValue(32),
115  MakeUintegerChecker<uint8_t>(2))
116  .AddAttribute(
117  "UnicastPerrThreshold",
118  "Maximum number of PERR receivers, when we send a PERR as a chain of unicasts",
119  UintegerValue(32),
121  MakeUintegerChecker<uint8_t>(1))
122  .AddAttribute(
123  "UnicastPreqThreshold",
124  "Maximum number of PREQ receivers, when we send a PREQ as a chain of unicasts",
125  UintegerValue(1),
127  MakeUintegerChecker<uint8_t>(1))
128  .AddAttribute("UnicastDataThreshold",
129  "Maximum number of broadcast receivers, when we send a broadcast as a "
130  "chain of unicasts",
131  UintegerValue(1),
133  MakeUintegerChecker<uint8_t>(1))
134  .AddAttribute("DoFlag",
135  "Destination only HWMP flag",
136  BooleanValue(false),
139  .AddAttribute("RfFlag",
140  "Reply and forward flag",
141  BooleanValue(true),
144  .AddTraceSource("RouteDiscoveryTime",
145  "The time of route discovery procedure",
147  "ns3::Time::TracedCallback")
148  .AddTraceSource("RouteChange",
149  "Routing table changed",
151  "ns3::HwmpProtocol::RouteChangeTracedCallback");
152  return tid;
153 }
154 
156  : m_dataSeqno(1),
157  m_hwmpSeqno(1),
158  m_preqId(0),
159  m_rtable(CreateObject<HwmpRtable>()),
160  m_randomStart(Seconds(0.1)),
161  m_maxQueueSize(255),
162  m_dot11MeshHWMPmaxPREQretries(3),
163  m_dot11MeshHWMPnetDiameterTraversalTime(MicroSeconds(1024 * 100)),
164  m_dot11MeshHWMPpreqMinInterval(MicroSeconds(1024 * 100)),
165  m_dot11MeshHWMPperrMinInterval(MicroSeconds(1024 * 100)),
166  m_dot11MeshHWMPactiveRootTimeout(MicroSeconds(1024 * 5000)),
167  m_dot11MeshHWMPactivePathTimeout(MicroSeconds(1024 * 5000)),
168  m_dot11MeshHWMPpathToRootInterval(MicroSeconds(1024 * 2000)),
169  m_dot11MeshHWMPrannInterval(MicroSeconds(1024 * 5000)),
170  m_isRoot(false),
171  m_maxTtl(32),
172  m_unicastPerrThreshold(32),
173  m_unicastPreqThreshold(1),
174  m_unicastDataThreshold(1),
175  m_doFlag(false),
176  m_rfFlag(false)
177 {
178  NS_LOG_FUNCTION(this);
179  m_coefficient = CreateObject<UniformRandomVariable>();
180 }
181 
183 {
184  NS_LOG_FUNCTION(this);
185 }
186 
187 void
189 {
190  NS_LOG_FUNCTION(this);
192  if (m_isRoot)
193  {
194  Time randomStart = Seconds(m_coefficient->GetValue());
197  }
198 }
199 
200 void
202 {
203  NS_LOG_FUNCTION(this);
204  for (std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.begin();
205  i != m_preqTimeouts.end();
206  i++)
207  {
208  i->second.preqTimeout.Cancel();
209  }
211  m_preqTimeouts.clear();
212  m_lastDataSeqno.clear();
214  m_interfaces.clear();
215  m_rqueue.clear();
216  m_rtable = nullptr;
217  m_mp = nullptr;
218 }
219 
220 bool
221 HwmpProtocol::RequestRoute(uint32_t sourceIface,
222  const Mac48Address source,
223  const Mac48Address destination,
224  Ptr<const Packet> constPacket,
225  uint16_t protocolType, // ethrnet 'Protocol' field
227 {
228  NS_LOG_FUNCTION(this << sourceIface << source << destination << constPacket << protocolType);
229  Ptr<Packet> packet = constPacket->Copy();
230  HwmpTag tag;
231  if (sourceIface == GetMeshPoint()->GetIfIndex())
232  {
233  // packet from level 3
234  if (packet->PeekPacketTag(tag))
235  {
237  "HWMP tag has come with a packet from upper layer. This must not occur...");
238  }
239  // Filling TAG:
240  if (destination == Mac48Address::GetBroadcast())
241  {
242  tag.SetSeqno(m_dataSeqno++);
243  }
244  tag.SetTtl(m_maxTtl);
245  }
246  else
247  {
248  if (!packet->RemovePacketTag(tag))
249  {
250  NS_FATAL_ERROR("HWMP tag is supposed to be here at this point.");
251  }
252  tag.DecrementTtl();
253  if (tag.GetTtl() == 0)
254  {
255  NS_LOG_DEBUG("Dropping frame due to TTL expiry");
257  return false;
258  }
259  }
260  if (destination == Mac48Address::GetBroadcast())
261  {
263  m_stats.txBytes += packet->GetSize();
264  // channel IDs where we have already sent broadcast:
265  std::vector<uint16_t> channels;
266  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin();
267  plugin != m_interfaces.end();
268  plugin++)
269  {
270  bool shouldSend = true;
271  for (std::vector<uint16_t>::const_iterator chan = channels.begin();
272  chan != channels.end();
273  chan++)
274  {
275  if ((*chan) == plugin->second->GetChannelId())
276  {
277  shouldSend = false;
278  }
279  }
280  if (!shouldSend)
281  {
282  continue;
283  }
284  channels.push_back(plugin->second->GetChannelId());
285  std::vector<Mac48Address> receivers = GetBroadcastReceivers(plugin->first);
286  for (std::vector<Mac48Address>::const_iterator i = receivers.begin();
287  i != receivers.end();
288  i++)
289  {
290  Ptr<Packet> packetCopy = packet->Copy();
291  //
292  // 64-bit Intel valgrind complains about tag.SetAddress (*i). It
293  // likes this just fine.
294  //
295  Mac48Address address = *i;
296  tag.SetAddress(address);
297  packetCopy->AddPacketTag(tag);
298  NS_LOG_DEBUG("Sending route reply for broadcast; address " << address);
299  routeReply(true, packetCopy, source, destination, protocolType, plugin->first);
300  }
301  }
302  }
303  else
304  {
305  return ForwardUnicast(sourceIface,
306  source,
307  destination,
308  packet,
309  protocolType,
310  routeReply,
311  tag.GetTtl());
312  }
313  return true;
314 }
315 
316 bool
318  const Mac48Address source,
319  const Mac48Address destination,
320  Ptr<Packet> packet,
321  uint16_t& protocolType)
322 {
323  HwmpTag tag;
324  if (!packet->RemovePacketTag(tag))
325  {
326  NS_FATAL_ERROR("HWMP tag must exist when packet received from the network");
327  }
328  return true;
329 }
330 
331 bool
332 HwmpProtocol::ForwardUnicast(uint32_t sourceIface,
333  const Mac48Address source,
334  const Mac48Address destination,
335  Ptr<Packet> packet,
336  uint16_t protocolType,
337  RouteReplyCallback routeReply,
338  uint32_t ttl)
339 {
340  NS_LOG_FUNCTION(this << sourceIface << source << destination << packet << protocolType << ttl);
341  NS_ASSERT(destination != Mac48Address::GetBroadcast());
342  HwmpRtable::LookupResult result = m_rtable->LookupReactive(destination);
343  NS_LOG_DEBUG("Requested src = " << source << ", dst = " << destination << ", I am "
344  << GetAddress() << ", RA = " << result.retransmitter);
346  {
347  result = m_rtable->LookupProactive();
348  }
349  HwmpTag tag;
350  tag.SetAddress(result.retransmitter);
351  tag.SetTtl(ttl);
352  // seqno and metric is not used;
353  packet->AddPacketTag(tag);
355  {
356  // reply immediately:
357  routeReply(true, packet, source, destination, protocolType, result.ifIndex);
358  m_stats.txUnicast++;
359  m_stats.txBytes += packet->GetSize();
360  return true;
361  }
362  if (sourceIface != GetMeshPoint()->GetIfIndex())
363  {
364  // Start path error procedure:
365  NS_LOG_DEBUG("Must Send PERR");
366  result = m_rtable->LookupReactiveExpired(destination);
367  NS_LOG_DEBUG("Path error " << result.retransmitter);
368  // 1. Lookup expired reactive path. If exists - start path error
369  // procedure towards a next hop of this path
370  // 2. If there was no reactive path, we lookup expired proactive
371  // path. If exist - start path error procedure towards path to
372  // root
374  {
375  NS_LOG_DEBUG("Path error, lookup expired proactive path");
376  result = m_rtable->LookupProactiveExpired();
377  }
379  {
380  NS_LOG_DEBUG("Path error, initiate reactive path error");
381  std::vector<FailedDestination> destinations =
383  InitiatePathError(MakePathError(destinations));
384  }
386  return false;
387  }
388  // Request a destination:
389  result = m_rtable->LookupReactiveExpired(destination);
390  if (ShouldSendPreq(destination))
391  {
392  uint32_t originator_seqno = GetNextHwmpSeqno();
393  uint32_t dst_seqno = 0;
395  {
396  dst_seqno = result.seqnum;
397  }
399  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin(); i != m_interfaces.end();
400  i++)
401  {
402  i->second->RequestDestination(destination, originator_seqno, dst_seqno);
403  }
404  }
405  QueuedPacket pkt;
406  pkt.pkt = packet;
407  pkt.dst = destination;
408  pkt.src = source;
409  pkt.protocol = protocolType;
410  pkt.reply = routeReply;
411  pkt.inInterface = sourceIface;
412  if (QueuePacket(pkt))
413  {
415  return true;
416  }
417  else
418  {
420  NS_LOG_DEBUG("Dropping packet from " << source << " to " << destination
421  << " due to queue overflow");
422  return false;
423  }
424 }
425 
426 void
428  Mac48Address from,
429  uint32_t interface,
430  Mac48Address fromMp,
431  uint32_t metric)
432 {
433  NS_LOG_FUNCTION(this << from << interface << fromMp << metric);
434  preq.IncrementMetric(metric);
435  // acceptance cretirea:
436  std::map<Mac48Address, std::pair<uint32_t, uint32_t>>::const_iterator i =
438  bool freshInfo(true);
439  if (i != m_hwmpSeqnoMetricDatabase.end())
440  {
441  if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber()) > 0)
442  {
443  return;
444  }
445  if (i->second.first == preq.GetOriginatorSeqNumber())
446  {
447  freshInfo = false;
448  if (i->second.second <= preq.GetMetric())
449  {
450  return;
451  }
452  }
453  }
455  std::make_pair(preq.GetOriginatorSeqNumber(), preq.GetMetric());
456  NS_LOG_DEBUG("I am " << GetAddress() << ", Accepted preq from address" << from
457  << ", preq:" << preq);
458  std::vector<Ptr<DestinationAddressUnit>> destinations = preq.GetDestinationList();
459  // Add reactive path to originator:
460  if ((freshInfo) ||
464  {
466  from,
467  interface,
468  preq.GetMetric(),
469  MicroSeconds(preq.GetLifetime() * 1024),
470  preq.GetOriginatorSeqNumber());
471  // Notify trace source of routing change
472  RouteChange rChange;
473  rChange.type = "Add Reactive";
474  rChange.destination = preq.GetOriginatorAddress();
475  rChange.retransmitter = from;
476  rChange.interface = interface;
477  rChange.metric = preq.GetMetric();
478  rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
479  rChange.seqnum = preq.GetOriginatorSeqNumber();
480  m_routeChangeTraceSource(rChange);
482  }
484  (m_rtable->LookupReactive(fromMp).metric > metric))
485  {
486  m_rtable->AddReactivePath(fromMp,
487  from,
488  interface,
489  metric,
490  MicroSeconds(preq.GetLifetime() * 1024),
491  preq.GetOriginatorSeqNumber());
492  // Notify trace source of routing change
493  RouteChange rChange;
494  rChange.type = "Add Reactive";
495  rChange.destination = fromMp;
496  rChange.retransmitter = from;
497  rChange.interface = interface;
498  rChange.metric = metric;
499  rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
500  rChange.seqnum = preq.GetOriginatorSeqNumber();
501  m_routeChangeTraceSource(rChange);
502  ReactivePathResolved(fromMp);
503  }
504  for (std::vector<Ptr<DestinationAddressUnit>>::const_iterator i = destinations.begin();
505  i != destinations.end();
506  i++)
507  {
508  if ((*i)->GetDestinationAddress() == Mac48Address::GetBroadcast())
509  {
510  // only proactive PREQ contains destination
511  // address as broadcast! Proactive preq MUST
512  // have destination count equal to 1 and
513  // per destination flags DO and RF
514  NS_ASSERT(preq.GetDestCount() == 1);
515  NS_ASSERT(((*i)->IsDo()) && ((*i)->IsRf()));
516  // Add proactive path only if it is the better then existed
517  // before
518  if (((m_rtable->LookupProactive()).retransmitter == Mac48Address::GetBroadcast()) ||
519  ((m_rtable->LookupProactive()).metric > preq.GetMetric()))
520  {
522  preq.GetOriginatorAddress(),
523  from,
524  interface,
525  MicroSeconds(preq.GetLifetime() * 1024),
526  preq.GetOriginatorSeqNumber());
527  // Notify trace source of routing change
528  RouteChange rChange;
529  rChange.type = "Add Proactive";
530  rChange.destination = preq.GetOriginatorAddress();
531  rChange.retransmitter = from;
532  rChange.interface = interface;
533  rChange.metric = preq.GetMetric();
534  rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
535  rChange.seqnum = preq.GetOriginatorSeqNumber();
536  m_routeChangeTraceSource(rChange);
538  }
539  if (!preq.IsNeedNotPrep())
540  {
542  preq.GetOriginatorAddress(),
543  from,
544  (uint32_t)0,
545  preq.GetOriginatorSeqNumber(),
547  preq.GetLifetime(),
548  interface);
549  }
550  break;
551  }
552  if ((*i)->GetDestinationAddress() == GetAddress())
553  {
555  preq.GetOriginatorAddress(),
556  from,
557  (uint32_t)0,
558  preq.GetOriginatorSeqNumber(),
560  preq.GetLifetime(),
561  interface);
564  preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
565  continue;
566  }
567  // check if can answer:
568  HwmpRtable::LookupResult result = m_rtable->LookupReactive((*i)->GetDestinationAddress());
569  if ((!((*i)->IsDo())) && (result.retransmitter != Mac48Address::GetBroadcast()))
570  {
571  // have a valid information and can answer
572  uint32_t lifetime = result.lifetime.GetMicroSeconds() / 1024;
573  if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber()) >= 0))
574  {
575  SendPrep((*i)->GetDestinationAddress(),
576  preq.GetOriginatorAddress(),
577  from,
578  result.metric,
579  preq.GetOriginatorSeqNumber(),
580  result.seqnum,
581  lifetime,
582  interface);
583  m_rtable->AddPrecursor((*i)->GetDestinationAddress(),
584  interface,
585  from,
586  MicroSeconds(preq.GetLifetime() * 1024));
587  if ((*i)->IsRf())
588  {
589  (*i)->SetFlags(true, false, (*i)->IsUsn()); // DO = 1, RF = 0
590  }
591  else
592  {
593  preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
594  continue;
595  }
596  }
597  }
598  }
599  // check if must retransmit:
600  if (preq.GetDestCount() == 0)
601  {
602  return;
603  }
604  // Forward PREQ to all interfaces:
605  NS_LOG_DEBUG("I am " << GetAddress() << "retransmitting PREQ:" << preq);
606  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin(); i != m_interfaces.end(); i++)
607  {
608  Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
609  NS_LOG_DEBUG("Forwarding PREQ from " << from << " with delay "
610  << forwardingDelay.As(Time::US));
611  Simulator::Schedule(forwardingDelay, &HwmpProtocolMac::SendPreq, i->second, preq);
612  }
613 }
614 
615 void
617  Mac48Address from,
618  uint32_t interface,
619  Mac48Address fromMp,
620  uint32_t metric)
621 {
622  NS_LOG_FUNCTION(this << from << interface << fromMp << metric);
623  prep.IncrementMetric(metric);
624  // acceptance cretirea:
625  std::map<Mac48Address, std::pair<uint32_t, uint32_t>>::const_iterator i =
627  bool freshInfo(true);
628  uint32_t sequence = prep.GetDestinationSeqNumber();
629  if (i != m_hwmpSeqnoMetricDatabase.end())
630  {
631  if ((int32_t)(i->second.first - sequence) > 0)
632  {
633  return;
634  }
635  if (i->second.first == sequence)
636  {
637  freshInfo = false;
638  }
639  }
641  std::make_pair(sequence, prep.GetMetric());
642  // update routing info
643  // Now add a path to destination and add precursor to source
644  NS_LOG_DEBUG("I am " << GetAddress() << ", received prep from " << prep.GetOriginatorAddress()
645  << ", receiver was:" << from);
647  // Add a reactive path only if seqno is fresher or it improves the
648  // metric
649  if ((freshInfo) ||
650  (((m_rtable->LookupReactive(prep.GetOriginatorAddress())).retransmitter ==
652  ((m_rtable->LookupReactive(prep.GetOriginatorAddress())).metric > prep.GetMetric())))
653  {
655  from,
656  interface,
657  prep.GetMetric(),
658  MicroSeconds(prep.GetLifetime() * 1024),
659  sequence);
660  // Notify trace source of routing change
661  RouteChange rChange;
662  rChange.type = "Add Reactive";
663  rChange.destination = prep.GetOriginatorAddress();
664  rChange.retransmitter = from;
665  rChange.interface = interface;
666  rChange.metric = prep.GetMetric();
667  rChange.lifetime = MicroSeconds(prep.GetLifetime() * 1024);
668  rChange.seqnum = sequence;
669  m_routeChangeTraceSource(rChange);
671  interface,
672  from,
673  MicroSeconds(prep.GetLifetime() * 1024));
675  {
677  interface,
678  result.retransmitter,
679  result.lifetime);
680  }
682  }
683  if (((m_rtable->LookupReactive(fromMp)).retransmitter == Mac48Address::GetBroadcast()) ||
684  ((m_rtable->LookupReactive(fromMp)).metric > metric))
685  {
686  m_rtable->AddReactivePath(fromMp,
687  from,
688  interface,
689  metric,
690  MicroSeconds(prep.GetLifetime() * 1024),
691  sequence);
692  // Notify trace source of routing change
693  RouteChange rChange;
694  rChange.type = "Add Reactive";
695  rChange.destination = fromMp;
696  rChange.retransmitter = from;
697  rChange.interface = interface;
698  rChange.metric = metric;
699  rChange.lifetime = MicroSeconds(prep.GetLifetime() * 1024);
700  rChange.seqnum = sequence;
701  m_routeChangeTraceSource(rChange);
702  ReactivePathResolved(fromMp);
703  }
704  if (prep.GetDestinationAddress() == GetAddress())
705  {
706  NS_LOG_DEBUG("I am " << GetAddress() << ", resolved " << prep.GetOriginatorAddress());
707  return;
708  }
710  {
711  return;
712  }
713  // Forward PREP
714  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find(result.ifIndex);
715  NS_ASSERT(prep_sender != m_interfaces.end());
716  Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
717  NS_LOG_DEBUG("Forwarding PREP from " << from << " with delay " << forwardingDelay.As(Time::US));
718  Simulator::Schedule(forwardingDelay,
720  prep_sender->second,
721  prep,
722  result.retransmitter);
723 }
724 
725 void
726 HwmpProtocol::ReceivePerr(std::vector<FailedDestination> destinations,
727  Mac48Address from,
728  uint32_t interface,
729  Mac48Address fromMp)
730 {
731  NS_LOG_FUNCTION(this << from << interface << fromMp);
732  // Acceptance cretirea:
733  NS_LOG_DEBUG("I am " << GetAddress() << ", received PERR from " << from);
734  std::vector<FailedDestination> retval;
736  for (unsigned int i = 0; i < destinations.size(); i++)
737  {
738  result = m_rtable->LookupReactiveExpired(destinations[i].destination);
739  if (!((result.retransmitter != from) || (result.ifIndex != interface) ||
740  ((int32_t)(result.seqnum - destinations[i].seqnum) > 0)))
741  {
742  retval.push_back(destinations[i]);
743  }
744  }
745  if (retval.empty())
746  {
747  return;
748  }
750 }
751 
752 void
754  Mac48Address dst,
755  Mac48Address retransmitter,
756  uint32_t initMetric,
757  uint32_t originatorDsn,
758  uint32_t destinationSN,
759  uint32_t lifetime,
760  uint32_t interface)
761 {
762  IePrep prep;
763  prep.SetHopcount(0);
764  prep.SetTtl(m_maxTtl);
765  prep.SetDestinationAddress(dst);
766  prep.SetDestinationSeqNumber(destinationSN);
767  prep.SetLifetime(lifetime);
768  prep.SetMetric(initMetric);
769  prep.SetOriginatorAddress(src);
770  prep.SetOriginatorSeqNumber(originatorDsn);
771  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find(interface);
772  NS_ASSERT(prep_sender != m_interfaces.end());
773  prep_sender->second->SendPrep(prep, retransmitter);
775 }
776 
777 bool
779 {
780  NS_LOG_FUNCTION(this << mp);
781  m_mp = mp;
782  std::vector<Ptr<NetDevice>> interfaces = mp->GetInterfaces();
783  for (std::vector<Ptr<NetDevice>>::const_iterator i = interfaces.begin(); i != interfaces.end();
784  i++)
785  {
786  // Checking for compatible net device
787  Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice>();
788  if (!wifiNetDev)
789  {
790  return false;
791  }
793  if (!mac)
794  {
795  return false;
796  }
797  // Installing plugins:
798  Ptr<HwmpProtocolMac> hwmpMac = Create<HwmpProtocolMac>(wifiNetDev->GetIfIndex(), this);
799  m_interfaces[wifiNetDev->GetIfIndex()] = hwmpMac;
800  mac->InstallPlugin(hwmpMac);
801  // Installing airtime link metric:
802  Ptr<AirtimeLinkMetricCalculator> metric = CreateObject<AirtimeLinkMetricCalculator>();
803  mac->SetLinkMetricCallback(
805  }
806  mp->SetRoutingProtocol(this);
807  // Mesh point aggregates all installed protocols
808  mp->AggregateObject(this);
809  m_address = Mac48Address::ConvertFrom(mp->GetAddress()); // address;
810  return true;
811 }
812 
813 void
815  Mac48Address peerAddress,
816  uint32_t interface,
817  bool status)
818 {
819  NS_LOG_FUNCTION(this << meshPointAddress << peerAddress << interface << status);
820  if (status)
821  {
822  return;
823  }
824  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations(peerAddress);
825  NS_LOG_DEBUG(destinations.size() << " failed destinations for peer address " << peerAddress);
826  InitiatePathError(MakePathError(destinations));
827 }
828 
829 void
830 HwmpProtocol::SetNeighboursCallback(Callback<std::vector<Mac48Address>, uint32_t> cb)
831 {
833 }
834 
835 bool
837 {
838  NS_LOG_FUNCTION(this << seqno << source);
839  if (source == GetAddress())
840  {
841  NS_LOG_DEBUG("Dropping seqno " << seqno << "; from self");
842  return true;
843  }
844  std::map<Mac48Address, uint32_t, std::less<Mac48Address>>::const_iterator i =
845  m_lastDataSeqno.find(source);
846  if (i == m_lastDataSeqno.end())
847  {
848  m_lastDataSeqno[source] = seqno;
849  }
850  else
851  {
852  if ((int32_t)(i->second - seqno) >= 0)
853  {
854  NS_LOG_DEBUG("Dropping seqno " << seqno << "; stale frame");
855  return true;
856  }
857  m_lastDataSeqno[source] = seqno;
858  }
859  return false;
860 }
861 
863 HwmpProtocol::MakePathError(std::vector<FailedDestination> destinations)
864 {
865  NS_LOG_FUNCTION(this);
866  PathError retval;
867  // HwmpRtable increments a sequence number as written in 11B.9.7.2
868  retval.receivers = GetPerrReceivers(destinations);
869  if (retval.receivers.empty())
870  {
871  return retval;
872  }
874  for (unsigned int i = 0; i < destinations.size(); i++)
875  {
876  retval.destinations.push_back(destinations[i]);
877  m_rtable->DeleteReactivePath(destinations[i].destination);
878  // Notify trace source of routing change
879  RouteChange rChange;
880  rChange.type = "Delete Reactive";
881  rChange.destination = destinations[i].destination;
882  rChange.seqnum = destinations[i].seqnum;
883  m_routeChangeTraceSource(rChange);
884  }
885  return retval;
886 }
887 
888 void
890 {
891  NS_LOG_FUNCTION(this);
892  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin(); i != m_interfaces.end(); i++)
893  {
894  std::vector<Mac48Address> receivers_for_interface;
895  for (unsigned int j = 0; j < perr.receivers.size(); j++)
896  {
897  if (i->first == perr.receivers[j].first)
898  {
899  receivers_for_interface.push_back(perr.receivers[j].second);
900  }
901  }
902  i->second->InitiatePerr(perr.destinations, receivers_for_interface);
903  }
904 }
905 
906 void
908 {
909  NS_LOG_FUNCTION(this);
910  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin(); i != m_interfaces.end(); i++)
911  {
912  std::vector<Mac48Address> receivers_for_interface;
913  for (unsigned int j = 0; j < perr.receivers.size(); j++)
914  {
915  if (i->first == perr.receivers[j].first)
916  {
917  receivers_for_interface.push_back(perr.receivers[j].second);
918  }
919  }
920  Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
921  NS_LOG_DEBUG("Forwarding PERR with delay " << forwardingDelay.As(Time::US));
922  Simulator::Schedule(forwardingDelay,
924  i->second,
925  perr.destinations,
926  receivers_for_interface);
927  i->second->ForwardPerr(perr.destinations, receivers_for_interface);
928  }
929 }
930 
931 std::vector<std::pair<uint32_t, Mac48Address>>
932 HwmpProtocol::GetPerrReceivers(std::vector<FailedDestination> failedDest)
933 {
934  NS_LOG_FUNCTION(this);
936  for (unsigned int i = 0; i < failedDest.size(); i++)
937  {
938  HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors(failedDest[i].destination);
939  m_rtable->DeleteReactivePath(failedDest[i].destination);
940  // Notify trace source of routing change
941  RouteChange rChange;
942  rChange.type = "Delete Reactive";
943  rChange.destination = failedDest[i].destination;
944  rChange.seqnum = failedDest[i].seqnum;
945  m_routeChangeTraceSource(rChange);
946  m_rtable->DeleteProactivePath(failedDest[i].destination);
947  // Notify trace source of routing change
948  RouteChange rChangePro;
949  rChangePro.type = "Delete Proactive";
950  rChangePro.destination = failedDest[i].destination;
951  rChangePro.seqnum = failedDest[i].seqnum;
952  m_routeChangeTraceSource(rChangePro);
953  for (unsigned int j = 0; j < precursors.size(); j++)
954  {
955  retval.push_back(precursors[j]);
956  }
957  }
958  // Check if we have duplicates in retval and precursors:
959  for (unsigned int i = 0; i < retval.size(); i++)
960  {
961  for (unsigned int j = i + 1; j < retval.size(); j++)
962  {
963  if (retval[i].second == retval[j].second)
964  {
965  retval.erase(retval.begin() + j);
966  }
967  }
968  }
969  return retval;
970 }
971 
972 std::vector<Mac48Address>
974 {
975  NS_LOG_FUNCTION(this << interface);
976  std::vector<Mac48Address> retval;
977  if (!m_neighboursCallback.IsNull())
978  {
979  retval = m_neighboursCallback(interface);
980  }
981  if (retval.size() >= m_unicastPreqThreshold || retval.empty())
982  {
983  retval.clear();
984  retval.push_back(Mac48Address::GetBroadcast());
985  }
986  return retval;
987 }
988 
989 std::vector<Mac48Address>
991 {
992  NS_LOG_FUNCTION(this << interface);
993  std::vector<Mac48Address> retval;
994  if (!m_neighboursCallback.IsNull())
995  {
996  retval = m_neighboursCallback(interface);
997  }
998  if (retval.size() >= m_unicastDataThreshold || retval.empty())
999  {
1000  retval.clear();
1001  retval.push_back(Mac48Address::GetBroadcast());
1002  }
1003  return retval;
1004 }
1005 
1006 bool
1008 {
1009  NS_LOG_FUNCTION(this);
1010  if (m_rqueue.size() > m_maxQueueSize)
1011  {
1012  return false;
1013  }
1014  m_rqueue.push_back(packet);
1015  return true;
1016 }
1017 
1020 {
1021  NS_LOG_FUNCTION(this << dst);
1022  QueuedPacket retval;
1023  retval.pkt = nullptr;
1024  for (std::vector<QueuedPacket>::iterator i = m_rqueue.begin(); i != m_rqueue.end(); i++)
1025  {
1026  if ((*i).dst == dst)
1027  {
1028  retval = (*i);
1029  m_rqueue.erase(i);
1030  break;
1031  }
1032  }
1033  return retval;
1034 }
1035 
1038 {
1039  NS_LOG_FUNCTION(this);
1040  QueuedPacket retval;
1041  retval.pkt = nullptr;
1042  if (!m_rqueue.empty())
1043  {
1044  retval = m_rqueue[0];
1045  m_rqueue.erase(m_rqueue.begin());
1046  }
1047  return retval;
1048 }
1049 
1050 void
1052 {
1053  NS_LOG_FUNCTION(this << dst);
1054  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find(dst);
1055  if (i != m_preqTimeouts.end())
1056  {
1057  m_routeDiscoveryTimeCallback(Simulator::Now() - i->second.whenScheduled);
1058  }
1059 
1062  // Send all packets stored for this destination
1063  QueuedPacket packet = DequeueFirstPacketByDst(dst);
1064  while (packet.pkt)
1065  {
1066  // set RA tag for retransmitter:
1067  HwmpTag tag;
1068  packet.pkt->RemovePacketTag(tag);
1069  tag.SetAddress(result.retransmitter);
1070  packet.pkt->AddPacketTag(tag);
1071  m_stats.txUnicast++;
1072  m_stats.txBytes += packet.pkt->GetSize();
1073  packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1074 
1075  packet = DequeueFirstPacketByDst(dst);
1076  }
1077 }
1078 
1079 void
1081 {
1082  NS_LOG_FUNCTION(this);
1083  // send all packets to root
1086  QueuedPacket packet = DequeueFirstPacket();
1087  while (packet.pkt)
1088  {
1089  // set RA tag for retransmitter:
1090  HwmpTag tag;
1091  if (!packet.pkt->RemovePacketTag(tag))
1092  {
1093  NS_FATAL_ERROR("HWMP tag must be present at this point");
1094  }
1095  tag.SetAddress(result.retransmitter);
1096  packet.pkt->AddPacketTag(tag);
1097  m_stats.txUnicast++;
1098  m_stats.txBytes += packet.pkt->GetSize();
1099  packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1100 
1101  packet = DequeueFirstPacket();
1102  }
1103 }
1104 
1105 bool
1107 {
1108  NS_LOG_FUNCTION(this << dst);
1109  std::map<Mac48Address, PreqEvent>::const_iterator i = m_preqTimeouts.find(dst);
1110  if (i == m_preqTimeouts.end())
1111  {
1112  m_preqTimeouts[dst].preqTimeout =
1115  this,
1116  dst,
1117  1);
1118  m_preqTimeouts[dst].whenScheduled = Simulator::Now();
1119  return true;
1120  }
1121  return false;
1122 }
1123 
1124 void
1126 {
1127  NS_LOG_FUNCTION(this << dst << (uint16_t)numOfRetry);
1129  if (result.retransmitter == Mac48Address::GetBroadcast())
1130  {
1131  result = m_rtable->LookupProactive();
1132  }
1133  if (result.retransmitter != Mac48Address::GetBroadcast())
1134  {
1135  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find(dst);
1136  NS_ASSERT(i != m_preqTimeouts.end());
1137  m_preqTimeouts.erase(i);
1138  return;
1139  }
1140  if (numOfRetry > m_dot11MeshHWMPmaxPREQretries)
1141  {
1142  QueuedPacket packet = DequeueFirstPacketByDst(dst);
1143  // purge queue and delete entry from retryDatabase
1144  while (packet.pkt)
1145  {
1147  packet.reply(false,
1148  packet.pkt,
1149  packet.src,
1150  packet.dst,
1151  packet.protocol,
1153  packet = DequeueFirstPacketByDst(dst);
1154  }
1155  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find(dst);
1156  NS_ASSERT(i != m_preqTimeouts.end());
1157  m_routeDiscoveryTimeCallback(Simulator::Now() - i->second.whenScheduled);
1158  m_preqTimeouts.erase(i);
1159  return;
1160  }
1161  numOfRetry++;
1162  uint32_t originator_seqno = GetNextHwmpSeqno();
1163  uint32_t dst_seqno = m_rtable->LookupReactiveExpired(dst).seqnum;
1164  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin(); i != m_interfaces.end(); i++)
1165  {
1166  i->second->RequestDestination(dst, originator_seqno, dst_seqno);
1167  }
1168  m_preqTimeouts[dst].preqTimeout =
1171  this,
1172  dst,
1173  numOfRetry);
1174 }
1175 
1176 // Proactive PREQ routines:
1177 void
1179 {
1180  NS_LOG_FUNCTION(this);
1181  NS_LOG_DEBUG("ROOT IS: " << m_address);
1182  m_isRoot = true;
1183 }
1184 
1185 void
1187 {
1188  NS_LOG_FUNCTION(this);
1190 }
1191 
1192 void
1194 {
1195  NS_LOG_FUNCTION(this);
1196  IePreq preq;
1197  // By default: must answer
1198  preq.SetHopcount(0);
1199  preq.SetTTL(m_maxTtl);
1201  //\attention: do not forget to set originator address, sequence
1202  // number and preq ID in HWMP-MAC plugin
1205  preq.SetPreqID(GetNextPreqId());
1207  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin(); i != m_interfaces.end(); i++)
1208  {
1209  i->second->SendPreq(preq);
1210  }
1213  this);
1214 }
1215 
1216 bool
1218 {
1219  return m_doFlag;
1220 }
1221 
1222 bool
1224 {
1225  return m_rfFlag;
1226 }
1227 
1228 Time
1230 {
1232 }
1233 
1234 Time
1236 {
1238 }
1239 
1240 uint8_t
1242 {
1243  return m_maxTtl;
1244 }
1245 
1246 uint32_t
1248 {
1249  m_preqId++;
1250  return m_preqId;
1251 }
1252 
1253 uint32_t
1255 {
1256  m_hwmpSeqno++;
1257  return m_hwmpSeqno;
1258 }
1259 
1260 uint32_t
1262 {
1264 }
1265 
1266 uint8_t
1268 {
1269  return m_unicastPerrThreshold;
1270 }
1271 
1274 {
1275  return m_address;
1276 }
1277 
1278 // Statistics:
1280  : txUnicast(0),
1281  txBroadcast(0),
1282  txBytes(0),
1283  droppedTtl(0),
1284  totalQueued(0),
1285  totalDropped(0),
1286  initiatedPreq(0),
1287  initiatedPrep(0),
1288  initiatedPerr(0)
1289 {
1290 }
1291 
1292 void
1293 HwmpProtocol::Statistics::Print(std::ostream& os) const
1294 {
1295  os << "<Statistics "
1296  "txUnicast=\""
1297  << txUnicast
1298  << "\" "
1299  "txBroadcast=\""
1300  << txBroadcast
1301  << "\" "
1302  "txBytes=\""
1303  << txBytes
1304  << "\" "
1305  "droppedTtl=\""
1306  << droppedTtl
1307  << "\" "
1308  "totalQueued=\""
1309  << totalQueued
1310  << "\" "
1311  "totalDropped=\""
1312  << totalDropped
1313  << "\" "
1314  "initiatedPreq=\""
1315  << initiatedPreq
1316  << "\" "
1317  "initiatedPrep=\""
1318  << initiatedPrep
1319  << "\" "
1320  "initiatedPerr=\""
1321  << initiatedPerr << "\"/>" << std::endl;
1322 }
1323 
1324 void
1325 HwmpProtocol::Report(std::ostream& os) const
1326 {
1327  os << "<Hwmp "
1328  "address=\""
1329  << m_address << "\"" << std::endl
1330  << "maxQueueSize=\"" << m_maxQueueSize << "\"" << std::endl
1331  << "Dot11MeshHWMPmaxPREQretries=\"" << (uint16_t)m_dot11MeshHWMPmaxPREQretries << "\""
1332  << std::endl
1333  << "Dot11MeshHWMPnetDiameterTraversalTime=\""
1334  << m_dot11MeshHWMPnetDiameterTraversalTime.GetSeconds() << "\"" << std::endl
1335  << "Dot11MeshHWMPpreqMinInterval=\"" << m_dot11MeshHWMPpreqMinInterval.GetSeconds() << "\""
1336  << std::endl
1337  << "Dot11MeshHWMPperrMinInterval=\"" << m_dot11MeshHWMPperrMinInterval.GetSeconds() << "\""
1338  << std::endl
1339  << "Dot11MeshHWMPactiveRootTimeout=\"" << m_dot11MeshHWMPactiveRootTimeout.GetSeconds()
1340  << "\"" << std::endl
1341  << "Dot11MeshHWMPactivePathTimeout=\"" << m_dot11MeshHWMPactivePathTimeout.GetSeconds()
1342  << "\"" << std::endl
1343  << "Dot11MeshHWMPpathToRootInterval=\"" << m_dot11MeshHWMPpathToRootInterval.GetSeconds()
1344  << "\"" << std::endl
1345  << "Dot11MeshHWMPrannInterval=\"" << m_dot11MeshHWMPrannInterval.GetSeconds() << "\""
1346  << std::endl
1347  << "isRoot=\"" << m_isRoot << "\"" << std::endl
1348  << "maxTtl=\"" << (uint16_t)m_maxTtl << "\"" << std::endl
1349  << "unicastPerrThreshold=\"" << (uint16_t)m_unicastPerrThreshold << "\"" << std::endl
1350  << "unicastPreqThreshold=\"" << (uint16_t)m_unicastPreqThreshold << "\"" << std::endl
1351  << "unicastDataThreshold=\"" << (uint16_t)m_unicastDataThreshold << "\"" << std::endl
1352  << "doFlag=\"" << m_doFlag << "\"" << std::endl
1353  << "rfFlag=\"" << m_rfFlag << "\">" << std::endl;
1354  m_stats.Print(os);
1355  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin();
1356  plugin != m_interfaces.end();
1357  plugin++)
1358  {
1359  plugin->second->Report(os);
1360  }
1361  os << "</Hwmp>" << std::endl;
1362 }
1363 
1364 void
1366 {
1367  NS_LOG_FUNCTION(this);
1368  m_stats = Statistics();
1369  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin();
1370  plugin != m_interfaces.end();
1371  plugin++)
1372  {
1373  plugin->second->ResetStats();
1374  }
1375 }
1376 
1377 int64_t
1379 {
1380  NS_LOG_FUNCTION(this << stream);
1381  m_coefficient->SetStream(stream);
1382  return 1;
1383 }
1384 
1387 {
1388  return m_rtable;
1389 }
1390 
1392  : pkt(nullptr),
1393  protocol(0),
1394  inInterface(0)
1395 {
1396 }
1397 } // namespace dot11s
1398 } // namespace ns3
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Callback template class.
Definition: callback.h:443
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address GetBroadcast()
Interface for L2 mesh routing protocol and mesh point communication.
Ptr< MeshPointDevice > GetMeshPoint() const
Each mesh protocol must be installed on the mesh point to work.
Ptr< MeshPointDevice > m_mp
Host mesh point.
Basic MAC of mesh point Wi-Fi interface.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:200
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:986
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:979
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:1002
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:402
@ US
microsecond
Definition: nstime.h:118
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:412
AttributeValue implementation for Time.
Definition: nstime.h:1423
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
Hold together all Wifi-related objects.
Ptr< WifiMac > GetMac() const
uint32_t GetIfIndex() const override
Hybrid wireless mesh protocol – a mesh routing protocol defined in IEEE 802.11-2012 standard.
Definition: hwmp-protocol.h:68
void SetRoot()
Unset the current node as root.
std::vector< Mac48Address > GetPreqReceivers(uint32_t interface)
Get PREQ receivers.
QueuedPacket DequeueFirstPacket()
Dequeue the first packet in the queue.
Ptr< HwmpRtable > m_rtable
Routing table.
uint8_t m_unicastDataThreshold
Maximum number of broadcast receivers, when we send a broadcast as a chain of unicasts.
void ReceivePrep(IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
Handler for receiving Path Reply.
void Report(std::ostream &os) const
Statistics:
uint32_t GetNextHwmpSeqno()
Get next HWMP sequence no function.
PathError MakePathError(std::vector< FailedDestination > destinations)
forms a path error information element when list of destination fails on a given interface
Time m_dot11MeshHWMPrannInterval
Lifetime of proactive routing information.
Time GetPerrMinInterval()
Get PERR minimum interval function.
Ptr< HwmpRtable > GetRoutingTable() const
Get pointer to HWMP routing table.
uint8_t m_unicastPreqThreshold
Maximum number of PREQ receivers, when we send a PREQ as a chain of unicasts.
void UnsetRoot()
Unset the current node as root.
uint32_t m_dataSeqno
data sequence no
Time m_dot11MeshHWMPnetDiameterTraversalTime
Time we suppose the packet to go from one edge of the network to another.
Time m_dot11MeshHWMPactivePathTimeout
Lifetime of reactive routing information.
bool QueuePacket(QueuedPacket packet)
Queue a packet.
bool m_isRoot
True if the node is a root.
Statistics m_stats
statistics
uint32_t m_hwmpSeqno
HWMP sequence no.
uint8_t GetMaxTtl() const
Get maximum TTL function.
Time m_randomStart
Random start in Proactive PREQ propagation.
void SendPrep(Mac48Address src, Mac48Address dst, Mac48Address retransmitter, uint32_t initMetric, uint32_t originatorDsn, uint32_t destinationSN, uint32_t lifetime, uint32_t interface)
Send Path Reply.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
bool GetDoFlag() const
Get do flag function.
TracedCallback< Time > m_routeDiscoveryTimeCallback
Route discovery time:
static TypeId GetTypeId()
Get the type ID.
bool ShouldSendPreq(Mac48Address dst)
checks when the last path discovery procedure was started for a given destination.
void PeerLinkStatus(Mac48Address meshPontAddress, Mac48Address peerAddress, uint32_t interface, bool status)
Peer link status function.
void ReceivePerr(std::vector< FailedDestination > destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
Handler for receiving Path Error.
std::map< Mac48Address, PreqEvent > m_preqTimeouts
PREQ timeouts.
Time m_dot11MeshHWMPperrMinInterval
Minimal interval between to successive PREQs.
bool m_rfFlag
Reply and forward flag.
bool RequestRoute(uint32_t sourceIface, const Mac48Address source, const Mac48Address destination, Ptr< const Packet > packet, uint16_t protocolType, RouteReplyCallback routeReply) override
Route request, inherited from MeshL2RoutingProtocol.
Time GetPreqMinInterval()
Get PREQ minimum interval function.
QueuedPacket DequeueFirstPacketByDst(Mac48Address dst)
Dequeue the first packet for a given destination.
EventId m_proactivePreqTimer
proactive PREQ timer
Ptr< UniformRandomVariable > m_coefficient
Random variable for random start time.
uint32_t GetNextPreqId()
Get next period function.
void InitiatePathError(PathError perr)
Passes a self-generated PERR to interface-plugin.
void SendProactivePreq()
Proactive Preq routines:
void ForwardPathError(PathError perr)
Forwards a received path error.
Time m_dot11MeshHWMPpathToRootInterval
Interval between two successive proactive PREQs.
void RetryPathDiscovery(Mac48Address dst, uint8_t numOfRetry)
Generates PREQ retry when retry timeout has expired and route is still unresolved.
bool RemoveRoutingStuff(uint32_t fromIface, const Mac48Address source, const Mac48Address destination, Ptr< Packet > packet, uint16_t &protocolType) override
Clean HWMP packet tag from packet; only the packet parameter is used.
bool m_doFlag
Destination only HWMP flag.
Mac48Address m_address
address
void DoInitialize() override
Initialize() implementation.
Time m_dot11MeshHWMPactiveRootTimeout
Lifetime of proactive routing information.
void DoDispose() override
Destructor implementation.
void ReceivePreq(IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
Handler for receiving Path Request.
Time m_dot11MeshHWMPpreqMinInterval
Minimal interval between to successive PREQs.
uint8_t GetUnicastPerrThreshold() const
Get unicast PERR threshold function.
void ReactivePathResolved(Mac48Address dst)
Signal the protocol that the reactive path toward a destination is now available.
std::vector< Mac48Address > GetBroadcastReceivers(uint32_t interface)
Get broadcast receivers.
bool GetRfFlag() const
Get rf flag function.
bool Install(Ptr< MeshPointDevice > mp)
Install HWMP on given mesh point.
uint32_t GetActivePathLifetime()
Get active path lifetime function.
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.
void ProactivePathResolved()
Signal the protocol that the proactive path is now available.
void SetNeighboursCallback(Callback< std::vector< Mac48Address >, uint32_t > cb)
This callback is used to obtain active neighbours on a given interface.
std::vector< QueuedPacket > m_rqueue
Packet Queue.
Callback< std::vector< Mac48Address >, uint32_t > m_neighboursCallback
neighbors callback
std::vector< std::pair< uint32_t, Mac48Address > > GetPerrReceivers(std::vector< FailedDestination > failedDest)
Get PERR receivers.
HwmpProtocolMacMap m_interfaces
interfaces
uint16_t m_maxQueueSize
Maximum number of packets we can store when resolving route.
uint8_t m_maxTtl
Initial value of Time To Live field.
std::map< Mac48Address, uint32_t > m_lastDataSeqno
keeps HWMP seqno (first in pair) and HWMP metric (second in pair) for each address
void ResetStats()
Reset Statistics:
bool DropDataFrame(uint32_t seqno, Mac48Address source)
MAC-plugin asks whether the frame can be dropped.
uint8_t m_unicastPerrThreshold
Maximum number of PERR receivers, when we send a PERR as a chain of unicasts.
uint32_t m_preqId
PREQ ID.
uint8_t m_dot11MeshHWMPmaxPREQretries
Maximum number of retries before we suppose the destination to be unreachable.
std::map< Mac48Address, std::pair< uint32_t, uint32_t > > m_hwmpSeqnoMetricDatabase
keeps HWMP seqno (first in pair) and HWMP metric (second in pair) for each address
TracedCallback< struct RouteChange > m_routeChangeTraceSource
Route change trace source.
void SendPreq(IePreq preq)
Send PREQ function.
void SendPrep(IePrep prep, Mac48Address receiver)
Send PREP function.
void ForwardPerr(std::vector< HwmpProtocol::FailedDestination > destinations, std::vector< Mac48Address > receivers)
Forward a path error.
Routing table for HWMP – 802.11s routing protocol.
Definition: hwmp-rtable.h:39
void DeleteReactivePath(Mac48Address destination)
Delete the reactive paths toward a destination.
Definition: hwmp-rtable.cc:161
static const uint32_t MAX_METRIC
Maximum (the best?) path metric.
Definition: hwmp-rtable.h:44
LookupResult LookupReactive(Mac48Address destination)
Lookup path to destination.
Definition: hwmp-rtable.cc:172
LookupResult LookupReactiveExpired(Mac48Address destination)
Return all reactive paths, including expired.
Definition: hwmp-rtable.cc:189
PrecursorList GetPrecursors(Mac48Address destination)
Get the precursors list.
Definition: hwmp-rtable.cc:257
void DeleteProactivePath()
Delete all the proactive paths.
Definition: hwmp-rtable.cc:139
LookupResult LookupProactiveExpired()
Return all proactive paths, including expired.
Definition: hwmp-rtable.cc:218
std::vector< std::pair< uint32_t, Mac48Address > > PrecursorList
Path precursor = {MAC, interface ID}.
Definition: hwmp-rtable.h:81
std::vector< HwmpProtocol::FailedDestination > GetUnreachableDestinations(Mac48Address peerAddress)
When peer link with a given MAC-address fails - it returns list of unreachable destination addresses.
Definition: hwmp-rtable.cc:230
LookupResult LookupProactive()
Find proactive path to tree root.
Definition: hwmp-rtable.cc:206
void AddPrecursor(Mac48Address destination, uint32_t precursorInterface, Mac48Address precursorAddress, Time lifetime)
Add a precursor.
Definition: hwmp-rtable.cc:106
void AddProactivePath(uint32_t metric, Mac48Address root, Mac48Address retransmitter, uint32_t interface, Time lifetime, uint32_t seqnum)
Add a proactive path.
Definition: hwmp-rtable.cc:89
void AddReactivePath(Mac48Address destination, Mac48Address retransmitter, uint32_t interface, uint32_t metric, Time lifetime, uint32_t seqnum)
Add a reactive path.
Definition: hwmp-rtable.cc:64
Hwmp tag implements interaction between HWMP protocol and MeshWifiMac.
Definition: hwmp-tag.h:51
void SetTtl(uint8_t ttl)
Set the TTL value.
Definition: hwmp-tag.cc:55
void SetSeqno(uint32_t seqno)
Set sequence number.
Definition: hwmp-tag.cc:79
uint8_t GetTtl() const
Get the TTL value.
Definition: hwmp-tag.cc:61
void SetAddress(Mac48Address retransmitter)
Set address.
Definition: hwmp-tag.cc:43
void DecrementTtl()
Decrement TTL.
Definition: hwmp-tag.cc:159
See 7.3.2.97 of 802.11s draft 2.07.
uint32_t GetMetric() const
Get metric function.
void SetTtl(uint8_t ttl)
Set TTL function.
void SetDestinationSeqNumber(uint32_t dest_seq_number)
Set destination sequence number function.
Mac48Address GetDestinationAddress() const
Get destination address function.
void SetHopcount(uint8_t hopcount)
Set hop count function.
void IncrementMetric(uint32_t metric)
Increment metric function.
uint32_t GetLifetime() const
Get lifetime function.
void SetOriginatorAddress(Mac48Address originator_address)
Set originator address function.
void SetMetric(uint32_t metric)
Set metric function.
void SetDestinationAddress(Mac48Address dest_address)
Set destination address function.
void SetLifetime(uint32_t lifetime)
Set lifetime function.
Mac48Address GetOriginatorAddress() const
Get originator address function.
void SetOriginatorSeqNumber(uint32_t originator_seq_number)
Set originator sequence number function.
uint32_t GetDestinationSeqNumber() const
Get destination sequence number function.
See 7.3.2.96 of 802.11s draft 2.07.
uint32_t GetOriginatorSeqNumber() const
Get originator sequence number value.
void DelDestinationAddressElement(Mac48Address dest_address)
Delete a destination address unit by destination.
void SetHopcount(uint8_t hopcount)
Set number of hops from originator to mesh STA transmitting this element.
uint8_t GetDestCount() const
Get destination count.
std::vector< Ptr< DestinationAddressUnit > > GetDestinationList()
Get all destinations, which are stored in PREQ:
void SetOriginatorSeqNumber(uint32_t originator_seq_number)
Set originator sequence number.
uint32_t GetMetric() const
Get metric value.
void SetTTL(uint8_t ttl)
Set remaining number of hops allowed for this element.
void SetOriginatorAddress(Mac48Address originator_address)
Set originator address value.
Mac48Address GetOriginatorAddress() const
Get originator address value.
void SetPreqID(uint32_t id)
Set path discovery id field.
void IncrementMetric(uint32_t metric)
Handle Metric:
uint32_t GetLifetime() const
Get lifetime value.
void AddDestinationAddressElement(bool doFlag, bool rfFlag, Mac48Address dest_address, uint32_t dest_seq_number)
Add a destination address unit: flags, destination and sequence number.
bool IsNeedNotPrep() const
Check whether Proactive PREP subfield to off.
void SetLifetime(uint32_t lifetime)
Set lifetime in TUs for the forwarding information to be considered valid.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: nstime.h:1424
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:46
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:579
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1360
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
address
Definition: first.py:40
interfaces
Definition: first.py:44
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:848
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:707
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535
Definition: second.py:1
mac
Definition: third.py:85
Structure of path error: IePerr and list of receivers: interfaces and MAC address.
std::vector< FailedDestination > destinations
destination list: Mac48Address and sequence number
std::vector< std::pair< uint32_t, Mac48Address > > receivers
list of PathError receivers (in case of unicast PERR)
Packet waiting its routing information.
RouteReplyCallback reply
how to reply
uint32_t inInterface
incoming device interface ID.
void Print(std::ostream &os) const
Print function.
uint16_t initiatedPrep
initiated PREP
uint16_t txBroadcast
transmit broadcast
uint16_t txUnicast
transmit unicast
uint16_t initiatedPerr
initiated PERR
uint16_t initiatedPreq
initiated PREQ
Route lookup result, return type of LookupXXX methods.
Definition: hwmp-rtable.h:48
uint32_t seqnum
sequence number
Definition: hwmp-rtable.h:52
Mac48Address retransmitter
retransmitter
Definition: hwmp-rtable.h:49
Structure to encapsulate route change information.
Definition: hwmp-protocol.h:51
Time lifetime
lifetime of route
Definition: hwmp-protocol.h:57
Mac48Address retransmitter
route source
Definition: hwmp-protocol.h:54
uint32_t seqnum
sequence number of route
Definition: hwmp-protocol.h:58
uint32_t metric
metric of route
Definition: hwmp-protocol.h:56
Mac48Address destination
route destination
Definition: hwmp-protocol.h:53
std::string type
type of change
Definition: hwmp-protocol.h:52
uint32_t interface
interface index
Definition: hwmp-protocol.h:55