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 (auto i = m_preqTimeouts.begin(); i != m_preqTimeouts.end(); i++)
205  {
206  i->second.preqTimeout.Cancel();
207  }
209  m_preqTimeouts.clear();
210  m_lastDataSeqno.clear();
212  m_interfaces.clear();
213  m_rqueue.clear();
214  m_rtable = nullptr;
215  m_mp = nullptr;
216 }
217 
218 bool
219 HwmpProtocol::RequestRoute(uint32_t sourceIface,
220  const Mac48Address source,
221  const Mac48Address destination,
222  Ptr<const Packet> constPacket,
223  uint16_t protocolType, // ethrnet 'Protocol' field
225 {
226  NS_LOG_FUNCTION(this << sourceIface << source << destination << constPacket << protocolType);
227  Ptr<Packet> packet = constPacket->Copy();
228  HwmpTag tag;
229  if (sourceIface == GetMeshPoint()->GetIfIndex())
230  {
231  // packet from level 3
232  if (packet->PeekPacketTag(tag))
233  {
235  "HWMP tag has come with a packet from upper layer. This must not occur...");
236  }
237  // Filling TAG:
238  if (destination == Mac48Address::GetBroadcast())
239  {
240  tag.SetSeqno(m_dataSeqno++);
241  }
242  tag.SetTtl(m_maxTtl);
243  }
244  else
245  {
246  if (!packet->RemovePacketTag(tag))
247  {
248  NS_FATAL_ERROR("HWMP tag is supposed to be here at this point.");
249  }
250  tag.DecrementTtl();
251  if (tag.GetTtl() == 0)
252  {
253  NS_LOG_DEBUG("Dropping frame due to TTL expiry");
255  return false;
256  }
257  }
258  if (destination == Mac48Address::GetBroadcast())
259  {
261  m_stats.txBytes += packet->GetSize();
262  // channel IDs where we have already sent broadcast:
263  std::vector<uint16_t> channels;
264  for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
265  {
266  bool shouldSend = true;
267  for (auto chan = channels.begin(); chan != channels.end(); chan++)
268  {
269  if ((*chan) == plugin->second->GetChannelId())
270  {
271  shouldSend = false;
272  }
273  }
274  if (!shouldSend)
275  {
276  continue;
277  }
278  channels.push_back(plugin->second->GetChannelId());
279  std::vector<Mac48Address> receivers = GetBroadcastReceivers(plugin->first);
280  for (auto i = receivers.begin(); i != receivers.end(); i++)
281  {
282  Ptr<Packet> packetCopy = packet->Copy();
283  //
284  // 64-bit Intel valgrind complains about tag.SetAddress (*i). It
285  // likes this just fine.
286  //
287  Mac48Address address = *i;
288  tag.SetAddress(address);
289  packetCopy->AddPacketTag(tag);
290  NS_LOG_DEBUG("Sending route reply for broadcast; address " << address);
291  routeReply(true, packetCopy, source, destination, protocolType, plugin->first);
292  }
293  }
294  }
295  else
296  {
297  return ForwardUnicast(sourceIface,
298  source,
299  destination,
300  packet,
301  protocolType,
302  routeReply,
303  tag.GetTtl());
304  }
305  return true;
306 }
307 
308 bool
310  const Mac48Address source,
311  const Mac48Address destination,
312  Ptr<Packet> packet,
313  uint16_t& protocolType)
314 {
315  HwmpTag tag;
316  if (!packet->RemovePacketTag(tag))
317  {
318  NS_FATAL_ERROR("HWMP tag must exist when packet received from the network");
319  }
320  return true;
321 }
322 
323 bool
324 HwmpProtocol::ForwardUnicast(uint32_t sourceIface,
325  const Mac48Address source,
326  const Mac48Address destination,
327  Ptr<Packet> packet,
328  uint16_t protocolType,
329  RouteReplyCallback routeReply,
330  uint32_t ttl)
331 {
332  NS_LOG_FUNCTION(this << sourceIface << source << destination << packet << protocolType << ttl);
333  NS_ASSERT(destination != Mac48Address::GetBroadcast());
334  HwmpRtable::LookupResult result = m_rtable->LookupReactive(destination);
335  NS_LOG_DEBUG("Requested src = " << source << ", dst = " << destination << ", I am "
336  << GetAddress() << ", RA = " << result.retransmitter);
338  {
339  result = m_rtable->LookupProactive();
340  }
341  HwmpTag tag;
342  tag.SetAddress(result.retransmitter);
343  tag.SetTtl(ttl);
344  // seqno and metric is not used;
345  packet->AddPacketTag(tag);
347  {
348  // reply immediately:
349  routeReply(true, packet, source, destination, protocolType, result.ifIndex);
350  m_stats.txUnicast++;
351  m_stats.txBytes += packet->GetSize();
352  return true;
353  }
354  if (sourceIface != GetMeshPoint()->GetIfIndex())
355  {
356  // Start path error procedure:
357  NS_LOG_DEBUG("Must Send PERR");
358  result = m_rtable->LookupReactiveExpired(destination);
359  NS_LOG_DEBUG("Path error " << result.retransmitter);
360  // 1. Lookup expired reactive path. If exists - start path error
361  // procedure towards a next hop of this path
362  // 2. If there was no reactive path, we lookup expired proactive
363  // path. If exist - start path error procedure towards path to
364  // root
366  {
367  NS_LOG_DEBUG("Path error, lookup expired proactive path");
368  result = m_rtable->LookupProactiveExpired();
369  }
371  {
372  NS_LOG_DEBUG("Path error, initiate reactive path error");
373  std::vector<FailedDestination> destinations =
375  InitiatePathError(MakePathError(destinations));
376  }
378  return false;
379  }
380  // Request a destination:
381  result = m_rtable->LookupReactiveExpired(destination);
382  if (ShouldSendPreq(destination))
383  {
384  uint32_t originator_seqno = GetNextHwmpSeqno();
385  uint32_t dst_seqno = 0;
387  {
388  dst_seqno = result.seqnum;
389  }
391  for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
392  {
393  i->second->RequestDestination(destination, originator_seqno, dst_seqno);
394  }
395  }
396  QueuedPacket pkt;
397  pkt.pkt = packet;
398  pkt.dst = destination;
399  pkt.src = source;
400  pkt.protocol = protocolType;
401  pkt.reply = routeReply;
402  pkt.inInterface = sourceIface;
403  if (QueuePacket(pkt))
404  {
406  return true;
407  }
408  else
409  {
411  NS_LOG_DEBUG("Dropping packet from " << source << " to " << destination
412  << " due to queue overflow");
413  return false;
414  }
415 }
416 
417 void
419  Mac48Address from,
420  uint32_t interface,
421  Mac48Address fromMp,
422  uint32_t metric)
423 {
424  NS_LOG_FUNCTION(this << from << interface << fromMp << metric);
425  preq.IncrementMetric(metric);
426  // acceptance cretirea:
427  auto i = m_hwmpSeqnoMetricDatabase.find(preq.GetOriginatorAddress());
428  bool freshInfo(true);
429  if (i != m_hwmpSeqnoMetricDatabase.end())
430  {
431  if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber()) > 0)
432  {
433  return;
434  }
435  if (i->second.first == preq.GetOriginatorSeqNumber())
436  {
437  freshInfo = false;
438  if (i->second.second <= preq.GetMetric())
439  {
440  return;
441  }
442  }
443  }
445  std::make_pair(preq.GetOriginatorSeqNumber(), preq.GetMetric());
446  NS_LOG_DEBUG("I am " << GetAddress() << ", Accepted preq from address" << from
447  << ", preq:" << preq);
448  std::vector<Ptr<DestinationAddressUnit>> destinations = preq.GetDestinationList();
449  // Add reactive path to originator:
450  if ((freshInfo) ||
454  {
456  from,
457  interface,
458  preq.GetMetric(),
459  MicroSeconds(preq.GetLifetime() * 1024),
460  preq.GetOriginatorSeqNumber());
461  // Notify trace source of routing change
462  RouteChange rChange;
463  rChange.type = "Add Reactive";
464  rChange.destination = preq.GetOriginatorAddress();
465  rChange.retransmitter = from;
466  rChange.interface = interface;
467  rChange.metric = preq.GetMetric();
468  rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
469  rChange.seqnum = preq.GetOriginatorSeqNumber();
470  m_routeChangeTraceSource(rChange);
472  }
474  (m_rtable->LookupReactive(fromMp).metric > metric))
475  {
476  m_rtable->AddReactivePath(fromMp,
477  from,
478  interface,
479  metric,
480  MicroSeconds(preq.GetLifetime() * 1024),
481  preq.GetOriginatorSeqNumber());
482  // Notify trace source of routing change
483  RouteChange rChange;
484  rChange.type = "Add Reactive";
485  rChange.destination = fromMp;
486  rChange.retransmitter = from;
487  rChange.interface = interface;
488  rChange.metric = metric;
489  rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
490  rChange.seqnum = preq.GetOriginatorSeqNumber();
491  m_routeChangeTraceSource(rChange);
492  ReactivePathResolved(fromMp);
493  }
494  for (auto i = destinations.begin(); i != destinations.end(); i++)
495  {
496  if ((*i)->GetDestinationAddress() == Mac48Address::GetBroadcast())
497  {
498  // only proactive PREQ contains destination
499  // address as broadcast! Proactive preq MUST
500  // have destination count equal to 1 and
501  // per destination flags DO and RF
502  NS_ASSERT(preq.GetDestCount() == 1);
503  NS_ASSERT(((*i)->IsDo()) && ((*i)->IsRf()));
504  // Add proactive path only if it is the better then existed
505  // before
506  if (((m_rtable->LookupProactive()).retransmitter == Mac48Address::GetBroadcast()) ||
507  ((m_rtable->LookupProactive()).metric > preq.GetMetric()))
508  {
510  preq.GetOriginatorAddress(),
511  from,
512  interface,
513  MicroSeconds(preq.GetLifetime() * 1024),
514  preq.GetOriginatorSeqNumber());
515  // Notify trace source of routing change
516  RouteChange rChange;
517  rChange.type = "Add Proactive";
518  rChange.destination = preq.GetOriginatorAddress();
519  rChange.retransmitter = from;
520  rChange.interface = interface;
521  rChange.metric = preq.GetMetric();
522  rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
523  rChange.seqnum = preq.GetOriginatorSeqNumber();
524  m_routeChangeTraceSource(rChange);
526  }
527  if (!preq.IsNeedNotPrep())
528  {
530  preq.GetOriginatorAddress(),
531  from,
532  (uint32_t)0,
533  preq.GetOriginatorSeqNumber(),
535  preq.GetLifetime(),
536  interface);
537  }
538  break;
539  }
540  if ((*i)->GetDestinationAddress() == GetAddress())
541  {
543  preq.GetOriginatorAddress(),
544  from,
545  (uint32_t)0,
546  preq.GetOriginatorSeqNumber(),
548  preq.GetLifetime(),
549  interface);
552  preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
553  continue;
554  }
555  // check if can answer:
556  HwmpRtable::LookupResult result = m_rtable->LookupReactive((*i)->GetDestinationAddress());
557  if ((!((*i)->IsDo())) && (result.retransmitter != Mac48Address::GetBroadcast()))
558  {
559  // have a valid information and can answer
560  uint32_t lifetime = result.lifetime.GetMicroSeconds() / 1024;
561  if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber()) >= 0))
562  {
563  SendPrep((*i)->GetDestinationAddress(),
564  preq.GetOriginatorAddress(),
565  from,
566  result.metric,
567  preq.GetOriginatorSeqNumber(),
568  result.seqnum,
569  lifetime,
570  interface);
571  m_rtable->AddPrecursor((*i)->GetDestinationAddress(),
572  interface,
573  from,
574  MicroSeconds(preq.GetLifetime() * 1024));
575  if ((*i)->IsRf())
576  {
577  (*i)->SetFlags(true, false, (*i)->IsUsn()); // DO = 1, RF = 0
578  }
579  else
580  {
581  preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
582  continue;
583  }
584  }
585  }
586  }
587  // check if must retransmit:
588  if (preq.GetDestCount() == 0)
589  {
590  return;
591  }
592  // Forward PREQ to all interfaces:
593  NS_LOG_DEBUG("I am " << GetAddress() << "retransmitting PREQ:" << preq);
594  for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
595  {
596  Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
597  NS_LOG_DEBUG("Forwarding PREQ from " << from << " with delay "
598  << forwardingDelay.As(Time::US));
599  Simulator::Schedule(forwardingDelay, &HwmpProtocolMac::SendPreq, i->second, preq);
600  }
601 }
602 
603 void
605  Mac48Address from,
606  uint32_t interface,
607  Mac48Address fromMp,
608  uint32_t metric)
609 {
610  NS_LOG_FUNCTION(this << from << interface << fromMp << metric);
611  prep.IncrementMetric(metric);
612  // acceptance cretirea:
613  auto i = m_hwmpSeqnoMetricDatabase.find(prep.GetOriginatorAddress());
614  bool freshInfo(true);
615  uint32_t sequence = prep.GetDestinationSeqNumber();
616  if (i != m_hwmpSeqnoMetricDatabase.end())
617  {
618  if ((int32_t)(i->second.first - sequence) > 0)
619  {
620  return;
621  }
622  if (i->second.first == sequence)
623  {
624  freshInfo = false;
625  }
626  }
628  std::make_pair(sequence, prep.GetMetric());
629  // update routing info
630  // Now add a path to destination and add precursor to source
631  NS_LOG_DEBUG("I am " << GetAddress() << ", received prep from " << prep.GetOriginatorAddress()
632  << ", receiver was:" << from);
634  // Add a reactive path only if seqno is fresher or it improves the
635  // metric
636  if ((freshInfo) ||
637  (((m_rtable->LookupReactive(prep.GetOriginatorAddress())).retransmitter ==
639  ((m_rtable->LookupReactive(prep.GetOriginatorAddress())).metric > prep.GetMetric())))
640  {
642  from,
643  interface,
644  prep.GetMetric(),
645  MicroSeconds(prep.GetLifetime() * 1024),
646  sequence);
647  // Notify trace source of routing change
648  RouteChange rChange;
649  rChange.type = "Add Reactive";
650  rChange.destination = prep.GetOriginatorAddress();
651  rChange.retransmitter = from;
652  rChange.interface = interface;
653  rChange.metric = prep.GetMetric();
654  rChange.lifetime = MicroSeconds(prep.GetLifetime() * 1024);
655  rChange.seqnum = sequence;
656  m_routeChangeTraceSource(rChange);
658  interface,
659  from,
660  MicroSeconds(prep.GetLifetime() * 1024));
662  {
664  interface,
665  result.retransmitter,
666  result.lifetime);
667  }
669  }
670  if (((m_rtable->LookupReactive(fromMp)).retransmitter == Mac48Address::GetBroadcast()) ||
671  ((m_rtable->LookupReactive(fromMp)).metric > metric))
672  {
673  m_rtable->AddReactivePath(fromMp,
674  from,
675  interface,
676  metric,
677  MicroSeconds(prep.GetLifetime() * 1024),
678  sequence);
679  // Notify trace source of routing change
680  RouteChange rChange;
681  rChange.type = "Add Reactive";
682  rChange.destination = fromMp;
683  rChange.retransmitter = from;
684  rChange.interface = interface;
685  rChange.metric = metric;
686  rChange.lifetime = MicroSeconds(prep.GetLifetime() * 1024);
687  rChange.seqnum = sequence;
688  m_routeChangeTraceSource(rChange);
689  ReactivePathResolved(fromMp);
690  }
691  if (prep.GetDestinationAddress() == GetAddress())
692  {
693  NS_LOG_DEBUG("I am " << GetAddress() << ", resolved " << prep.GetOriginatorAddress());
694  return;
695  }
697  {
698  return;
699  }
700  // Forward PREP
701  auto prep_sender = m_interfaces.find(result.ifIndex);
702  NS_ASSERT(prep_sender != m_interfaces.end());
703  Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
704  NS_LOG_DEBUG("Forwarding PREP from " << from << " with delay " << forwardingDelay.As(Time::US));
705  Simulator::Schedule(forwardingDelay,
707  prep_sender->second,
708  prep,
709  result.retransmitter);
710 }
711 
712 void
713 HwmpProtocol::ReceivePerr(std::vector<FailedDestination> destinations,
714  Mac48Address from,
715  uint32_t interface,
716  Mac48Address fromMp)
717 {
718  NS_LOG_FUNCTION(this << from << interface << fromMp);
719  // Acceptance cretirea:
720  NS_LOG_DEBUG("I am " << GetAddress() << ", received PERR from " << from);
721  std::vector<FailedDestination> retval;
723  for (unsigned int i = 0; i < destinations.size(); i++)
724  {
725  result = m_rtable->LookupReactiveExpired(destinations[i].destination);
726  if (!((result.retransmitter != from) || (result.ifIndex != interface) ||
727  ((int32_t)(result.seqnum - destinations[i].seqnum) > 0)))
728  {
729  retval.push_back(destinations[i]);
730  }
731  }
732  if (retval.empty())
733  {
734  return;
735  }
737 }
738 
739 void
741  Mac48Address dst,
742  Mac48Address retransmitter,
743  uint32_t initMetric,
744  uint32_t originatorDsn,
745  uint32_t destinationSN,
746  uint32_t lifetime,
747  uint32_t interface)
748 {
749  IePrep prep;
750  prep.SetHopcount(0);
751  prep.SetTtl(m_maxTtl);
752  prep.SetDestinationAddress(dst);
753  prep.SetDestinationSeqNumber(destinationSN);
754  prep.SetLifetime(lifetime);
755  prep.SetMetric(initMetric);
756  prep.SetOriginatorAddress(src);
757  prep.SetOriginatorSeqNumber(originatorDsn);
758  auto prep_sender = m_interfaces.find(interface);
759  NS_ASSERT(prep_sender != m_interfaces.end());
760  prep_sender->second->SendPrep(prep, retransmitter);
762 }
763 
764 bool
766 {
767  NS_LOG_FUNCTION(this << mp);
768  m_mp = mp;
769  std::vector<Ptr<NetDevice>> interfaces = mp->GetInterfaces();
770  for (auto i = interfaces.begin(); i != interfaces.end(); i++)
771  {
772  // Checking for compatible net device
773  Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice>();
774  if (!wifiNetDev)
775  {
776  return false;
777  }
779  if (!mac)
780  {
781  return false;
782  }
783  // Installing plugins:
784  Ptr<HwmpProtocolMac> hwmpMac = Create<HwmpProtocolMac>(wifiNetDev->GetIfIndex(), this);
785  m_interfaces[wifiNetDev->GetIfIndex()] = hwmpMac;
786  mac->InstallPlugin(hwmpMac);
787  // Installing airtime link metric:
788  Ptr<AirtimeLinkMetricCalculator> metric = CreateObject<AirtimeLinkMetricCalculator>();
789  mac->SetLinkMetricCallback(
791  }
792  mp->SetRoutingProtocol(this);
793  // Mesh point aggregates all installed protocols
794  mp->AggregateObject(this);
795  m_address = Mac48Address::ConvertFrom(mp->GetAddress()); // address;
796  return true;
797 }
798 
799 void
801  Mac48Address peerAddress,
802  uint32_t interface,
803  bool status)
804 {
805  NS_LOG_FUNCTION(this << meshPointAddress << peerAddress << interface << status);
806  if (status)
807  {
808  return;
809  }
810  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations(peerAddress);
811  NS_LOG_DEBUG(destinations.size() << " failed destinations for peer address " << peerAddress);
812  InitiatePathError(MakePathError(destinations));
813 }
814 
815 void
816 HwmpProtocol::SetNeighboursCallback(Callback<std::vector<Mac48Address>, uint32_t> cb)
817 {
819 }
820 
821 bool
823 {
824  NS_LOG_FUNCTION(this << seqno << source);
825  if (source == GetAddress())
826  {
827  NS_LOG_DEBUG("Dropping seqno " << seqno << "; from self");
828  return true;
829  }
830  const auto i = m_lastDataSeqno.find(source);
831  if (i == m_lastDataSeqno.end())
832  {
833  m_lastDataSeqno[source] = seqno;
834  }
835  else
836  {
837  if ((int32_t)(i->second - seqno) >= 0)
838  {
839  NS_LOG_DEBUG("Dropping seqno " << seqno << "; stale frame");
840  return true;
841  }
842  m_lastDataSeqno[source] = seqno;
843  }
844  return false;
845 }
846 
848 HwmpProtocol::MakePathError(std::vector<FailedDestination> destinations)
849 {
850  NS_LOG_FUNCTION(this);
851  PathError retval;
852  // HwmpRtable increments a sequence number as written in 11B.9.7.2
853  retval.receivers = GetPerrReceivers(destinations);
854  if (retval.receivers.empty())
855  {
856  return retval;
857  }
859  for (unsigned int i = 0; i < destinations.size(); i++)
860  {
861  retval.destinations.push_back(destinations[i]);
862  m_rtable->DeleteReactivePath(destinations[i].destination);
863  // Notify trace source of routing change
864  RouteChange rChange;
865  rChange.type = "Delete Reactive";
866  rChange.destination = destinations[i].destination;
867  rChange.seqnum = destinations[i].seqnum;
868  m_routeChangeTraceSource(rChange);
869  }
870  return retval;
871 }
872 
873 void
875 {
876  NS_LOG_FUNCTION(this);
877  for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
878  {
879  std::vector<Mac48Address> receivers_for_interface;
880  for (unsigned int j = 0; j < perr.receivers.size(); j++)
881  {
882  if (i->first == perr.receivers[j].first)
883  {
884  receivers_for_interface.push_back(perr.receivers[j].second);
885  }
886  }
887  i->second->InitiatePerr(perr.destinations, receivers_for_interface);
888  }
889 }
890 
891 void
893 {
894  NS_LOG_FUNCTION(this);
895  for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
896  {
897  std::vector<Mac48Address> receivers_for_interface;
898  for (unsigned int j = 0; j < perr.receivers.size(); j++)
899  {
900  if (i->first == perr.receivers[j].first)
901  {
902  receivers_for_interface.push_back(perr.receivers[j].second);
903  }
904  }
905  Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
906  NS_LOG_DEBUG("Forwarding PERR with delay " << forwardingDelay.As(Time::US));
907  Simulator::Schedule(forwardingDelay,
909  i->second,
910  perr.destinations,
911  receivers_for_interface);
912  i->second->ForwardPerr(perr.destinations, receivers_for_interface);
913  }
914 }
915 
916 std::vector<std::pair<uint32_t, Mac48Address>>
917 HwmpProtocol::GetPerrReceivers(std::vector<FailedDestination> failedDest)
918 {
919  NS_LOG_FUNCTION(this);
921  for (unsigned int i = 0; i < failedDest.size(); i++)
922  {
923  HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors(failedDest[i].destination);
924  m_rtable->DeleteReactivePath(failedDest[i].destination);
925  // Notify trace source of routing change
926  RouteChange rChange;
927  rChange.type = "Delete Reactive";
928  rChange.destination = failedDest[i].destination;
929  rChange.seqnum = failedDest[i].seqnum;
930  m_routeChangeTraceSource(rChange);
931  m_rtable->DeleteProactivePath(failedDest[i].destination);
932  // Notify trace source of routing change
933  RouteChange rChangePro;
934  rChangePro.type = "Delete Proactive";
935  rChangePro.destination = failedDest[i].destination;
936  rChangePro.seqnum = failedDest[i].seqnum;
937  m_routeChangeTraceSource(rChangePro);
938  for (unsigned int j = 0; j < precursors.size(); j++)
939  {
940  retval.push_back(precursors[j]);
941  }
942  }
943  // Check if we have duplicates in retval and precursors:
944  for (unsigned int i = 0; i < retval.size(); i++)
945  {
946  for (unsigned int j = i + 1; j < retval.size(); j++)
947  {
948  if (retval[i].second == retval[j].second)
949  {
950  retval.erase(retval.begin() + j);
951  }
952  }
953  }
954  return retval;
955 }
956 
957 std::vector<Mac48Address>
959 {
960  NS_LOG_FUNCTION(this << interface);
961  std::vector<Mac48Address> retval;
962  if (!m_neighboursCallback.IsNull())
963  {
964  retval = m_neighboursCallback(interface);
965  }
966  if (retval.size() >= m_unicastPreqThreshold || retval.empty())
967  {
968  retval.clear();
969  retval.push_back(Mac48Address::GetBroadcast());
970  }
971  return retval;
972 }
973 
974 std::vector<Mac48Address>
976 {
977  NS_LOG_FUNCTION(this << interface);
978  std::vector<Mac48Address> retval;
979  if (!m_neighboursCallback.IsNull())
980  {
981  retval = m_neighboursCallback(interface);
982  }
983  if (retval.size() >= m_unicastDataThreshold || retval.empty())
984  {
985  retval.clear();
986  retval.push_back(Mac48Address::GetBroadcast());
987  }
988  return retval;
989 }
990 
991 bool
993 {
994  NS_LOG_FUNCTION(this);
995  if (m_rqueue.size() > m_maxQueueSize)
996  {
997  return false;
998  }
999  m_rqueue.push_back(packet);
1000  return true;
1001 }
1002 
1005 {
1006  NS_LOG_FUNCTION(this << dst);
1007  QueuedPacket retval;
1008  retval.pkt = nullptr;
1009  for (auto i = m_rqueue.begin(); i != m_rqueue.end(); i++)
1010  {
1011  if ((*i).dst == dst)
1012  {
1013  retval = (*i);
1014  m_rqueue.erase(i);
1015  break;
1016  }
1017  }
1018  return retval;
1019 }
1020 
1023 {
1024  NS_LOG_FUNCTION(this);
1025  QueuedPacket retval;
1026  retval.pkt = nullptr;
1027  if (!m_rqueue.empty())
1028  {
1029  retval = m_rqueue[0];
1030  m_rqueue.erase(m_rqueue.begin());
1031  }
1032  return retval;
1033 }
1034 
1035 void
1037 {
1038  NS_LOG_FUNCTION(this << dst);
1039  auto i = m_preqTimeouts.find(dst);
1040  if (i != m_preqTimeouts.end())
1041  {
1042  m_routeDiscoveryTimeCallback(Simulator::Now() - i->second.whenScheduled);
1043  }
1044 
1047  // Send all packets stored for this destination
1048  QueuedPacket packet = DequeueFirstPacketByDst(dst);
1049  while (packet.pkt)
1050  {
1051  // set RA tag for retransmitter:
1052  HwmpTag tag;
1053  packet.pkt->RemovePacketTag(tag);
1054  tag.SetAddress(result.retransmitter);
1055  packet.pkt->AddPacketTag(tag);
1056  m_stats.txUnicast++;
1057  m_stats.txBytes += packet.pkt->GetSize();
1058  packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1059 
1060  packet = DequeueFirstPacketByDst(dst);
1061  }
1062 }
1063 
1064 void
1066 {
1067  NS_LOG_FUNCTION(this);
1068  // send all packets to root
1071  QueuedPacket packet = DequeueFirstPacket();
1072  while (packet.pkt)
1073  {
1074  // set RA tag for retransmitter:
1075  HwmpTag tag;
1076  if (!packet.pkt->RemovePacketTag(tag))
1077  {
1078  NS_FATAL_ERROR("HWMP tag must be present at this point");
1079  }
1080  tag.SetAddress(result.retransmitter);
1081  packet.pkt->AddPacketTag(tag);
1082  m_stats.txUnicast++;
1083  m_stats.txBytes += packet.pkt->GetSize();
1084  packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1085 
1086  packet = DequeueFirstPacket();
1087  }
1088 }
1089 
1090 bool
1092 {
1093  NS_LOG_FUNCTION(this << dst);
1094  auto i = m_preqTimeouts.find(dst);
1095  if (i == m_preqTimeouts.end())
1096  {
1097  m_preqTimeouts[dst].preqTimeout =
1100  this,
1101  dst,
1102  1);
1103  m_preqTimeouts[dst].whenScheduled = Simulator::Now();
1104  return true;
1105  }
1106  return false;
1107 }
1108 
1109 void
1111 {
1112  NS_LOG_FUNCTION(this << dst << (uint16_t)numOfRetry);
1114  if (result.retransmitter == Mac48Address::GetBroadcast())
1115  {
1116  result = m_rtable->LookupProactive();
1117  }
1118  if (result.retransmitter != Mac48Address::GetBroadcast())
1119  {
1120  auto i = m_preqTimeouts.find(dst);
1121  NS_ASSERT(i != m_preqTimeouts.end());
1122  m_preqTimeouts.erase(i);
1123  return;
1124  }
1125  if (numOfRetry > m_dot11MeshHWMPmaxPREQretries)
1126  {
1127  QueuedPacket packet = DequeueFirstPacketByDst(dst);
1128  // purge queue and delete entry from retryDatabase
1129  while (packet.pkt)
1130  {
1132  packet.reply(false,
1133  packet.pkt,
1134  packet.src,
1135  packet.dst,
1136  packet.protocol,
1138  packet = DequeueFirstPacketByDst(dst);
1139  }
1140  auto i = m_preqTimeouts.find(dst);
1141  NS_ASSERT(i != m_preqTimeouts.end());
1142  m_routeDiscoveryTimeCallback(Simulator::Now() - i->second.whenScheduled);
1143  m_preqTimeouts.erase(i);
1144  return;
1145  }
1146  numOfRetry++;
1147  uint32_t originator_seqno = GetNextHwmpSeqno();
1148  uint32_t dst_seqno = m_rtable->LookupReactiveExpired(dst).seqnum;
1149  for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
1150  {
1151  i->second->RequestDestination(dst, originator_seqno, dst_seqno);
1152  }
1153  m_preqTimeouts[dst].preqTimeout =
1156  this,
1157  dst,
1158  numOfRetry);
1159 }
1160 
1161 // Proactive PREQ routines:
1162 void
1164 {
1165  NS_LOG_FUNCTION(this);
1166  NS_LOG_DEBUG("ROOT IS: " << m_address);
1167  m_isRoot = true;
1168 }
1169 
1170 void
1172 {
1173  NS_LOG_FUNCTION(this);
1175 }
1176 
1177 void
1179 {
1180  NS_LOG_FUNCTION(this);
1181  IePreq preq;
1182  // By default: must answer
1183  preq.SetHopcount(0);
1184  preq.SetTTL(m_maxTtl);
1186  //\attention: do not forget to set originator address, sequence
1187  // number and preq ID in HWMP-MAC plugin
1190  preq.SetPreqID(GetNextPreqId());
1192  for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
1193  {
1194  i->second->SendPreq(preq);
1195  }
1198  this);
1199 }
1200 
1201 bool
1203 {
1204  return m_doFlag;
1205 }
1206 
1207 bool
1209 {
1210  return m_rfFlag;
1211 }
1212 
1213 Time
1215 {
1217 }
1218 
1219 Time
1221 {
1223 }
1224 
1225 uint8_t
1227 {
1228  return m_maxTtl;
1229 }
1230 
1231 uint32_t
1233 {
1234  m_preqId++;
1235  return m_preqId;
1236 }
1237 
1238 uint32_t
1240 {
1241  m_hwmpSeqno++;
1242  return m_hwmpSeqno;
1243 }
1244 
1245 uint32_t
1247 {
1249 }
1250 
1251 uint8_t
1253 {
1254  return m_unicastPerrThreshold;
1255 }
1256 
1259 {
1260  return m_address;
1261 }
1262 
1263 // Statistics:
1265  : txUnicast(0),
1266  txBroadcast(0),
1267  txBytes(0),
1268  droppedTtl(0),
1269  totalQueued(0),
1270  totalDropped(0),
1271  initiatedPreq(0),
1272  initiatedPrep(0),
1273  initiatedPerr(0)
1274 {
1275 }
1276 
1277 void
1278 HwmpProtocol::Statistics::Print(std::ostream& os) const
1279 {
1280  os << "<Statistics "
1281  "txUnicast=\""
1282  << txUnicast
1283  << "\" "
1284  "txBroadcast=\""
1285  << txBroadcast
1286  << "\" "
1287  "txBytes=\""
1288  << txBytes
1289  << "\" "
1290  "droppedTtl=\""
1291  << droppedTtl
1292  << "\" "
1293  "totalQueued=\""
1294  << totalQueued
1295  << "\" "
1296  "totalDropped=\""
1297  << totalDropped
1298  << "\" "
1299  "initiatedPreq=\""
1300  << initiatedPreq
1301  << "\" "
1302  "initiatedPrep=\""
1303  << initiatedPrep
1304  << "\" "
1305  "initiatedPerr=\""
1306  << initiatedPerr << "\"/>" << std::endl;
1307 }
1308 
1309 void
1310 HwmpProtocol::Report(std::ostream& os) const
1311 {
1312  os << "<Hwmp "
1313  "address=\""
1314  << m_address << "\"" << std::endl
1315  << "maxQueueSize=\"" << m_maxQueueSize << "\"" << std::endl
1316  << "Dot11MeshHWMPmaxPREQretries=\"" << (uint16_t)m_dot11MeshHWMPmaxPREQretries << "\""
1317  << std::endl
1318  << "Dot11MeshHWMPnetDiameterTraversalTime=\""
1319  << m_dot11MeshHWMPnetDiameterTraversalTime.GetSeconds() << "\"" << std::endl
1320  << "Dot11MeshHWMPpreqMinInterval=\"" << m_dot11MeshHWMPpreqMinInterval.GetSeconds() << "\""
1321  << std::endl
1322  << "Dot11MeshHWMPperrMinInterval=\"" << m_dot11MeshHWMPperrMinInterval.GetSeconds() << "\""
1323  << std::endl
1324  << "Dot11MeshHWMPactiveRootTimeout=\"" << m_dot11MeshHWMPactiveRootTimeout.GetSeconds()
1325  << "\"" << std::endl
1326  << "Dot11MeshHWMPactivePathTimeout=\"" << m_dot11MeshHWMPactivePathTimeout.GetSeconds()
1327  << "\"" << std::endl
1328  << "Dot11MeshHWMPpathToRootInterval=\"" << m_dot11MeshHWMPpathToRootInterval.GetSeconds()
1329  << "\"" << std::endl
1330  << "Dot11MeshHWMPrannInterval=\"" << m_dot11MeshHWMPrannInterval.GetSeconds() << "\""
1331  << std::endl
1332  << "isRoot=\"" << m_isRoot << "\"" << std::endl
1333  << "maxTtl=\"" << (uint16_t)m_maxTtl << "\"" << std::endl
1334  << "unicastPerrThreshold=\"" << (uint16_t)m_unicastPerrThreshold << "\"" << std::endl
1335  << "unicastPreqThreshold=\"" << (uint16_t)m_unicastPreqThreshold << "\"" << std::endl
1336  << "unicastDataThreshold=\"" << (uint16_t)m_unicastDataThreshold << "\"" << std::endl
1337  << "doFlag=\"" << m_doFlag << "\"" << std::endl
1338  << "rfFlag=\"" << m_rfFlag << "\">" << std::endl;
1339  m_stats.Print(os);
1340  for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
1341  {
1342  plugin->second->Report(os);
1343  }
1344  os << "</Hwmp>" << std::endl;
1345 }
1346 
1347 void
1349 {
1350  NS_LOG_FUNCTION(this);
1351  m_stats = Statistics();
1352  for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
1353  {
1354  plugin->second->ResetStats();
1355  }
1356 }
1357 
1358 int64_t
1360 {
1361  NS_LOG_FUNCTION(this << stream);
1362  m_coefficient->SetStream(stream);
1363  return 1;
1364 }
1365 
1368 {
1369  return m_rtable;
1370 }
1371 
1373  : pkt(nullptr),
1374  protocol(0),
1375  inInterface(0)
1376 {
1377 }
1378 } // namespace dot11s
1379 } // namespace ns3
Callback template class.
Definition: callback.h:438
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:204
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:967
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
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:960
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:983
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:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
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:415
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
@ 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:413
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
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.
void PeerLinkStatus(Mac48Address meshPointAddress, Mac48Address peerAddress, uint32_t interface, bool status)
Peer link status function.
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.
TracedCallback< RouteChange > m_routeChangeTraceSource
Route change trace source.
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 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
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:40
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:45
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:256
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:82
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
#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:1350
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
address
Definition: first.py:47
interfaces
Definition: first.py:50
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:839
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
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:704
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
Definition: second.py:1
mac
Definition: third.py:92
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:49
uint32_t seqnum
sequence number
Definition: hwmp-rtable.h:53
Mac48Address retransmitter
retransmitter
Definition: hwmp-rtable.h:50
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