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