A Discrete-Event Network Simulator
API
hwmp-protocol.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008,2009 IITP RAS
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Kirill Andreev <andreev@iitp.ru>
19  */
20 
21 #include "hwmp-protocol.h"
22 #include "hwmp-protocol-mac.h"
23 #include "hwmp-tag.h"
24 #include "hwmp-rtable.h"
25 #include "ns3/log.h"
26 #include "ns3/simulator.h"
27 #include "ns3/packet.h"
28 #include "ns3/mesh-point-device.h"
29 #include "ns3/wifi-net-device.h"
30 #include "ns3/mesh-wifi-interface-mac.h"
31 #include "ns3/random-variable-stream.h"
32 #include "airtime-metric.h"
33 #include "ie-dot11s-preq.h"
34 #include "ie-dot11s-prep.h"
35 #include "ns3/trace-source-accessor.h"
36 #include "ie-dot11s-perr.h"
37 
38 namespace ns3 {
39 
40 NS_LOG_COMPONENT_DEFINE ("HwmpProtocol");
41 
42 namespace dot11s {
43 
44 NS_OBJECT_ENSURE_REGISTERED (HwmpProtocol);
45 
46 TypeId
48 {
49  static TypeId tid = TypeId ("ns3::dot11s::HwmpProtocol")
51  .SetGroupName ("Mesh")
52  .AddConstructor<HwmpProtocol> ()
53  .AddAttribute ( "RandomStart",
54  "Random delay at first proactive PREQ",
55  TimeValue (Seconds (0.1)),
59  )
60  .AddAttribute ( "MaxQueueSize",
61  "Maximum number of packets we can store when resolving route",
62  UintegerValue (255),
65  MakeUintegerChecker<uint16_t> (1)
66  )
67  .AddAttribute ( "Dot11MeshHWMPmaxPREQretries",
68  "Maximum number of retries before we suppose the destination to be unreachable",
69  UintegerValue (3),
72  MakeUintegerChecker<uint8_t> (1)
73  )
74  .AddAttribute ( "Dot11MeshHWMPnetDiameterTraversalTime",
75  "Time we suppose the packet to go from one edge of the network to another",
76  TimeValue (MicroSeconds (1024*100)),
80  )
81  .AddAttribute ( "Dot11MeshHWMPpreqMinInterval",
82  "Minimal interval between to successive PREQs",
83  TimeValue (MicroSeconds (1024*100)),
87  )
88  .AddAttribute ( "Dot11MeshHWMPperrMinInterval",
89  "Minimal interval between to successive PREQs",
90  TimeValue (MicroSeconds (1024*100)),
93  )
94  .AddAttribute ( "Dot11MeshHWMPactiveRootTimeout",
95  "Lifetime of proactive routing information",
96  TimeValue (MicroSeconds (1024*5000)),
100  )
101  .AddAttribute ( "Dot11MeshHWMPactivePathTimeout",
102  "Lifetime of reactive routing information",
103  TimeValue (MicroSeconds (1024*5000)),
106  MakeTimeChecker ()
107  )
108  .AddAttribute ( "Dot11MeshHWMPpathToRootInterval",
109  "Interval between two successive proactive PREQs",
110  TimeValue (MicroSeconds (1024*2000)),
113  MakeTimeChecker ()
114  )
115  .AddAttribute ( "Dot11MeshHWMPrannInterval",
116  "Lifetime of proactive routing information",
117  TimeValue (MicroSeconds (1024*5000)),
120  MakeTimeChecker ()
121  )
122  .AddAttribute ( "MaxTtl",
123  "Initial value of Time To Live field",
124  UintegerValue (32),
127  MakeUintegerChecker<uint8_t> (2)
128  )
129  .AddAttribute ( "UnicastPerrThreshold",
130  "Maximum number of PERR receivers, when we send a PERR as a chain of unicasts",
131  UintegerValue (32),
134  MakeUintegerChecker<uint8_t> (1)
135  )
136  .AddAttribute ( "UnicastPreqThreshold",
137  "Maximum number of PREQ receivers, when we send a PREQ as a chain of unicasts",
138  UintegerValue (1),
141  MakeUintegerChecker<uint8_t> (1)
142  )
143  .AddAttribute ( "UnicastDataThreshold",
144  "Maximum number of broadcast receivers, when we send a broadcast as a chain of unicasts",
145  UintegerValue (1),
148  MakeUintegerChecker<uint8_t> (1)
149  )
150  .AddAttribute ( "DoFlag",
151  "Destination only HWMP flag",
152  BooleanValue (false),
156  )
157  .AddAttribute ( "RfFlag",
158  "Reply and forward flag",
159  BooleanValue (true),
163  )
164  .AddTraceSource ( "RouteDiscoveryTime",
165  "The time of route discovery procedure",
168  "ns3::Time::TracedCallback"
169  )
170  .AddTraceSource ("RouteChange",
171  "Routing table changed",
173  "ns3::HwmpProtocol::RouteChangeTracedCallback"
174  )
175  ;
176  return tid;
177 }
178 
180  m_dataSeqno (1),
181  m_hwmpSeqno (1),
182  m_preqId (0),
183  m_rtable (CreateObject<HwmpRtable> ()),
184  m_randomStart (Seconds (0.1)),
185  m_maxQueueSize (255),
186  m_dot11MeshHWMPmaxPREQretries (3),
187  m_dot11MeshHWMPnetDiameterTraversalTime (MicroSeconds (1024*100)),
188  m_dot11MeshHWMPpreqMinInterval (MicroSeconds (1024*100)),
189  m_dot11MeshHWMPperrMinInterval (MicroSeconds (1024*100)),
190  m_dot11MeshHWMPactiveRootTimeout (MicroSeconds (1024*5000)),
191  m_dot11MeshHWMPactivePathTimeout (MicroSeconds (1024*5000)),
192  m_dot11MeshHWMPpathToRootInterval (MicroSeconds (1024*2000)),
193  m_dot11MeshHWMPrannInterval (MicroSeconds (1024*5000)),
194  m_isRoot (false),
195  m_maxTtl (32),
196  m_unicastPerrThreshold (32),
197  m_unicastPreqThreshold (1),
198  m_unicastDataThreshold (1),
199  m_doFlag (false),
200  m_rfFlag (false)
201 {
202  NS_LOG_FUNCTION (this);
203  m_coefficient = CreateObject<UniformRandomVariable> ();
204 }
205 
207 {
208  NS_LOG_FUNCTION (this);
209 }
210 
211 void
213 {
214  NS_LOG_FUNCTION (this);
216  if (m_isRoot)
217  {
218  Time randomStart = Seconds (m_coefficient->GetValue ());
220  }
221 }
222 
223 void
225 {
226  NS_LOG_FUNCTION (this);
227  for (std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.begin (); i != m_preqTimeouts.end (); i++)
228  {
229  i->second.preqTimeout.Cancel ();
230  }
232  m_preqTimeouts.clear ();
233  m_lastDataSeqno.clear ();
234  m_hwmpSeqnoMetricDatabase.clear ();
235  m_interfaces.clear ();
236  m_rqueue.clear ();
237  m_rtable = 0;
238  m_mp = 0;
239 }
240 
241 bool
243  uint32_t sourceIface,
244  const Mac48Address source,
245  const Mac48Address destination,
246  Ptr<const Packet> constPacket,
247  uint16_t protocolType, //ethrnet 'Protocol' field
249  )
250 {
251  NS_LOG_FUNCTION (this << sourceIface << source << destination << constPacket << protocolType);
252  Ptr <Packet> packet = constPacket->Copy ();
253  HwmpTag tag;
254  if (sourceIface == GetMeshPoint ()->GetIfIndex ())
255  {
256  // packet from level 3
257  if (packet->PeekPacketTag (tag))
258  {
259  NS_FATAL_ERROR ("HWMP tag has come with a packet from upper layer. This must not occur...");
260  }
261  //Filling TAG:
262  if (destination == Mac48Address::GetBroadcast ())
263  {
264  tag.SetSeqno (m_dataSeqno++);
265  }
266  tag.SetTtl (m_maxTtl);
267  }
268  else
269  {
270  if (!packet->RemovePacketTag (tag))
271  {
272  NS_FATAL_ERROR ("HWMP tag is supposed to be here at this point.");
273  }
274  tag.DecrementTtl ();
275  if (tag.GetTtl () == 0)
276  {
278  return false;
279  }
280  }
281  if (destination == Mac48Address::GetBroadcast ())
282  {
284  m_stats.txBytes += packet->GetSize ();
285  //channel IDs where we have already sent broadcast:
286  std::vector<uint16_t> channels;
287  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
288  {
289  bool shouldSend = true;
290  for (std::vector<uint16_t>::const_iterator chan = channels.begin (); chan != channels.end (); chan++)
291  {
292  if ((*chan) == plugin->second->GetChannelId ())
293  {
294  shouldSend = false;
295  }
296  }
297  if (!shouldSend)
298  {
299  continue;
300  }
301  channels.push_back (plugin->second->GetChannelId ());
302  std::vector<Mac48Address> receivers = GetBroadcastReceivers (plugin->first);
303  for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i++)
304  {
305  Ptr<Packet> packetCopy = packet->Copy ();
306  //
307  // 64-bit Intel valgrind complains about tag.SetAddress (*i). It
308  // likes this just fine.
309  //
310  Mac48Address address = *i;
311  tag.SetAddress (address);
312  packetCopy->AddPacketTag (tag);
313  routeReply (true, packetCopy, source, destination, protocolType, plugin->first);
314  }
315  }
316  }
317  else
318  {
319  return ForwardUnicast (sourceIface, source, destination, packet, protocolType, routeReply, tag.GetTtl ());
320  }
321  return true;
322 }
323 bool
324 HwmpProtocol::RemoveRoutingStuff (uint32_t fromIface, const Mac48Address source,
325  const Mac48Address destination, Ptr<Packet> packet, uint16_t& protocolType)
326 {
327  HwmpTag tag;
328  if (!packet->RemovePacketTag (tag))
329  {
330  NS_FATAL_ERROR ("HWMP tag must exist when packet received from the network");
331  }
332  return true;
333 }
334 bool
335 HwmpProtocol::ForwardUnicast (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination,
336  Ptr<Packet> packet, uint16_t protocolType, RouteReplyCallback routeReply, uint32_t ttl)
337 {
338  NS_LOG_FUNCTION (this << sourceIface << source << destination << packet << protocolType << ttl);
339  NS_ASSERT (destination != Mac48Address::GetBroadcast ());
340  HwmpRtable::LookupResult result = m_rtable->LookupReactive (destination);
341  NS_LOG_DEBUG ("Requested src = "<<source<<", dst = "<<destination<<", I am "<<GetAddress ()<<", RA = "<<result.retransmitter);
342  if (result.retransmitter == Mac48Address::GetBroadcast ())
343  {
344  result = m_rtable->LookupProactive ();
345  }
346  HwmpTag tag;
347  tag.SetAddress (result.retransmitter);
348  tag.SetTtl (ttl);
349  //seqno and metric is not used;
350  packet->AddPacketTag (tag);
351  if (result.retransmitter != Mac48Address::GetBroadcast ())
352  {
353  //reply immediately:
354  routeReply (true, packet, source, destination, protocolType, result.ifIndex);
355  m_stats.txUnicast++;
356  m_stats.txBytes += packet->GetSize ();
357  return true;
358  }
359  if (sourceIface != GetMeshPoint ()->GetIfIndex ())
360  {
361  //Start path error procedure:
362  NS_LOG_DEBUG ("Must Send PERR");
363  result = m_rtable->LookupReactiveExpired (destination);
364  NS_LOG_DEBUG ("Path error " << result.retransmitter);
365  //1. Lookup expired reactive path. If exists - start path error
366  // procedure towards a next hop of this path
367  //2. If there was no reactive path, we lookup expired proactive
368  // path. If exist - start path error procedure towards path to
369  // root
370  if (result.retransmitter == Mac48Address::GetBroadcast ())
371  {
372  NS_LOG_DEBUG ("Path error, lookup expired proactive path");
373  result = m_rtable->LookupProactiveExpired ();
374  }
375  if (result.retransmitter != Mac48Address::GetBroadcast ())
376  {
377  NS_LOG_DEBUG ("Path error, initiate reactive path error");
378  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (result.retransmitter);
379  InitiatePathError (MakePathError (destinations));
380  }
382  return false;
383  }
384  //Request a destination:
385  result = m_rtable->LookupReactiveExpired (destination);
386  if (ShouldSendPreq (destination))
387  {
388  uint32_t originator_seqno = GetNextHwmpSeqno ();
389  uint32_t dst_seqno = 0;
390  if (result.retransmitter != Mac48Address::GetBroadcast ())
391  {
392  dst_seqno = result.seqnum;
393  }
395  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
396  {
397  i->second->RequestDestination (destination, originator_seqno, dst_seqno);
398  }
399  }
400  QueuedPacket pkt;
401  pkt.pkt = packet;
402  pkt.dst = destination;
403  pkt.src = source;
404  pkt.protocol = protocolType;
405  pkt.reply = routeReply;
406  pkt.inInterface = sourceIface;
407  if (QueuePacket (pkt))
408  {
410  return true;
411  }
412  else
413  {
415  NS_LOG_DEBUG ("Dropping packet from " << source << " to " << destination << " due to queue overflow");
416  return false;
417  }
418 }
419 void
420 HwmpProtocol::ReceivePreq (IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
421 {
422  NS_LOG_FUNCTION (this << from << interface << fromMp << metric);
423  preq.IncrementMetric (metric);
424  //acceptance cretirea:
425  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
426  preq.GetOriginatorAddress ());
427  bool freshInfo (true);
428  if (i != m_hwmpSeqnoMetricDatabase.end ())
429  {
430  if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber ()) > 0)
431  {
432  return;
433  }
434  if (i->second.first == preq.GetOriginatorSeqNumber ())
435  {
436  freshInfo = false;
437  if (i->second.second <= preq.GetMetric ())
438  {
439  return;
440  }
441  }
442  }
444  std::make_pair (preq.GetOriginatorSeqNumber (), preq.GetMetric ());
445  NS_LOG_DEBUG ("I am " << GetAddress () << ", Accepted preq from address" << from << ", preq:" << preq);
446  std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
447  //Add reactive path to originator:
448  if (
449  (freshInfo) ||
450  (
453  )
454  )
455  {
457  preq.GetOriginatorAddress (),
458  from,
459  interface,
460  preq.GetMetric (),
461  MicroSeconds (preq.GetLifetime () * 1024),
462  preq.GetOriginatorSeqNumber ()
463  );
464  // Notify trace source of routing change
465  struct RouteChange rChange;
466  rChange.type = "Add Reactive";
467  rChange.destination = preq.GetOriginatorAddress ();
468  rChange.retransmitter = from;
469  rChange.interface = interface;
470  rChange.metric = preq.GetMetric ();
471  rChange.lifetime = MicroSeconds (preq.GetLifetime () * 1024);
472  rChange.seqnum = preq.GetOriginatorSeqNumber ();
473  m_routeChangeTraceSource (rChange);
475  }
476  if (
478  (m_rtable->LookupReactive (fromMp).metric > metric)
479  )
480  {
482  fromMp,
483  from,
484  interface,
485  metric,
486  MicroSeconds (preq.GetLifetime () * 1024),
487  preq.GetOriginatorSeqNumber ()
488  );
489  // Notify trace source of routing change
490  struct RouteChange rChange;
491  rChange.type = "Add Reactive";
492  rChange.destination = fromMp;
493  rChange.retransmitter = from;
494  rChange.interface = interface;
495  rChange.metric = metric;
496  rChange.lifetime = MicroSeconds (preq.GetLifetime () * 1024);
497  rChange.seqnum = preq.GetOriginatorSeqNumber ();
498  m_routeChangeTraceSource (rChange);
499  ReactivePathResolved (fromMp);
500  }
501  for (std::vector<Ptr<DestinationAddressUnit> >::const_iterator i = destinations.begin (); i != destinations.end (); i++)
502  {
503  if ((*i)->GetDestinationAddress () == Mac48Address::GetBroadcast ())
504  {
505  //only proactive PREQ contains destination
506  //address as broadcast! Proactive preq MUST
507  //have destination count equal to 1 and
508  //per destination flags DO and RF
509  NS_ASSERT (preq.GetDestCount () == 1);
510  NS_ASSERT (((*i)->IsDo ()) && ((*i)->IsRf ()));
511  //Add proactive path only if it is the better then existed
512  //before
513  if (
514  ((m_rtable->LookupProactive ()).retransmitter == Mac48Address::GetBroadcast ()) ||
515  ((m_rtable->LookupProactive ()).metric > preq.GetMetric ())
516  )
517  {
519  preq.GetMetric (),
520  preq.GetOriginatorAddress (),
521  from,
522  interface,
523  MicroSeconds (preq.GetLifetime () * 1024),
524  preq.GetOriginatorSeqNumber ()
525  );
526  // Notify trace source of routing change
527  struct RouteChange rChange;
528  rChange.type = "Add Proactive";
529  rChange.destination = preq.GetOriginatorAddress ();
530  rChange.retransmitter = from;
531  rChange.interface = interface;
532  rChange.metric = preq.GetMetric ();
533  rChange.lifetime = MicroSeconds (preq.GetLifetime () * 1024);
534  rChange.seqnum = preq.GetOriginatorSeqNumber ();
535  m_routeChangeTraceSource (rChange);
537  }
538  if (!preq.IsNeedNotPrep ())
539  {
540  SendPrep (
541  GetAddress (),
542  preq.GetOriginatorAddress (),
543  from,
544  (uint32_t)0,
545  preq.GetOriginatorSeqNumber (),
546  GetNextHwmpSeqno (),
547  preq.GetLifetime (),
548  interface
549  );
550  }
551  break;
552  }
553  if ((*i)->GetDestinationAddress () == GetAddress ())
554  {
555  SendPrep (
556  GetAddress (),
557  preq.GetOriginatorAddress (),
558  from,
559  (uint32_t)0,
560  preq.GetOriginatorSeqNumber (),
561  GetNextHwmpSeqno (),
562  preq.GetLifetime (),
563  interface
564  );
566  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
567  continue;
568  }
569  //check if can answer:
570  HwmpRtable::LookupResult result = m_rtable->LookupReactive ((*i)->GetDestinationAddress ());
571  if ((!((*i)->IsDo ())) && (result.retransmitter != Mac48Address::GetBroadcast ()))
572  {
573  //have a valid information and can answer
574  uint32_t lifetime = result.lifetime.GetMicroSeconds () / 1024;
575  if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber ()) >= 0))
576  {
577  SendPrep (
578  (*i)->GetDestinationAddress (),
579  preq.GetOriginatorAddress (),
580  from,
581  result.metric,
582  preq.GetOriginatorSeqNumber (),
583  result.seqnum,
584  lifetime,
585  interface
586  );
587  m_rtable->AddPrecursor ((*i)->GetDestinationAddress (), interface, from,
588  MicroSeconds (preq.GetLifetime () * 1024));
589  if ((*i)->IsRf ())
590  {
591  (*i)->SetFlags (true, false, (*i)->IsUsn ()); //DO = 1, RF = 0
592  }
593  else
594  {
595  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
596  continue;
597  }
598  }
599  }
600  }
601  //check if must retransmit:
602  if (preq.GetDestCount () == 0)
603  {
604  return;
605  }
606  //Forward PREQ to all interfaces:
607  NS_LOG_DEBUG ("I am " << GetAddress () << "retransmitting PREQ:" << preq);
608  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
609  {
610  i->second->SendPreq (preq);
611  }
612 }
613 void
614 HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
615 {
616  NS_LOG_FUNCTION (this << from << interface << fromMp << metric);
617  prep.IncrementMetric (metric);
618  //acceptance cretirea:
619  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
620  prep.GetOriginatorAddress ());
621  bool freshInfo (true);
622  uint32_t sequence = prep.GetDestinationSeqNumber ();
623  if (i != m_hwmpSeqnoMetricDatabase.end ())
624  {
625  if ((int32_t)(i->second.first - sequence) > 0)
626  {
627  return;
628  }
629  if (i->second.first == sequence)
630  {
631  freshInfo = false;
632  }
633  }
634  m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (sequence, prep.GetMetric ());
635  //update routing info
636  //Now add a path to destination and add precursor to source
637  NS_LOG_DEBUG ("I am " << GetAddress () << ", received prep from " << prep.GetOriginatorAddress () << ", receiver was:" << from);
639  //Add a reactive path only if seqno is fresher or it improves the
640  //metric
641  if (
642  (freshInfo) ||
643  (
644  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).retransmitter == Mac48Address::GetBroadcast ()) ||
645  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).metric > prep.GetMetric ())
646  )
647  )
648  {
650  prep.GetOriginatorAddress (),
651  from,
652  interface,
653  prep.GetMetric (),
654  MicroSeconds (prep.GetLifetime () * 1024),
655  sequence);
656  // Notify trace source of routing change
657  struct RouteChange rChange;
658  rChange.type = "Add Reactive";
659  rChange.destination = prep.GetOriginatorAddress ();
660  rChange.retransmitter = from;
661  rChange.interface = interface;
662  rChange.metric = prep.GetMetric ();
663  rChange.lifetime = MicroSeconds (prep.GetLifetime () * 1024);
664  rChange.seqnum = sequence;
665  m_routeChangeTraceSource (rChange);
666  m_rtable->AddPrecursor (prep.GetDestinationAddress (), interface, from,
667  MicroSeconds (prep.GetLifetime () * 1024));
668  if (result.retransmitter != Mac48Address::GetBroadcast ())
669  {
670  m_rtable->AddPrecursor (prep.GetOriginatorAddress (), interface, result.retransmitter,
671  result.lifetime);
672  }
674  }
675  if (
676  ((m_rtable->LookupReactive (fromMp)).retransmitter == Mac48Address::GetBroadcast ()) ||
677  ((m_rtable->LookupReactive (fromMp)).metric > metric)
678  )
679  {
681  fromMp,
682  from,
683  interface,
684  metric,
685  MicroSeconds (prep.GetLifetime () * 1024),
686  sequence);
687  // Notify trace source of routing change
688  struct RouteChange rChange;
689  rChange.type = "Add Reactive";
690  rChange.destination = fromMp;
691  rChange.retransmitter = from;
692  rChange.interface = interface;
693  rChange.metric = metric;
694  rChange.lifetime = MicroSeconds (prep.GetLifetime () * 1024);
695  rChange.seqnum = sequence;
696  m_routeChangeTraceSource (rChange);
697  ReactivePathResolved (fromMp);
698  }
699  if (prep.GetDestinationAddress () == GetAddress ())
700  {
701  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", resolved "<<prep.GetOriginatorAddress ());
702  return;
703  }
704  if (result.retransmitter == Mac48Address::GetBroadcast ())
705  {
706  return;
707  }
708  //Forward PREP
709  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (result.ifIndex);
710  NS_ASSERT (prep_sender != m_interfaces.end ());
711  prep_sender->second->SendPrep (prep, result.retransmitter);
712 }
713 void
714 HwmpProtocol::ReceivePerr (std::vector<FailedDestination> destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
715 {
716  NS_LOG_FUNCTION (this << from << interface << fromMp);
717  //Acceptance cretirea:
718  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", received PERR from "<<from);
719  std::vector<FailedDestination> retval;
721  for (unsigned int i = 0; i < destinations.size (); i++)
722  {
723  result = m_rtable->LookupReactiveExpired (destinations[i].destination);
724  if (!(
725  (result.retransmitter != from) ||
726  (result.ifIndex != interface) ||
727  ((int32_t)(result.seqnum - destinations[i].seqnum) > 0)
728  ))
729  {
730  retval.push_back (destinations[i]);
731  }
732  }
733  if (retval.size () == 0)
734  {
735  return;
736  }
737  ForwardPathError (MakePathError (retval));
738 }
739 void
741  Mac48Address src,
742  Mac48Address dst,
743  Mac48Address retransmitter,
744  uint32_t initMetric,
745  uint32_t originatorDsn,
746  uint32_t destinationSN,
747  uint32_t lifetime,
748  uint32_t interface)
749 {
750  IePrep prep;
751  prep.SetHopcount (0);
752  prep.SetTtl (m_maxTtl);
753  prep.SetDestinationAddress (dst);
754  prep.SetDestinationSeqNumber (destinationSN);
755  prep.SetLifetime (lifetime);
756  prep.SetMetric (initMetric);
757  prep.SetOriginatorAddress (src);
758  prep.SetOriginatorSeqNumber (originatorDsn);
759  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (interface);
760  NS_ASSERT (prep_sender != m_interfaces.end ());
761  prep_sender->second->SendPrep (prep, retransmitter);
763 }
764 bool
766 {
767  NS_LOG_FUNCTION (this << mp);
768  m_mp = mp;
769  std::vector<Ptr<NetDevice> > interfaces = mp->GetInterfaces ();
770  for (std::vector<Ptr<NetDevice> >::const_iterator i = interfaces.begin (); i != interfaces.end (); i++)
771  {
772  // Checking for compatible net device
773  Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice> ();
774  if (wifiNetDev == 0)
775  {
776  return false;
777  }
778  Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
779  if (mac == 0)
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 (MakeCallback (&AirtimeLinkMetricCalculator::CalculateMetric, metric));
790  }
791  mp->SetRoutingProtocol (this);
792  // Mesh point aggregates all installed protocols
793  mp->AggregateObject (this);
794  m_address = Mac48Address::ConvertFrom (mp->GetAddress ()); // address;
795  return true;
796 }
797 void
798 HwmpProtocol::PeerLinkStatus (Mac48Address meshPointAddress, Mac48Address peerAddress, uint32_t interface, bool status)
799 {
800  NS_LOG_FUNCTION (this << meshPointAddress << peerAddress << interface << status);
801  if (status)
802  {
803  return;
804  }
805  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (peerAddress);
806  NS_LOG_DEBUG (destinations.size () << " failed destinations for peer address " << peerAddress);
807  InitiatePathError (MakePathError (destinations));
808 }
809 void
810 HwmpProtocol::SetNeighboursCallback (Callback<std::vector<Mac48Address>, uint32_t> cb)
811 {
813 }
814 bool
816 {
817  NS_LOG_FUNCTION (this << seqno << source);
818  if (source == GetAddress ())
819  {
820  return true;
821  }
822  std::map<Mac48Address, uint32_t,std::less<Mac48Address> >::const_iterator i = m_lastDataSeqno.find (source);
823  if (i == m_lastDataSeqno.end ())
824  {
825  m_lastDataSeqno[source] = seqno;
826  }
827  else
828  {
829  if ((int32_t)(i->second - seqno) >= 0)
830  {
831  return true;
832  }
833  m_lastDataSeqno[source] = seqno;
834  }
835  return false;
836 }
838 HwmpProtocol::MakePathError (std::vector<FailedDestination> destinations)
839 {
840  NS_LOG_FUNCTION (this);
841  PathError retval;
842  //HwmpRtable increments a sequence number as written in 11B.9.7.2
843  retval.receivers = GetPerrReceivers (destinations);
844  if (retval.receivers.size () == 0)
845  {
846  return retval;
847  }
849  for (unsigned int i = 0; i < destinations.size (); i++)
850  {
851  retval.destinations.push_back (destinations[i]);
852  m_rtable->DeleteReactivePath (destinations[i].destination);
853  // Notify trace source of routing change
854  struct RouteChange rChange;
855  rChange.type = "Delete Reactive";
856  rChange.destination = destinations[i].destination;
857  rChange.seqnum = destinations[i].seqnum;
858  m_routeChangeTraceSource (rChange);
859  }
860  return retval;
861 }
862 void
864 {
865  NS_LOG_FUNCTION (this);
866  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
867  {
868  std::vector<Mac48Address> receivers_for_interface;
869  for (unsigned int j = 0; j < perr.receivers.size (); j++)
870  {
871  if (i->first == perr.receivers[j].first)
872  {
873  receivers_for_interface.push_back (perr.receivers[j].second);
874  }
875  }
876  i->second->InitiatePerr (perr.destinations, receivers_for_interface);
877  }
878 }
879 void
881 {
882  NS_LOG_FUNCTION (this);
883  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
884  {
885  std::vector<Mac48Address> receivers_for_interface;
886  for (unsigned int j = 0; j < perr.receivers.size (); j++)
887  {
888  if (i->first == perr.receivers[j].first)
889  {
890  receivers_for_interface.push_back (perr.receivers[j].second);
891  }
892  }
893  i->second->ForwardPerr (perr.destinations, receivers_for_interface);
894  }
895 }
896 
897 std::vector<std::pair<uint32_t, Mac48Address> >
898 HwmpProtocol::GetPerrReceivers (std::vector<FailedDestination> failedDest)
899 {
900  NS_LOG_FUNCTION (this);
902  for (unsigned int i = 0; i < failedDest.size (); i++)
903  {
904  HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors (failedDest[i].destination);
905  m_rtable->DeleteReactivePath (failedDest[i].destination);
906  // Notify trace source of routing change
907  struct RouteChange rChange;
908  rChange.type = "Delete Reactive";
909  rChange.destination = failedDest[i].destination;
910  rChange.seqnum = failedDest[i].seqnum;
911  m_routeChangeTraceSource (rChange);
912  m_rtable->DeleteProactivePath (failedDest[i].destination);
913  // Notify trace source of routing change
914  struct RouteChange rChangePro;
915  rChangePro.type = "Delete Proactive";
916  rChangePro.destination = failedDest[i].destination;
917  rChangePro.seqnum = failedDest[i].seqnum;
918  m_routeChangeTraceSource (rChangePro);
919  for (unsigned int j = 0; j < precursors.size (); j++)
920  {
921  retval.push_back (precursors[j]);
922  }
923  }
924  //Check if we have duplicates in retval and precursors:
925  for (unsigned int i = 0; i < retval.size (); i++)
926  {
927  for (unsigned int j = i+1; j < retval.size (); j++)
928  {
929  if (retval[i].second == retval[j].second)
930  {
931  retval.erase (retval.begin () + j);
932  }
933  }
934  }
935  return retval;
936 }
937 std::vector<Mac48Address>
938 HwmpProtocol::GetPreqReceivers (uint32_t interface)
939 {
940  NS_LOG_FUNCTION (this << interface);
941  std::vector<Mac48Address> retval;
942  if (!m_neighboursCallback.IsNull ())
943  {
944  retval = m_neighboursCallback (interface);
945  }
946  if ((retval.size () >= m_unicastPreqThreshold) || (retval.size () == 0))
947  {
948  retval.clear ();
949  retval.push_back (Mac48Address::GetBroadcast ());
950  }
951  return retval;
952 }
953 std::vector<Mac48Address>
955 {
956  NS_LOG_FUNCTION (this << interface);
957  std::vector<Mac48Address> retval;
958  if (!m_neighboursCallback.IsNull ())
959  {
960  retval = m_neighboursCallback (interface);
961  }
962  if ((retval.size () >= m_unicastDataThreshold) || (retval.size () == 0))
963  {
964  retval.clear ();
965  retval.push_back (Mac48Address::GetBroadcast ());
966  }
967  return retval;
968 }
969 
970 bool
972 {
973  NS_LOG_FUNCTION (this);
974  if (m_rqueue.size () > m_maxQueueSize)
975  {
976  return false;
977  }
978  m_rqueue.push_back (packet);
979  return true;
980 }
981 
984 {
985  NS_LOG_FUNCTION (this << dst);
986  QueuedPacket retval;
987  retval.pkt = 0;
988  for (std::vector<QueuedPacket>::iterator i = m_rqueue.begin (); i != m_rqueue.end (); i++)
989  {
990  if ((*i).dst == dst)
991  {
992  retval = (*i);
993  m_rqueue.erase (i);
994  break;
995  }
996  }
997  return retval;
998 }
999 
1002 {
1003  NS_LOG_FUNCTION (this);
1004  QueuedPacket retval;
1005  retval.pkt = 0;
1006  if (m_rqueue.size () != 0)
1007  {
1008  retval = m_rqueue[0];
1009  m_rqueue.erase (m_rqueue.begin ());
1010  }
1011  return retval;
1012 }
1013 
1014 void
1016 {
1017  NS_LOG_FUNCTION (this << dst);
1018  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1019  if (i != m_preqTimeouts.end ())
1020  {
1021  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
1022  }
1023 
1026  //Send all packets stored for this destination
1027  QueuedPacket packet = DequeueFirstPacketByDst (dst);
1028  while (packet.pkt != 0)
1029  {
1030  //set RA tag for retransmitter:
1031  HwmpTag tag;
1032  packet.pkt->RemovePacketTag (tag);
1033  tag.SetAddress (result.retransmitter);
1034  packet.pkt->AddPacketTag (tag);
1035  m_stats.txUnicast++;
1036  m_stats.txBytes += packet.pkt->GetSize ();
1037  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1038 
1039  packet = DequeueFirstPacketByDst (dst);
1040  }
1041 }
1042 void
1044 {
1045  NS_LOG_FUNCTION (this);
1046  //send all packets to root
1049  QueuedPacket packet = DequeueFirstPacket ();
1050  while (packet.pkt != 0)
1051  {
1052  //set RA tag for retransmitter:
1053  HwmpTag tag;
1054  if (!packet.pkt->RemovePacketTag (tag))
1055  {
1056  NS_FATAL_ERROR ("HWMP tag must be present at this point");
1057  }
1058  tag.SetAddress (result.retransmitter);
1059  packet.pkt->AddPacketTag (tag);
1060  m_stats.txUnicast++;
1061  m_stats.txBytes += packet.pkt->GetSize ();
1062  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1063 
1064  packet = DequeueFirstPacket ();
1065  }
1066 }
1067 
1068 bool
1070 {
1071  NS_LOG_FUNCTION (this << dst);
1072  std::map<Mac48Address, PreqEvent>::const_iterator i = m_preqTimeouts.find (dst);
1073  if (i == m_preqTimeouts.end ())
1074  {
1075  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
1077  &HwmpProtocol::RetryPathDiscovery, this, dst, 1);
1078  m_preqTimeouts[dst].whenScheduled = Simulator::Now ();
1079  return true;
1080  }
1081  return false;
1082 }
1083 void
1085 {
1086  NS_LOG_FUNCTION (this << dst << (uint16_t) numOfRetry);
1088  if (result.retransmitter == Mac48Address::GetBroadcast ())
1089  {
1090  result = m_rtable->LookupProactive ();
1091  }
1092  if (result.retransmitter != Mac48Address::GetBroadcast ())
1093  {
1094  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1095  NS_ASSERT (i != m_preqTimeouts.end ());
1096  m_preqTimeouts.erase (i);
1097  return;
1098  }
1099  if (numOfRetry > m_dot11MeshHWMPmaxPREQretries)
1100  {
1101  QueuedPacket packet = DequeueFirstPacketByDst (dst);
1102  //purge queue and delete entry from retryDatabase
1103  while (packet.pkt != 0)
1104  {
1106  packet.reply (false, packet.pkt, packet.src, packet.dst, packet.protocol, HwmpRtable::MAX_METRIC);
1107  packet = DequeueFirstPacketByDst (dst);
1108  }
1109  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1110  NS_ASSERT (i != m_preqTimeouts.end ());
1111  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
1112  m_preqTimeouts.erase (i);
1113  return;
1114  }
1115  numOfRetry++;
1116  uint32_t originator_seqno = GetNextHwmpSeqno ();
1117  uint32_t dst_seqno = m_rtable->LookupReactiveExpired (dst).seqnum;
1118  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1119  {
1120  i->second->RequestDestination (dst, originator_seqno, dst_seqno);
1121  }
1122  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
1123  Time ((2 * (numOfRetry + 1)) * m_dot11MeshHWMPnetDiameterTraversalTime),
1124  &HwmpProtocol::RetryPathDiscovery, this, dst, numOfRetry);
1125 }
1126 //Proactive PREQ routines:
1127 void
1129 {
1130  NS_LOG_FUNCTION (this);
1131  NS_LOG_DEBUG ("ROOT IS: " << m_address);
1132  m_isRoot = true;
1133 }
1134 void
1136 {
1137  NS_LOG_FUNCTION (this);
1139 }
1140 void
1142 {
1143  NS_LOG_FUNCTION (this);
1144  IePreq preq;
1145  //By default: must answer
1146  preq.SetHopcount (0);
1147  preq.SetTTL (m_maxTtl);
1149  //\attention: do not forget to set originator address, sequence
1150  //number and preq ID in HWMP-MAC plugin
1152  preq.SetOriginatorAddress (GetAddress ());
1153  preq.SetPreqID (GetNextPreqId ());
1155  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1156  {
1157  i->second->SendPreq (preq);
1158  }
1160 }
1161 bool
1163 {
1164  return m_doFlag;
1165 }
1166 bool
1168 {
1169  return m_rfFlag;
1170 }
1171 Time
1173 {
1175 }
1176 Time
1178 {
1180 }
1181 uint8_t
1183 {
1184  return m_maxTtl;
1185 }
1186 uint32_t
1188 {
1189  m_preqId++;
1190  return m_preqId;
1191 }
1192 uint32_t
1194 {
1195  m_hwmpSeqno++;
1196  return m_hwmpSeqno;
1197 }
1198 uint32_t
1200 {
1202 }
1203 uint8_t
1205 {
1206  return m_unicastPerrThreshold;
1207 }
1210 {
1211  return m_address;
1212 }
1213 //Statistics:
1215  txUnicast (0),
1216  txBroadcast (0),
1217  txBytes (0),
1218  droppedTtl (0),
1219  totalQueued (0),
1220  totalDropped (0),
1221  initiatedPreq (0),
1222  initiatedPrep (0),
1223  initiatedPerr (0)
1224 {
1225 }
1226 void HwmpProtocol::Statistics::Print (std::ostream & os) const
1227 {
1228  os << "<Statistics "
1229  "txUnicast=\"" << txUnicast << "\" "
1230  "txBroadcast=\"" << txBroadcast << "\" "
1231  "txBytes=\"" << txBytes << "\" "
1232  "droppedTtl=\"" << droppedTtl << "\" "
1233  "totalQueued=\"" << totalQueued << "\" "
1234  "totalDropped=\"" << totalDropped << "\" "
1235  "initiatedPreq=\"" << initiatedPreq << "\" "
1236  "initiatedPrep=\"" << initiatedPrep << "\" "
1237  "initiatedPerr=\"" << initiatedPerr << "\"/>" << std::endl;
1238 }
1239 void
1240 HwmpProtocol::Report (std::ostream & os) const
1241 {
1242  os << "<Hwmp "
1243  "address=\"" << m_address << "\"" << std::endl <<
1244  "maxQueueSize=\"" << m_maxQueueSize << "\"" << std::endl <<
1245  "Dot11MeshHWMPmaxPREQretries=\"" << (uint16_t)m_dot11MeshHWMPmaxPREQretries << "\"" << std::endl <<
1246  "Dot11MeshHWMPnetDiameterTraversalTime=\"" << m_dot11MeshHWMPnetDiameterTraversalTime.GetSeconds () << "\"" << std::endl <<
1247  "Dot11MeshHWMPpreqMinInterval=\"" << m_dot11MeshHWMPpreqMinInterval.GetSeconds () << "\"" << std::endl <<
1248  "Dot11MeshHWMPperrMinInterval=\"" << m_dot11MeshHWMPperrMinInterval.GetSeconds () << "\"" << std::endl <<
1249  "Dot11MeshHWMPactiveRootTimeout=\"" << m_dot11MeshHWMPactiveRootTimeout.GetSeconds () << "\"" << std::endl <<
1250  "Dot11MeshHWMPactivePathTimeout=\"" << m_dot11MeshHWMPactivePathTimeout.GetSeconds () << "\"" << std::endl <<
1251  "Dot11MeshHWMPpathToRootInterval=\"" << m_dot11MeshHWMPpathToRootInterval.GetSeconds () << "\"" << std::endl <<
1252  "Dot11MeshHWMPrannInterval=\"" << m_dot11MeshHWMPrannInterval.GetSeconds () << "\"" << std::endl <<
1253  "isRoot=\"" << m_isRoot << "\"" << std::endl <<
1254  "maxTtl=\"" << (uint16_t)m_maxTtl << "\"" << std::endl <<
1255  "unicastPerrThreshold=\"" << (uint16_t)m_unicastPerrThreshold << "\"" << std::endl <<
1256  "unicastPreqThreshold=\"" << (uint16_t)m_unicastPreqThreshold << "\"" << std::endl <<
1257  "unicastDataThreshold=\"" << (uint16_t)m_unicastDataThreshold << "\"" << std::endl <<
1258  "doFlag=\"" << m_doFlag << "\"" << std::endl <<
1259  "rfFlag=\"" << m_rfFlag << "\">" << std::endl;
1260  m_stats.Print (os);
1261  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
1262  {
1263  plugin->second->Report (os);
1264  }
1265  os << "</Hwmp>" << std::endl;
1266 }
1267 void
1269 {
1270  NS_LOG_FUNCTION (this);
1271  m_stats = Statistics ();
1272  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
1273  {
1274  plugin->second->ResetStats ();
1275  }
1276 }
1277 
1278 int64_t
1280 {
1281  NS_LOG_FUNCTION (this << stream);
1282  m_coefficient->SetStream (stream);
1283  return 1;
1284 }
1285 
1288 {
1289  return m_rtable;
1290 }
1291 
1293  pkt (0),
1294  protocol (0),
1295  inInterface (0)
1296 {
1297 }
1298 } // namespace dot11s
1299 } // namespace ns3
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Callback template class.
Definition: callback.h:1279
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
an EUI-48 address
Definition: mac48-address.h:44
static Mac48Address GetBroadcast(void)
static Mac48Address ConvertFrom(const Address &address)
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:185
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:963
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:956
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:978
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:388
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380
AttributeValue implementation for Time.
Definition: nstime.h:1353
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
Hold an unsigned integer type.
Definition: uinteger.h:44
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
Hold together all Wifi-related objects.
Ptr< WifiMac > GetMac(void) const
uint32_t GetIfIndex(void) const override
Hybrid wireless mesh protocol – a mesh routing protocol defined in IEEE 802.11-2012 standard.
Definition: hwmp-protocol.h:63
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.
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.
bool RemoveRoutingStuff(uint32_t fromIface, const Mac48Address source, const Mac48Address destination, Ptr< Packet > packet, uint16_t &protocolType)
Clean HWMP packet tag from packet; only the packet parameter is used.
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.
virtual void DoInitialize()
Initialize() implementation.
TracedCallback< Time > m_routeDiscoveryTimeCallback
Route discovery time:
static TypeId GetTypeId()
Get the type ID.
bool GetRfFlag()
Get rf flag function.
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 GetDoFlag()
Get do flag function.
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.
uint8_t GetUnicastPerrThreshold()
Get unicast PERR threshold function.
void SendProactivePreq()
Proactive Preq routines:
void ForwardPathError(PathError perr)
Forwards a received path error.
void DoDispose()
Destructor implementation.
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 m_doFlag
Destination only HWMP flag.
Mac48Address m_address
address
Time m_dot11MeshHWMPactiveRootTimeout
Lifetime of proactive routing information.
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 GetMaxTtl()
Get maximum TTL 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 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
Ptr< HwmpRtable > GetRoutingTable(void) const
Get pointer to HWMP routing table.
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.
bool RequestRoute(uint32_t sourceIface, const Mac48Address source, const Mac48Address destination, Ptr< const Packet > packet, uint16_t protocolType, RouteReplyCallback routeReply)
Route request, inherited from MeshL2RoutingProtocol.
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.
Routing table for HWMP – 802.11s routing protocol.
Definition: hwmp-rtable.h:36
void DeleteReactivePath(Mac48Address destination)
Delete the reactive paths toward a destination.
Definition: hwmp-rtable.cc:140
static const uint32_t MAX_METRIC
Maximum (the best?) path metric.
Definition: hwmp-rtable.h:41
LookupResult LookupReactive(Mac48Address destination)
Lookup path to destination.
Definition: hwmp-rtable.cc:150
LookupResult LookupReactiveExpired(Mac48Address destination)
Return all reactive paths, including expired.
Definition: hwmp-rtable.cc:166
PrecursorList GetPrecursors(Mac48Address destination)
Get the precursors list.
Definition: hwmp-rtable.cc:223
void DeleteProactivePath()
Delete all the proactive paths.
Definition: hwmp-rtable.cc:120
LookupResult LookupProactiveExpired()
Return all proactive paths, including expired.
Definition: hwmp-rtable.cc:190
std::vector< std::pair< uint32_t, Mac48Address > > PrecursorList
Path precursor = {MAC, interface ID}.
Definition: hwmp-rtable.h:77
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:198
LookupResult LookupProactive()
Find proactive path to tree root.
Definition: hwmp-rtable.cc:179
void AddPrecursor(Mac48Address destination, uint32_t precursorInterface, Mac48Address precursorAddress, Time lifetime)
Add a precursor.
Definition: hwmp-rtable.cc:90
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:78
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:59
Hwmp tag implements interaction between HWMP protocol and MeshWifiMac.
Definition: hwmp-tag.h:49
void SetTtl(uint8_t ttl)
Set the TTL value.
Definition: hwmp-tag.cc:51
void SetSeqno(uint32_t seqno)
Set sequence number.
Definition: hwmp-tag.cc:75
uint8_t GetTtl()
Get the TTL value.
Definition: hwmp-tag.cc:57
void SetAddress(Mac48Address retransmitter)
Set address.
Definition: hwmp-tag.cc:39
void DecrementTtl()
Decrement TTL.
Definition: hwmp-tag.cc:155
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 numnber 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:67
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
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:85
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:1354
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:45
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#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:576
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
address
Definition: first.py:44
interfaces
Definition: first.py:48
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
Definition: second.py:1
mac
Definition: third.py:99
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. (if packet has come from upper layers, this is Mesh point 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:45
uint32_t seqnum
sequence number
Definition: hwmp-rtable.h:49
Mac48Address retransmitter
retransmitter
Definition: hwmp-rtable.h:46
Structure to encapsulate route change information.
Definition: hwmp-protocol.h:47
Time lifetime
lifetime of route
Definition: hwmp-protocol.h:53
Mac48Address retransmitter
route source
Definition: hwmp-protocol.h:50
uint32_t seqnum
sequence number of route
Definition: hwmp-protocol.h:54
uint32_t metric
metric of route
Definition: hwmp-protocol.h:52
Mac48Address destination
route destination
Definition: hwmp-protocol.h:49
std::string type
type of change
Definition: hwmp-protocol.h:48
uint32_t interface
interface index
Definition: hwmp-protocol.h:51