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-point-device.h"
31 #include "ns3/mesh-wifi-interface-mac.h"
32 #include "ns3/random-variable-stream.h"
33 #include "airtime-metric.h"
34 #include "ie-dot11s-preq.h"
35 #include "ie-dot11s-prep.h"
36 #include "ns3/trace-source-accessor.h"
37 #include "ie-dot11s-perr.h"
38 
39 namespace ns3 {
40 
41 NS_LOG_COMPONENT_DEFINE ("HwmpProtocol");
42 
43 namespace dot11s {
44 
45 NS_OBJECT_ENSURE_REGISTERED (HwmpProtocol);
46 
47 TypeId
49 {
50  static TypeId tid = TypeId ("ns3::dot11s::HwmpProtocol")
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 poractive 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 poractive 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 ofbroadcast 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  ;
171  return tid;
172 }
173 
175  m_dataSeqno (1),
176  m_hwmpSeqno (1),
177  m_preqId (0),
178  m_rtable (CreateObject<HwmpRtable> ()),
179  m_randomStart (Seconds (0.1)),
180  m_maxQueueSize (255),
181  m_dot11MeshHWMPmaxPREQretries (3),
182  m_dot11MeshHWMPnetDiameterTraversalTime (MicroSeconds (1024*100)),
183  m_dot11MeshHWMPpreqMinInterval (MicroSeconds (1024*100)),
184  m_dot11MeshHWMPperrMinInterval (MicroSeconds (1024*100)),
185  m_dot11MeshHWMPactiveRootTimeout (MicroSeconds (1024*5000)),
186  m_dot11MeshHWMPactivePathTimeout (MicroSeconds (1024*5000)),
187  m_dot11MeshHWMPpathToRootInterval (MicroSeconds (1024*2000)),
188  m_dot11MeshHWMPrannInterval (MicroSeconds (1024*5000)),
189  m_isRoot (false),
190  m_maxTtl (32),
191  m_unicastPerrThreshold (32),
192  m_unicastPreqThreshold (1),
193  m_unicastDataThreshold (1),
194  m_doFlag (false),
195  m_rfFlag (false)
196 {
198  m_coefficient = CreateObject<UniformRandomVariable> ();
199 }
200 
202 {
204 }
205 
206 void
208 {
210  if (m_isRoot)
211  {
212  SetRoot ();
213  }
214 }
215 
216 void
218 {
220  for (std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.begin (); i != m_preqTimeouts.end (); i++)
221  {
222  i->second.preqTimeout.Cancel ();
223  }
225  m_preqTimeouts.clear ();
226  m_lastDataSeqno.clear ();
227  m_hwmpSeqnoMetricDatabase.clear ();
228  m_interfaces.clear ();
229  m_rqueue.clear ();
230  m_rtable = 0;
231  m_mp = 0;
232 }
233 
234 bool
236  uint32_t sourceIface,
237  const Mac48Address source,
238  const Mac48Address destination,
239  Ptr<const Packet> constPacket,
240  uint16_t protocolType, //ethrnet 'Protocol' field
242  )
243 {
244  Ptr <Packet> packet = constPacket->Copy ();
245  HwmpTag tag;
246  if (sourceIface == GetMeshPoint ()->GetIfIndex ())
247  {
248  // packet from level 3
249  if (packet->PeekPacketTag (tag))
250  {
251  NS_FATAL_ERROR ("HWMP tag has come with a packet from upper layer. This must not occur...");
252  }
253  //Filling TAG:
254  if (destination == Mac48Address::GetBroadcast ())
255  {
256  tag.SetSeqno (m_dataSeqno++);
257  }
258  tag.SetTtl (m_maxTtl);
259  }
260  else
261  {
262  if (!packet->RemovePacketTag (tag))
263  {
264  NS_FATAL_ERROR ("HWMP tag is supposed to be here at this point.");
265  }
266  tag.DecrementTtl ();
267  if (tag.GetTtl () == 0)
268  {
270  return false;
271  }
272  }
273  if (destination == Mac48Address::GetBroadcast ())
274  {
276  m_stats.txBytes += packet->GetSize ();
277  //channel IDs where we have already sent broadcast:
278  std::vector<uint16_t> channels;
279  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
280  {
281  bool shouldSend = true;
282  for (std::vector<uint16_t>::const_iterator chan = channels.begin (); chan != channels.end (); chan++)
283  {
284  if ((*chan) == plugin->second->GetChannelId ())
285  {
286  shouldSend = false;
287  }
288  }
289  if (!shouldSend)
290  {
291  continue;
292  }
293  channels.push_back (plugin->second->GetChannelId ());
294  std::vector<Mac48Address> receivers = GetBroadcastReceivers (plugin->first);
295  for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i++)
296  {
297  Ptr<Packet> packetCopy = packet->Copy ();
298  //
299  // 64-bit Intel valgrind complains about tag.SetAddress (*i). It
300  // likes this just fine.
301  //
302  Mac48Address address = *i;
303  tag.SetAddress (address);
304  packetCopy->AddPacketTag (tag);
305  routeReply (true, packetCopy, source, destination, protocolType, plugin->first);
306  }
307  }
308  }
309  else
310  {
311  return ForwardUnicast (sourceIface, source, destination, packet, protocolType, routeReply, tag.GetTtl ());
312  }
313  return true;
314 }
315 bool
316 HwmpProtocol::RemoveRoutingStuff (uint32_t fromIface, const Mac48Address source,
317  const Mac48Address destination, Ptr<Packet> packet, uint16_t& protocolType)
318 {
319  HwmpTag tag;
320  if (!packet->RemovePacketTag (tag))
321  {
322  NS_FATAL_ERROR ("HWMP tag must exist when packet received from the network");
323  }
324  return true;
325 }
326 bool
327 HwmpProtocol::ForwardUnicast (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination,
328  Ptr<Packet> packet, uint16_t protocolType, RouteReplyCallback routeReply, uint32_t ttl)
329 {
330  NS_ASSERT (destination != Mac48Address::GetBroadcast ());
331  HwmpRtable::LookupResult result = m_rtable->LookupReactive (destination);
332  NS_LOG_DEBUG ("Requested src = "<<source<<", dst = "<<destination<<", I am "<<GetAddress ()<<", RA = "<<result.retransmitter);
333  if (result.retransmitter == Mac48Address::GetBroadcast ())
334  {
335  result = m_rtable->LookupProactive ();
336  }
337  HwmpTag tag;
338  tag.SetAddress (result.retransmitter);
339  tag.SetTtl (ttl);
340  //seqno and metric is not used;
341  packet->AddPacketTag (tag);
342  if (result.retransmitter != Mac48Address::GetBroadcast ())
343  {
344  //reply immediately:
345  routeReply (true, packet, source, destination, protocolType, result.ifIndex);
346  m_stats.txUnicast++;
347  m_stats.txBytes += packet->GetSize ();
348  return true;
349  }
350  if (sourceIface != GetMeshPoint ()->GetIfIndex ())
351  {
352  //Start path error procedure:
353  NS_LOG_DEBUG ("Must Send PERR");
354  result = m_rtable->LookupReactiveExpired (destination);
355  //1. Lookup expired reactive path. If exists - start path error
356  // procedure towards a next hop of this path
357  //2. If there was no reactive path, we lookup expired proactive
358  // path. If exist - start path error procedure towards path to
359  // root
360  if (result.retransmitter == Mac48Address::GetBroadcast ())
361  {
362  result = m_rtable->LookupProactiveExpired ();
363  }
364  if (result.retransmitter != Mac48Address::GetBroadcast ())
365  {
366  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (result.retransmitter);
367  InitiatePathError (MakePathError (destinations));
368  }
370  return false;
371  }
372  //Request a destination:
373  result = m_rtable->LookupReactiveExpired (destination);
374  if (ShouldSendPreq (destination))
375  {
376  uint32_t originator_seqno = GetNextHwmpSeqno ();
377  uint32_t dst_seqno = 0;
378  if (result.retransmitter != Mac48Address::GetBroadcast ())
379  {
380  dst_seqno = result.seqnum;
381  }
383  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
384  {
385  i->second->RequestDestination (destination, originator_seqno, dst_seqno);
386  }
387  }
388  QueuedPacket pkt;
389  pkt.pkt = packet;
390  pkt.dst = destination;
391  pkt.src = source;
392  pkt.protocol = protocolType;
393  pkt.reply = routeReply;
394  pkt.inInterface = sourceIface;
395  if (QueuePacket (pkt))
396  {
398  return true;
399  }
400  else
401  {
403  return false;
404  }
405 }
406 void
407 HwmpProtocol::ReceivePreq (IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
408 {
409  preq.IncrementMetric (metric);
410  //acceptance cretirea:
411  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
412  preq.GetOriginatorAddress ());
413  bool freshInfo (true);
414  if (i != m_hwmpSeqnoMetricDatabase.end ())
415  {
416  if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber ()) > 0)
417  {
418  return;
419  }
420  if (i->second.first == preq.GetOriginatorSeqNumber ())
421  {
422  freshInfo = false;
423  if (i->second.second <= preq.GetMetric ())
424  {
425  return;
426  }
427  }
428  }
430  std::make_pair (preq.GetOriginatorSeqNumber (), preq.GetMetric ());
431  NS_LOG_DEBUG ("I am " << GetAddress () << "Accepted preq from address" << from << ", preq:" << preq);
432  std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
433  //Add reactive path to originator:
434  if (
435  (freshInfo) ||
436  (
437  (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).retransmitter == Mac48Address::GetBroadcast ()) ||
438  (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).metric > preq.GetMetric ())
439  )
440  )
441  {
443  preq.GetOriginatorAddress (),
444  from,
445  interface,
446  preq.GetMetric (),
447  MicroSeconds (preq.GetLifetime () * 1024),
448  preq.GetOriginatorSeqNumber ()
449  );
451  }
452  if (
454  (m_rtable->LookupReactive (fromMp).metric > metric)
455  )
456  {
458  fromMp,
459  from,
460  interface,
461  metric,
462  MicroSeconds (preq.GetLifetime () * 1024),
463  preq.GetOriginatorSeqNumber ()
464  );
465  ReactivePathResolved (fromMp);
466  }
467  for (std::vector<Ptr<DestinationAddressUnit> >::const_iterator i = destinations.begin (); i != destinations.end (); i++)
468  {
469  if ((*i)->GetDestinationAddress () == Mac48Address::GetBroadcast ())
470  {
471  //only proactive PREQ contains destination
472  //address as broadcast! Proactive preq MUST
473  //have destination count equal to 1 and
474  //per destination flags DO and RF
475  NS_ASSERT (preq.GetDestCount () == 1);
476  NS_ASSERT (((*i)->IsDo ()) && ((*i)->IsRf ()));
477  //Add proactive path only if it is the better then existed
478  //before
479  if (
480  ((m_rtable->LookupProactive ()).retransmitter == Mac48Address::GetBroadcast ()) ||
481  ((m_rtable->LookupProactive ()).metric > preq.GetMetric ())
482  )
483  {
485  preq.GetMetric (),
486  preq.GetOriginatorAddress (),
487  from,
488  interface,
489  MicroSeconds (preq.GetLifetime () * 1024),
490  preq.GetOriginatorSeqNumber ()
491  );
493  }
494  if (!preq.IsNeedNotPrep ())
495  {
496  SendPrep (
497  GetAddress (),
498  preq.GetOriginatorAddress (),
499  from,
500  (uint32_t)0,
501  preq.GetOriginatorSeqNumber (),
502  GetNextHwmpSeqno (),
503  preq.GetLifetime (),
504  interface
505  );
506  }
507  break;
508  }
509  if ((*i)->GetDestinationAddress () == GetAddress ())
510  {
511  SendPrep (
512  GetAddress (),
513  preq.GetOriginatorAddress (),
514  from,
515  (uint32_t)0,
516  preq.GetOriginatorSeqNumber (),
517  GetNextHwmpSeqno (),
518  preq.GetLifetime (),
519  interface
520  );
522  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
523  continue;
524  }
525  //check if can answer:
526  HwmpRtable::LookupResult result = m_rtable->LookupReactive ((*i)->GetDestinationAddress ());
527  if ((!((*i)->IsDo ())) && (result.retransmitter != Mac48Address::GetBroadcast ()))
528  {
529  //have a valid information and can answer
530  uint32_t lifetime = result.lifetime.GetMicroSeconds () / 1024;
531  if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber ()) >= 0))
532  {
533  SendPrep (
534  (*i)->GetDestinationAddress (),
535  preq.GetOriginatorAddress (),
536  from,
537  result.metric,
538  preq.GetOriginatorSeqNumber (),
539  result.seqnum,
540  lifetime,
541  interface
542  );
543  m_rtable->AddPrecursor ((*i)->GetDestinationAddress (), interface, from,
544  MicroSeconds (preq.GetLifetime () * 1024));
545  if ((*i)->IsRf ())
546  {
547  (*i)->SetFlags (true, false, (*i)->IsUsn ()); //DO = 1, RF = 0
548  }
549  else
550  {
551  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
552  continue;
553  }
554  }
555  }
556  }
557  //check if must retransmit:
558  if (preq.GetDestCount () == 0)
559  {
560  return;
561  }
562  //Forward PREQ to all interfaces:
563  NS_LOG_DEBUG ("I am " << GetAddress () << "retransmitting PREQ:" << preq);
564  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
565  {
566  i->second->SendPreq (preq);
567  }
568 }
569 void
570 HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
571 {
572  prep.IncrementMetric (metric);
573  //acceptance cretirea:
574  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
575  prep.GetOriginatorAddress ());
576  bool freshInfo (true);
577  uint32_t sequence = prep.GetDestinationSeqNumber ();
578  if (i != m_hwmpSeqnoMetricDatabase.end ())
579  {
580  if ((int32_t)(i->second.first - sequence) > 0)
581  {
582  return;
583  }
584  if (i->second.first == sequence)
585  {
586  freshInfo = false;
587  }
588  }
589  m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (sequence, prep.GetMetric ());
590  //update routing info
591  //Now add a path to destination and add precursor to source
592  NS_LOG_DEBUG ("I am " << GetAddress () << ", received prep from " << prep.GetOriginatorAddress () << ", receiver was:" << from);
594  //Add a reactive path only if seqno is fresher or it improves the
595  //metric
596  if (
597  (freshInfo) ||
598  (
599  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).retransmitter == Mac48Address::GetBroadcast ()) ||
600  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).metric > prep.GetMetric ())
601  )
602  )
603  {
605  prep.GetOriginatorAddress (),
606  from,
607  interface,
608  prep.GetMetric (),
609  MicroSeconds (prep.GetLifetime () * 1024),
610  sequence);
611  m_rtable->AddPrecursor (prep.GetDestinationAddress (), interface, from,
612  MicroSeconds (prep.GetLifetime () * 1024));
613  if (result.retransmitter != Mac48Address::GetBroadcast ())
614  {
615  m_rtable->AddPrecursor (prep.GetOriginatorAddress (), interface, result.retransmitter,
616  result.lifetime);
617  }
619  }
620  if (
621  ((m_rtable->LookupReactive (fromMp)).retransmitter == Mac48Address::GetBroadcast ()) ||
622  ((m_rtable->LookupReactive (fromMp)).metric > metric)
623  )
624  {
626  fromMp,
627  from,
628  interface,
629  metric,
630  MicroSeconds (prep.GetLifetime () * 1024),
631  sequence);
632  ReactivePathResolved (fromMp);
633  }
634  if (prep.GetDestinationAddress () == GetAddress ())
635  {
636  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", resolved "<<prep.GetOriginatorAddress ());
637  return;
638  }
639  if (result.retransmitter == Mac48Address::GetBroadcast ())
640  {
641  return;
642  }
643  //Forward PREP
644  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (result.ifIndex);
645  NS_ASSERT (prep_sender != m_interfaces.end ());
646  prep_sender->second->SendPrep (prep, result.retransmitter);
647 }
648 void
649 HwmpProtocol::ReceivePerr (std::vector<FailedDestination> destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
650 {
651  //Acceptance cretirea:
652  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", received PERR from "<<from);
653  std::vector<FailedDestination> retval;
655  for (unsigned int i = 0; i < destinations.size (); i++)
656  {
657  result = m_rtable->LookupReactiveExpired (destinations[i].destination);
658  if (!(
659  (result.retransmitter != from) ||
660  (result.ifIndex != interface) ||
661  ((int32_t)(result.seqnum - destinations[i].seqnum) > 0)
662  ))
663  {
664  retval.push_back (destinations[i]);
665  }
666  }
667  if (retval.size () == 0)
668  {
669  return;
670  }
671  ForwardPathError (MakePathError (retval));
672 }
673 void
675  Mac48Address src,
676  Mac48Address dst,
677  Mac48Address retransmitter,
678  uint32_t initMetric,
679  uint32_t originatorDsn,
680  uint32_t destinationSN,
681  uint32_t lifetime,
682  uint32_t interface)
683 {
684  IePrep prep;
685  prep.SetHopcount (0);
686  prep.SetTtl (m_maxTtl);
687  prep.SetDestinationAddress (dst);
688  prep.SetDestinationSeqNumber (destinationSN);
689  prep.SetLifetime (lifetime);
690  prep.SetMetric (initMetric);
691  prep.SetOriginatorAddress (src);
692  prep.SetOriginatorSeqNumber (originatorDsn);
693  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (interface);
694  NS_ASSERT (prep_sender != m_interfaces.end ());
695  prep_sender->second->SendPrep (prep, retransmitter);
697 }
698 bool
700 {
701  m_mp = mp;
702  std::vector<Ptr<NetDevice> > interfaces = mp->GetInterfaces ();
703  for (std::vector<Ptr<NetDevice> >::const_iterator i = interfaces.begin (); i != interfaces.end (); i++)
704  {
705  // Checking for compatible net device
706  Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice> ();
707  if (wifiNetDev == 0)
708  {
709  return false;
710  }
711  Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
712  if (mac == 0)
713  {
714  return false;
715  }
716  // Installing plugins:
717  Ptr<HwmpProtocolMac> hwmpMac = Create<HwmpProtocolMac> (wifiNetDev->GetIfIndex (), this);
718  m_interfaces[wifiNetDev->GetIfIndex ()] = hwmpMac;
719  mac->InstallPlugin (hwmpMac);
720  //Installing airtime link metric:
721  Ptr<AirtimeLinkMetricCalculator> metric = CreateObject <AirtimeLinkMetricCalculator> ();
722  mac->SetLinkMetricCallback (MakeCallback (&AirtimeLinkMetricCalculator::CalculateMetric, metric));
723  }
724  mp->SetRoutingProtocol (this);
725  // Mesh point aggregates all installed protocols
726  mp->AggregateObject (this);
727  m_address = Mac48Address::ConvertFrom (mp->GetAddress ()); // address;
728  return true;
729 }
730 void
731 HwmpProtocol::PeerLinkStatus (Mac48Address meshPointAddress, Mac48Address peerAddress, uint32_t interface, bool status)
732 {
733  if (status)
734  {
735  return;
736  }
737  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (peerAddress);
738  InitiatePathError (MakePathError (destinations));
739 }
740 void
741 HwmpProtocol::SetNeighboursCallback (Callback<std::vector<Mac48Address>, uint32_t> cb)
742 {
744 }
745 bool
747 {
748  if (source == GetAddress ())
749  {
750  return true;
751  }
752  std::map<Mac48Address, uint32_t,std::less<Mac48Address> >::const_iterator i = m_lastDataSeqno.find (source);
753  if (i == m_lastDataSeqno.end ())
754  {
755  m_lastDataSeqno[source] = seqno;
756  }
757  else
758  {
759  if ((int32_t)(i->second - seqno) >= 0)
760  {
761  return true;
762  }
763  m_lastDataSeqno[source] = seqno;
764  }
765  return false;
766 }
768 HwmpProtocol::MakePathError (std::vector<FailedDestination> destinations)
769 {
770  PathError retval;
771  //HwmpRtable increments a sequence number as written in 11B.9.7.2
772  retval.receivers = GetPerrReceivers (destinations);
773  if (retval.receivers.size () == 0)
774  {
775  return retval;
776  }
778  for (unsigned int i = 0; i < destinations.size (); i++)
779  {
780  retval.destinations.push_back (destinations[i]);
781  m_rtable->DeleteReactivePath (destinations[i].destination);
782  }
783  return retval;
784 }
785 void
787 {
788  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
789  {
790  std::vector<Mac48Address> receivers_for_interface;
791  for (unsigned int j = 0; j < perr.receivers.size (); j++)
792  {
793  if (i->first == perr.receivers[j].first)
794  {
795  receivers_for_interface.push_back (perr.receivers[j].second);
796  }
797  }
798  i->second->InitiatePerr (perr.destinations, receivers_for_interface);
799  }
800 }
801 void
803 {
804  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
805  {
806  std::vector<Mac48Address> receivers_for_interface;
807  for (unsigned int j = 0; j < perr.receivers.size (); j++)
808  {
809  if (i->first == perr.receivers[j].first)
810  {
811  receivers_for_interface.push_back (perr.receivers[j].second);
812  }
813  }
814  i->second->ForwardPerr (perr.destinations, receivers_for_interface);
815  }
816 }
817 
818 std::vector<std::pair<uint32_t, Mac48Address> >
819 HwmpProtocol::GetPerrReceivers (std::vector<FailedDestination> failedDest)
820 {
822  for (unsigned int i = 0; i < failedDest.size (); i++)
823  {
824  HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors (failedDest[i].destination);
825  m_rtable->DeleteReactivePath (failedDest[i].destination);
826  m_rtable->DeleteProactivePath (failedDest[i].destination);
827  for (unsigned int j = 0; j < precursors.size (); j++)
828  {
829  retval.push_back (precursors[j]);
830  }
831  }
832  //Check if we have dublicates in retval and precursors:
833  for (unsigned int i = 0; i < retval.size (); i++)
834  {
835  for (unsigned int j = i+1; j < retval.size (); j++)
836  {
837  if (retval[i].second == retval[j].second)
838  {
839  retval.erase (retval.begin () + j);
840  }
841  }
842  }
843  return retval;
844 }
845 std::vector<Mac48Address>
846 HwmpProtocol::GetPreqReceivers (uint32_t interface)
847 {
848  std::vector<Mac48Address> retval;
849  if (!m_neighboursCallback.IsNull ())
850  {
851  retval = m_neighboursCallback (interface);
852  }
853  if ((retval.size () >= m_unicastPreqThreshold) || (retval.size () == 0))
854  {
855  retval.clear ();
856  retval.push_back (Mac48Address::GetBroadcast ());
857  }
858  return retval;
859 }
860 std::vector<Mac48Address>
862 {
863  std::vector<Mac48Address> retval;
864  if (!m_neighboursCallback.IsNull ())
865  {
866  retval = m_neighboursCallback (interface);
867  }
868  if ((retval.size () >= m_unicastDataThreshold) || (retval.size () == 0))
869  {
870  retval.clear ();
871  retval.push_back (Mac48Address::GetBroadcast ());
872  }
873  return retval;
874 }
875 
876 bool
878 {
879  if (m_rqueue.size () > m_maxQueueSize)
880  {
881  return false;
882  }
883  m_rqueue.push_back (packet);
884  return true;
885 }
886 
889 {
890  QueuedPacket retval;
891  retval.pkt = 0;
892  for (std::vector<QueuedPacket>::iterator i = m_rqueue.begin (); i != m_rqueue.end (); i++)
893  {
894  if ((*i).dst == dst)
895  {
896  retval = (*i);
897  m_rqueue.erase (i);
898  break;
899  }
900  }
901  return retval;
902 }
903 
906 {
907  QueuedPacket retval;
908  retval.pkt = 0;
909  if (m_rqueue.size () != 0)
910  {
911  retval = m_rqueue[0];
912  m_rqueue.erase (m_rqueue.begin ());
913  }
914  return retval;
915 }
916 
917 void
919 {
920  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
921  if (i != m_preqTimeouts.end ())
922  {
923  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
924  }
925 
928  //Send all packets stored for this destination
929  QueuedPacket packet = DequeueFirstPacketByDst (dst);
930  while (packet.pkt != 0)
931  {
932  //set RA tag for retransmitter:
933  HwmpTag tag;
934  packet.pkt->RemovePacketTag (tag);
935  tag.SetAddress (result.retransmitter);
936  packet.pkt->AddPacketTag (tag);
937  m_stats.txUnicast++;
938  m_stats.txBytes += packet.pkt->GetSize ();
939  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
940 
941  packet = DequeueFirstPacketByDst (dst);
942  }
943 }
944 void
946 {
947  //send all packets to root
950  QueuedPacket packet = DequeueFirstPacket ();
951  while (packet.pkt != 0)
952  {
953  //set RA tag for retransmitter:
954  HwmpTag tag;
955  if (!packet.pkt->RemovePacketTag (tag))
956  {
957  NS_FATAL_ERROR ("HWMP tag must be present at this point");
958  }
959  tag.SetAddress (result.retransmitter);
960  packet.pkt->AddPacketTag (tag);
961  m_stats.txUnicast++;
962  m_stats.txBytes += packet.pkt->GetSize ();
963  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
964 
965  packet = DequeueFirstPacket ();
966  }
967 }
968 
969 bool
971 {
972  std::map<Mac48Address, PreqEvent>::const_iterator i = m_preqTimeouts.find (dst);
973  if (i == m_preqTimeouts.end ())
974  {
975  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
977  &HwmpProtocol::RetryPathDiscovery, this, dst, 1);
978  m_preqTimeouts[dst].whenScheduled = Simulator::Now ();
979  return true;
980  }
981  return false;
982 }
983 void
985 {
987  if (result.retransmitter == Mac48Address::GetBroadcast ())
988  {
989  result = m_rtable->LookupProactive ();
990  }
991  if (result.retransmitter != Mac48Address::GetBroadcast ())
992  {
993  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
994  NS_ASSERT (i != m_preqTimeouts.end ());
995  m_preqTimeouts.erase (i);
996  return;
997  }
998  if (numOfRetry > m_dot11MeshHWMPmaxPREQretries)
999  {
1000  QueuedPacket packet = DequeueFirstPacketByDst (dst);
1001  //purge queue and delete entry from retryDatabase
1002  while (packet.pkt != 0)
1003  {
1005  packet.reply (false, packet.pkt, packet.src, packet.dst, packet.protocol, HwmpRtable::MAX_METRIC);
1006  packet = DequeueFirstPacketByDst (dst);
1007  }
1008  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1009  NS_ASSERT (i != m_preqTimeouts.end ());
1010  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
1011  m_preqTimeouts.erase (i);
1012  return;
1013  }
1014  numOfRetry++;
1015  uint32_t originator_seqno = GetNextHwmpSeqno ();
1016  uint32_t dst_seqno = m_rtable->LookupReactiveExpired (dst).seqnum;
1017  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1018  {
1019  i->second->RequestDestination (dst, originator_seqno, dst_seqno);
1020  }
1021  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
1022  Time ((2 * (numOfRetry + 1)) * m_dot11MeshHWMPnetDiameterTraversalTime),
1023  &HwmpProtocol::RetryPathDiscovery, this, dst, numOfRetry);
1024 }
1025 //Proactive PREQ routines:
1026 void
1028 {
1029  Time randomStart = Seconds (m_coefficient->GetValue ());
1031  NS_LOG_DEBUG ("ROOT IS: " << m_address);
1032  m_isRoot = true;
1033 }
1034 void
1036 {
1038 }
1039 void
1041 {
1042  IePreq preq;
1043  //By default: must answer
1044  preq.SetHopcount (0);
1045  preq.SetTTL (m_maxTtl);
1047  //\attention: do not forget to set originator address, sequence
1048  //number and preq ID in HWMP-MAC plugin
1050  preq.SetOriginatorAddress (GetAddress ());
1051  preq.SetPreqID (GetNextPreqId ());
1053  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1054  {
1055  i->second->SendPreq (preq);
1056  }
1058 }
1059 bool
1061 {
1062  return m_doFlag;
1063 }
1064 bool
1066 {
1067  return m_rfFlag;
1068 }
1069 Time
1071 {
1073 }
1074 Time
1076 {
1078 }
1079 uint8_t
1081 {
1082  return m_maxTtl;
1083 }
1084 uint32_t
1086 {
1087  m_preqId++;
1088  return m_preqId;
1089 }
1090 uint32_t
1092 {
1093  m_hwmpSeqno++;
1094  return m_hwmpSeqno;
1095 }
1096 uint32_t
1098 {
1100 }
1101 uint8_t
1103 {
1104  return m_unicastPerrThreshold;
1105 }
1108 {
1109  return m_address;
1110 }
1111 //Statistics:
1113  txUnicast (0),
1114  txBroadcast (0),
1115  txBytes (0),
1116  droppedTtl (0),
1117  totalQueued (0),
1118  totalDropped (0),
1119  initiatedPreq (0),
1120  initiatedPrep (0),
1121  initiatedPerr (0)
1122 {
1123 }
1124 void HwmpProtocol::Statistics::Print (std::ostream & os) const
1125 {
1126  os << "<Statistics "
1127  "txUnicast=\"" << txUnicast << "\" "
1128  "txBroadcast=\"" << txBroadcast << "\" "
1129  "txBytes=\"" << txBytes << "\" "
1130  "droppedTtl=\"" << droppedTtl << "\" "
1131  "totalQueued=\"" << totalQueued << "\" "
1132  "totalDropped=\"" << totalDropped << "\" "
1133  "initiatedPreq=\"" << initiatedPreq << "\" "
1134  "initiatedPrep=\"" << initiatedPrep << "\" "
1135  "initiatedPerr=\"" << initiatedPerr << "\"/>" << std::endl;
1136 }
1137 void
1138 HwmpProtocol::Report (std::ostream & os) const
1139 {
1140  os << "<Hwmp "
1141  "address=\"" << m_address << "\"" << std::endl <<
1142  "maxQueueSize=\"" << m_maxQueueSize << "\"" << std::endl <<
1143  "Dot11MeshHWMPmaxPREQretries=\"" << (uint16_t)m_dot11MeshHWMPmaxPREQretries << "\"" << std::endl <<
1144  "Dot11MeshHWMPnetDiameterTraversalTime=\"" << m_dot11MeshHWMPnetDiameterTraversalTime.GetSeconds () << "\"" << std::endl <<
1145  "Dot11MeshHWMPpreqMinInterval=\"" << m_dot11MeshHWMPpreqMinInterval.GetSeconds () << "\"" << std::endl <<
1146  "Dot11MeshHWMPperrMinInterval=\"" << m_dot11MeshHWMPperrMinInterval.GetSeconds () << "\"" << std::endl <<
1147  "Dot11MeshHWMPactiveRootTimeout=\"" << m_dot11MeshHWMPactiveRootTimeout.GetSeconds () << "\"" << std::endl <<
1148  "Dot11MeshHWMPactivePathTimeout=\"" << m_dot11MeshHWMPactivePathTimeout.GetSeconds () << "\"" << std::endl <<
1149  "Dot11MeshHWMPpathToRootInterval=\"" << m_dot11MeshHWMPpathToRootInterval.GetSeconds () << "\"" << std::endl <<
1150  "Dot11MeshHWMPrannInterval=\"" << m_dot11MeshHWMPrannInterval.GetSeconds () << "\"" << std::endl <<
1151  "isRoot=\"" << m_isRoot << "\"" << std::endl <<
1152  "maxTtl=\"" << (uint16_t)m_maxTtl << "\"" << std::endl <<
1153  "unicastPerrThreshold=\"" << (uint16_t)m_unicastPerrThreshold << "\"" << std::endl <<
1154  "unicastPreqThreshold=\"" << (uint16_t)m_unicastPreqThreshold << "\"" << std::endl <<
1155  "unicastDataThreshold=\"" << (uint16_t)m_unicastDataThreshold << "\"" << std::endl <<
1156  "doFlag=\"" << m_doFlag << "\"" << std::endl <<
1157  "rfFlag=\"" << m_rfFlag << "\">" << std::endl;
1158  m_stats.Print (os);
1159  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
1160  {
1161  plugin->second->Report (os);
1162  }
1163  os << "</Hwmp>" << std::endl;
1164 }
1165 void
1167 {
1168  m_stats = Statistics ();
1169  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
1170  {
1171  plugin->second->ResetStats ();
1172  }
1173 }
1174 
1175 int64_t
1177 {
1178  NS_LOG_FUNCTION (this << stream);
1179  m_coefficient->SetStream (stream);
1180  return 1;
1181 }
1182 
1184  pkt (0),
1185  protocol (0),
1186  inInterface (0)
1187 {
1188 }
1189 } // namespace dot11s
1190 } // namespace ns3
Structure of path error: IePerr and list of receivers: interfaces and MAC address.
void SetDestinationAddress(Mac48Address dest_address)
void SetPreqID(uint32_t id)
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.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:95
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
AttributeValue implementation for Boolean.
Definition: boolean.h:34
uint32_t GetDestinationSeqNumber() const
Callback template class.
Definition: callback.h:978
Hwmp tag implements interaction between HWMP protocol and MeshWifiMac.
Definition: hwmp-tag.h:48
void SetTTL(uint8_t ttl)
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
void IncrementMetric(uint32_t metric)
static const uint32_t MAX_METRIC
Maximum (the best?) path metric.
Definition: hwmp-rtable.h:41
void SetOriginatorSeqNumber(uint32_t originator_seq_number)
Route lookup result, return type of LookupXXX methods.
Definition: hwmp-rtable.h:44
void SendPrep(Mac48Address src, Mac48Address dst, Mac48Address retransmitter, uint32_t initMetric, uint32_t originatorDsn, uint32_t destinationSN, uint32_t lifetime, uint32_t interface)
forms a path error information element when list of destination fails on a given interface ...
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:81
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:836
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
void ForwardPathError(PathError perr)
Forwards a received path error.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
See 7.3.2.97 of 802.11s draft 2.07.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:766
LookupResult LookupReactiveExpired(Mac48Address destination)
Return all reactive paths, including expired.
Definition: hwmp-rtable.cc:158
Mac48Address GetDestinationAddress() const
bool Install(Ptr< MeshPointDevice >)
Install HWMP on given mesh point.
#define NS_FATAL_ERROR(msg)
Fatal error handling.
Definition: fatal-error.h:100
void InitiatePathError(PathError perr)
Passes a self-generated PERR to interface-plugin.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:819
void SetTtl(uint8_t ttl)
uint32_t GetLifetime() const
void SetTtl(uint8_t ttl)
Definition: hwmp-tag.cc:51
void ReactivePathResolved(Mac48Address dst)
void SetOriginatorAddress(Mac48Address originator_address)
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 SetAddress(Mac48Address retransmitter)
Definition: hwmp-tag.cc:39
LookupResult LookupReactive(Mac48Address destination)
Lookup path to destination.
Definition: hwmp-rtable.cc:143
TracedCallback< Time > m_routeDiscoveryTimeCallback
Route discovery time:
void SetLifetime(uint32_t lifetime)
void ReceivePrep(IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
forms a path error information element when list of destination fails on a given interface ...
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
void SendProactivePreq()
Proactive Preq routines:
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:439
bool DropDataFrame(uint32_t seqno, Mac48Address source)
MAC-plugin asks whether the frame can be dropped.
QueuedPacket DequeueFirstPacket()
std::vector< std::pair< uint32_t, Mac48Address > > PrecursorList
Path precursor = {MAC, interface ID}.
Definition: hwmp-rtable.h:62
Mac48Address GetOriginatorAddress() const
Routing table for HWMP – 802.11s routing protocol.
Definition: hwmp-rtable.h:35
void Print(std::ostream &os) const
std::vector< Mac48Address > GetPreqReceivers(uint32_t interface)
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:327
bool RemoveRoutingStuff(uint32_t fromIface, const Mac48Address source, const Mac48Address destination, Ptr< Packet > packet, uint16_t &protocolType)
Cleanup packet from all tags.
Mac48Address GetOriginatorAddress() const
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:858
Ptr< MeshPointDevice > GetMeshPoint() const
Each mesh protocol must be installed on the mesh point to work.
std::vector< QueuedPacket > m_rqueue
Packet Queue.
std::vector< std::pair< uint32_t, Mac48Address > > GetPerrReceivers(std::vector< FailedDestination > failedDest)
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:335
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:185
void RetryPathDiscovery(Mac48Address dst, uint8_t numOfRetry)
Generates PREQ retry when retry timeout has expired and route is still unresolved.
Ptr< MeshPointDevice > m_mp
Host mesh point.
void IncrementMetric(uint32_t metric)
AttributeValue implementation for Time.
Definition: nstime.h:921
void DoDispose()
Destructor implementation.
See 7.3.2.96 of 802.11s draft 2.07.
Hold an unsigned integer type.
Definition: uinteger.h:44
PrecursorList GetPrecursors(Mac48Address destination)
Definition: hwmp-rtable.cc:209
tuple interfaces
Definition: first.py:41
bool ForwardUnicast(uint32_t sourceIface, const Mac48Address source, const Mac48Address destination, Ptr< Packet > packet, uint16_t protocolType, RouteReplyCallback routeReply, uint32_t ttl)
Like RequestRoute, but for unicast packets.
Packet waiting its routing information.
Hold together all Wifi-related objects.
static Mac48Address GetBroadcast(void)
HwmpProtocolMacMap m_interfaces
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1290
uint32_t GetOriginatorSeqNumber() const
void AddPrecursor(Mac48Address destination, uint32_t precursorInterface, Mac48Address precursorAddress, Time lifetime)
Definition: hwmp-rtable.cc:87
Ptr< HwmpRtable > m_rtable
Routing table.
void SetOriginatorAddress(Mac48Address originator_address)
void SetLifetime(uint32_t lifetime)
static TypeId GetTypeId()
LookupResult LookupProactiveExpired()
Return all proactive paths, including expired.
Definition: hwmp-rtable.cc:179
void ReceivePreq(IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
forms a path error information element when list of destination fails on a given interface ...
Time m_randomStart
Random start in Proactive PREQ propagation.
static Mac48Address ConvertFrom(const Address &address)
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
void SetOriginatorSeqNumber(uint32_t originator_seq_number)
void SetMetric(uint32_t metric)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void AddDestinationAddressElement(bool doFlag, bool rfFlag, Mac48Address dest_address, uint32_t dest_seq_number)
Add a destination address unit: flags, destination and sequence number.
void AddReactivePath(Mac48Address destination, Mac48Address retransmitter, uint32_t interface, uint32_t metric, Time lifetime, uint32_t seqnum)
Definition: hwmp-rtable.cc:58
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
void DelDestinationAddressElement(Mac48Address dest_address)
Delete a destination address unit by destination.
PathError MakePathError(std::vector< FailedDestination > destinations)
forms a path error information element when list of destination fails on a given interface ...
std::vector< std::pair< uint32_t, Mac48Address > > receivers
list of PathError receivers (in case of unicast PERR)
double GetValue(double min, double max)
Returns a random double from the uniform distribution with the specified range.
bool IsNeedNotPrep() const
an EUI-48 address
Definition: mac48-address.h:43
uint8_t GetDestCount() const
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:922
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
std::vector< Ptr< DestinationAddressUnit > > GetDestinationList()
Get all destinations, which are stored in PREQ:
RouteReplyCallback reply
how to reply
Interface for L2 mesh routing protocol and mesh point communication.
uint8_t GetTtl()
Definition: hwmp-tag.cc:57
void Report(std::ostream &) const
Statistics:
Ptr< UniformRandomVariable > m_coefficient
Random variable for random start time.
EventId m_proactivePreqTimer
Random start in Proactive PREQ propagation.
std::vector< Mac48Address > GetBroadcastReceivers(uint32_t interface)
std::vector< FailedDestination > destinations
destination list: Mac48Address and sequence number
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:843
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:859
Callback< std::vector< Mac48Address >, uint32_t > m_neighboursCallback
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
uint32_t GetLifetime() const
std::map< Mac48Address, uint32_t > m_lastDataSeqno
keeps HWMP seqno (first in pair) and HWMP metric (second in pair) for each address ...
Ptr< T > CreateObject(void)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:524
void DeleteReactivePath(Mac48Address destination)
Definition: hwmp-rtable.cc:134
QueuedPacket DequeueFirstPacketByDst(Mac48Address dst)
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:875
void AddProactivePath(uint32_t metric, Mac48Address root, Mac48Address retransmitter, uint32_t interface, Time lifetime, uint32_t seqnum)
Definition: hwmp-rtable.cc:76
uint32_t GetMetric() const
tuple address
Definition: first.py:37
void SetSeqno(uint32_t seqno)
Definition: hwmp-tag.cc:75
uint32_t inInterface
incoming device interface ID. (if packet has come from upper layers, this is Mesh point ID) ...
bool QueuePacket(QueuedPacket packet)
uint32_t GetMetric() const
bool ShouldSendPreq(Mac48Address dst)
checks when the last path discovery procedure was started for a given destination.
This class can be used to hold variables of floating point type such as 'double' or 'float'...
Definition: double.h:41
void SetDestinationSeqNumber(uint32_t dest_seq_number)
void SetHopcount(uint8_t hopcount)
void PeerLinkStatus(Mac48Address meshPontAddress, Mac48Address peerAddress, uint32_t interface, bool status)
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:190
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
a unique identifier for an interface.
Definition: type-id.h:51
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
Basic MAC of mesh point Wi-Fi interface.
void SetHopcount(uint8_t hopcount)
std::map< Mac48Address, PreqEvent > m_preqTimeouts
Random start in Proactive PREQ propagation.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
LookupResult LookupProactive()
Find proactive path to tree root. Note that calling this method has side effect of deleting expired p...
Definition: hwmp-rtable.cc:169
void ReceivePerr(std::vector< FailedDestination >, Mac48Address from, uint32_t interface, Mac48Address fromMp)
forms a path error information element when list of destination fails on a given interface ...
void SetNeighboursCallback(Callback< std::vector< Mac48Address >, uint32_t > cb)
This callback is used to obtain active neighbours on a given interface.
virtual void DoInitialize()
Initialize() implementation.