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  .SetGroupName ("Mesh")
53  .AddConstructor<HwmpProtocol> ()
54  .AddAttribute ( "RandomStart",
55  "Random delay at first proactive PREQ",
56  TimeValue (Seconds (0.1)),
60  )
61  .AddAttribute ( "MaxQueueSize",
62  "Maximum number of packets we can store when resolving route",
63  UintegerValue (255),
66  MakeUintegerChecker<uint16_t> (1)
67  )
68  .AddAttribute ( "Dot11MeshHWMPmaxPREQretries",
69  "Maximum number of retries before we suppose the destination to be unreachable",
70  UintegerValue (3),
73  MakeUintegerChecker<uint8_t> (1)
74  )
75  .AddAttribute ( "Dot11MeshHWMPnetDiameterTraversalTime",
76  "Time we suppose the packet to go from one edge of the network to another",
77  TimeValue (MicroSeconds (1024*100)),
81  )
82  .AddAttribute ( "Dot11MeshHWMPpreqMinInterval",
83  "Minimal interval between to successive PREQs",
84  TimeValue (MicroSeconds (1024*100)),
88  )
89  .AddAttribute ( "Dot11MeshHWMPperrMinInterval",
90  "Minimal interval between to successive PREQs",
91  TimeValue (MicroSeconds (1024*100)),
94  )
95  .AddAttribute ( "Dot11MeshHWMPactiveRootTimeout",
96  "Lifetime of poractive routing information",
97  TimeValue (MicroSeconds (1024*5000)),
100  MakeTimeChecker ()
101  )
102  .AddAttribute ( "Dot11MeshHWMPactivePathTimeout",
103  "Lifetime of reactive routing information",
104  TimeValue (MicroSeconds (1024*5000)),
107  MakeTimeChecker ()
108  )
109  .AddAttribute ( "Dot11MeshHWMPpathToRootInterval",
110  "Interval between two successive proactive PREQs",
111  TimeValue (MicroSeconds (1024*2000)),
114  MakeTimeChecker ()
115  )
116  .AddAttribute ( "Dot11MeshHWMPrannInterval",
117  "Lifetime of poractive routing information",
118  TimeValue (MicroSeconds (1024*5000)),
121  MakeTimeChecker ()
122  )
123  .AddAttribute ( "MaxTtl",
124  "Initial value of Time To Live field",
125  UintegerValue (32),
128  MakeUintegerChecker<uint8_t> (2)
129  )
130  .AddAttribute ( "UnicastPerrThreshold",
131  "Maximum number of PERR receivers, when we send a PERR as a chain of unicasts",
132  UintegerValue (32),
135  MakeUintegerChecker<uint8_t> (1)
136  )
137  .AddAttribute ( "UnicastPreqThreshold",
138  "Maximum number of PREQ receivers, when we send a PREQ as a chain of unicasts",
139  UintegerValue (1),
142  MakeUintegerChecker<uint8_t> (1)
143  )
144  .AddAttribute ( "UnicastDataThreshold",
145  "Maximum number ofbroadcast receivers, when we send a broadcast as a chain of unicasts",
146  UintegerValue (1),
149  MakeUintegerChecker<uint8_t> (1)
150  )
151  .AddAttribute ( "DoFlag",
152  "Destination only HWMP flag",
153  BooleanValue (false),
157  )
158  .AddAttribute ( "RfFlag",
159  "Reply and forward flag",
160  BooleanValue (true),
164  )
165  .AddTraceSource ( "RouteDiscoveryTime",
166  "The time of route discovery procedure",
169  "ns3::Time::TracedCallback"
170  )
171  ;
172  return tid;
173 }
174 
176  m_dataSeqno (1),
177  m_hwmpSeqno (1),
178  m_preqId (0),
179  m_rtable (CreateObject<HwmpRtable> ()),
180  m_randomStart (Seconds (0.1)),
181  m_maxQueueSize (255),
182  m_dot11MeshHWMPmaxPREQretries (3),
183  m_dot11MeshHWMPnetDiameterTraversalTime (MicroSeconds (1024*100)),
184  m_dot11MeshHWMPpreqMinInterval (MicroSeconds (1024*100)),
185  m_dot11MeshHWMPperrMinInterval (MicroSeconds (1024*100)),
186  m_dot11MeshHWMPactiveRootTimeout (MicroSeconds (1024*5000)),
187  m_dot11MeshHWMPactivePathTimeout (MicroSeconds (1024*5000)),
188  m_dot11MeshHWMPpathToRootInterval (MicroSeconds (1024*2000)),
189  m_dot11MeshHWMPrannInterval (MicroSeconds (1024*5000)),
190  m_isRoot (false),
191  m_maxTtl (32),
192  m_unicastPerrThreshold (32),
193  m_unicastPreqThreshold (1),
194  m_unicastDataThreshold (1),
195  m_doFlag (false),
196  m_rfFlag (false)
197 {
199  m_coefficient = CreateObject<UniformRandomVariable> ();
200 }
201 
203 {
205 }
206 
207 void
209 {
211  if (m_isRoot)
212  {
213  Time randomStart = Seconds (m_coefficient->GetValue ());
215  }
216 }
217 
218 void
220 {
222  for (std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.begin (); i != m_preqTimeouts.end (); i++)
223  {
224  i->second.preqTimeout.Cancel ();
225  }
227  m_preqTimeouts.clear ();
228  m_lastDataSeqno.clear ();
229  m_hwmpSeqnoMetricDatabase.clear ();
230  m_interfaces.clear ();
231  m_rqueue.clear ();
232  m_rtable = 0;
233  m_mp = 0;
234 }
235 
236 bool
238  uint32_t sourceIface,
239  const Mac48Address source,
240  const Mac48Address destination,
241  Ptr<const Packet> constPacket,
242  uint16_t protocolType, //ethrnet 'Protocol' field
244  )
245 {
246  Ptr <Packet> packet = constPacket->Copy ();
247  HwmpTag tag;
248  if (sourceIface == GetMeshPoint ()->GetIfIndex ())
249  {
250  // packet from level 3
251  if (packet->PeekPacketTag (tag))
252  {
253  NS_FATAL_ERROR ("HWMP tag has come with a packet from upper layer. This must not occur...");
254  }
255  //Filling TAG:
256  if (destination == Mac48Address::GetBroadcast ())
257  {
258  tag.SetSeqno (m_dataSeqno++);
259  }
260  tag.SetTtl (m_maxTtl);
261  }
262  else
263  {
264  if (!packet->RemovePacketTag (tag))
265  {
266  NS_FATAL_ERROR ("HWMP tag is supposed to be here at this point.");
267  }
268  tag.DecrementTtl ();
269  if (tag.GetTtl () == 0)
270  {
272  return false;
273  }
274  }
275  if (destination == Mac48Address::GetBroadcast ())
276  {
278  m_stats.txBytes += packet->GetSize ();
279  //channel IDs where we have already sent broadcast:
280  std::vector<uint16_t> channels;
281  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
282  {
283  bool shouldSend = true;
284  for (std::vector<uint16_t>::const_iterator chan = channels.begin (); chan != channels.end (); chan++)
285  {
286  if ((*chan) == plugin->second->GetChannelId ())
287  {
288  shouldSend = false;
289  }
290  }
291  if (!shouldSend)
292  {
293  continue;
294  }
295  channels.push_back (plugin->second->GetChannelId ());
296  std::vector<Mac48Address> receivers = GetBroadcastReceivers (plugin->first);
297  for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i++)
298  {
299  Ptr<Packet> packetCopy = packet->Copy ();
300  //
301  // 64-bit Intel valgrind complains about tag.SetAddress (*i). It
302  // likes this just fine.
303  //
304  Mac48Address address = *i;
305  tag.SetAddress (address);
306  packetCopy->AddPacketTag (tag);
307  routeReply (true, packetCopy, source, destination, protocolType, plugin->first);
308  }
309  }
310  }
311  else
312  {
313  return ForwardUnicast (sourceIface, source, destination, packet, protocolType, routeReply, tag.GetTtl ());
314  }
315  return true;
316 }
317 bool
318 HwmpProtocol::RemoveRoutingStuff (uint32_t fromIface, const Mac48Address source,
319  const Mac48Address destination, Ptr<Packet> packet, uint16_t& protocolType)
320 {
321  HwmpTag tag;
322  if (!packet->RemovePacketTag (tag))
323  {
324  NS_FATAL_ERROR ("HWMP tag must exist when packet received from the network");
325  }
326  return true;
327 }
328 bool
329 HwmpProtocol::ForwardUnicast (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination,
330  Ptr<Packet> packet, uint16_t protocolType, RouteReplyCallback routeReply, uint32_t ttl)
331 {
332  NS_ASSERT (destination != Mac48Address::GetBroadcast ());
333  HwmpRtable::LookupResult result = m_rtable->LookupReactive (destination);
334  NS_LOG_DEBUG ("Requested src = "<<source<<", dst = "<<destination<<", I am "<<GetAddress ()<<", RA = "<<result.retransmitter);
335  if (result.retransmitter == Mac48Address::GetBroadcast ())
336  {
337  result = m_rtable->LookupProactive ();
338  }
339  HwmpTag tag;
340  tag.SetAddress (result.retransmitter);
341  tag.SetTtl (ttl);
342  //seqno and metric is not used;
343  packet->AddPacketTag (tag);
344  if (result.retransmitter != Mac48Address::GetBroadcast ())
345  {
346  //reply immediately:
347  routeReply (true, packet, source, destination, protocolType, result.ifIndex);
348  m_stats.txUnicast++;
349  m_stats.txBytes += packet->GetSize ();
350  return true;
351  }
352  if (sourceIface != GetMeshPoint ()->GetIfIndex ())
353  {
354  //Start path error procedure:
355  NS_LOG_DEBUG ("Must Send PERR");
356  result = m_rtable->LookupReactiveExpired (destination);
357  //1. Lookup expired reactive path. If exists - start path error
358  // procedure towards a next hop of this path
359  //2. If there was no reactive path, we lookup expired proactive
360  // path. If exist - start path error procedure towards path to
361  // root
362  if (result.retransmitter == Mac48Address::GetBroadcast ())
363  {
364  result = m_rtable->LookupProactiveExpired ();
365  }
366  if (result.retransmitter != Mac48Address::GetBroadcast ())
367  {
368  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (result.retransmitter);
369  InitiatePathError (MakePathError (destinations));
370  }
372  return false;
373  }
374  //Request a destination:
375  result = m_rtable->LookupReactiveExpired (destination);
376  if (ShouldSendPreq (destination))
377  {
378  uint32_t originator_seqno = GetNextHwmpSeqno ();
379  uint32_t dst_seqno = 0;
380  if (result.retransmitter != Mac48Address::GetBroadcast ())
381  {
382  dst_seqno = result.seqnum;
383  }
385  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
386  {
387  i->second->RequestDestination (destination, originator_seqno, dst_seqno);
388  }
389  }
390  QueuedPacket pkt;
391  pkt.pkt = packet;
392  pkt.dst = destination;
393  pkt.src = source;
394  pkt.protocol = protocolType;
395  pkt.reply = routeReply;
396  pkt.inInterface = sourceIface;
397  if (QueuePacket (pkt))
398  {
400  return true;
401  }
402  else
403  {
405  return false;
406  }
407 }
408 void
409 HwmpProtocol::ReceivePreq (IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
410 {
411  preq.IncrementMetric (metric);
412  //acceptance cretirea:
413  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
414  preq.GetOriginatorAddress ());
415  bool freshInfo (true);
416  if (i != m_hwmpSeqnoMetricDatabase.end ())
417  {
418  if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber ()) > 0)
419  {
420  return;
421  }
422  if (i->second.first == preq.GetOriginatorSeqNumber ())
423  {
424  freshInfo = false;
425  if (i->second.second <= preq.GetMetric ())
426  {
427  return;
428  }
429  }
430  }
432  std::make_pair (preq.GetOriginatorSeqNumber (), preq.GetMetric ());
433  NS_LOG_DEBUG ("I am " << GetAddress () << "Accepted preq from address" << from << ", preq:" << preq);
434  std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
435  //Add reactive path to originator:
436  if (
437  (freshInfo) ||
438  (
439  (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).retransmitter == Mac48Address::GetBroadcast ()) ||
440  (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).metric > preq.GetMetric ())
441  )
442  )
443  {
445  preq.GetOriginatorAddress (),
446  from,
447  interface,
448  preq.GetMetric (),
449  MicroSeconds (preq.GetLifetime () * 1024),
450  preq.GetOriginatorSeqNumber ()
451  );
453  }
454  if (
456  (m_rtable->LookupReactive (fromMp).metric > metric)
457  )
458  {
460  fromMp,
461  from,
462  interface,
463  metric,
464  MicroSeconds (preq.GetLifetime () * 1024),
465  preq.GetOriginatorSeqNumber ()
466  );
467  ReactivePathResolved (fromMp);
468  }
469  for (std::vector<Ptr<DestinationAddressUnit> >::const_iterator i = destinations.begin (); i != destinations.end (); i++)
470  {
471  if ((*i)->GetDestinationAddress () == Mac48Address::GetBroadcast ())
472  {
473  //only proactive PREQ contains destination
474  //address as broadcast! Proactive preq MUST
475  //have destination count equal to 1 and
476  //per destination flags DO and RF
477  NS_ASSERT (preq.GetDestCount () == 1);
478  NS_ASSERT (((*i)->IsDo ()) && ((*i)->IsRf ()));
479  //Add proactive path only if it is the better then existed
480  //before
481  if (
482  ((m_rtable->LookupProactive ()).retransmitter == Mac48Address::GetBroadcast ()) ||
483  ((m_rtable->LookupProactive ()).metric > preq.GetMetric ())
484  )
485  {
487  preq.GetMetric (),
488  preq.GetOriginatorAddress (),
489  from,
490  interface,
491  MicroSeconds (preq.GetLifetime () * 1024),
492  preq.GetOriginatorSeqNumber ()
493  );
495  }
496  if (!preq.IsNeedNotPrep ())
497  {
498  SendPrep (
499  GetAddress (),
500  preq.GetOriginatorAddress (),
501  from,
502  (uint32_t)0,
503  preq.GetOriginatorSeqNumber (),
504  GetNextHwmpSeqno (),
505  preq.GetLifetime (),
506  interface
507  );
508  }
509  break;
510  }
511  if ((*i)->GetDestinationAddress () == GetAddress ())
512  {
513  SendPrep (
514  GetAddress (),
515  preq.GetOriginatorAddress (),
516  from,
517  (uint32_t)0,
518  preq.GetOriginatorSeqNumber (),
519  GetNextHwmpSeqno (),
520  preq.GetLifetime (),
521  interface
522  );
524  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
525  continue;
526  }
527  //check if can answer:
528  HwmpRtable::LookupResult result = m_rtable->LookupReactive ((*i)->GetDestinationAddress ());
529  if ((!((*i)->IsDo ())) && (result.retransmitter != Mac48Address::GetBroadcast ()))
530  {
531  //have a valid information and can answer
532  uint32_t lifetime = result.lifetime.GetMicroSeconds () / 1024;
533  if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber ()) >= 0))
534  {
535  SendPrep (
536  (*i)->GetDestinationAddress (),
537  preq.GetOriginatorAddress (),
538  from,
539  result.metric,
540  preq.GetOriginatorSeqNumber (),
541  result.seqnum,
542  lifetime,
543  interface
544  );
545  m_rtable->AddPrecursor ((*i)->GetDestinationAddress (), interface, from,
546  MicroSeconds (preq.GetLifetime () * 1024));
547  if ((*i)->IsRf ())
548  {
549  (*i)->SetFlags (true, false, (*i)->IsUsn ()); //DO = 1, RF = 0
550  }
551  else
552  {
553  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
554  continue;
555  }
556  }
557  }
558  }
559  //check if must retransmit:
560  if (preq.GetDestCount () == 0)
561  {
562  return;
563  }
564  //Forward PREQ to all interfaces:
565  NS_LOG_DEBUG ("I am " << GetAddress () << "retransmitting PREQ:" << preq);
566  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
567  {
568  i->second->SendPreq (preq);
569  }
570 }
571 void
572 HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
573 {
574  prep.IncrementMetric (metric);
575  //acceptance cretirea:
576  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
577  prep.GetOriginatorAddress ());
578  bool freshInfo (true);
579  uint32_t sequence = prep.GetDestinationSeqNumber ();
580  if (i != m_hwmpSeqnoMetricDatabase.end ())
581  {
582  if ((int32_t)(i->second.first - sequence) > 0)
583  {
584  return;
585  }
586  if (i->second.first == sequence)
587  {
588  freshInfo = false;
589  }
590  }
591  m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (sequence, prep.GetMetric ());
592  //update routing info
593  //Now add a path to destination and add precursor to source
594  NS_LOG_DEBUG ("I am " << GetAddress () << ", received prep from " << prep.GetOriginatorAddress () << ", receiver was:" << from);
596  //Add a reactive path only if seqno is fresher or it improves the
597  //metric
598  if (
599  (freshInfo) ||
600  (
601  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).retransmitter == Mac48Address::GetBroadcast ()) ||
602  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).metric > prep.GetMetric ())
603  )
604  )
605  {
607  prep.GetOriginatorAddress (),
608  from,
609  interface,
610  prep.GetMetric (),
611  MicroSeconds (prep.GetLifetime () * 1024),
612  sequence);
613  m_rtable->AddPrecursor (prep.GetDestinationAddress (), interface, from,
614  MicroSeconds (prep.GetLifetime () * 1024));
615  if (result.retransmitter != Mac48Address::GetBroadcast ())
616  {
617  m_rtable->AddPrecursor (prep.GetOriginatorAddress (), interface, result.retransmitter,
618  result.lifetime);
619  }
621  }
622  if (
623  ((m_rtable->LookupReactive (fromMp)).retransmitter == Mac48Address::GetBroadcast ()) ||
624  ((m_rtable->LookupReactive (fromMp)).metric > metric)
625  )
626  {
628  fromMp,
629  from,
630  interface,
631  metric,
632  MicroSeconds (prep.GetLifetime () * 1024),
633  sequence);
634  ReactivePathResolved (fromMp);
635  }
636  if (prep.GetDestinationAddress () == GetAddress ())
637  {
638  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", resolved "<<prep.GetOriginatorAddress ());
639  return;
640  }
641  if (result.retransmitter == Mac48Address::GetBroadcast ())
642  {
643  return;
644  }
645  //Forward PREP
646  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (result.ifIndex);
647  NS_ASSERT (prep_sender != m_interfaces.end ());
648  prep_sender->second->SendPrep (prep, result.retransmitter);
649 }
650 void
651 HwmpProtocol::ReceivePerr (std::vector<FailedDestination> destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
652 {
653  //Acceptance cretirea:
654  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", received PERR from "<<from);
655  std::vector<FailedDestination> retval;
657  for (unsigned int i = 0; i < destinations.size (); i++)
658  {
659  result = m_rtable->LookupReactiveExpired (destinations[i].destination);
660  if (!(
661  (result.retransmitter != from) ||
662  (result.ifIndex != interface) ||
663  ((int32_t)(result.seqnum - destinations[i].seqnum) > 0)
664  ))
665  {
666  retval.push_back (destinations[i]);
667  }
668  }
669  if (retval.size () == 0)
670  {
671  return;
672  }
673  ForwardPathError (MakePathError (retval));
674 }
675 void
677  Mac48Address src,
678  Mac48Address dst,
679  Mac48Address retransmitter,
680  uint32_t initMetric,
681  uint32_t originatorDsn,
682  uint32_t destinationSN,
683  uint32_t lifetime,
684  uint32_t interface)
685 {
686  IePrep prep;
687  prep.SetHopcount (0);
688  prep.SetTtl (m_maxTtl);
689  prep.SetDestinationAddress (dst);
690  prep.SetDestinationSeqNumber (destinationSN);
691  prep.SetLifetime (lifetime);
692  prep.SetMetric (initMetric);
693  prep.SetOriginatorAddress (src);
694  prep.SetOriginatorSeqNumber (originatorDsn);
695  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (interface);
696  NS_ASSERT (prep_sender != m_interfaces.end ());
697  prep_sender->second->SendPrep (prep, retransmitter);
699 }
700 bool
702 {
703  m_mp = mp;
704  std::vector<Ptr<NetDevice> > interfaces = mp->GetInterfaces ();
705  for (std::vector<Ptr<NetDevice> >::const_iterator i = interfaces.begin (); i != interfaces.end (); i++)
706  {
707  // Checking for compatible net device
708  Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice> ();
709  if (wifiNetDev == 0)
710  {
711  return false;
712  }
713  Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
714  if (mac == 0)
715  {
716  return false;
717  }
718  // Installing plugins:
719  Ptr<HwmpProtocolMac> hwmpMac = Create<HwmpProtocolMac> (wifiNetDev->GetIfIndex (), this);
720  m_interfaces[wifiNetDev->GetIfIndex ()] = hwmpMac;
721  mac->InstallPlugin (hwmpMac);
722  //Installing airtime link metric:
723  Ptr<AirtimeLinkMetricCalculator> metric = CreateObject <AirtimeLinkMetricCalculator> ();
724  mac->SetLinkMetricCallback (MakeCallback (&AirtimeLinkMetricCalculator::CalculateMetric, metric));
725  }
726  mp->SetRoutingProtocol (this);
727  // Mesh point aggregates all installed protocols
728  mp->AggregateObject (this);
729  m_address = Mac48Address::ConvertFrom (mp->GetAddress ()); // address;
730  return true;
731 }
732 void
733 HwmpProtocol::PeerLinkStatus (Mac48Address meshPointAddress, Mac48Address peerAddress, uint32_t interface, bool status)
734 {
735  if (status)
736  {
737  return;
738  }
739  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (peerAddress);
740  InitiatePathError (MakePathError (destinations));
741 }
742 void
743 HwmpProtocol::SetNeighboursCallback (Callback<std::vector<Mac48Address>, uint32_t> cb)
744 {
746 }
747 bool
749 {
750  if (source == GetAddress ())
751  {
752  return true;
753  }
754  std::map<Mac48Address, uint32_t,std::less<Mac48Address> >::const_iterator i = m_lastDataSeqno.find (source);
755  if (i == m_lastDataSeqno.end ())
756  {
757  m_lastDataSeqno[source] = seqno;
758  }
759  else
760  {
761  if ((int32_t)(i->second - seqno) >= 0)
762  {
763  return true;
764  }
765  m_lastDataSeqno[source] = seqno;
766  }
767  return false;
768 }
770 HwmpProtocol::MakePathError (std::vector<FailedDestination> destinations)
771 {
772  PathError retval;
773  //HwmpRtable increments a sequence number as written in 11B.9.7.2
774  retval.receivers = GetPerrReceivers (destinations);
775  if (retval.receivers.size () == 0)
776  {
777  return retval;
778  }
780  for (unsigned int i = 0; i < destinations.size (); i++)
781  {
782  retval.destinations.push_back (destinations[i]);
783  m_rtable->DeleteReactivePath (destinations[i].destination);
784  }
785  return retval;
786 }
787 void
789 {
790  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
791  {
792  std::vector<Mac48Address> receivers_for_interface;
793  for (unsigned int j = 0; j < perr.receivers.size (); j++)
794  {
795  if (i->first == perr.receivers[j].first)
796  {
797  receivers_for_interface.push_back (perr.receivers[j].second);
798  }
799  }
800  i->second->InitiatePerr (perr.destinations, receivers_for_interface);
801  }
802 }
803 void
805 {
806  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
807  {
808  std::vector<Mac48Address> receivers_for_interface;
809  for (unsigned int j = 0; j < perr.receivers.size (); j++)
810  {
811  if (i->first == perr.receivers[j].first)
812  {
813  receivers_for_interface.push_back (perr.receivers[j].second);
814  }
815  }
816  i->second->ForwardPerr (perr.destinations, receivers_for_interface);
817  }
818 }
819 
820 std::vector<std::pair<uint32_t, Mac48Address> >
821 HwmpProtocol::GetPerrReceivers (std::vector<FailedDestination> failedDest)
822 {
824  for (unsigned int i = 0; i < failedDest.size (); i++)
825  {
826  HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors (failedDest[i].destination);
827  m_rtable->DeleteReactivePath (failedDest[i].destination);
828  m_rtable->DeleteProactivePath (failedDest[i].destination);
829  for (unsigned int j = 0; j < precursors.size (); j++)
830  {
831  retval.push_back (precursors[j]);
832  }
833  }
834  //Check if we have dublicates in retval and precursors:
835  for (unsigned int i = 0; i < retval.size (); i++)
836  {
837  for (unsigned int j = i+1; j < retval.size (); j++)
838  {
839  if (retval[i].second == retval[j].second)
840  {
841  retval.erase (retval.begin () + j);
842  }
843  }
844  }
845  return retval;
846 }
847 std::vector<Mac48Address>
848 HwmpProtocol::GetPreqReceivers (uint32_t interface)
849 {
850  std::vector<Mac48Address> retval;
851  if (!m_neighboursCallback.IsNull ())
852  {
853  retval = m_neighboursCallback (interface);
854  }
855  if ((retval.size () >= m_unicastPreqThreshold) || (retval.size () == 0))
856  {
857  retval.clear ();
858  retval.push_back (Mac48Address::GetBroadcast ());
859  }
860  return retval;
861 }
862 std::vector<Mac48Address>
864 {
865  std::vector<Mac48Address> retval;
866  if (!m_neighboursCallback.IsNull ())
867  {
868  retval = m_neighboursCallback (interface);
869  }
870  if ((retval.size () >= m_unicastDataThreshold) || (retval.size () == 0))
871  {
872  retval.clear ();
873  retval.push_back (Mac48Address::GetBroadcast ());
874  }
875  return retval;
876 }
877 
878 bool
880 {
881  if (m_rqueue.size () > m_maxQueueSize)
882  {
883  return false;
884  }
885  m_rqueue.push_back (packet);
886  return true;
887 }
888 
891 {
892  QueuedPacket retval;
893  retval.pkt = 0;
894  for (std::vector<QueuedPacket>::iterator i = m_rqueue.begin (); i != m_rqueue.end (); i++)
895  {
896  if ((*i).dst == dst)
897  {
898  retval = (*i);
899  m_rqueue.erase (i);
900  break;
901  }
902  }
903  return retval;
904 }
905 
908 {
909  QueuedPacket retval;
910  retval.pkt = 0;
911  if (m_rqueue.size () != 0)
912  {
913  retval = m_rqueue[0];
914  m_rqueue.erase (m_rqueue.begin ());
915  }
916  return retval;
917 }
918 
919 void
921 {
922  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
923  if (i != m_preqTimeouts.end ())
924  {
925  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
926  }
927 
930  //Send all packets stored for this destination
931  QueuedPacket packet = DequeueFirstPacketByDst (dst);
932  while (packet.pkt != 0)
933  {
934  //set RA tag for retransmitter:
935  HwmpTag tag;
936  packet.pkt->RemovePacketTag (tag);
937  tag.SetAddress (result.retransmitter);
938  packet.pkt->AddPacketTag (tag);
939  m_stats.txUnicast++;
940  m_stats.txBytes += packet.pkt->GetSize ();
941  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
942 
943  packet = DequeueFirstPacketByDst (dst);
944  }
945 }
946 void
948 {
949  //send all packets to root
952  QueuedPacket packet = DequeueFirstPacket ();
953  while (packet.pkt != 0)
954  {
955  //set RA tag for retransmitter:
956  HwmpTag tag;
957  if (!packet.pkt->RemovePacketTag (tag))
958  {
959  NS_FATAL_ERROR ("HWMP tag must be present at this point");
960  }
961  tag.SetAddress (result.retransmitter);
962  packet.pkt->AddPacketTag (tag);
963  m_stats.txUnicast++;
964  m_stats.txBytes += packet.pkt->GetSize ();
965  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
966 
967  packet = DequeueFirstPacket ();
968  }
969 }
970 
971 bool
973 {
974  std::map<Mac48Address, PreqEvent>::const_iterator i = m_preqTimeouts.find (dst);
975  if (i == m_preqTimeouts.end ())
976  {
977  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
979  &HwmpProtocol::RetryPathDiscovery, this, dst, 1);
980  m_preqTimeouts[dst].whenScheduled = Simulator::Now ();
981  return true;
982  }
983  return false;
984 }
985 void
987 {
989  if (result.retransmitter == Mac48Address::GetBroadcast ())
990  {
991  result = m_rtable->LookupProactive ();
992  }
993  if (result.retransmitter != Mac48Address::GetBroadcast ())
994  {
995  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
996  NS_ASSERT (i != m_preqTimeouts.end ());
997  m_preqTimeouts.erase (i);
998  return;
999  }
1000  if (numOfRetry > m_dot11MeshHWMPmaxPREQretries)
1001  {
1002  QueuedPacket packet = DequeueFirstPacketByDst (dst);
1003  //purge queue and delete entry from retryDatabase
1004  while (packet.pkt != 0)
1005  {
1007  packet.reply (false, packet.pkt, packet.src, packet.dst, packet.protocol, HwmpRtable::MAX_METRIC);
1008  packet = DequeueFirstPacketByDst (dst);
1009  }
1010  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1011  NS_ASSERT (i != m_preqTimeouts.end ());
1012  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
1013  m_preqTimeouts.erase (i);
1014  return;
1015  }
1016  numOfRetry++;
1017  uint32_t originator_seqno = GetNextHwmpSeqno ();
1018  uint32_t dst_seqno = m_rtable->LookupReactiveExpired (dst).seqnum;
1019  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1020  {
1021  i->second->RequestDestination (dst, originator_seqno, dst_seqno);
1022  }
1023  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
1024  Time ((2 * (numOfRetry + 1)) * m_dot11MeshHWMPnetDiameterTraversalTime),
1025  &HwmpProtocol::RetryPathDiscovery, this, dst, numOfRetry);
1026 }
1027 //Proactive PREQ routines:
1028 void
1030 {
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:102
#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:1176
Definition: second.py:1
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)
Send Path Reply.
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:824
#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
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:792
LookupResult LookupReactiveExpired(Mac48Address destination)
Return all reactive paths, including expired.
Definition: hwmp-rtable.cc:159
Mac48Address GetDestinationAddress() const
bool Install(Ptr< MeshPointDevice >)
Install HWMP on given mesh point.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
void InitiatePathError(PathError perr)
Passes a self-generated PERR to interface-plugin.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
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:144
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)
Handler for receiving Path Reply.
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:446
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:341
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:846
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)
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1238
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:349
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:186
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:957
void DoDispose()
Destructor implementation.
Hybrid wireless mesh protocol – a routing protocol of IEEE 802.11s draft.
Definition: hwmp-protocol.h:47
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:210
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:1489
uint32_t GetOriginatorSeqNumber() const
void AddPrecursor(Mac48Address destination, uint32_t precursorInterface, Mac48Address precursorAddress, Time lifetime)
Definition: hwmp-rtable.cc:88
Ptr< HwmpRtable > m_rtable
Routing table.
void SetOriginatorAddress(Mac48Address originator_address)
void SetLifetime(uint32_t lifetime)
tuple mac
Definition: third.py:92
static TypeId GetTypeId()
LookupResult LookupProactiveExpired()
Return all proactive paths, including expired.
Definition: hwmp-rtable.cc:180
void ReceivePreq(IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
Handler for receiving Path Request.
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:59
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)
Get the next random value, as a double in 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:958
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:224
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:831
#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:895
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:531
void DeleteReactivePath(Mac48Address destination)
Definition: hwmp-rtable.cc:135
QueuedPacket DequeueFirstPacketByDst(Mac48Address dst)
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:911
void AddProactivePath(uint32_t metric, Mac48Address root, Mac48Address retransmitter, uint32_t interface, Time lifetime, uint32_t seqnum)
Definition: hwmp-rtable.cc:77
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:191
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:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904
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:170
void ReceivePerr(std::vector< FailedDestination >, Mac48Address from, uint32_t interface, Mac48Address fromMp)
Handler for receiving Path Error.
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.