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-wifi-interface-mac.h"
31 #include "ns3/random-variable-stream.h"
32 #include "airtime-metric.h"
33 #include "ie-dot11s-preq.h"
34 #include "ie-dot11s-prep.h"
35 #include "ns3/trace-source-accessor.h"
36 #include "ie-dot11s-perr.h"
37 
38 namespace ns3 {
39 
40 NS_LOG_COMPONENT_DEFINE ("HwmpProtocol");
41 
42 namespace dot11s {
43 
44 NS_OBJECT_ENSURE_REGISTERED (HwmpProtocol);
45 
46 TypeId
48 {
49  static TypeId tid = TypeId ("ns3::dot11s::HwmpProtocol")
51  .SetGroupName ("Mesh")
52  .AddConstructor<HwmpProtocol> ()
53  .AddAttribute ( "RandomStart",
54  "Random delay at first proactive PREQ",
55  TimeValue (Seconds (0.1)),
59  )
60  .AddAttribute ( "MaxQueueSize",
61  "Maximum number of packets we can store when resolving route",
62  UintegerValue (255),
65  MakeUintegerChecker<uint16_t> (1)
66  )
67  .AddAttribute ( "Dot11MeshHWMPmaxPREQretries",
68  "Maximum number of retries before we suppose the destination to be unreachable",
69  UintegerValue (3),
72  MakeUintegerChecker<uint8_t> (1)
73  )
74  .AddAttribute ( "Dot11MeshHWMPnetDiameterTraversalTime",
75  "Time we suppose the packet to go from one edge of the network to another",
76  TimeValue (MicroSeconds (1024*100)),
80  )
81  .AddAttribute ( "Dot11MeshHWMPpreqMinInterval",
82  "Minimal interval between to successive PREQs",
83  TimeValue (MicroSeconds (1024*100)),
87  )
88  .AddAttribute ( "Dot11MeshHWMPperrMinInterval",
89  "Minimal interval between to successive PREQs",
90  TimeValue (MicroSeconds (1024*100)),
93  )
94  .AddAttribute ( "Dot11MeshHWMPactiveRootTimeout",
95  "Lifetime of poractive routing information",
96  TimeValue (MicroSeconds (1024*5000)),
100  )
101  .AddAttribute ( "Dot11MeshHWMPactivePathTimeout",
102  "Lifetime of reactive routing information",
103  TimeValue (MicroSeconds (1024*5000)),
106  MakeTimeChecker ()
107  )
108  .AddAttribute ( "Dot11MeshHWMPpathToRootInterval",
109  "Interval between two successive proactive PREQs",
110  TimeValue (MicroSeconds (1024*2000)),
113  MakeTimeChecker ()
114  )
115  .AddAttribute ( "Dot11MeshHWMPrannInterval",
116  "Lifetime of poractive routing information",
117  TimeValue (MicroSeconds (1024*5000)),
120  MakeTimeChecker ()
121  )
122  .AddAttribute ( "MaxTtl",
123  "Initial value of Time To Live field",
124  UintegerValue (32),
127  MakeUintegerChecker<uint8_t> (2)
128  )
129  .AddAttribute ( "UnicastPerrThreshold",
130  "Maximum number of PERR receivers, when we send a PERR as a chain of unicasts",
131  UintegerValue (32),
134  MakeUintegerChecker<uint8_t> (1)
135  )
136  .AddAttribute ( "UnicastPreqThreshold",
137  "Maximum number of PREQ receivers, when we send a PREQ as a chain of unicasts",
138  UintegerValue (1),
141  MakeUintegerChecker<uint8_t> (1)
142  )
143  .AddAttribute ( "UnicastDataThreshold",
144  "Maximum number ofbroadcast receivers, when we send a broadcast as a chain of unicasts",
145  UintegerValue (1),
148  MakeUintegerChecker<uint8_t> (1)
149  )
150  .AddAttribute ( "DoFlag",
151  "Destination only HWMP flag",
152  BooleanValue (false),
156  )
157  .AddAttribute ( "RfFlag",
158  "Reply and forward flag",
159  BooleanValue (true),
163  )
164  .AddTraceSource ( "RouteDiscoveryTime",
165  "The time of route discovery procedure",
168  "ns3::Time::TracedCallback"
169  )
170  .AddTraceSource ("RouteChange",
171  "Routing table changed",
173  "ns3::HwmpProtocol::RouteChangeTracedCallback"
174  )
175  ;
176  return tid;
177 }
178 
180  m_dataSeqno (1),
181  m_hwmpSeqno (1),
182  m_preqId (0),
183  m_rtable (CreateObject<HwmpRtable> ()),
184  m_randomStart (Seconds (0.1)),
185  m_maxQueueSize (255),
186  m_dot11MeshHWMPmaxPREQretries (3),
187  m_dot11MeshHWMPnetDiameterTraversalTime (MicroSeconds (1024*100)),
188  m_dot11MeshHWMPpreqMinInterval (MicroSeconds (1024*100)),
189  m_dot11MeshHWMPperrMinInterval (MicroSeconds (1024*100)),
190  m_dot11MeshHWMPactiveRootTimeout (MicroSeconds (1024*5000)),
191  m_dot11MeshHWMPactivePathTimeout (MicroSeconds (1024*5000)),
192  m_dot11MeshHWMPpathToRootInterval (MicroSeconds (1024*2000)),
193  m_dot11MeshHWMPrannInterval (MicroSeconds (1024*5000)),
194  m_isRoot (false),
195  m_maxTtl (32),
196  m_unicastPerrThreshold (32),
197  m_unicastPreqThreshold (1),
198  m_unicastDataThreshold (1),
199  m_doFlag (false),
200  m_rfFlag (false)
201 {
202  NS_LOG_FUNCTION (this);
203  m_coefficient = CreateObject<UniformRandomVariable> ();
204 }
205 
207 {
208  NS_LOG_FUNCTION (this);
209 }
210 
211 void
213 {
214  NS_LOG_FUNCTION (this);
216  if (m_isRoot)
217  {
218  Time randomStart = Seconds (m_coefficient->GetValue ());
220  }
221 }
222 
223 void
225 {
226  NS_LOG_FUNCTION (this);
227  for (std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.begin (); i != m_preqTimeouts.end (); i++)
228  {
229  i->second.preqTimeout.Cancel ();
230  }
232  m_preqTimeouts.clear ();
233  m_lastDataSeqno.clear ();
234  m_hwmpSeqnoMetricDatabase.clear ();
235  m_interfaces.clear ();
236  m_rqueue.clear ();
237  m_rtable = 0;
238  m_mp = 0;
239 }
240 
241 bool
243  uint32_t sourceIface,
244  const Mac48Address source,
245  const Mac48Address destination,
246  Ptr<const Packet> constPacket,
247  uint16_t protocolType, //ethrnet 'Protocol' field
249  )
250 {
251  NS_LOG_FUNCTION (this << sourceIface << source << destination << constPacket << protocolType);
252  Ptr <Packet> packet = constPacket->Copy ();
253  HwmpTag tag;
254  if (sourceIface == GetMeshPoint ()->GetIfIndex ())
255  {
256  // packet from level 3
257  if (packet->PeekPacketTag (tag))
258  {
259  NS_FATAL_ERROR ("HWMP tag has come with a packet from upper layer. This must not occur...");
260  }
261  //Filling TAG:
262  if (destination == Mac48Address::GetBroadcast ())
263  {
264  tag.SetSeqno (m_dataSeqno++);
265  }
266  tag.SetTtl (m_maxTtl);
267  }
268  else
269  {
270  if (!packet->RemovePacketTag (tag))
271  {
272  NS_FATAL_ERROR ("HWMP tag is supposed to be here at this point.");
273  }
274  tag.DecrementTtl ();
275  if (tag.GetTtl () == 0)
276  {
278  return false;
279  }
280  }
281  if (destination == Mac48Address::GetBroadcast ())
282  {
284  m_stats.txBytes += packet->GetSize ();
285  //channel IDs where we have already sent broadcast:
286  std::vector<uint16_t> channels;
287  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
288  {
289  bool shouldSend = true;
290  for (std::vector<uint16_t>::const_iterator chan = channels.begin (); chan != channels.end (); chan++)
291  {
292  if ((*chan) == plugin->second->GetChannelId ())
293  {
294  shouldSend = false;
295  }
296  }
297  if (!shouldSend)
298  {
299  continue;
300  }
301  channels.push_back (plugin->second->GetChannelId ());
302  std::vector<Mac48Address> receivers = GetBroadcastReceivers (plugin->first);
303  for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i++)
304  {
305  Ptr<Packet> packetCopy = packet->Copy ();
306  //
307  // 64-bit Intel valgrind complains about tag.SetAddress (*i). It
308  // likes this just fine.
309  //
310  Mac48Address address = *i;
311  tag.SetAddress (address);
312  packetCopy->AddPacketTag (tag);
313  routeReply (true, packetCopy, source, destination, protocolType, plugin->first);
314  }
315  }
316  }
317  else
318  {
319  return ForwardUnicast (sourceIface, source, destination, packet, protocolType, routeReply, tag.GetTtl ());
320  }
321  return true;
322 }
323 bool
324 HwmpProtocol::RemoveRoutingStuff (uint32_t fromIface, const Mac48Address source,
325  const Mac48Address destination, Ptr<Packet> packet, uint16_t& protocolType)
326 {
327  HwmpTag tag;
328  if (!packet->RemovePacketTag (tag))
329  {
330  NS_FATAL_ERROR ("HWMP tag must exist when packet received from the network");
331  }
332  return true;
333 }
334 bool
335 HwmpProtocol::ForwardUnicast (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination,
336  Ptr<Packet> packet, uint16_t protocolType, RouteReplyCallback routeReply, uint32_t ttl)
337 {
338  NS_LOG_FUNCTION (this << sourceIface << source << destination << packet << protocolType << ttl);
339  NS_ASSERT (destination != Mac48Address::GetBroadcast ());
340  HwmpRtable::LookupResult result = m_rtable->LookupReactive (destination);
341  NS_LOG_DEBUG ("Requested src = "<<source<<", dst = "<<destination<<", I am "<<GetAddress ()<<", RA = "<<result.retransmitter);
342  if (result.retransmitter == Mac48Address::GetBroadcast ())
343  {
344  result = m_rtable->LookupProactive ();
345  }
346  HwmpTag tag;
347  tag.SetAddress (result.retransmitter);
348  tag.SetTtl (ttl);
349  //seqno and metric is not used;
350  packet->AddPacketTag (tag);
351  if (result.retransmitter != Mac48Address::GetBroadcast ())
352  {
353  //reply immediately:
354  routeReply (true, packet, source, destination, protocolType, result.ifIndex);
355  m_stats.txUnicast++;
356  m_stats.txBytes += packet->GetSize ();
357  return true;
358  }
359  if (sourceIface != GetMeshPoint ()->GetIfIndex ())
360  {
361  //Start path error procedure:
362  NS_LOG_DEBUG ("Must Send PERR");
363  result = m_rtable->LookupReactiveExpired (destination);
364  NS_LOG_DEBUG ("Path error " << result.retransmitter);
365  //1. Lookup expired reactive path. If exists - start path error
366  // procedure towards a next hop of this path
367  //2. If there was no reactive path, we lookup expired proactive
368  // path. If exist - start path error procedure towards path to
369  // root
370  if (result.retransmitter == Mac48Address::GetBroadcast ())
371  {
372  NS_LOG_DEBUG ("Path error, lookup expired proactive path");
373  result = m_rtable->LookupProactiveExpired ();
374  }
375  if (result.retransmitter != Mac48Address::GetBroadcast ())
376  {
377  NS_LOG_DEBUG ("Path error, initiate reactive path error");
378  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (result.retransmitter);
379  InitiatePathError (MakePathError (destinations));
380  }
382  return false;
383  }
384  //Request a destination:
385  result = m_rtable->LookupReactiveExpired (destination);
386  if (ShouldSendPreq (destination))
387  {
388  uint32_t originator_seqno = GetNextHwmpSeqno ();
389  uint32_t dst_seqno = 0;
390  if (result.retransmitter != Mac48Address::GetBroadcast ())
391  {
392  dst_seqno = result.seqnum;
393  }
395  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
396  {
397  i->second->RequestDestination (destination, originator_seqno, dst_seqno);
398  }
399  }
400  QueuedPacket pkt;
401  pkt.pkt = packet;
402  pkt.dst = destination;
403  pkt.src = source;
404  pkt.protocol = protocolType;
405  pkt.reply = routeReply;
406  pkt.inInterface = sourceIface;
407  if (QueuePacket (pkt))
408  {
410  return true;
411  }
412  else
413  {
415  NS_LOG_DEBUG ("Dropping packet from " << source << " to " << destination << " due to queue overflow");
416  return false;
417  }
418 }
419 void
420 HwmpProtocol::ReceivePreq (IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
421 {
422  NS_LOG_FUNCTION (this << from << interface << fromMp << metric);
423  preq.IncrementMetric (metric);
424  //acceptance cretirea:
425  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
426  preq.GetOriginatorAddress ());
427  bool freshInfo (true);
428  if (i != m_hwmpSeqnoMetricDatabase.end ())
429  {
430  if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber ()) > 0)
431  {
432  return;
433  }
434  if (i->second.first == preq.GetOriginatorSeqNumber ())
435  {
436  freshInfo = false;
437  if (i->second.second <= preq.GetMetric ())
438  {
439  return;
440  }
441  }
442  }
444  std::make_pair (preq.GetOriginatorSeqNumber (), preq.GetMetric ());
445  NS_LOG_DEBUG ("I am " << GetAddress () << ", Accepted preq from address" << from << ", preq:" << preq);
446  std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
447  //Add reactive path to originator:
448  if (
449  (freshInfo) ||
450  (
451  (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).retransmitter == Mac48Address::GetBroadcast ()) ||
452  (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).metric > preq.GetMetric ())
453  )
454  )
455  {
457  preq.GetOriginatorAddress (),
458  from,
459  interface,
460  preq.GetMetric (),
461  MicroSeconds (preq.GetLifetime () * 1024),
462  preq.GetOriginatorSeqNumber ()
463  );
464  // Notify trace source of routing change
465  struct RouteChange rChange;
466  rChange.type = "Add Reactive";
467  rChange.destination = preq.GetOriginatorAddress ();
468  rChange.retransmitter = from;
469  rChange.interface = interface;
470  rChange.metric = preq.GetMetric ();
471  rChange.lifetime = MicroSeconds (preq.GetLifetime () * 1024);
472  rChange.seqnum = preq.GetOriginatorSeqNumber ();
473  m_routeChangeTraceSource (rChange);
475  }
476  if (
478  (m_rtable->LookupReactive (fromMp).metric > metric)
479  )
480  {
482  fromMp,
483  from,
484  interface,
485  metric,
486  MicroSeconds (preq.GetLifetime () * 1024),
487  preq.GetOriginatorSeqNumber ()
488  );
489  // Notify trace source of routing change
490  struct RouteChange rChange;
491  rChange.type = "Add Reactive";
492  rChange.destination = fromMp;
493  rChange.retransmitter = from;
494  rChange.interface = interface;
495  rChange.metric = metric;
496  rChange.lifetime = MicroSeconds (preq.GetLifetime () * 1024);
497  rChange.seqnum = preq.GetOriginatorSeqNumber ();
498  m_routeChangeTraceSource (rChange);
499  ReactivePathResolved (fromMp);
500  }
501  for (std::vector<Ptr<DestinationAddressUnit> >::const_iterator i = destinations.begin (); i != destinations.end (); i++)
502  {
503  if ((*i)->GetDestinationAddress () == Mac48Address::GetBroadcast ())
504  {
505  //only proactive PREQ contains destination
506  //address as broadcast! Proactive preq MUST
507  //have destination count equal to 1 and
508  //per destination flags DO and RF
509  NS_ASSERT (preq.GetDestCount () == 1);
510  NS_ASSERT (((*i)->IsDo ()) && ((*i)->IsRf ()));
511  //Add proactive path only if it is the better then existed
512  //before
513  if (
514  ((m_rtable->LookupProactive ()).retransmitter == Mac48Address::GetBroadcast ()) ||
515  ((m_rtable->LookupProactive ()).metric > preq.GetMetric ())
516  )
517  {
519  preq.GetMetric (),
520  preq.GetOriginatorAddress (),
521  from,
522  interface,
523  MicroSeconds (preq.GetLifetime () * 1024),
524  preq.GetOriginatorSeqNumber ()
525  );
526  // Notify trace source of routing change
527  struct RouteChange rChange;
528  rChange.type = "Add Proactive";
529  rChange.destination = preq.GetOriginatorAddress ();
530  rChange.retransmitter = from;
531  rChange.interface = interface;
532  rChange.metric = preq.GetMetric ();
533  rChange.lifetime = MicroSeconds (preq.GetLifetime () * 1024);
534  rChange.seqnum = preq.GetOriginatorSeqNumber ();
535  m_routeChangeTraceSource (rChange);
537  }
538  if (!preq.IsNeedNotPrep ())
539  {
540  SendPrep (
541  GetAddress (),
542  preq.GetOriginatorAddress (),
543  from,
544  (uint32_t)0,
545  preq.GetOriginatorSeqNumber (),
546  GetNextHwmpSeqno (),
547  preq.GetLifetime (),
548  interface
549  );
550  }
551  break;
552  }
553  if ((*i)->GetDestinationAddress () == GetAddress ())
554  {
555  SendPrep (
556  GetAddress (),
557  preq.GetOriginatorAddress (),
558  from,
559  (uint32_t)0,
560  preq.GetOriginatorSeqNumber (),
561  GetNextHwmpSeqno (),
562  preq.GetLifetime (),
563  interface
564  );
566  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
567  continue;
568  }
569  //check if can answer:
570  HwmpRtable::LookupResult result = m_rtable->LookupReactive ((*i)->GetDestinationAddress ());
571  if ((!((*i)->IsDo ())) && (result.retransmitter != Mac48Address::GetBroadcast ()))
572  {
573  //have a valid information and can answer
574  uint32_t lifetime = result.lifetime.GetMicroSeconds () / 1024;
575  if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber ()) >= 0))
576  {
577  SendPrep (
578  (*i)->GetDestinationAddress (),
579  preq.GetOriginatorAddress (),
580  from,
581  result.metric,
582  preq.GetOriginatorSeqNumber (),
583  result.seqnum,
584  lifetime,
585  interface
586  );
587  m_rtable->AddPrecursor ((*i)->GetDestinationAddress (), interface, from,
588  MicroSeconds (preq.GetLifetime () * 1024));
589  if ((*i)->IsRf ())
590  {
591  (*i)->SetFlags (true, false, (*i)->IsUsn ()); //DO = 1, RF = 0
592  }
593  else
594  {
595  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
596  continue;
597  }
598  }
599  }
600  }
601  //check if must retransmit:
602  if (preq.GetDestCount () == 0)
603  {
604  return;
605  }
606  //Forward PREQ to all interfaces:
607  NS_LOG_DEBUG ("I am " << GetAddress () << "retransmitting PREQ:" << preq);
608  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
609  {
610  i->second->SendPreq (preq);
611  }
612 }
613 void
614 HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
615 {
616  NS_LOG_FUNCTION (this << from << interface << fromMp << metric);
617  prep.IncrementMetric (metric);
618  //acceptance cretirea:
619  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
620  prep.GetOriginatorAddress ());
621  bool freshInfo (true);
622  uint32_t sequence = prep.GetDestinationSeqNumber ();
623  if (i != m_hwmpSeqnoMetricDatabase.end ())
624  {
625  if ((int32_t)(i->second.first - sequence) > 0)
626  {
627  return;
628  }
629  if (i->second.first == sequence)
630  {
631  freshInfo = false;
632  }
633  }
634  m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (sequence, prep.GetMetric ());
635  //update routing info
636  //Now add a path to destination and add precursor to source
637  NS_LOG_DEBUG ("I am " << GetAddress () << ", received prep from " << prep.GetOriginatorAddress () << ", receiver was:" << from);
639  //Add a reactive path only if seqno is fresher or it improves the
640  //metric
641  if (
642  (freshInfo) ||
643  (
644  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).retransmitter == Mac48Address::GetBroadcast ()) ||
645  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).metric > prep.GetMetric ())
646  )
647  )
648  {
650  prep.GetOriginatorAddress (),
651  from,
652  interface,
653  prep.GetMetric (),
654  MicroSeconds (prep.GetLifetime () * 1024),
655  sequence);
656  // Notify trace source of routing change
657  struct RouteChange rChange;
658  rChange.type = "Add Reactive";
659  rChange.destination = prep.GetOriginatorAddress ();
660  rChange.retransmitter = from;
661  rChange.interface = interface;
662  rChange.metric = prep.GetMetric ();
663  rChange.lifetime = MicroSeconds (prep.GetLifetime () * 1024);
664  rChange.seqnum = sequence;
665  m_routeChangeTraceSource (rChange);
666  m_rtable->AddPrecursor (prep.GetDestinationAddress (), interface, from,
667  MicroSeconds (prep.GetLifetime () * 1024));
668  if (result.retransmitter != Mac48Address::GetBroadcast ())
669  {
670  m_rtable->AddPrecursor (prep.GetOriginatorAddress (), interface, result.retransmitter,
671  result.lifetime);
672  }
674  }
675  if (
676  ((m_rtable->LookupReactive (fromMp)).retransmitter == Mac48Address::GetBroadcast ()) ||
677  ((m_rtable->LookupReactive (fromMp)).metric > metric)
678  )
679  {
681  fromMp,
682  from,
683  interface,
684  metric,
685  MicroSeconds (prep.GetLifetime () * 1024),
686  sequence);
687  // Notify trace source of routing change
688  struct RouteChange rChange;
689  rChange.type = "Add Reactive";
690  rChange.destination = fromMp;
691  rChange.retransmitter = from;
692  rChange.interface = interface;
693  rChange.metric = metric;
694  rChange.lifetime = MicroSeconds (prep.GetLifetime () * 1024);
695  rChange.seqnum = sequence;
696  m_routeChangeTraceSource (rChange);
697  ReactivePathResolved (fromMp);
698  }
699  if (prep.GetDestinationAddress () == GetAddress ())
700  {
701  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", resolved "<<prep.GetOriginatorAddress ());
702  return;
703  }
704  if (result.retransmitter == Mac48Address::GetBroadcast ())
705  {
706  return;
707  }
708  //Forward PREP
709  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (result.ifIndex);
710  NS_ASSERT (prep_sender != m_interfaces.end ());
711  prep_sender->second->SendPrep (prep, result.retransmitter);
712 }
713 void
714 HwmpProtocol::ReceivePerr (std::vector<FailedDestination> destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
715 {
716  NS_LOG_FUNCTION (this << from << interface << fromMp);
717  //Acceptance cretirea:
718  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", received PERR from "<<from);
719  std::vector<FailedDestination> retval;
721  for (unsigned int i = 0; i < destinations.size (); i++)
722  {
723  result = m_rtable->LookupReactiveExpired (destinations[i].destination);
724  if (!(
725  (result.retransmitter != from) ||
726  (result.ifIndex != interface) ||
727  ((int32_t)(result.seqnum - destinations[i].seqnum) > 0)
728  ))
729  {
730  retval.push_back (destinations[i]);
731  }
732  }
733  if (retval.size () == 0)
734  {
735  return;
736  }
737  ForwardPathError (MakePathError (retval));
738 }
739 void
741  Mac48Address src,
742  Mac48Address dst,
743  Mac48Address retransmitter,
744  uint32_t initMetric,
745  uint32_t originatorDsn,
746  uint32_t destinationSN,
747  uint32_t lifetime,
748  uint32_t interface)
749 {
750  IePrep prep;
751  prep.SetHopcount (0);
752  prep.SetTtl (m_maxTtl);
753  prep.SetDestinationAddress (dst);
754  prep.SetDestinationSeqNumber (destinationSN);
755  prep.SetLifetime (lifetime);
756  prep.SetMetric (initMetric);
757  prep.SetOriginatorAddress (src);
758  prep.SetOriginatorSeqNumber (originatorDsn);
759  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (interface);
760  NS_ASSERT (prep_sender != m_interfaces.end ());
761  prep_sender->second->SendPrep (prep, retransmitter);
763 }
764 bool
766 {
767  NS_LOG_FUNCTION (this << mp);
768  m_mp = mp;
769  std::vector<Ptr<NetDevice> > interfaces = mp->GetInterfaces ();
770  for (std::vector<Ptr<NetDevice> >::const_iterator i = interfaces.begin (); i != interfaces.end (); i++)
771  {
772  // Checking for compatible net device
773  Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice> ();
774  if (wifiNetDev == 0)
775  {
776  return false;
777  }
778  Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
779  if (mac == 0)
780  {
781  return false;
782  }
783  // Installing plugins:
784  Ptr<HwmpProtocolMac> hwmpMac = Create<HwmpProtocolMac> (wifiNetDev->GetIfIndex (), this);
785  m_interfaces[wifiNetDev->GetIfIndex ()] = hwmpMac;
786  mac->InstallPlugin (hwmpMac);
787  //Installing airtime link metric:
788  Ptr<AirtimeLinkMetricCalculator> metric = CreateObject <AirtimeLinkMetricCalculator> ();
789  mac->SetLinkMetricCallback (MakeCallback (&AirtimeLinkMetricCalculator::CalculateMetric, metric));
790  }
791  mp->SetRoutingProtocol (this);
792  // Mesh point aggregates all installed protocols
793  mp->AggregateObject (this);
794  m_address = Mac48Address::ConvertFrom (mp->GetAddress ()); // address;
795  return true;
796 }
797 void
798 HwmpProtocol::PeerLinkStatus (Mac48Address meshPointAddress, Mac48Address peerAddress, uint32_t interface, bool status)
799 {
800  NS_LOG_FUNCTION (this << meshPointAddress << peerAddress << interface << status);
801  if (status)
802  {
803  return;
804  }
805  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (peerAddress);
806  NS_LOG_DEBUG (destinations.size () << " failed destinations for peer address " << peerAddress);
807  InitiatePathError (MakePathError (destinations));
808 }
809 void
810 HwmpProtocol::SetNeighboursCallback (Callback<std::vector<Mac48Address>, uint32_t> cb)
811 {
813 }
814 bool
816 {
817  NS_LOG_FUNCTION (this << seqno << source);
818  if (source == GetAddress ())
819  {
820  return true;
821  }
822  std::map<Mac48Address, uint32_t,std::less<Mac48Address> >::const_iterator i = m_lastDataSeqno.find (source);
823  if (i == m_lastDataSeqno.end ())
824  {
825  m_lastDataSeqno[source] = seqno;
826  }
827  else
828  {
829  if ((int32_t)(i->second - seqno) >= 0)
830  {
831  return true;
832  }
833  m_lastDataSeqno[source] = seqno;
834  }
835  return false;
836 }
838 HwmpProtocol::MakePathError (std::vector<FailedDestination> destinations)
839 {
840  NS_LOG_FUNCTION (this);
841  PathError retval;
842  //HwmpRtable increments a sequence number as written in 11B.9.7.2
843  retval.receivers = GetPerrReceivers (destinations);
844  if (retval.receivers.size () == 0)
845  {
846  return retval;
847  }
849  for (unsigned int i = 0; i < destinations.size (); i++)
850  {
851  retval.destinations.push_back (destinations[i]);
852  m_rtable->DeleteReactivePath (destinations[i].destination);
853  // Notify trace source of routing change
854  struct RouteChange rChange;
855  rChange.type = "Delete Reactive";
856  rChange.destination = destinations[i].destination;
857  rChange.seqnum = destinations[i].seqnum;
858  m_routeChangeTraceSource (rChange);
859  }
860  return retval;
861 }
862 void
864 {
865  NS_LOG_FUNCTION (this);
866  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
867  {
868  std::vector<Mac48Address> receivers_for_interface;
869  for (unsigned int j = 0; j < perr.receivers.size (); j++)
870  {
871  if (i->first == perr.receivers[j].first)
872  {
873  receivers_for_interface.push_back (perr.receivers[j].second);
874  }
875  }
876  i->second->InitiatePerr (perr.destinations, receivers_for_interface);
877  }
878 }
879 void
881 {
882  NS_LOG_FUNCTION (this);
883  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
884  {
885  std::vector<Mac48Address> receivers_for_interface;
886  for (unsigned int j = 0; j < perr.receivers.size (); j++)
887  {
888  if (i->first == perr.receivers[j].first)
889  {
890  receivers_for_interface.push_back (perr.receivers[j].second);
891  }
892  }
893  i->second->ForwardPerr (perr.destinations, receivers_for_interface);
894  }
895 }
896 
897 std::vector<std::pair<uint32_t, Mac48Address> >
898 HwmpProtocol::GetPerrReceivers (std::vector<FailedDestination> failedDest)
899 {
900  NS_LOG_FUNCTION (this);
902  for (unsigned int i = 0; i < failedDest.size (); i++)
903  {
904  HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors (failedDest[i].destination);
905  m_rtable->DeleteReactivePath (failedDest[i].destination);
906  // Notify trace source of routing change
907  struct RouteChange rChange;
908  rChange.type = "Delete Reactive";
909  rChange.destination = failedDest[i].destination;
910  rChange.seqnum = failedDest[i].seqnum;
911  m_routeChangeTraceSource (rChange);
912  m_rtable->DeleteProactivePath (failedDest[i].destination);
913  // Notify trace source of routing change
914  struct RouteChange rChangePro;
915  rChangePro.type = "Delete Proactive";
916  rChangePro.destination = failedDest[i].destination;
917  rChangePro.seqnum = failedDest[i].seqnum;
918  m_routeChangeTraceSource (rChangePro);
919  for (unsigned int j = 0; j < precursors.size (); j++)
920  {
921  retval.push_back (precursors[j]);
922  }
923  }
924  //Check if we have duplicates in retval and precursors:
925  for (unsigned int i = 0; i < retval.size (); i++)
926  {
927  for (unsigned int j = i+1; j < retval.size (); j++)
928  {
929  if (retval[i].second == retval[j].second)
930  {
931  retval.erase (retval.begin () + j);
932  }
933  }
934  }
935  return retval;
936 }
937 std::vector<Mac48Address>
938 HwmpProtocol::GetPreqReceivers (uint32_t interface)
939 {
940  NS_LOG_FUNCTION (this << interface);
941  std::vector<Mac48Address> retval;
942  if (!m_neighboursCallback.IsNull ())
943  {
944  retval = m_neighboursCallback (interface);
945  }
946  if ((retval.size () >= m_unicastPreqThreshold) || (retval.size () == 0))
947  {
948  retval.clear ();
949  retval.push_back (Mac48Address::GetBroadcast ());
950  }
951  return retval;
952 }
953 std::vector<Mac48Address>
955 {
956  NS_LOG_FUNCTION (this << interface);
957  std::vector<Mac48Address> retval;
958  if (!m_neighboursCallback.IsNull ())
959  {
960  retval = m_neighboursCallback (interface);
961  }
962  if ((retval.size () >= m_unicastDataThreshold) || (retval.size () == 0))
963  {
964  retval.clear ();
965  retval.push_back (Mac48Address::GetBroadcast ());
966  }
967  return retval;
968 }
969 
970 bool
972 {
973  NS_LOG_FUNCTION (this);
974  if (m_rqueue.size () > m_maxQueueSize)
975  {
976  return false;
977  }
978  m_rqueue.push_back (packet);
979  return true;
980 }
981 
984 {
985  NS_LOG_FUNCTION (this << dst);
986  QueuedPacket retval;
987  retval.pkt = 0;
988  for (std::vector<QueuedPacket>::iterator i = m_rqueue.begin (); i != m_rqueue.end (); i++)
989  {
990  if ((*i).dst == dst)
991  {
992  retval = (*i);
993  m_rqueue.erase (i);
994  break;
995  }
996  }
997  return retval;
998 }
999 
1002 {
1003  NS_LOG_FUNCTION (this);
1004  QueuedPacket retval;
1005  retval.pkt = 0;
1006  if (m_rqueue.size () != 0)
1007  {
1008  retval = m_rqueue[0];
1009  m_rqueue.erase (m_rqueue.begin ());
1010  }
1011  return retval;
1012 }
1013 
1014 void
1016 {
1017  NS_LOG_FUNCTION (this << dst);
1018  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1019  if (i != m_preqTimeouts.end ())
1020  {
1021  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
1022  }
1023 
1026  //Send all packets stored for this destination
1027  QueuedPacket packet = DequeueFirstPacketByDst (dst);
1028  while (packet.pkt != 0)
1029  {
1030  //set RA tag for retransmitter:
1031  HwmpTag tag;
1032  packet.pkt->RemovePacketTag (tag);
1033  tag.SetAddress (result.retransmitter);
1034  packet.pkt->AddPacketTag (tag);
1035  m_stats.txUnicast++;
1036  m_stats.txBytes += packet.pkt->GetSize ();
1037  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1038 
1039  packet = DequeueFirstPacketByDst (dst);
1040  }
1041 }
1042 void
1044 {
1045  NS_LOG_FUNCTION (this);
1046  //send all packets to root
1049  QueuedPacket packet = DequeueFirstPacket ();
1050  while (packet.pkt != 0)
1051  {
1052  //set RA tag for retransmitter:
1053  HwmpTag tag;
1054  if (!packet.pkt->RemovePacketTag (tag))
1055  {
1056  NS_FATAL_ERROR ("HWMP tag must be present at this point");
1057  }
1058  tag.SetAddress (result.retransmitter);
1059  packet.pkt->AddPacketTag (tag);
1060  m_stats.txUnicast++;
1061  m_stats.txBytes += packet.pkt->GetSize ();
1062  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1063 
1064  packet = DequeueFirstPacket ();
1065  }
1066 }
1067 
1068 bool
1070 {
1071  NS_LOG_FUNCTION (this << dst);
1072  std::map<Mac48Address, PreqEvent>::const_iterator i = m_preqTimeouts.find (dst);
1073  if (i == m_preqTimeouts.end ())
1074  {
1075  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
1077  &HwmpProtocol::RetryPathDiscovery, this, dst, 1);
1078  m_preqTimeouts[dst].whenScheduled = Simulator::Now ();
1079  return true;
1080  }
1081  return false;
1082 }
1083 void
1085 {
1086  NS_LOG_FUNCTION (this << dst << (uint16_t) numOfRetry);
1088  if (result.retransmitter == Mac48Address::GetBroadcast ())
1089  {
1090  result = m_rtable->LookupProactive ();
1091  }
1092  if (result.retransmitter != Mac48Address::GetBroadcast ())
1093  {
1094  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1095  NS_ASSERT (i != m_preqTimeouts.end ());
1096  m_preqTimeouts.erase (i);
1097  return;
1098  }
1099  if (numOfRetry > m_dot11MeshHWMPmaxPREQretries)
1100  {
1101  QueuedPacket packet = DequeueFirstPacketByDst (dst);
1102  //purge queue and delete entry from retryDatabase
1103  while (packet.pkt != 0)
1104  {
1106  packet.reply (false, packet.pkt, packet.src, packet.dst, packet.protocol, HwmpRtable::MAX_METRIC);
1107  packet = DequeueFirstPacketByDst (dst);
1108  }
1109  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1110  NS_ASSERT (i != m_preqTimeouts.end ());
1111  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
1112  m_preqTimeouts.erase (i);
1113  return;
1114  }
1115  numOfRetry++;
1116  uint32_t originator_seqno = GetNextHwmpSeqno ();
1117  uint32_t dst_seqno = m_rtable->LookupReactiveExpired (dst).seqnum;
1118  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1119  {
1120  i->second->RequestDestination (dst, originator_seqno, dst_seqno);
1121  }
1122  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
1123  Time ((2 * (numOfRetry + 1)) * m_dot11MeshHWMPnetDiameterTraversalTime),
1124  &HwmpProtocol::RetryPathDiscovery, this, dst, numOfRetry);
1125 }
1126 //Proactive PREQ routines:
1127 void
1129 {
1130  NS_LOG_FUNCTION (this);
1131  NS_LOG_DEBUG ("ROOT IS: " << m_address);
1132  m_isRoot = true;
1133 }
1134 void
1136 {
1137  NS_LOG_FUNCTION (this);
1139 }
1140 void
1142 {
1143  NS_LOG_FUNCTION (this);
1144  IePreq preq;
1145  //By default: must answer
1146  preq.SetHopcount (0);
1147  preq.SetTTL (m_maxTtl);
1149  //\attention: do not forget to set originator address, sequence
1150  //number and preq ID in HWMP-MAC plugin
1152  preq.SetOriginatorAddress (GetAddress ());
1153  preq.SetPreqID (GetNextPreqId ());
1155  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1156  {
1157  i->second->SendPreq (preq);
1158  }
1160 }
1161 bool
1163 {
1164  return m_doFlag;
1165 }
1166 bool
1168 {
1169  return m_rfFlag;
1170 }
1171 Time
1173 {
1175 }
1176 Time
1178 {
1180 }
1181 uint8_t
1183 {
1184  return m_maxTtl;
1185 }
1186 uint32_t
1188 {
1189  m_preqId++;
1190  return m_preqId;
1191 }
1192 uint32_t
1194 {
1195  m_hwmpSeqno++;
1196  return m_hwmpSeqno;
1197 }
1198 uint32_t
1200 {
1202 }
1203 uint8_t
1205 {
1206  return m_unicastPerrThreshold;
1207 }
1210 {
1211  return m_address;
1212 }
1213 //Statistics:
1215  txUnicast (0),
1216  txBroadcast (0),
1217  txBytes (0),
1218  droppedTtl (0),
1219  totalQueued (0),
1220  totalDropped (0),
1221  initiatedPreq (0),
1222  initiatedPrep (0),
1223  initiatedPerr (0)
1224 {
1225 }
1226 void HwmpProtocol::Statistics::Print (std::ostream & os) const
1227 {
1228  os << "<Statistics "
1229  "txUnicast=\"" << txUnicast << "\" "
1230  "txBroadcast=\"" << txBroadcast << "\" "
1231  "txBytes=\"" << txBytes << "\" "
1232  "droppedTtl=\"" << droppedTtl << "\" "
1233  "totalQueued=\"" << totalQueued << "\" "
1234  "totalDropped=\"" << totalDropped << "\" "
1235  "initiatedPreq=\"" << initiatedPreq << "\" "
1236  "initiatedPrep=\"" << initiatedPrep << "\" "
1237  "initiatedPerr=\"" << initiatedPerr << "\"/>" << std::endl;
1238 }
1239 void
1240 HwmpProtocol::Report (std::ostream & os) const
1241 {
1242  os << "<Hwmp "
1243  "address=\"" << m_address << "\"" << std::endl <<
1244  "maxQueueSize=\"" << m_maxQueueSize << "\"" << std::endl <<
1245  "Dot11MeshHWMPmaxPREQretries=\"" << (uint16_t)m_dot11MeshHWMPmaxPREQretries << "\"" << std::endl <<
1246  "Dot11MeshHWMPnetDiameterTraversalTime=\"" << m_dot11MeshHWMPnetDiameterTraversalTime.GetSeconds () << "\"" << std::endl <<
1247  "Dot11MeshHWMPpreqMinInterval=\"" << m_dot11MeshHWMPpreqMinInterval.GetSeconds () << "\"" << std::endl <<
1248  "Dot11MeshHWMPperrMinInterval=\"" << m_dot11MeshHWMPperrMinInterval.GetSeconds () << "\"" << std::endl <<
1249  "Dot11MeshHWMPactiveRootTimeout=\"" << m_dot11MeshHWMPactiveRootTimeout.GetSeconds () << "\"" << std::endl <<
1250  "Dot11MeshHWMPactivePathTimeout=\"" << m_dot11MeshHWMPactivePathTimeout.GetSeconds () << "\"" << std::endl <<
1251  "Dot11MeshHWMPpathToRootInterval=\"" << m_dot11MeshHWMPpathToRootInterval.GetSeconds () << "\"" << std::endl <<
1252  "Dot11MeshHWMPrannInterval=\"" << m_dot11MeshHWMPrannInterval.GetSeconds () << "\"" << std::endl <<
1253  "isRoot=\"" << m_isRoot << "\"" << std::endl <<
1254  "maxTtl=\"" << (uint16_t)m_maxTtl << "\"" << std::endl <<
1255  "unicastPerrThreshold=\"" << (uint16_t)m_unicastPerrThreshold << "\"" << std::endl <<
1256  "unicastPreqThreshold=\"" << (uint16_t)m_unicastPreqThreshold << "\"" << std::endl <<
1257  "unicastDataThreshold=\"" << (uint16_t)m_unicastDataThreshold << "\"" << std::endl <<
1258  "doFlag=\"" << m_doFlag << "\"" << std::endl <<
1259  "rfFlag=\"" << m_rfFlag << "\">" << std::endl;
1260  m_stats.Print (os);
1261  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
1262  {
1263  plugin->second->Report (os);
1264  }
1265  os << "</Hwmp>" << std::endl;
1266 }
1267 void
1269 {
1270  NS_LOG_FUNCTION (this);
1271  m_stats = Statistics ();
1272  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
1273  {
1274  plugin->second->ResetStats ();
1275  }
1276 }
1277 
1278 int64_t
1280 {
1281  NS_LOG_FUNCTION (this << stream);
1282  m_coefficient->SetStream (stream);
1283  return 1;
1284 }
1285 
1288 {
1289  return m_rtable;
1290 }
1291 
1293  pkt (0),
1294  protocol (0),
1295  inInterface (0)
1296 {
1297 }
1298 } // namespace dot11s
1299 } // namespace ns3
Mac48Address GetDestinationAddress() const
Get destination address function.
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
Ptr< MeshPointDevice > GetMeshPoint() const
Each mesh protocol must be installed on the mesh point to work.
std::string type
type of change
Definition: hwmp-protocol.h:48
AttributeValue implementation for Boolean.
Definition: boolean.h:36
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.
Mac48Address GetOriginatorAddress() const
Get originator address value.
#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.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:831
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
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:355
uint32_t GetOriginatorSeqNumber() const
Get originator sequence numnber value.
uint32_t GetDestinationSeqNumber() const
Get destination sequence number function.
#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:202
See 7.3.2.97 of 802.11s draft 2.07.
LookupResult LookupReactiveExpired(Mac48Address destination)
Return all reactive paths, including expired.
Definition: hwmp-rtable.cc:166
bool GetRfFlag()
Get rf flag 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.
uint8_t GetDestCount() const
Get destination count.
void SetTtl(uint8_t ttl)
Set TTL function.
Time lifetime
lifetime of route
Definition: hwmp-protocol.h:53
Statistics m_stats
statistics
Ptr< HwmpRtable > GetRoutingTable(void) const
Get pointer to HWMP routing table.
uint8_t GetMaxTtl()
Get maximum TTL function.
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
uint32_t seqnum
sequence number
Definition: hwmp-rtable.h:49
Routing table for HWMP – 802.11s routing protocol.
Definition: hwmp-rtable.h:35
std::vector< Mac48Address > GetPreqReceivers(uint32_t interface)
Get PREQ receivers.
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.
Time GetPerrMinInterval()
Get PERR minimum interval function.
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:1381
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:1076
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
mac
Definition: third.py:92
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 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.
Mac48Address GetOriginatorAddress() const
Get originator address function.
void SetLifetime(uint32_t lifetime)
Set lifetime function.
static TypeId GetTypeId()
Get the type ID.
void Report(std::ostream &) const
Statistics:
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
uint32_t GetLifetime() const
Get lifetime function.
Time m_randomStart
Random start in Proactive PREQ propagation.
static Mac48Address ConvertFrom(const Address &address)
uint32_t m_hwmpSeqno
HWMP sequence no.
void SetOriginatorSeqNumber(uint32_t originator_seq_number)
Set originator sequence number.
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:363
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
address
Definition: first.py:37
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
uint32_t GetLifetime() const
Get lifetime value.
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 ...
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
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 .
an EUI-48 address
Definition: mac48-address.h:43
uint32_t GetNextHwmpSeqno()
Get next HWMP sequence no function.
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:1077
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:
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
bool IsNeedNotPrep() const
Check whether Proactive PREP subfield to off.
void ReceivePerr(std::vector< FailedDestination > destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
Handler for receiving Path Error.
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.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:852
std::vector< FailedDestination > destinations
destination list: Mac48Address and sequence number
void Print(std::ostream &os) const
Print function.
uint32_t GetMetric() const
Get metric value.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:859
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:270
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1014
Callback< std::vector< Mac48Address >, uint32_t > m_neighboursCallback
neighbors callback
interfaces
Definition: first.py:41
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
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:1030
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.
void SetSeqno(uint32_t seqno)
Set sequence number.
Definition: hwmp-tag.cc:75
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:874
uint32_t inInterface
incoming device interface ID. (if packet has come from upper layers, this is Mesh point ID) ...
bool QueuePacket(QueuedPacket packet)
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 &#39;double&#39; or &#39;float&#39;...
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:915
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.
uint32_t GetMetric() const
Get metric function.
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.