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  .AddTraceSource ("RouteChange",
172  "Routing table changed",
174  "ns3::HwmpProtocol::RouteChangeTracedCallback"
175  )
176  ;
177  return tid;
178 }
179 
181  m_dataSeqno (1),
182  m_hwmpSeqno (1),
183  m_preqId (0),
184  m_rtable (CreateObject<HwmpRtable> ()),
185  m_randomStart (Seconds (0.1)),
186  m_maxQueueSize (255),
187  m_dot11MeshHWMPmaxPREQretries (3),
188  m_dot11MeshHWMPnetDiameterTraversalTime (MicroSeconds (1024*100)),
189  m_dot11MeshHWMPpreqMinInterval (MicroSeconds (1024*100)),
190  m_dot11MeshHWMPperrMinInterval (MicroSeconds (1024*100)),
191  m_dot11MeshHWMPactiveRootTimeout (MicroSeconds (1024*5000)),
192  m_dot11MeshHWMPactivePathTimeout (MicroSeconds (1024*5000)),
193  m_dot11MeshHWMPpathToRootInterval (MicroSeconds (1024*2000)),
194  m_dot11MeshHWMPrannInterval (MicroSeconds (1024*5000)),
195  m_isRoot (false),
196  m_maxTtl (32),
197  m_unicastPerrThreshold (32),
198  m_unicastPreqThreshold (1),
199  m_unicastDataThreshold (1),
200  m_doFlag (false),
201  m_rfFlag (false)
202 {
203  NS_LOG_FUNCTION (this);
204  m_coefficient = CreateObject<UniformRandomVariable> ();
205 }
206 
208 {
209  NS_LOG_FUNCTION (this);
210 }
211 
212 void
214 {
215  NS_LOG_FUNCTION (this);
217  if (m_isRoot)
218  {
219  Time randomStart = Seconds (m_coefficient->GetValue ());
221  }
222 }
223 
224 void
226 {
227  NS_LOG_FUNCTION (this);
228  for (std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.begin (); i != m_preqTimeouts.end (); i++)
229  {
230  i->second.preqTimeout.Cancel ();
231  }
233  m_preqTimeouts.clear ();
234  m_lastDataSeqno.clear ();
235  m_hwmpSeqnoMetricDatabase.clear ();
236  m_interfaces.clear ();
237  m_rqueue.clear ();
238  m_rtable = 0;
239  m_mp = 0;
240 }
241 
242 bool
244  uint32_t sourceIface,
245  const Mac48Address source,
246  const Mac48Address destination,
247  Ptr<const Packet> constPacket,
248  uint16_t protocolType, //ethrnet 'Protocol' field
250  )
251 {
252  NS_LOG_FUNCTION (this << sourceIface << source << destination << constPacket << protocolType);
253  Ptr <Packet> packet = constPacket->Copy ();
254  HwmpTag tag;
255  if (sourceIface == GetMeshPoint ()->GetIfIndex ())
256  {
257  // packet from level 3
258  if (packet->PeekPacketTag (tag))
259  {
260  NS_FATAL_ERROR ("HWMP tag has come with a packet from upper layer. This must not occur...");
261  }
262  //Filling TAG:
263  if (destination == Mac48Address::GetBroadcast ())
264  {
265  tag.SetSeqno (m_dataSeqno++);
266  }
267  tag.SetTtl (m_maxTtl);
268  }
269  else
270  {
271  if (!packet->RemovePacketTag (tag))
272  {
273  NS_FATAL_ERROR ("HWMP tag is supposed to be here at this point.");
274  }
275  tag.DecrementTtl ();
276  if (tag.GetTtl () == 0)
277  {
279  return false;
280  }
281  }
282  if (destination == Mac48Address::GetBroadcast ())
283  {
285  m_stats.txBytes += packet->GetSize ();
286  //channel IDs where we have already sent broadcast:
287  std::vector<uint16_t> channels;
288  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
289  {
290  bool shouldSend = true;
291  for (std::vector<uint16_t>::const_iterator chan = channels.begin (); chan != channels.end (); chan++)
292  {
293  if ((*chan) == plugin->second->GetChannelId ())
294  {
295  shouldSend = false;
296  }
297  }
298  if (!shouldSend)
299  {
300  continue;
301  }
302  channels.push_back (plugin->second->GetChannelId ());
303  std::vector<Mac48Address> receivers = GetBroadcastReceivers (plugin->first);
304  for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i++)
305  {
306  Ptr<Packet> packetCopy = packet->Copy ();
307  //
308  // 64-bit Intel valgrind complains about tag.SetAddress (*i). It
309  // likes this just fine.
310  //
311  Mac48Address address = *i;
312  tag.SetAddress (address);
313  packetCopy->AddPacketTag (tag);
314  routeReply (true, packetCopy, source, destination, protocolType, plugin->first);
315  }
316  }
317  }
318  else
319  {
320  return ForwardUnicast (sourceIface, source, destination, packet, protocolType, routeReply, tag.GetTtl ());
321  }
322  return true;
323 }
324 bool
325 HwmpProtocol::RemoveRoutingStuff (uint32_t fromIface, const Mac48Address source,
326  const Mac48Address destination, Ptr<Packet> packet, uint16_t& protocolType)
327 {
328  HwmpTag tag;
329  if (!packet->RemovePacketTag (tag))
330  {
331  NS_FATAL_ERROR ("HWMP tag must exist when packet received from the network");
332  }
333  return true;
334 }
335 bool
336 HwmpProtocol::ForwardUnicast (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination,
337  Ptr<Packet> packet, uint16_t protocolType, RouteReplyCallback routeReply, uint32_t ttl)
338 {
339  NS_LOG_FUNCTION (this << sourceIface << source << destination << packet << protocolType << ttl);
340  NS_ASSERT (destination != Mac48Address::GetBroadcast ());
341  HwmpRtable::LookupResult result = m_rtable->LookupReactive (destination);
342  NS_LOG_DEBUG ("Requested src = "<<source<<", dst = "<<destination<<", I am "<<GetAddress ()<<", RA = "<<result.retransmitter);
343  if (result.retransmitter == Mac48Address::GetBroadcast ())
344  {
345  result = m_rtable->LookupProactive ();
346  }
347  HwmpTag tag;
348  tag.SetAddress (result.retransmitter);
349  tag.SetTtl (ttl);
350  //seqno and metric is not used;
351  packet->AddPacketTag (tag);
352  if (result.retransmitter != Mac48Address::GetBroadcast ())
353  {
354  //reply immediately:
355  routeReply (true, packet, source, destination, protocolType, result.ifIndex);
356  m_stats.txUnicast++;
357  m_stats.txBytes += packet->GetSize ();
358  return true;
359  }
360  if (sourceIface != GetMeshPoint ()->GetIfIndex ())
361  {
362  //Start path error procedure:
363  NS_LOG_DEBUG ("Must Send PERR");
364  result = m_rtable->LookupReactiveExpired (destination);
365  NS_LOG_DEBUG ("Path error " << result.retransmitter);
366  //1. Lookup expired reactive path. If exists - start path error
367  // procedure towards a next hop of this path
368  //2. If there was no reactive path, we lookup expired proactive
369  // path. If exist - start path error procedure towards path to
370  // root
371  if (result.retransmitter == Mac48Address::GetBroadcast ())
372  {
373  NS_LOG_DEBUG ("Path error, lookup expired proactive path");
374  result = m_rtable->LookupProactiveExpired ();
375  }
376  if (result.retransmitter != Mac48Address::GetBroadcast ())
377  {
378  NS_LOG_DEBUG ("Path error, initiate reactive path error");
379  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (result.retransmitter);
380  InitiatePathError (MakePathError (destinations));
381  }
383  return false;
384  }
385  //Request a destination:
386  result = m_rtable->LookupReactiveExpired (destination);
387  if (ShouldSendPreq (destination))
388  {
389  uint32_t originator_seqno = GetNextHwmpSeqno ();
390  uint32_t dst_seqno = 0;
391  if (result.retransmitter != Mac48Address::GetBroadcast ())
392  {
393  dst_seqno = result.seqnum;
394  }
396  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
397  {
398  i->second->RequestDestination (destination, originator_seqno, dst_seqno);
399  }
400  }
401  QueuedPacket pkt;
402  pkt.pkt = packet;
403  pkt.dst = destination;
404  pkt.src = source;
405  pkt.protocol = protocolType;
406  pkt.reply = routeReply;
407  pkt.inInterface = sourceIface;
408  if (QueuePacket (pkt))
409  {
411  return true;
412  }
413  else
414  {
416  NS_LOG_DEBUG ("Dropping packet from " << source << " to " << destination << " due to queue overflow");
417  return false;
418  }
419 }
420 void
421 HwmpProtocol::ReceivePreq (IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
422 {
423  NS_LOG_FUNCTION (this << from << interface << fromMp << metric);
424  preq.IncrementMetric (metric);
425  //acceptance cretirea:
426  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
427  preq.GetOriginatorAddress ());
428  bool freshInfo (true);
429  if (i != m_hwmpSeqnoMetricDatabase.end ())
430  {
431  if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber ()) > 0)
432  {
433  return;
434  }
435  if (i->second.first == preq.GetOriginatorSeqNumber ())
436  {
437  freshInfo = false;
438  if (i->second.second <= preq.GetMetric ())
439  {
440  return;
441  }
442  }
443  }
445  std::make_pair (preq.GetOriginatorSeqNumber (), preq.GetMetric ());
446  NS_LOG_DEBUG ("I am " << GetAddress () << ", Accepted preq from address" << from << ", preq:" << preq);
447  std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
448  //Add reactive path to originator:
449  if (
450  (freshInfo) ||
451  (
452  (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).retransmitter == Mac48Address::GetBroadcast ()) ||
453  (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).metric > preq.GetMetric ())
454  )
455  )
456  {
458  preq.GetOriginatorAddress (),
459  from,
460  interface,
461  preq.GetMetric (),
462  MicroSeconds (preq.GetLifetime () * 1024),
463  preq.GetOriginatorSeqNumber ()
464  );
465  // Notify trace source of routing change
466  struct RouteChange rChange;
467  rChange.type = "Add Reactive";
468  rChange.destination = preq.GetOriginatorAddress ();
469  rChange.retransmitter = from;
470  rChange.interface = interface;
471  rChange.metric = preq.GetMetric ();
472  rChange.lifetime = MicroSeconds (preq.GetLifetime () * 1024);
473  rChange.seqnum = preq.GetOriginatorSeqNumber ();
474  m_routeChangeTraceSource (rChange);
476  }
477  if (
479  (m_rtable->LookupReactive (fromMp).metric > metric)
480  )
481  {
483  fromMp,
484  from,
485  interface,
486  metric,
487  MicroSeconds (preq.GetLifetime () * 1024),
488  preq.GetOriginatorSeqNumber ()
489  );
490  // Notify trace source of routing change
491  struct RouteChange rChange;
492  rChange.type = "Add Reactive";
493  rChange.destination = fromMp;
494  rChange.retransmitter = from;
495  rChange.interface = interface;
496  rChange.metric = metric;
497  rChange.lifetime = MicroSeconds (preq.GetLifetime () * 1024);
498  rChange.seqnum = preq.GetOriginatorSeqNumber ();
499  m_routeChangeTraceSource (rChange);
500  ReactivePathResolved (fromMp);
501  }
502  for (std::vector<Ptr<DestinationAddressUnit> >::const_iterator i = destinations.begin (); i != destinations.end (); i++)
503  {
504  if ((*i)->GetDestinationAddress () == Mac48Address::GetBroadcast ())
505  {
506  //only proactive PREQ contains destination
507  //address as broadcast! Proactive preq MUST
508  //have destination count equal to 1 and
509  //per destination flags DO and RF
510  NS_ASSERT (preq.GetDestCount () == 1);
511  NS_ASSERT (((*i)->IsDo ()) && ((*i)->IsRf ()));
512  //Add proactive path only if it is the better then existed
513  //before
514  if (
515  ((m_rtable->LookupProactive ()).retransmitter == Mac48Address::GetBroadcast ()) ||
516  ((m_rtable->LookupProactive ()).metric > preq.GetMetric ())
517  )
518  {
520  preq.GetMetric (),
521  preq.GetOriginatorAddress (),
522  from,
523  interface,
524  MicroSeconds (preq.GetLifetime () * 1024),
525  preq.GetOriginatorSeqNumber ()
526  );
527  // Notify trace source of routing change
528  struct RouteChange rChange;
529  rChange.type = "Add Proactive";
530  rChange.destination = preq.GetOriginatorAddress ();
531  rChange.retransmitter = from;
532  rChange.interface = interface;
533  rChange.metric = preq.GetMetric ();
534  rChange.lifetime = MicroSeconds (preq.GetLifetime () * 1024);
535  rChange.seqnum = preq.GetOriginatorSeqNumber ();
536  m_routeChangeTraceSource (rChange);
538  }
539  if (!preq.IsNeedNotPrep ())
540  {
541  SendPrep (
542  GetAddress (),
543  preq.GetOriginatorAddress (),
544  from,
545  (uint32_t)0,
546  preq.GetOriginatorSeqNumber (),
547  GetNextHwmpSeqno (),
548  preq.GetLifetime (),
549  interface
550  );
551  }
552  break;
553  }
554  if ((*i)->GetDestinationAddress () == GetAddress ())
555  {
556  SendPrep (
557  GetAddress (),
558  preq.GetOriginatorAddress (),
559  from,
560  (uint32_t)0,
561  preq.GetOriginatorSeqNumber (),
562  GetNextHwmpSeqno (),
563  preq.GetLifetime (),
564  interface
565  );
567  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
568  continue;
569  }
570  //check if can answer:
571  HwmpRtable::LookupResult result = m_rtable->LookupReactive ((*i)->GetDestinationAddress ());
572  if ((!((*i)->IsDo ())) && (result.retransmitter != Mac48Address::GetBroadcast ()))
573  {
574  //have a valid information and can answer
575  uint32_t lifetime = result.lifetime.GetMicroSeconds () / 1024;
576  if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber ()) >= 0))
577  {
578  SendPrep (
579  (*i)->GetDestinationAddress (),
580  preq.GetOriginatorAddress (),
581  from,
582  result.metric,
583  preq.GetOriginatorSeqNumber (),
584  result.seqnum,
585  lifetime,
586  interface
587  );
588  m_rtable->AddPrecursor ((*i)->GetDestinationAddress (), interface, from,
589  MicroSeconds (preq.GetLifetime () * 1024));
590  if ((*i)->IsRf ())
591  {
592  (*i)->SetFlags (true, false, (*i)->IsUsn ()); //DO = 1, RF = 0
593  }
594  else
595  {
596  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
597  continue;
598  }
599  }
600  }
601  }
602  //check if must retransmit:
603  if (preq.GetDestCount () == 0)
604  {
605  return;
606  }
607  //Forward PREQ to all interfaces:
608  NS_LOG_DEBUG ("I am " << GetAddress () << "retransmitting PREQ:" << preq);
609  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
610  {
611  i->second->SendPreq (preq);
612  }
613 }
614 void
615 HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
616 {
617  NS_LOG_FUNCTION (this << from << interface << fromMp << metric);
618  prep.IncrementMetric (metric);
619  //acceptance cretirea:
620  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
621  prep.GetOriginatorAddress ());
622  bool freshInfo (true);
623  uint32_t sequence = prep.GetDestinationSeqNumber ();
624  if (i != m_hwmpSeqnoMetricDatabase.end ())
625  {
626  if ((int32_t)(i->second.first - sequence) > 0)
627  {
628  return;
629  }
630  if (i->second.first == sequence)
631  {
632  freshInfo = false;
633  }
634  }
635  m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (sequence, prep.GetMetric ());
636  //update routing info
637  //Now add a path to destination and add precursor to source
638  NS_LOG_DEBUG ("I am " << GetAddress () << ", received prep from " << prep.GetOriginatorAddress () << ", receiver was:" << from);
640  //Add a reactive path only if seqno is fresher or it improves the
641  //metric
642  if (
643  (freshInfo) ||
644  (
645  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).retransmitter == Mac48Address::GetBroadcast ()) ||
646  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).metric > prep.GetMetric ())
647  )
648  )
649  {
651  prep.GetOriginatorAddress (),
652  from,
653  interface,
654  prep.GetMetric (),
655  MicroSeconds (prep.GetLifetime () * 1024),
656  sequence);
657  // Notify trace source of routing change
658  struct RouteChange rChange;
659  rChange.type = "Add Reactive";
660  rChange.destination = prep.GetOriginatorAddress ();
661  rChange.retransmitter = from;
662  rChange.interface = interface;
663  rChange.metric = prep.GetMetric ();
664  rChange.lifetime = MicroSeconds (prep.GetLifetime () * 1024);
665  rChange.seqnum = sequence;
666  m_routeChangeTraceSource (rChange);
667  m_rtable->AddPrecursor (prep.GetDestinationAddress (), interface, from,
668  MicroSeconds (prep.GetLifetime () * 1024));
669  if (result.retransmitter != Mac48Address::GetBroadcast ())
670  {
671  m_rtable->AddPrecursor (prep.GetOriginatorAddress (), interface, result.retransmitter,
672  result.lifetime);
673  }
675  }
676  if (
677  ((m_rtable->LookupReactive (fromMp)).retransmitter == Mac48Address::GetBroadcast ()) ||
678  ((m_rtable->LookupReactive (fromMp)).metric > metric)
679  )
680  {
682  fromMp,
683  from,
684  interface,
685  metric,
686  MicroSeconds (prep.GetLifetime () * 1024),
687  sequence);
688  // Notify trace source of routing change
689  struct RouteChange rChange;
690  rChange.type = "Add Reactive";
691  rChange.destination = fromMp;
692  rChange.retransmitter = from;
693  rChange.interface = interface;
694  rChange.metric = metric;
695  rChange.lifetime = MicroSeconds (prep.GetLifetime () * 1024);
696  rChange.seqnum = sequence;
697  m_routeChangeTraceSource (rChange);
698  ReactivePathResolved (fromMp);
699  }
700  if (prep.GetDestinationAddress () == GetAddress ())
701  {
702  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", resolved "<<prep.GetOriginatorAddress ());
703  return;
704  }
705  if (result.retransmitter == Mac48Address::GetBroadcast ())
706  {
707  return;
708  }
709  //Forward PREP
710  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (result.ifIndex);
711  NS_ASSERT (prep_sender != m_interfaces.end ());
712  prep_sender->second->SendPrep (prep, result.retransmitter);
713 }
714 void
715 HwmpProtocol::ReceivePerr (std::vector<FailedDestination> destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
716 {
717  NS_LOG_FUNCTION (this << from << interface << fromMp);
718  //Acceptance cretirea:
719  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", received PERR from "<<from);
720  std::vector<FailedDestination> retval;
722  for (unsigned int i = 0; i < destinations.size (); i++)
723  {
724  result = m_rtable->LookupReactiveExpired (destinations[i].destination);
725  if (!(
726  (result.retransmitter != from) ||
727  (result.ifIndex != interface) ||
728  ((int32_t)(result.seqnum - destinations[i].seqnum) > 0)
729  ))
730  {
731  retval.push_back (destinations[i]);
732  }
733  }
734  if (retval.size () == 0)
735  {
736  return;
737  }
738  ForwardPathError (MakePathError (retval));
739 }
740 void
742  Mac48Address src,
743  Mac48Address dst,
744  Mac48Address retransmitter,
745  uint32_t initMetric,
746  uint32_t originatorDsn,
747  uint32_t destinationSN,
748  uint32_t lifetime,
749  uint32_t interface)
750 {
751  IePrep prep;
752  prep.SetHopcount (0);
753  prep.SetTtl (m_maxTtl);
754  prep.SetDestinationAddress (dst);
755  prep.SetDestinationSeqNumber (destinationSN);
756  prep.SetLifetime (lifetime);
757  prep.SetMetric (initMetric);
758  prep.SetOriginatorAddress (src);
759  prep.SetOriginatorSeqNumber (originatorDsn);
760  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (interface);
761  NS_ASSERT (prep_sender != m_interfaces.end ());
762  prep_sender->second->SendPrep (prep, retransmitter);
764 }
765 bool
767 {
768  NS_LOG_FUNCTION (this << mp);
769  m_mp = mp;
770  std::vector<Ptr<NetDevice> > interfaces = mp->GetInterfaces ();
771  for (std::vector<Ptr<NetDevice> >::const_iterator i = interfaces.begin (); i != interfaces.end (); i++)
772  {
773  // Checking for compatible net device
774  Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice> ();
775  if (wifiNetDev == 0)
776  {
777  return false;
778  }
779  Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
780  if (mac == 0)
781  {
782  return false;
783  }
784  // Installing plugins:
785  Ptr<HwmpProtocolMac> hwmpMac = Create<HwmpProtocolMac> (wifiNetDev->GetIfIndex (), this);
786  m_interfaces[wifiNetDev->GetIfIndex ()] = hwmpMac;
787  mac->InstallPlugin (hwmpMac);
788  //Installing airtime link metric:
789  Ptr<AirtimeLinkMetricCalculator> metric = CreateObject <AirtimeLinkMetricCalculator> ();
790  mac->SetLinkMetricCallback (MakeCallback (&AirtimeLinkMetricCalculator::CalculateMetric, metric));
791  }
792  mp->SetRoutingProtocol (this);
793  // Mesh point aggregates all installed protocols
794  mp->AggregateObject (this);
795  m_address = Mac48Address::ConvertFrom (mp->GetAddress ()); // address;
796  return true;
797 }
798 void
799 HwmpProtocol::PeerLinkStatus (Mac48Address meshPointAddress, Mac48Address peerAddress, uint32_t interface, bool status)
800 {
801  NS_LOG_FUNCTION (this << meshPointAddress << peerAddress << interface << status);
802  if (status)
803  {
804  return;
805  }
806  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (peerAddress);
807  NS_LOG_DEBUG (destinations.size () << " failed destinations for peer address " << peerAddress);
808  InitiatePathError (MakePathError (destinations));
809 }
810 void
811 HwmpProtocol::SetNeighboursCallback (Callback<std::vector<Mac48Address>, uint32_t> cb)
812 {
814 }
815 bool
817 {
818  NS_LOG_FUNCTION (this << seqno << source);
819  if (source == GetAddress ())
820  {
821  return true;
822  }
823  std::map<Mac48Address, uint32_t,std::less<Mac48Address> >::const_iterator i = m_lastDataSeqno.find (source);
824  if (i == m_lastDataSeqno.end ())
825  {
826  m_lastDataSeqno[source] = seqno;
827  }
828  else
829  {
830  if ((int32_t)(i->second - seqno) >= 0)
831  {
832  return true;
833  }
834  m_lastDataSeqno[source] = seqno;
835  }
836  return false;
837 }
839 HwmpProtocol::MakePathError (std::vector<FailedDestination> destinations)
840 {
841  NS_LOG_FUNCTION (this);
842  PathError retval;
843  //HwmpRtable increments a sequence number as written in 11B.9.7.2
844  retval.receivers = GetPerrReceivers (destinations);
845  if (retval.receivers.size () == 0)
846  {
847  return retval;
848  }
850  for (unsigned int i = 0; i < destinations.size (); i++)
851  {
852  retval.destinations.push_back (destinations[i]);
853  m_rtable->DeleteReactivePath (destinations[i].destination);
854  // Notify trace source of routing change
855  struct RouteChange rChange;
856  rChange.type = "Delete Reactive";
857  rChange.destination = destinations[i].destination;
858  rChange.seqnum = destinations[i].seqnum;
859  m_routeChangeTraceSource (rChange);
860  }
861  return retval;
862 }
863 void
865 {
866  NS_LOG_FUNCTION (this);
867  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
868  {
869  std::vector<Mac48Address> receivers_for_interface;
870  for (unsigned int j = 0; j < perr.receivers.size (); j++)
871  {
872  if (i->first == perr.receivers[j].first)
873  {
874  receivers_for_interface.push_back (perr.receivers[j].second);
875  }
876  }
877  i->second->InitiatePerr (perr.destinations, receivers_for_interface);
878  }
879 }
880 void
882 {
883  NS_LOG_FUNCTION (this);
884  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
885  {
886  std::vector<Mac48Address> receivers_for_interface;
887  for (unsigned int j = 0; j < perr.receivers.size (); j++)
888  {
889  if (i->first == perr.receivers[j].first)
890  {
891  receivers_for_interface.push_back (perr.receivers[j].second);
892  }
893  }
894  i->second->ForwardPerr (perr.destinations, receivers_for_interface);
895  }
896 }
897 
898 std::vector<std::pair<uint32_t, Mac48Address> >
899 HwmpProtocol::GetPerrReceivers (std::vector<FailedDestination> failedDest)
900 {
901  NS_LOG_FUNCTION (this);
903  for (unsigned int i = 0; i < failedDest.size (); i++)
904  {
905  HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors (failedDest[i].destination);
906  m_rtable->DeleteReactivePath (failedDest[i].destination);
907  // Notify trace source of routing change
908  struct RouteChange rChange;
909  rChange.type = "Delete Reactive";
910  rChange.destination = failedDest[i].destination;
911  rChange.seqnum = failedDest[i].seqnum;
912  m_routeChangeTraceSource (rChange);
913  m_rtable->DeleteProactivePath (failedDest[i].destination);
914  // Notify trace source of routing change
915  struct RouteChange rChangePro;
916  rChangePro.type = "Delete Proactive";
917  rChangePro.destination = failedDest[i].destination;
918  rChangePro.seqnum = failedDest[i].seqnum;
919  m_routeChangeTraceSource (rChangePro);
920  for (unsigned int j = 0; j < precursors.size (); j++)
921  {
922  retval.push_back (precursors[j]);
923  }
924  }
925  //Check if we have dublicates in retval and precursors:
926  for (unsigned int i = 0; i < retval.size (); i++)
927  {
928  for (unsigned int j = i+1; j < retval.size (); j++)
929  {
930  if (retval[i].second == retval[j].second)
931  {
932  retval.erase (retval.begin () + j);
933  }
934  }
935  }
936  return retval;
937 }
938 std::vector<Mac48Address>
939 HwmpProtocol::GetPreqReceivers (uint32_t interface)
940 {
941  NS_LOG_FUNCTION (this << interface);
942  std::vector<Mac48Address> retval;
943  if (!m_neighboursCallback.IsNull ())
944  {
945  retval = m_neighboursCallback (interface);
946  }
947  if ((retval.size () >= m_unicastPreqThreshold) || (retval.size () == 0))
948  {
949  retval.clear ();
950  retval.push_back (Mac48Address::GetBroadcast ());
951  }
952  return retval;
953 }
954 std::vector<Mac48Address>
956 {
957  NS_LOG_FUNCTION (this << interface);
958  std::vector<Mac48Address> retval;
959  if (!m_neighboursCallback.IsNull ())
960  {
961  retval = m_neighboursCallback (interface);
962  }
963  if ((retval.size () >= m_unicastDataThreshold) || (retval.size () == 0))
964  {
965  retval.clear ();
966  retval.push_back (Mac48Address::GetBroadcast ());
967  }
968  return retval;
969 }
970 
971 bool
973 {
974  NS_LOG_FUNCTION (this);
975  if (m_rqueue.size () > m_maxQueueSize)
976  {
977  return false;
978  }
979  m_rqueue.push_back (packet);
980  return true;
981 }
982 
985 {
986  NS_LOG_FUNCTION (this << dst);
987  QueuedPacket retval;
988  retval.pkt = 0;
989  for (std::vector<QueuedPacket>::iterator i = m_rqueue.begin (); i != m_rqueue.end (); i++)
990  {
991  if ((*i).dst == dst)
992  {
993  retval = (*i);
994  m_rqueue.erase (i);
995  break;
996  }
997  }
998  return retval;
999 }
1000 
1003 {
1004  NS_LOG_FUNCTION (this);
1005  QueuedPacket retval;
1006  retval.pkt = 0;
1007  if (m_rqueue.size () != 0)
1008  {
1009  retval = m_rqueue[0];
1010  m_rqueue.erase (m_rqueue.begin ());
1011  }
1012  return retval;
1013 }
1014 
1015 void
1017 {
1018  NS_LOG_FUNCTION (this << dst);
1019  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1020  if (i != m_preqTimeouts.end ())
1021  {
1022  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
1023  }
1024 
1027  //Send all packets stored for this destination
1028  QueuedPacket packet = DequeueFirstPacketByDst (dst);
1029  while (packet.pkt != 0)
1030  {
1031  //set RA tag for retransmitter:
1032  HwmpTag tag;
1033  packet.pkt->RemovePacketTag (tag);
1034  tag.SetAddress (result.retransmitter);
1035  packet.pkt->AddPacketTag (tag);
1036  m_stats.txUnicast++;
1037  m_stats.txBytes += packet.pkt->GetSize ();
1038  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1039 
1040  packet = DequeueFirstPacketByDst (dst);
1041  }
1042 }
1043 void
1045 {
1046  NS_LOG_FUNCTION (this);
1047  //send all packets to root
1050  QueuedPacket packet = DequeueFirstPacket ();
1051  while (packet.pkt != 0)
1052  {
1053  //set RA tag for retransmitter:
1054  HwmpTag tag;
1055  if (!packet.pkt->RemovePacketTag (tag))
1056  {
1057  NS_FATAL_ERROR ("HWMP tag must be present at this point");
1058  }
1059  tag.SetAddress (result.retransmitter);
1060  packet.pkt->AddPacketTag (tag);
1061  m_stats.txUnicast++;
1062  m_stats.txBytes += packet.pkt->GetSize ();
1063  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1064 
1065  packet = DequeueFirstPacket ();
1066  }
1067 }
1068 
1069 bool
1071 {
1072  NS_LOG_FUNCTION (this << dst);
1073  std::map<Mac48Address, PreqEvent>::const_iterator i = m_preqTimeouts.find (dst);
1074  if (i == m_preqTimeouts.end ())
1075  {
1076  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
1078  &HwmpProtocol::RetryPathDiscovery, this, dst, 1);
1079  m_preqTimeouts[dst].whenScheduled = Simulator::Now ();
1080  return true;
1081  }
1082  return false;
1083 }
1084 void
1086 {
1087  NS_LOG_FUNCTION (this << dst << (uint16_t) numOfRetry);
1089  if (result.retransmitter == Mac48Address::GetBroadcast ())
1090  {
1091  result = m_rtable->LookupProactive ();
1092  }
1093  if (result.retransmitter != Mac48Address::GetBroadcast ())
1094  {
1095  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1096  NS_ASSERT (i != m_preqTimeouts.end ());
1097  m_preqTimeouts.erase (i);
1098  return;
1099  }
1100  if (numOfRetry > m_dot11MeshHWMPmaxPREQretries)
1101  {
1102  QueuedPacket packet = DequeueFirstPacketByDst (dst);
1103  //purge queue and delete entry from retryDatabase
1104  while (packet.pkt != 0)
1105  {
1107  packet.reply (false, packet.pkt, packet.src, packet.dst, packet.protocol, HwmpRtable::MAX_METRIC);
1108  packet = DequeueFirstPacketByDst (dst);
1109  }
1110  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1111  NS_ASSERT (i != m_preqTimeouts.end ());
1112  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
1113  m_preqTimeouts.erase (i);
1114  return;
1115  }
1116  numOfRetry++;
1117  uint32_t originator_seqno = GetNextHwmpSeqno ();
1118  uint32_t dst_seqno = m_rtable->LookupReactiveExpired (dst).seqnum;
1119  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1120  {
1121  i->second->RequestDestination (dst, originator_seqno, dst_seqno);
1122  }
1123  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
1124  Time ((2 * (numOfRetry + 1)) * m_dot11MeshHWMPnetDiameterTraversalTime),
1125  &HwmpProtocol::RetryPathDiscovery, this, dst, numOfRetry);
1126 }
1127 //Proactive PREQ routines:
1128 void
1130 {
1131  NS_LOG_FUNCTION (this);
1132  NS_LOG_DEBUG ("ROOT IS: " << m_address);
1133  m_isRoot = true;
1134 }
1135 void
1137 {
1138  NS_LOG_FUNCTION (this);
1140 }
1141 void
1143 {
1144  NS_LOG_FUNCTION (this);
1145  IePreq preq;
1146  //By default: must answer
1147  preq.SetHopcount (0);
1148  preq.SetTTL (m_maxTtl);
1150  //\attention: do not forget to set originator address, sequence
1151  //number and preq ID in HWMP-MAC plugin
1153  preq.SetOriginatorAddress (GetAddress ());
1154  preq.SetPreqID (GetNextPreqId ());
1156  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1157  {
1158  i->second->SendPreq (preq);
1159  }
1161 }
1162 bool
1164 {
1165  return m_doFlag;
1166 }
1167 bool
1169 {
1170  return m_rfFlag;
1171 }
1172 Time
1174 {
1176 }
1177 Time
1179 {
1181 }
1182 uint8_t
1184 {
1185  return m_maxTtl;
1186 }
1187 uint32_t
1189 {
1190  m_preqId++;
1191  return m_preqId;
1192 }
1193 uint32_t
1195 {
1196  m_hwmpSeqno++;
1197  return m_hwmpSeqno;
1198 }
1199 uint32_t
1201 {
1203 }
1204 uint8_t
1206 {
1207  return m_unicastPerrThreshold;
1208 }
1211 {
1212  return m_address;
1213 }
1214 //Statistics:
1216  txUnicast (0),
1217  txBroadcast (0),
1218  txBytes (0),
1219  droppedTtl (0),
1220  totalQueued (0),
1221  totalDropped (0),
1222  initiatedPreq (0),
1223  initiatedPrep (0),
1224  initiatedPerr (0)
1225 {
1226 }
1227 void HwmpProtocol::Statistics::Print (std::ostream & os) const
1228 {
1229  os << "<Statistics "
1230  "txUnicast=\"" << txUnicast << "\" "
1231  "txBroadcast=\"" << txBroadcast << "\" "
1232  "txBytes=\"" << txBytes << "\" "
1233  "droppedTtl=\"" << droppedTtl << "\" "
1234  "totalQueued=\"" << totalQueued << "\" "
1235  "totalDropped=\"" << totalDropped << "\" "
1236  "initiatedPreq=\"" << initiatedPreq << "\" "
1237  "initiatedPrep=\"" << initiatedPrep << "\" "
1238  "initiatedPerr=\"" << initiatedPerr << "\"/>" << std::endl;
1239 }
1240 void
1241 HwmpProtocol::Report (std::ostream & os) const
1242 {
1243  os << "<Hwmp "
1244  "address=\"" << m_address << "\"" << std::endl <<
1245  "maxQueueSize=\"" << m_maxQueueSize << "\"" << std::endl <<
1246  "Dot11MeshHWMPmaxPREQretries=\"" << (uint16_t)m_dot11MeshHWMPmaxPREQretries << "\"" << std::endl <<
1247  "Dot11MeshHWMPnetDiameterTraversalTime=\"" << m_dot11MeshHWMPnetDiameterTraversalTime.GetSeconds () << "\"" << std::endl <<
1248  "Dot11MeshHWMPpreqMinInterval=\"" << m_dot11MeshHWMPpreqMinInterval.GetSeconds () << "\"" << std::endl <<
1249  "Dot11MeshHWMPperrMinInterval=\"" << m_dot11MeshHWMPperrMinInterval.GetSeconds () << "\"" << std::endl <<
1250  "Dot11MeshHWMPactiveRootTimeout=\"" << m_dot11MeshHWMPactiveRootTimeout.GetSeconds () << "\"" << std::endl <<
1251  "Dot11MeshHWMPactivePathTimeout=\"" << m_dot11MeshHWMPactivePathTimeout.GetSeconds () << "\"" << std::endl <<
1252  "Dot11MeshHWMPpathToRootInterval=\"" << m_dot11MeshHWMPpathToRootInterval.GetSeconds () << "\"" << std::endl <<
1253  "Dot11MeshHWMPrannInterval=\"" << m_dot11MeshHWMPrannInterval.GetSeconds () << "\"" << std::endl <<
1254  "isRoot=\"" << m_isRoot << "\"" << std::endl <<
1255  "maxTtl=\"" << (uint16_t)m_maxTtl << "\"" << std::endl <<
1256  "unicastPerrThreshold=\"" << (uint16_t)m_unicastPerrThreshold << "\"" << std::endl <<
1257  "unicastPreqThreshold=\"" << (uint16_t)m_unicastPreqThreshold << "\"" << std::endl <<
1258  "unicastDataThreshold=\"" << (uint16_t)m_unicastDataThreshold << "\"" << std::endl <<
1259  "doFlag=\"" << m_doFlag << "\"" << std::endl <<
1260  "rfFlag=\"" << m_rfFlag << "\">" << std::endl;
1261  m_stats.Print (os);
1262  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
1263  {
1264  plugin->second->Report (os);
1265  }
1266  os << "</Hwmp>" << std::endl;
1267 }
1268 void
1270 {
1271  NS_LOG_FUNCTION (this);
1272  m_stats = Statistics ();
1273  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
1274  {
1275  plugin->second->ResetStats ();
1276  }
1277 }
1278 
1279 int64_t
1281 {
1282  NS_LOG_FUNCTION (this << stream);
1283  m_coefficient->SetStream (stream);
1284  return 1;
1285 }
1286 
1289 {
1290  return m_rtable;
1291 }
1292 
1294  pkt (0),
1295  protocol (0),
1296  inInterface (0)
1297 {
1298 }
1299 } // namespace dot11s
1300 } // namespace ns3
Structure of path error: IePerr and list of receivers: interfaces and MAC address.
void SetDestinationAddress(Mac48Address dest_address)
Set destination address function.
void SetPreqID(uint32_t id)
Set path discovery id field.
uint16_t txBroadcast
transmit broadcast
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 the RngStream.
Mac48Address retransmitter
route source
Definition: hwmp-protocol.h:50
std::string type
type of change
Definition: hwmp-protocol.h:48
AttributeValue implementation for Boolean.
Definition: boolean.h:36
uint32_t GetDestinationSeqNumber() const
Get destination sequence number function.
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)
Set remaining number of hops allowed for this element.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
void IncrementMetric(uint32_t metric)
Increment metric function.
static const uint32_t MAX_METRIC
Maximum (the best?) path metric.
Definition: hwmp-rtable.h:41
void SetOriginatorSeqNumber(uint32_t originator_seq_number)
Set originator sequence number function.
Route lookup result, return type of LookupXXX methods.
Definition: hwmp-rtable.h:44
uint16_t initiatedPreq
initiated PREQ
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:84
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:814
#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:796
LookupResult LookupReactiveExpired(Mac48Address destination)
Return all reactive paths, including expired.
Definition: hwmp-rtable.cc:166
bool GetRfFlag()
Get rf flag function.
Mac48Address GetDestinationAddress() const
Get destination address function.
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.
void SetTtl(uint8_t ttl)
Set TTL function.
Time lifetime
lifetime of route
Definition: hwmp-protocol.h:53
Statistics m_stats
statistics
uint8_t GetMaxTtl()
Get maximum TTL function.
uint32_t GetLifetime() const
Get lifetime value.
void SetTtl(uint8_t ttl)
Set the TTL value.
Definition: hwmp-tag.cc:51
void ReactivePathResolved(Mac48Address dst)
void SetOriginatorAddress(Mac48Address originator_address)
Set originator address function.
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)
Set address.
Definition: hwmp-tag.cc:39
LookupResult LookupReactive(Mac48Address destination)
Lookup path to destination.
Definition: hwmp-rtable.cc:150
TracedCallback< Time > m_routeDiscoveryTimeCallback
Route discovery time:
void SetLifetime(uint32_t lifetime)
Set lifetime in TUs for the forwarding information to be considered valid.
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:77
Mac48Address GetOriginatorAddress() const
Get originator address function.
uint32_t seqnum
sequence number
Definition: hwmp-rtable.h:49
Routing table for HWMP – 802.11s routing protocol.
Definition: hwmp-rtable.h:35
void Print(std::ostream &os) const
Print function.
std::vector< Mac48Address > GetPreqReceivers(uint32_t interface)
Get PREQ receivers.
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)
Clean HWMP packet tag from packet; only the packet parameter is used.
Mac48Address GetOriginatorAddress() const
Get originator address value.
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:836
Time GetPerrMinInterval()
Get PERR minimum interval function.
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)
Get PERR receivers.
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1375
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:198
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)
Handle Metric:
AttributeValue implementation for Time.
Definition: nstime.h:1055
void DoDispose()
Destructor implementation.
Mac48Address destination
route destination
Definition: hwmp-protocol.h:49
Hybrid wireless mesh protocol – a mesh routing protocol defined in IEEE 802.11-2012 standard...
Definition: hwmp-protocol.h:62
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:223
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.
uint32_t seqnum
sequence number of route
Definition: hwmp-protocol.h:54
Packet waiting its routing information.
Hold together all Wifi-related objects.
static Mac48Address GetBroadcast(void)
HwmpProtocolMacMap m_interfaces
interfaces
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
uint32_t GetOriginatorSeqNumber() const
Get originator sequence numnber value.
uint32_t GetActivePathLifetime()
Get active path lifetime function.
void AddPrecursor(Mac48Address destination, uint32_t precursorInterface, Mac48Address precursorAddress, Time lifetime)
Definition: hwmp-rtable.cc:90
uint16_t totalDropped
total dropped
Ptr< HwmpRtable > m_rtable
Routing table.
void SetOriginatorAddress(Mac48Address originator_address)
Set originator address value.
void SetLifetime(uint32_t lifetime)
Set lifetime function.
tuple mac
Definition: third.py:92
static TypeId GetTypeId()
Get the type ID.
uint16_t initiatedPerr
initiated PERR
LookupResult LookupProactiveExpired()
Return all proactive paths, including expired.
Definition: hwmp-rtable.cc:190
void ReceivePreq(IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
Handler for receiving Path Request.
uint32_t m_dataSeqno
data sequence no
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:121
uint32_t m_hwmpSeqno
HWMP sequence no.
void SetOriginatorSeqNumber(uint32_t originator_seq_number)
Set originator sequence number.
void SetMetric(uint32_t metric)
Set metric function.
Mac48Address m_address
address
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
uint16_t initiatedPrep
initiated PREP
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
uint32_t GetNextPreqId()
Get next period function.
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
Check whether Proactive PREP subfield to off.
an EUI-48 address
Definition: mac48-address.h:43
uint32_t GetNextHwmpSeqno()
Get next HWMP sequence no function.
uint8_t GetDestCount() const
Get destination count.
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:1056
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
std::vector< Ptr< DestinationAddressUnit > > GetDestinationList()
Get all destinations, which are stored in PREQ:
Ptr< HwmpRtable > GetRoutingTable(void) const
Get pointer to HWMP routing table.
RouteReplyCallback reply
how to reply
uint32_t m_preqId
PREQ ID.
Interface for L2 mesh routing protocol and mesh point communication.
uint8_t GetTtl()
Get the TTL value.
Definition: hwmp-tag.cc:57
void ReceivePerr(std::vector< FailedDestination > destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
Handler for receiving Path Error.
void Report(std::ostream &) const
Statistics:
uint32_t metric
metric of route
Definition: hwmp-protocol.h:52
Ptr< UniformRandomVariable > m_coefficient
Random variable for random start time.
uint8_t GetUnicastPerrThreshold()
Get unicast PERR threshold function.
EventId m_proactivePreqTimer
proactive PREQ timer
Mac48Address retransmitter
retransmitter
Definition: hwmp-rtable.h:46
std::vector< Mac48Address > GetBroadcastReceivers(uint32_t interface)
Get broadcast receivers.
std::vector< FailedDestination > destinations
destination list: Mac48Address and sequence number
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:821
uint16_t txUnicast
transmit unicast
void DecrementTtl()
Decrement TTL.
Definition: hwmp-tag.cc:155
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
Callback< std::vector< Mac48Address >, uint32_t > m_neighboursCallback
neighbors callback
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
uint32_t GetLifetime() const
Get lifetime function.
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:528
void DeleteReactivePath(Mac48Address destination)
Definition: hwmp-rtable.cc:140
QueuedPacket DequeueFirstPacketByDst(Mac48Address dst)
Time GetPreqMinInterval()
Get PREQ minimum interval function.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1009
void AddProactivePath(uint32_t metric, Mac48Address root, Mac48Address retransmitter, uint32_t interface, Time lifetime, uint32_t seqnum)
Definition: hwmp-rtable.cc:78
TracedCallback< struct RouteChange > m_routeChangeTraceSource
Route change trace source.
uint32_t GetMetric() const
Get metric value.
tuple address
Definition: first.py:37
void SetSeqno(uint32_t seqno)
Set sequence number.
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
Get metric function.
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)
Set destination sequence number function.
void SetHopcount(uint8_t hopcount)
Set hop count function.
void PeerLinkStatus(Mac48Address meshPontAddress, Mac48Address peerAddress, uint32_t interface, bool status)
Peer link status function.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
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
void ResetStats()
Reset Statistics:
uint32_t interface
interface index
Definition: hwmp-protocol.h:51
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:914
Basic MAC of mesh point Wi-Fi interface.
void SetHopcount(uint8_t hopcount)
Set number of hops from originator to mesh STA transmitting this element.
std::map< Mac48Address, PreqEvent > m_preqTimeouts
PREQ timeouts.
bool GetDoFlag()
Get do flag function.
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:179
Structure to encapsulate route change information.
Definition: hwmp-protocol.h:46
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.