A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 NS_LOG_COMPONENT_DEFINE ("HwmpProtocol");
40 
41 namespace ns3 {
42 namespace dot11s {
43 
44 NS_OBJECT_ENSURE_REGISTERED (HwmpProtocol);
45 
46 TypeId
48 {
49  static TypeId tid = TypeId ("ns3::dot11s::HwmpProtocol")
51  .AddConstructor<HwmpProtocol> ()
52  .AddAttribute ( "RandomStart",
53  "Random delay at first proactive PREQ",
54  TimeValue (Seconds (0.1)),
55  MakeTimeAccessor (
58  )
59  .AddAttribute ( "MaxQueueSize",
60  "Maximum number of packets we can store when resolving route",
61  UintegerValue (255),
62  MakeUintegerAccessor (
64  MakeUintegerChecker<uint16_t> (1)
65  )
66  .AddAttribute ( "Dot11MeshHWMPmaxPREQretries",
67  "Maximum number of retries before we suppose the destination to be unreachable",
68  UintegerValue (3),
69  MakeUintegerAccessor (
71  MakeUintegerChecker<uint8_t> (1)
72  )
73  .AddAttribute ( "Dot11MeshHWMPnetDiameterTraversalTime",
74  "Time we suppose the packet to go from one edge of the network to another",
75  TimeValue (MicroSeconds (1024*100)),
76  MakeTimeAccessor (
79  )
80  .AddAttribute ( "Dot11MeshHWMPpreqMinInterval",
81  "Minimal interval between to successive PREQs",
82  TimeValue (MicroSeconds (1024*100)),
83  MakeTimeAccessor (
86  )
87  .AddAttribute ( "Dot11MeshHWMPperrMinInterval",
88  "Minimal interval between to successive PREQs",
89  TimeValue (MicroSeconds (1024*100)),
92  )
93  .AddAttribute ( "Dot11MeshHWMPactiveRootTimeout",
94  "Lifetime of poractive routing information",
95  TimeValue (MicroSeconds (1024*5000)),
96  MakeTimeAccessor (
99  )
100  .AddAttribute ( "Dot11MeshHWMPactivePathTimeout",
101  "Lifetime of reactive routing information",
102  TimeValue (MicroSeconds (1024*5000)),
103  MakeTimeAccessor (
105  MakeTimeChecker ()
106  )
107  .AddAttribute ( "Dot11MeshHWMPpathToRootInterval",
108  "Interval between two successive proactive PREQs",
109  TimeValue (MicroSeconds (1024*2000)),
110  MakeTimeAccessor (
112  MakeTimeChecker ()
113  )
114  .AddAttribute ( "Dot11MeshHWMPrannInterval",
115  "Lifetime of poractive routing information",
116  TimeValue (MicroSeconds (1024*5000)),
117  MakeTimeAccessor (
119  MakeTimeChecker ()
120  )
121  .AddAttribute ( "MaxTtl",
122  "Initial value of Time To Live field",
123  UintegerValue (32),
124  MakeUintegerAccessor (
126  MakeUintegerChecker<uint8_t> (2)
127  )
128  .AddAttribute ( "UnicastPerrThreshold",
129  "Maximum number of PERR receivers, when we send a PERR as a chain of unicasts",
130  UintegerValue (32),
131  MakeUintegerAccessor (
133  MakeUintegerChecker<uint8_t> (1)
134  )
135  .AddAttribute ( "UnicastPreqThreshold",
136  "Maximum number of PREQ receivers, when we send a PREQ as a chain of unicasts",
137  UintegerValue (1),
138  MakeUintegerAccessor (
140  MakeUintegerChecker<uint8_t> (1)
141  )
142  .AddAttribute ( "UnicastDataThreshold",
143  "Maximum number ofbroadcast receivers, when we send a broadcast as a chain of unicasts",
144  UintegerValue (1),
145  MakeUintegerAccessor (
147  MakeUintegerChecker<uint8_t> (1)
148  )
149  .AddAttribute ( "DoFlag",
150  "Destination only HWMP flag",
151  BooleanValue (false),
152  MakeBooleanAccessor (
154  MakeBooleanChecker ()
155  )
156  .AddAttribute ( "RfFlag",
157  "Reply and forward flag",
158  BooleanValue (true),
159  MakeBooleanAccessor (
161  MakeBooleanChecker ()
162  )
163  .AddTraceSource ( "RouteDiscoveryTime",
164  "The time of route discovery procedure",
167  )
168  ;
169  return tid;
170 }
171 
173  m_dataSeqno (1),
174  m_hwmpSeqno (1),
175  m_preqId (0),
176  m_rtable (CreateObject<HwmpRtable> ()),
177  m_randomStart (Seconds (0.1)),
178  m_maxQueueSize (255),
179  m_dot11MeshHWMPmaxPREQretries (3),
180  m_dot11MeshHWMPnetDiameterTraversalTime (MicroSeconds (1024*100)),
181  m_dot11MeshHWMPpreqMinInterval (MicroSeconds (1024*100)),
182  m_dot11MeshHWMPperrMinInterval (MicroSeconds (1024*100)),
183  m_dot11MeshHWMPactiveRootTimeout (MicroSeconds (1024*5000)),
184  m_dot11MeshHWMPactivePathTimeout (MicroSeconds (1024*5000)),
185  m_dot11MeshHWMPpathToRootInterval (MicroSeconds (1024*2000)),
186  m_dot11MeshHWMPrannInterval (MicroSeconds (1024*5000)),
187  m_isRoot (false),
188  m_maxTtl (32),
189  m_unicastPerrThreshold (32),
190  m_unicastPreqThreshold (1),
191  m_unicastDataThreshold (1),
192  m_doFlag (false),
193  m_rfFlag (false)
194 {
196  m_coefficient = CreateObject<UniformRandomVariable> ();
197 }
198 
200 {
202 }
203 
204 void
206 {
208  if (m_isRoot)
209  {
210  SetRoot ();
211  }
212 }
213 
214 void
216 {
218  for (std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.begin (); i != m_preqTimeouts.end (); i++)
219  {
220  i->second.preqTimeout.Cancel ();
221  }
223  m_preqTimeouts.clear ();
224  m_lastDataSeqno.clear ();
225  m_hwmpSeqnoMetricDatabase.clear ();
226  m_interfaces.clear ();
227  m_rqueue.clear ();
228  m_rtable = 0;
229  m_mp = 0;
230 }
231 
232 bool
234  uint32_t sourceIface,
235  const Mac48Address source,
236  const Mac48Address destination,
237  Ptr<const Packet> constPacket,
238  uint16_t protocolType, //ethrnet 'Protocol' field
240  )
241 {
242  Ptr <Packet> packet = constPacket->Copy ();
243  HwmpTag tag;
244  if (sourceIface == GetMeshPoint ()->GetIfIndex ())
245  {
246  // packet from level 3
247  if (packet->PeekPacketTag (tag))
248  {
249  NS_FATAL_ERROR ("HWMP tag has come with a packet from upper layer. This must not occur...");
250  }
251  //Filling TAG:
252  if (destination == Mac48Address::GetBroadcast ())
253  {
254  tag.SetSeqno (m_dataSeqno++);
255  }
256  tag.SetTtl (m_maxTtl);
257  }
258  else
259  {
260  if (!packet->RemovePacketTag (tag))
261  {
262  NS_FATAL_ERROR ("HWMP tag is supposed to be here at this point.");
263  }
264  tag.DecrementTtl ();
265  if (tag.GetTtl () == 0)
266  {
268  return false;
269  }
270  }
271  if (destination == Mac48Address::GetBroadcast ())
272  {
274  m_stats.txBytes += packet->GetSize ();
275  //channel IDs where we have already sent broadcast:
276  std::vector<uint16_t> channels;
277  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
278  {
279  bool shouldSend = true;
280  for (std::vector<uint16_t>::const_iterator chan = channels.begin (); chan != channels.end (); chan++)
281  {
282  if ((*chan) == plugin->second->GetChannelId ())
283  {
284  shouldSend = false;
285  }
286  }
287  if (!shouldSend)
288  {
289  continue;
290  }
291  channels.push_back (plugin->second->GetChannelId ());
292  std::vector<Mac48Address> receivers = GetBroadcastReceivers (plugin->first);
293  for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i++)
294  {
295  Ptr<Packet> packetCopy = packet->Copy ();
296  //
297  // 64-bit Intel valgrind complains about tag.SetAddress (*i). It
298  // likes this just fine.
299  //
300  Mac48Address address = *i;
301  tag.SetAddress (address);
302  packetCopy->AddPacketTag (tag);
303  routeReply (true, packetCopy, source, destination, protocolType, plugin->first);
304  }
305  }
306  }
307  else
308  {
309  return ForwardUnicast (sourceIface, source, destination, packet, protocolType, routeReply, tag.GetTtl ());
310  }
311  return true;
312 }
313 bool
314 HwmpProtocol::RemoveRoutingStuff (uint32_t fromIface, const Mac48Address source,
315  const Mac48Address destination, Ptr<Packet> packet, uint16_t& protocolType)
316 {
317  HwmpTag tag;
318  if (!packet->RemovePacketTag (tag))
319  {
320  NS_FATAL_ERROR ("HWMP tag must exist when packet received from the network");
321  }
322  return true;
323 }
324 bool
325 HwmpProtocol::ForwardUnicast (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination,
326  Ptr<Packet> packet, uint16_t protocolType, RouteReplyCallback routeReply, uint32_t ttl)
327 {
328  NS_ASSERT (destination != Mac48Address::GetBroadcast ());
329  HwmpRtable::LookupResult result = m_rtable->LookupReactive (destination);
330  NS_LOG_DEBUG ("Requested src = "<<source<<", dst = "<<destination<<", I am "<<GetAddress ()<<", RA = "<<result.retransmitter);
331  if (result.retransmitter == Mac48Address::GetBroadcast ())
332  {
333  result = m_rtable->LookupProactive ();
334  }
335  HwmpTag tag;
336  tag.SetAddress (result.retransmitter);
337  tag.SetTtl (ttl);
338  //seqno and metric is not used;
339  packet->AddPacketTag (tag);
340  if (result.retransmitter != Mac48Address::GetBroadcast ())
341  {
342  //reply immediately:
343  routeReply (true, packet, source, destination, protocolType, result.ifIndex);
344  m_stats.txUnicast++;
345  m_stats.txBytes += packet->GetSize ();
346  return true;
347  }
348  if (sourceIface != GetMeshPoint ()->GetIfIndex ())
349  {
350  //Start path error procedure:
351  NS_LOG_DEBUG ("Must Send PERR");
352  result = m_rtable->LookupReactiveExpired (destination);
353  //1. Lookup expired reactive path. If exists - start path error
354  // procedure towards a next hop of this path
355  //2. If there was no reactive path, we lookup expired proactive
356  // path. If exist - start path error procedure towards path to
357  // root
358  if (result.retransmitter == Mac48Address::GetBroadcast ())
359  {
360  result = m_rtable->LookupProactiveExpired ();
361  }
362  if (result.retransmitter != Mac48Address::GetBroadcast ())
363  {
364  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (result.retransmitter);
365  InitiatePathError (MakePathError (destinations));
366  }
368  return false;
369  }
370  //Request a destination:
371  result = m_rtable->LookupReactiveExpired (destination);
372  if (ShouldSendPreq (destination))
373  {
374  uint32_t originator_seqno = GetNextHwmpSeqno ();
375  uint32_t dst_seqno = 0;
376  if (result.retransmitter != Mac48Address::GetBroadcast ())
377  {
378  dst_seqno = result.seqnum;
379  }
381  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
382  {
383  i->second->RequestDestination (destination, originator_seqno, dst_seqno);
384  }
385  }
386  QueuedPacket pkt;
387  pkt.pkt = packet;
388  pkt.dst = destination;
389  pkt.src = source;
390  pkt.protocol = protocolType;
391  pkt.reply = routeReply;
392  pkt.inInterface = sourceIface;
393  if (QueuePacket (pkt))
394  {
396  return true;
397  }
398  else
399  {
401  return false;
402  }
403 }
404 void
405 HwmpProtocol::ReceivePreq (IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
406 {
407  preq.IncrementMetric (metric);
408  //acceptance cretirea:
409  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
410  preq.GetOriginatorAddress ());
411  bool freshInfo (true);
412  if (i != m_hwmpSeqnoMetricDatabase.end ())
413  {
414  if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber ()) > 0)
415  {
416  return;
417  }
418  if (i->second.first == preq.GetOriginatorSeqNumber ())
419  {
420  freshInfo = false;
421  if (i->second.second <= preq.GetMetric ())
422  {
423  return;
424  }
425  }
426  }
428  std::make_pair (preq.GetOriginatorSeqNumber (), preq.GetMetric ());
429  NS_LOG_DEBUG ("I am " << GetAddress () << "Accepted preq from address" << from << ", preq:" << preq);
430  std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
431  //Add reactive path to originator:
432  if (
433  (freshInfo) ||
434  (
435  (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).retransmitter == Mac48Address::GetBroadcast ()) ||
436  (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).metric > preq.GetMetric ())
437  )
438  )
439  {
441  preq.GetOriginatorAddress (),
442  from,
443  interface,
444  preq.GetMetric (),
445  MicroSeconds (preq.GetLifetime () * 1024),
446  preq.GetOriginatorSeqNumber ()
447  );
449  }
450  if (
452  (m_rtable->LookupReactive (fromMp).metric > metric)
453  )
454  {
456  fromMp,
457  from,
458  interface,
459  metric,
460  MicroSeconds (preq.GetLifetime () * 1024),
461  preq.GetOriginatorSeqNumber ()
462  );
463  ReactivePathResolved (fromMp);
464  }
465  for (std::vector<Ptr<DestinationAddressUnit> >::const_iterator i = destinations.begin (); i != destinations.end (); i++)
466  {
467  if ((*i)->GetDestinationAddress () == Mac48Address::GetBroadcast ())
468  {
469  //only proactive PREQ contains destination
470  //address as broadcast! Proactive preq MUST
471  //have destination count equal to 1 and
472  //per destination flags DO and RF
473  NS_ASSERT (preq.GetDestCount () == 1);
474  NS_ASSERT (((*i)->IsDo ()) && ((*i)->IsRf ()));
475  //Add proactive path only if it is the better then existed
476  //before
477  if (
478  ((m_rtable->LookupProactive ()).retransmitter == Mac48Address::GetBroadcast ()) ||
479  ((m_rtable->LookupProactive ()).metric > preq.GetMetric ())
480  )
481  {
483  preq.GetMetric (),
484  preq.GetOriginatorAddress (),
485  from,
486  interface,
487  MicroSeconds (preq.GetLifetime () * 1024),
488  preq.GetOriginatorSeqNumber ()
489  );
491  }
492  if (!preq.IsNeedNotPrep ())
493  {
494  SendPrep (
495  GetAddress (),
496  preq.GetOriginatorAddress (),
497  from,
498  (uint32_t)0,
499  preq.GetOriginatorSeqNumber (),
500  GetNextHwmpSeqno (),
501  preq.GetLifetime (),
502  interface
503  );
504  }
505  break;
506  }
507  if ((*i)->GetDestinationAddress () == GetAddress ())
508  {
509  SendPrep (
510  GetAddress (),
511  preq.GetOriginatorAddress (),
512  from,
513  (uint32_t)0,
514  preq.GetOriginatorSeqNumber (),
515  GetNextHwmpSeqno (),
516  preq.GetLifetime (),
517  interface
518  );
520  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
521  continue;
522  }
523  //check if can answer:
524  HwmpRtable::LookupResult result = m_rtable->LookupReactive ((*i)->GetDestinationAddress ());
525  if ((!((*i)->IsDo ())) && (result.retransmitter != Mac48Address::GetBroadcast ()))
526  {
527  //have a valid information and can answer
528  uint32_t lifetime = result.lifetime.GetMicroSeconds () / 1024;
529  if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber ()) >= 0))
530  {
531  SendPrep (
532  (*i)->GetDestinationAddress (),
533  preq.GetOriginatorAddress (),
534  from,
535  result.metric,
536  preq.GetOriginatorSeqNumber (),
537  result.seqnum,
538  lifetime,
539  interface
540  );
541  m_rtable->AddPrecursor ((*i)->GetDestinationAddress (), interface, from,
542  MicroSeconds (preq.GetLifetime () * 1024));
543  if ((*i)->IsRf ())
544  {
545  (*i)->SetFlags (true, false, (*i)->IsUsn ()); //DO = 1, RF = 0
546  }
547  else
548  {
549  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
550  continue;
551  }
552  }
553  }
554  }
555  //check if must retransmit:
556  if (preq.GetDestCount () == 0)
557  {
558  return;
559  }
560  //Forward PREQ to all interfaces:
561  NS_LOG_DEBUG ("I am " << GetAddress () << "retransmitting PREQ:" << preq);
562  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
563  {
564  i->second->SendPreq (preq);
565  }
566 }
567 void
568 HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
569 {
570  prep.IncrementMetric (metric);
571  //acceptance cretirea:
572  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
573  prep.GetOriginatorAddress ());
574  bool freshInfo (true);
575  uint32_t sequence = prep.GetDestinationSeqNumber ();
576  if (i != m_hwmpSeqnoMetricDatabase.end ())
577  {
578  if ((int32_t)(i->second.first - sequence) > 0)
579  {
580  return;
581  }
582  if (i->second.first == sequence)
583  {
584  freshInfo = false;
585  }
586  }
587  m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (sequence, prep.GetMetric ());
588  //update routing info
589  //Now add a path to destination and add precursor to source
590  NS_LOG_DEBUG ("I am " << GetAddress () << ", received prep from " << prep.GetOriginatorAddress () << ", receiver was:" << from);
592  //Add a reactive path only if seqno is fresher or it improves the
593  //metric
594  if (
595  (freshInfo) ||
596  (
597  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).retransmitter == Mac48Address::GetBroadcast ()) ||
598  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).metric > prep.GetMetric ())
599  )
600  )
601  {
603  prep.GetOriginatorAddress (),
604  from,
605  interface,
606  prep.GetMetric (),
607  MicroSeconds (prep.GetLifetime () * 1024),
608  sequence);
609  m_rtable->AddPrecursor (prep.GetDestinationAddress (), interface, from,
610  MicroSeconds (prep.GetLifetime () * 1024));
611  if (result.retransmitter != Mac48Address::GetBroadcast ())
612  {
613  m_rtable->AddPrecursor (prep.GetOriginatorAddress (), interface, result.retransmitter,
614  result.lifetime);
615  }
617  }
618  if (
619  ((m_rtable->LookupReactive (fromMp)).retransmitter == Mac48Address::GetBroadcast ()) ||
620  ((m_rtable->LookupReactive (fromMp)).metric > metric)
621  )
622  {
624  fromMp,
625  from,
626  interface,
627  metric,
628  MicroSeconds (prep.GetLifetime () * 1024),
629  sequence);
630  ReactivePathResolved (fromMp);
631  }
632  if (prep.GetDestinationAddress () == GetAddress ())
633  {
634  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", resolved "<<prep.GetOriginatorAddress ());
635  return;
636  }
637  if (result.retransmitter == Mac48Address::GetBroadcast ())
638  {
639  return;
640  }
641  //Forward PREP
642  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (result.ifIndex);
643  NS_ASSERT (prep_sender != m_interfaces.end ());
644  prep_sender->second->SendPrep (prep, result.retransmitter);
645 }
646 void
647 HwmpProtocol::ReceivePerr (std::vector<FailedDestination> destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
648 {
649  //Acceptance cretirea:
650  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", received PERR from "<<from);
651  std::vector<FailedDestination> retval;
653  for (unsigned int i = 0; i < destinations.size (); i++)
654  {
655  result = m_rtable->LookupReactiveExpired (destinations[i].destination);
656  if (!(
657  (result.retransmitter != from) ||
658  (result.ifIndex != interface) ||
659  ((int32_t)(result.seqnum - destinations[i].seqnum) > 0)
660  ))
661  {
662  retval.push_back (destinations[i]);
663  }
664  }
665  if (retval.size () == 0)
666  {
667  return;
668  }
669  ForwardPathError (MakePathError (retval));
670 }
671 void
673  Mac48Address src,
674  Mac48Address dst,
675  Mac48Address retransmitter,
676  uint32_t initMetric,
677  uint32_t originatorDsn,
678  uint32_t destinationSN,
679  uint32_t lifetime,
680  uint32_t interface)
681 {
682  IePrep prep;
683  prep.SetHopcount (0);
684  prep.SetTtl (m_maxTtl);
685  prep.SetDestinationAddress (dst);
686  prep.SetDestinationSeqNumber (destinationSN);
687  prep.SetLifetime (lifetime);
688  prep.SetMetric (initMetric);
689  prep.SetOriginatorAddress (src);
690  prep.SetOriginatorSeqNumber (originatorDsn);
691  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (interface);
692  NS_ASSERT (prep_sender != m_interfaces.end ());
693  prep_sender->second->SendPrep (prep, retransmitter);
695 }
696 bool
698 {
699  m_mp = mp;
700  std::vector<Ptr<NetDevice> > interfaces = mp->GetInterfaces ();
701  for (std::vector<Ptr<NetDevice> >::const_iterator i = interfaces.begin (); i != interfaces.end (); i++)
702  {
703  // Checking for compatible net device
704  Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice> ();
705  if (wifiNetDev == 0)
706  {
707  return false;
708  }
709  Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
710  if (mac == 0)
711  {
712  return false;
713  }
714  // Installing plugins:
715  Ptr<HwmpProtocolMac> hwmpMac = Create<HwmpProtocolMac> (wifiNetDev->GetIfIndex (), this);
716  m_interfaces[wifiNetDev->GetIfIndex ()] = hwmpMac;
717  mac->InstallPlugin (hwmpMac);
718  //Installing airtime link metric:
719  Ptr<AirtimeLinkMetricCalculator> metric = CreateObject <AirtimeLinkMetricCalculator> ();
720  mac->SetLinkMetricCallback (MakeCallback (&AirtimeLinkMetricCalculator::CalculateMetric, metric));
721  }
722  mp->SetRoutingProtocol (this);
723  // Mesh point aggregates all installed protocols
724  mp->AggregateObject (this);
725  m_address = Mac48Address::ConvertFrom (mp->GetAddress ()); // address;
726  return true;
727 }
728 void
729 HwmpProtocol::PeerLinkStatus (Mac48Address meshPointAddress, Mac48Address peerAddress, uint32_t interface, bool status)
730 {
731  if (status)
732  {
733  return;
734  }
735  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (peerAddress);
736  InitiatePathError (MakePathError (destinations));
737 }
738 void
739 HwmpProtocol::SetNeighboursCallback (Callback<std::vector<Mac48Address>, uint32_t> cb)
740 {
742 }
743 bool
745 {
746  if (source == GetAddress ())
747  {
748  return true;
749  }
750  std::map<Mac48Address, uint32_t,std::less<Mac48Address> >::const_iterator i = m_lastDataSeqno.find (source);
751  if (i == m_lastDataSeqno.end ())
752  {
753  m_lastDataSeqno[source] = seqno;
754  }
755  else
756  {
757  if ((int32_t)(i->second - seqno) >= 0)
758  {
759  return true;
760  }
761  m_lastDataSeqno[source] = seqno;
762  }
763  return false;
764 }
766 HwmpProtocol::MakePathError (std::vector<FailedDestination> destinations)
767 {
768  PathError retval;
769  //HwmpRtable increments a sequence number as written in 11B.9.7.2
770  retval.receivers = GetPerrReceivers (destinations);
771  if (retval.receivers.size () == 0)
772  {
773  return retval;
774  }
776  for (unsigned int i = 0; i < destinations.size (); i++)
777  {
778  retval.destinations.push_back (destinations[i]);
779  m_rtable->DeleteReactivePath (destinations[i].destination);
780  }
781  return retval;
782 }
783 void
785 {
786  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
787  {
788  std::vector<Mac48Address> receivers_for_interface;
789  for (unsigned int j = 0; j < perr.receivers.size (); j++)
790  {
791  if (i->first == perr.receivers[j].first)
792  {
793  receivers_for_interface.push_back (perr.receivers[j].second);
794  }
795  }
796  i->second->InitiatePerr (perr.destinations, receivers_for_interface);
797  }
798 }
799 void
801 {
802  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
803  {
804  std::vector<Mac48Address> receivers_for_interface;
805  for (unsigned int j = 0; j < perr.receivers.size (); j++)
806  {
807  if (i->first == perr.receivers[j].first)
808  {
809  receivers_for_interface.push_back (perr.receivers[j].second);
810  }
811  }
812  i->second->ForwardPerr (perr.destinations, receivers_for_interface);
813  }
814 }
815 
816 std::vector<std::pair<uint32_t, Mac48Address> >
817 HwmpProtocol::GetPerrReceivers (std::vector<FailedDestination> failedDest)
818 {
820  for (unsigned int i = 0; i < failedDest.size (); i++)
821  {
822  HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors (failedDest[i].destination);
823  m_rtable->DeleteReactivePath (failedDest[i].destination);
824  m_rtable->DeleteProactivePath (failedDest[i].destination);
825  for (unsigned int j = 0; j < precursors.size (); j++)
826  {
827  retval.push_back (precursors[j]);
828  }
829  }
830  //Check if we have dublicates in retval and precursors:
831  for (unsigned int i = 0; i < retval.size (); i++)
832  {
833  for (unsigned int j = i+1; j < retval.size (); j++)
834  {
835  if (retval[i].second == retval[j].second)
836  {
837  retval.erase (retval.begin () + j);
838  }
839  }
840  }
841  return retval;
842 }
843 std::vector<Mac48Address>
844 HwmpProtocol::GetPreqReceivers (uint32_t interface)
845 {
846  std::vector<Mac48Address> retval;
847  if (!m_neighboursCallback.IsNull ())
848  {
849  retval = m_neighboursCallback (interface);
850  }
851  if ((retval.size () >= m_unicastPreqThreshold) || (retval.size () == 0))
852  {
853  retval.clear ();
854  retval.push_back (Mac48Address::GetBroadcast ());
855  }
856  return retval;
857 }
858 std::vector<Mac48Address>
860 {
861  std::vector<Mac48Address> retval;
862  if (!m_neighboursCallback.IsNull ())
863  {
864  retval = m_neighboursCallback (interface);
865  }
866  if ((retval.size () >= m_unicastDataThreshold) || (retval.size () == 0))
867  {
868  retval.clear ();
869  retval.push_back (Mac48Address::GetBroadcast ());
870  }
871  return retval;
872 }
873 
874 bool
876 {
877  if (m_rqueue.size () > m_maxQueueSize)
878  {
879  return false;
880  }
881  m_rqueue.push_back (packet);
882  return true;
883 }
884 
887 {
888  QueuedPacket retval;
889  retval.pkt = 0;
890  for (std::vector<QueuedPacket>::iterator i = m_rqueue.begin (); i != m_rqueue.end (); i++)
891  {
892  if ((*i).dst == dst)
893  {
894  retval = (*i);
895  m_rqueue.erase (i);
896  break;
897  }
898  }
899  return retval;
900 }
901 
904 {
905  QueuedPacket retval;
906  retval.pkt = 0;
907  if (m_rqueue.size () != 0)
908  {
909  retval = m_rqueue[0];
910  m_rqueue.erase (m_rqueue.begin ());
911  }
912  return retval;
913 }
914 
915 void
917 {
918  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
919  if (i != m_preqTimeouts.end ())
920  {
921  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
922  }
923 
926  //Send all packets stored for this destination
927  QueuedPacket packet = DequeueFirstPacketByDst (dst);
928  while (packet.pkt != 0)
929  {
930  //set RA tag for retransmitter:
931  HwmpTag tag;
932  packet.pkt->RemovePacketTag (tag);
933  tag.SetAddress (result.retransmitter);
934  packet.pkt->AddPacketTag (tag);
935  m_stats.txUnicast++;
936  m_stats.txBytes += packet.pkt->GetSize ();
937  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
938 
939  packet = DequeueFirstPacketByDst (dst);
940  }
941 }
942 void
944 {
945  //send all packets to root
948  QueuedPacket packet = DequeueFirstPacket ();
949  while (packet.pkt != 0)
950  {
951  //set RA tag for retransmitter:
952  HwmpTag tag;
953  if (!packet.pkt->RemovePacketTag (tag))
954  {
955  NS_FATAL_ERROR ("HWMP tag must be present at this point");
956  }
957  tag.SetAddress (result.retransmitter);
958  packet.pkt->AddPacketTag (tag);
959  m_stats.txUnicast++;
960  m_stats.txBytes += packet.pkt->GetSize ();
961  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
962 
963  packet = DequeueFirstPacket ();
964  }
965 }
966 
967 bool
969 {
970  std::map<Mac48Address, PreqEvent>::const_iterator i = m_preqTimeouts.find (dst);
971  if (i == m_preqTimeouts.end ())
972  {
973  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
975  &HwmpProtocol::RetryPathDiscovery, this, dst, 1);
976  m_preqTimeouts[dst].whenScheduled = Simulator::Now ();
977  return true;
978  }
979  return false;
980 }
981 void
983 {
985  if (result.retransmitter == Mac48Address::GetBroadcast ())
986  {
987  result = m_rtable->LookupProactive ();
988  }
989  if (result.retransmitter != Mac48Address::GetBroadcast ())
990  {
991  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
992  NS_ASSERT (i != m_preqTimeouts.end ());
993  m_preqTimeouts.erase (i);
994  return;
995  }
996  if (numOfRetry > m_dot11MeshHWMPmaxPREQretries)
997  {
998  QueuedPacket packet = DequeueFirstPacketByDst (dst);
999  //purge queue and delete entry from retryDatabase
1000  while (packet.pkt != 0)
1001  {
1003  packet.reply (false, packet.pkt, packet.src, packet.dst, packet.protocol, HwmpRtable::MAX_METRIC);
1004  packet = DequeueFirstPacketByDst (dst);
1005  }
1006  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1007  NS_ASSERT (i != m_preqTimeouts.end ());
1008  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
1009  m_preqTimeouts.erase (i);
1010  return;
1011  }
1012  numOfRetry++;
1013  uint32_t originator_seqno = GetNextHwmpSeqno ();
1014  uint32_t dst_seqno = m_rtable->LookupReactiveExpired (dst).seqnum;
1015  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1016  {
1017  i->second->RequestDestination (dst, originator_seqno, dst_seqno);
1018  }
1019  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
1020  Time ((2 * (numOfRetry + 1)) * m_dot11MeshHWMPnetDiameterTraversalTime),
1021  &HwmpProtocol::RetryPathDiscovery, this, dst, numOfRetry);
1022 }
1023 //Proactive PREQ routines:
1024 void
1026 {
1027  Time randomStart = Seconds (m_coefficient->GetValue ());
1029  NS_LOG_DEBUG ("ROOT IS: " << m_address);
1030  m_isRoot = true;
1031 }
1032 void
1034 {
1036 }
1037 void
1039 {
1040  IePreq preq;
1041  //By default: must answer
1042  preq.SetHopcount (0);
1043  preq.SetTTL (m_maxTtl);
1045  //\attention: do not forget to set originator address, sequence
1046  //number and preq ID in HWMP-MAC plugin
1048  preq.SetOriginatorAddress (GetAddress ());
1049  preq.SetPreqID (GetNextPreqId ());
1051  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1052  {
1053  i->second->SendPreq (preq);
1054  }
1056 }
1057 bool
1059 {
1060  return m_doFlag;
1061 }
1062 bool
1064 {
1065  return m_rfFlag;
1066 }
1067 Time
1069 {
1071 }
1072 Time
1074 {
1076 }
1077 uint8_t
1079 {
1080  return m_maxTtl;
1081 }
1082 uint32_t
1084 {
1085  m_preqId++;
1086  return m_preqId;
1087 }
1088 uint32_t
1090 {
1091  m_hwmpSeqno++;
1092  return m_hwmpSeqno;
1093 }
1094 uint32_t
1096 {
1098 }
1099 uint8_t
1101 {
1102  return m_unicastPerrThreshold;
1103 }
1106 {
1107  return m_address;
1108 }
1109 //Statistics:
1111  txUnicast (0),
1112  txBroadcast (0),
1113  txBytes (0),
1114  droppedTtl (0),
1115  totalQueued (0),
1116  totalDropped (0),
1117  initiatedPreq (0),
1118  initiatedPrep (0),
1119  initiatedPerr (0)
1120 {
1121 }
1122 void HwmpProtocol::Statistics::Print (std::ostream & os) const
1123 {
1124  os << "<Statistics "
1125  "txUnicast=\"" << txUnicast << "\" "
1126  "txBroadcast=\"" << txBroadcast << "\" "
1127  "txBytes=\"" << txBytes << "\" "
1128  "droppedTtl=\"" << droppedTtl << "\" "
1129  "totalQueued=\"" << totalQueued << "\" "
1130  "totalDropped=\"" << totalDropped << "\" "
1131  "initiatedPreq=\"" << initiatedPreq << "\" "
1132  "initiatedPrep=\"" << initiatedPrep << "\" "
1133  "initiatedPerr=\"" << initiatedPerr << "\"/>" << std::endl;
1134 }
1135 void
1136 HwmpProtocol::Report (std::ostream & os) const
1137 {
1138  os << "<Hwmp "
1139  "address=\"" << m_address << "\"" << std::endl <<
1140  "maxQueueSize=\"" << m_maxQueueSize << "\"" << std::endl <<
1141  "Dot11MeshHWMPmaxPREQretries=\"" << (uint16_t)m_dot11MeshHWMPmaxPREQretries << "\"" << std::endl <<
1142  "Dot11MeshHWMPnetDiameterTraversalTime=\"" << m_dot11MeshHWMPnetDiameterTraversalTime.GetSeconds () << "\"" << std::endl <<
1143  "Dot11MeshHWMPpreqMinInterval=\"" << m_dot11MeshHWMPpreqMinInterval.GetSeconds () << "\"" << std::endl <<
1144  "Dot11MeshHWMPperrMinInterval=\"" << m_dot11MeshHWMPperrMinInterval.GetSeconds () << "\"" << std::endl <<
1145  "Dot11MeshHWMPactiveRootTimeout=\"" << m_dot11MeshHWMPactiveRootTimeout.GetSeconds () << "\"" << std::endl <<
1146  "Dot11MeshHWMPactivePathTimeout=\"" << m_dot11MeshHWMPactivePathTimeout.GetSeconds () << "\"" << std::endl <<
1147  "Dot11MeshHWMPpathToRootInterval=\"" << m_dot11MeshHWMPpathToRootInterval.GetSeconds () << "\"" << std::endl <<
1148  "Dot11MeshHWMPrannInterval=\"" << m_dot11MeshHWMPrannInterval.GetSeconds () << "\"" << std::endl <<
1149  "isRoot=\"" << m_isRoot << "\"" << std::endl <<
1150  "maxTtl=\"" << (uint16_t)m_maxTtl << "\"" << std::endl <<
1151  "unicastPerrThreshold=\"" << (uint16_t)m_unicastPerrThreshold << "\"" << std::endl <<
1152  "unicastPreqThreshold=\"" << (uint16_t)m_unicastPreqThreshold << "\"" << std::endl <<
1153  "unicastDataThreshold=\"" << (uint16_t)m_unicastDataThreshold << "\"" << std::endl <<
1154  "doFlag=\"" << m_doFlag << "\"" << std::endl <<
1155  "rfFlag=\"" << m_rfFlag << "\">" << std::endl;
1156  m_stats.Print (os);
1157  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
1158  {
1159  plugin->second->Report (os);
1160  }
1161  os << "</Hwmp>" << std::endl;
1162 }
1163 void
1165 {
1166  m_stats = Statistics ();
1167  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
1168  {
1169  plugin->second->ResetStats ();
1170  }
1171 }
1172 
1173 int64_t
1175 {
1176  NS_LOG_FUNCTION (this << stream);
1177  m_coefficient->SetStream (stream);
1178  return 1;
1179 }
1180 
1182  pkt (0),
1183  protocol (0),
1184  inInterface (0)
1185 {
1186 }
1187 } // namespace dot11s
1188 } // 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:79
#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.
Hold a bool native type.
Definition: boolean.h:38
uint32_t GetDestinationSeqNumber() const
Callback template class.
Definition: callback.h:924
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 the class in the ns-3 factory.
Definition: object-base.h:38
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 ...
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:841
#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:170
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:744
LookupResult LookupReactiveExpired(Mac48Address destination)
Return all reactive paths, including expired.
Definition: hwmp-rtable.cc:157
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:95
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:825
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:142
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 ...
void SendProactivePreq()
Proactive Preq routines:
bool DropDataFrame(uint32_t seqno, Mac48Address source)
MAC-plugin asks whether the frame can be dropped.
QueuedPacket DequeueFirstPacket()
Ptr< T > CreateObject(void)
Definition: object.h:421
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
Definition: nstime.h:272
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:863
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
Definition: nstime.h:289
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:184
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)
hold objects of type ns3::Time
Definition: nstime.h:1008
void DoDispose()
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
See 7.3.2.96 of 802.11s draft 2.07.
Hold an unsigned integer type.
Definition: uinteger.h:46
PrecursorList GetPrecursors(Mac48Address destination)
Definition: hwmp-rtable.cc:208
tuple interfaces
Definition: first.py:40
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:1242
uint32_t GetOriginatorSeqNumber() const
void AddPrecursor(Mac48Address destination, uint32_t precursorInterface, Mac48Address precursorAddress, Time lifetime)
Definition: hwmp-rtable.cc:86
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:178
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)
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:57
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
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:41
uint8_t GetDestCount() const
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
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:848
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
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:47
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< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:441
void DeleteReactivePath(Mac48Address destination)
Definition: hwmp-rtable.cc:133
QueuedPacket DequeueFirstPacketByDst(Mac48Address dst)
void AddProactivePath(uint32_t metric, Mac48Address root, Mac48Address retransmitter, uint32_t interface, Time lifetime, uint32_t seqnum)
Definition: hwmp-rtable.cc:75
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.
Hold a floating point type.
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)
Definition: object-base.cc:176
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
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:168
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()
This method is called only once by Object::Initialize.