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/random-variable-stream.h"
29 #include "ns3/string.h"
30 #include "ns3/pointer.h"
31 #include "ns3/mesh-point-device.h"
32 #include "ns3/wifi-net-device.h"
33 #include "ns3/mesh-wifi-interface-mac.h"
34 #include "ns3/random-variable-stream.h"
35 #include "airtime-metric.h"
36 #include "ie-dot11s-preq.h"
37 #include "ie-dot11s-prep.h"
38 #include "ns3/trace-source-accessor.h"
39 #include "ie-dot11s-perr.h"
40 
41 namespace ns3 {
42 
43 NS_LOG_COMPONENT_DEFINE ("HwmpProtocol");
44 
45 namespace dot11s {
46 
47 NS_OBJECT_ENSURE_REGISTERED (HwmpProtocol);
48 
49 TypeId
51 {
52  static TypeId tid = TypeId ("ns3::dot11s::HwmpProtocol")
54  .SetGroupName ("Mesh")
55  .AddConstructor<HwmpProtocol> ()
56  .AddAttribute ( "RandomStart",
57  "Random delay at first proactive PREQ",
58  TimeValue (Seconds (0.1)),
62  )
63  .AddAttribute ( "MaxQueueSize",
64  "Maximum number of packets we can store when resolving route",
65  UintegerValue (255),
68  MakeUintegerChecker<uint16_t> (1)
69  )
70  .AddAttribute ( "Dot11MeshHWMPmaxPREQretries",
71  "Maximum number of retries before we suppose the destination to be unreachable",
72  UintegerValue (3),
75  MakeUintegerChecker<uint8_t> (1)
76  )
77  .AddAttribute ( "Dot11MeshHWMPnetDiameterTraversalTime",
78  "Time we suppose the packet to go from one edge of the network to another",
79  TimeValue (MicroSeconds (1024*100)),
83  )
84  .AddAttribute ( "Dot11MeshHWMPpreqMinInterval",
85  "Minimal interval between to successive PREQs",
86  TimeValue (MicroSeconds (1024*100)),
90  )
91  .AddAttribute ( "Dot11MeshHWMPperrMinInterval",
92  "Minimal interval between to successive PREQs",
93  TimeValue (MicroSeconds (1024*100)),
96  )
97  .AddAttribute ( "Dot11MeshHWMPactiveRootTimeout",
98  "Lifetime of proactive routing information",
99  TimeValue (MicroSeconds (1024*5000)),
102  MakeTimeChecker ()
103  )
104  .AddAttribute ( "Dot11MeshHWMPactivePathTimeout",
105  "Lifetime of reactive routing information",
106  TimeValue (MicroSeconds (1024*5000)),
109  MakeTimeChecker ()
110  )
111  .AddAttribute ( "Dot11MeshHWMPpathToRootInterval",
112  "Interval between two successive proactive PREQs",
113  TimeValue (MicroSeconds (1024*2000)),
116  MakeTimeChecker ()
117  )
118  .AddAttribute ( "Dot11MeshHWMPrannInterval",
119  "Lifetime of proactive routing information",
120  TimeValue (MicroSeconds (1024*5000)),
123  MakeTimeChecker ()
124  )
125  .AddAttribute ( "MaxTtl",
126  "Initial value of Time To Live field",
127  UintegerValue (32),
130  MakeUintegerChecker<uint8_t> (2)
131  )
132  .AddAttribute ( "UnicastPerrThreshold",
133  "Maximum number of PERR receivers, when we send a PERR as a chain of unicasts",
134  UintegerValue (32),
137  MakeUintegerChecker<uint8_t> (1)
138  )
139  .AddAttribute ( "UnicastPreqThreshold",
140  "Maximum number of PREQ receivers, when we send a PREQ as a chain of unicasts",
141  UintegerValue (1),
144  MakeUintegerChecker<uint8_t> (1)
145  )
146  .AddAttribute ( "UnicastDataThreshold",
147  "Maximum number of broadcast receivers, when we send a broadcast as a chain of unicasts",
148  UintegerValue (1),
151  MakeUintegerChecker<uint8_t> (1)
152  )
153  .AddAttribute ( "DoFlag",
154  "Destination only HWMP flag",
155  BooleanValue (false),
159  )
160  .AddAttribute ( "RfFlag",
161  "Reply and forward flag",
162  BooleanValue (true),
166  )
167  .AddTraceSource ( "RouteDiscoveryTime",
168  "The time of route discovery procedure",
171  "ns3::Time::TracedCallback"
172  )
173  .AddTraceSource ("RouteChange",
174  "Routing table changed",
176  "ns3::HwmpProtocol::RouteChangeTracedCallback"
177  )
178  ;
179  return tid;
180 }
181 
183  m_dataSeqno (1),
184  m_hwmpSeqno (1),
185  m_preqId (0),
186  m_rtable (CreateObject<HwmpRtable> ()),
187  m_randomStart (Seconds (0.1)),
188  m_maxQueueSize (255),
189  m_dot11MeshHWMPmaxPREQretries (3),
190  m_dot11MeshHWMPnetDiameterTraversalTime (MicroSeconds (1024*100)),
191  m_dot11MeshHWMPpreqMinInterval (MicroSeconds (1024*100)),
192  m_dot11MeshHWMPperrMinInterval (MicroSeconds (1024*100)),
193  m_dot11MeshHWMPactiveRootTimeout (MicroSeconds (1024*5000)),
194  m_dot11MeshHWMPactivePathTimeout (MicroSeconds (1024*5000)),
195  m_dot11MeshHWMPpathToRootInterval (MicroSeconds (1024*2000)),
196  m_dot11MeshHWMPrannInterval (MicroSeconds (1024*5000)),
197  m_isRoot (false),
198  m_maxTtl (32),
199  m_unicastPerrThreshold (32),
200  m_unicastPreqThreshold (1),
201  m_unicastDataThreshold (1),
202  m_doFlag (false),
203  m_rfFlag (false)
204 {
205  NS_LOG_FUNCTION (this);
206  m_coefficient = CreateObject<UniformRandomVariable> ();
207 }
208 
210 {
211  NS_LOG_FUNCTION (this);
212 }
213 
214 void
216 {
217  NS_LOG_FUNCTION (this);
219  if (m_isRoot)
220  {
221  Time randomStart = Seconds (m_coefficient->GetValue ());
223  }
224 }
225 
226 void
228 {
229  NS_LOG_FUNCTION (this);
230  for (std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.begin (); i != m_preqTimeouts.end (); i++)
231  {
232  i->second.preqTimeout.Cancel ();
233  }
235  m_preqTimeouts.clear ();
236  m_lastDataSeqno.clear ();
237  m_hwmpSeqnoMetricDatabase.clear ();
238  m_interfaces.clear ();
239  m_rqueue.clear ();
240  m_rtable = 0;
241  m_mp = 0;
242 }
243 
244 bool
246  uint32_t sourceIface,
247  const Mac48Address source,
248  const Mac48Address destination,
249  Ptr<const Packet> constPacket,
250  uint16_t protocolType, //ethrnet 'Protocol' field
252  )
253 {
254  NS_LOG_FUNCTION (this << sourceIface << source << destination << constPacket << protocolType);
255  Ptr <Packet> packet = constPacket->Copy ();
256  HwmpTag tag;
257  if (sourceIface == GetMeshPoint ()->GetIfIndex ())
258  {
259  // packet from level 3
260  if (packet->PeekPacketTag (tag))
261  {
262  NS_FATAL_ERROR ("HWMP tag has come with a packet from upper layer. This must not occur...");
263  }
264  //Filling TAG:
265  if (destination == Mac48Address::GetBroadcast ())
266  {
267  tag.SetSeqno (m_dataSeqno++);
268  }
269  tag.SetTtl (m_maxTtl);
270  }
271  else
272  {
273  if (!packet->RemovePacketTag (tag))
274  {
275  NS_FATAL_ERROR ("HWMP tag is supposed to be here at this point.");
276  }
277  tag.DecrementTtl ();
278  if (tag.GetTtl () == 0)
279  {
280  NS_LOG_DEBUG ("Dropping frame due to TTL expiry");
282  return false;
283  }
284  }
285  if (destination == Mac48Address::GetBroadcast ())
286  {
288  m_stats.txBytes += packet->GetSize ();
289  //channel IDs where we have already sent broadcast:
290  std::vector<uint16_t> channels;
291  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
292  {
293  bool shouldSend = true;
294  for (std::vector<uint16_t>::const_iterator chan = channels.begin (); chan != channels.end (); chan++)
295  {
296  if ((*chan) == plugin->second->GetChannelId ())
297  {
298  shouldSend = false;
299  }
300  }
301  if (!shouldSend)
302  {
303  continue;
304  }
305  channels.push_back (plugin->second->GetChannelId ());
306  std::vector<Mac48Address> receivers = GetBroadcastReceivers (plugin->first);
307  for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i++)
308  {
309  Ptr<Packet> packetCopy = packet->Copy ();
310  //
311  // 64-bit Intel valgrind complains about tag.SetAddress (*i). It
312  // likes this just fine.
313  //
314  Mac48Address address = *i;
315  tag.SetAddress (address);
316  packetCopy->AddPacketTag (tag);
317  NS_LOG_DEBUG ("Sending route reply for broadcast; address " << address);
318  routeReply (true, packetCopy, source, destination, protocolType, plugin->first);
319  }
320  }
321  }
322  else
323  {
324  return ForwardUnicast (sourceIface, source, destination, packet, protocolType, routeReply, tag.GetTtl ());
325  }
326  return true;
327 }
328 bool
329 HwmpProtocol::RemoveRoutingStuff (uint32_t fromIface, const Mac48Address source,
330  const Mac48Address destination, Ptr<Packet> packet, uint16_t& protocolType)
331 {
332  HwmpTag tag;
333  if (!packet->RemovePacketTag (tag))
334  {
335  NS_FATAL_ERROR ("HWMP tag must exist when packet received from the network");
336  }
337  return true;
338 }
339 bool
340 HwmpProtocol::ForwardUnicast (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination,
341  Ptr<Packet> packet, uint16_t protocolType, RouteReplyCallback routeReply, uint32_t ttl)
342 {
343  NS_LOG_FUNCTION (this << sourceIface << source << destination << packet << protocolType << ttl);
344  NS_ASSERT (destination != Mac48Address::GetBroadcast ());
346  NS_LOG_DEBUG ("Requested src = "<<source<<", dst = "<<destination<<", I am "<<GetAddress ()<<", RA = "<<result.retransmitter);
347  if (result.retransmitter == Mac48Address::GetBroadcast ())
348  {
350  }
351  HwmpTag tag;
352  tag.SetAddress (result.retransmitter);
353  tag.SetTtl (ttl);
354  //seqno and metric is not used;
355  packet->AddPacketTag (tag);
356  if (result.retransmitter != Mac48Address::GetBroadcast ())
357  {
358  //reply immediately:
359  routeReply (true, packet, source, destination, protocolType, result.ifIndex);
360  m_stats.txUnicast++;
361  m_stats.txBytes += packet->GetSize ();
362  return true;
363  }
364  if (sourceIface != GetMeshPoint ()->GetIfIndex ())
365  {
366  //Start path error procedure:
367  NS_LOG_DEBUG ("Must Send PERR");
368  result = m_rtable->LookupReactiveExpired (destination);
369  NS_LOG_DEBUG ("Path error " << result.retransmitter);
370  //1. Lookup expired reactive path. If exists - start path error
371  // procedure towards a next hop of this path
372  //2. If there was no reactive path, we lookup expired proactive
373  // path. If exist - start path error procedure towards path to
374  // root
375  if (result.retransmitter == Mac48Address::GetBroadcast ())
376  {
377  NS_LOG_DEBUG ("Path error, lookup expired proactive path");
379  }
380  if (result.retransmitter != Mac48Address::GetBroadcast ())
381  {
382  NS_LOG_DEBUG ("Path error, initiate reactive path error");
383  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (result.retransmitter);
384  InitiatePathError (MakePathError (destinations));
385  }
387  return false;
388  }
389  //Request a destination:
390  result = m_rtable->LookupReactiveExpired (destination);
391  if (ShouldSendPreq (destination))
392  {
393  uint32_t originator_seqno = GetNextHwmpSeqno ();
394  uint32_t dst_seqno = 0;
395  if (result.retransmitter != Mac48Address::GetBroadcast ())
396  {
397  dst_seqno = result.seqnum;
398  }
400  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
401  {
402  i->second->RequestDestination (destination, originator_seqno, dst_seqno);
403  }
404  }
405  QueuedPacket pkt;
406  pkt.pkt = packet;
407  pkt.dst = destination;
408  pkt.src = source;
409  pkt.protocol = protocolType;
410  pkt.reply = routeReply;
411  pkt.inInterface = sourceIface;
412  if (QueuePacket (pkt))
413  {
415  return true;
416  }
417  else
418  {
420  NS_LOG_DEBUG ("Dropping packet from " << source << " to " << destination << " due to queue overflow");
421  return false;
422  }
423 }
424 void
425 HwmpProtocol::ReceivePreq (IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
426 {
427  NS_LOG_FUNCTION (this << from << interface << fromMp << metric);
428  preq.IncrementMetric (metric);
429  //acceptance cretirea:
430  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
431  preq.GetOriginatorAddress ());
432  bool freshInfo (true);
433  if (i != m_hwmpSeqnoMetricDatabase.end ())
434  {
435  if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber ()) > 0)
436  {
437  return;
438  }
439  if (i->second.first == preq.GetOriginatorSeqNumber ())
440  {
441  freshInfo = false;
442  if (i->second.second <= preq.GetMetric ())
443  {
444  return;
445  }
446  }
447  }
449  std::make_pair (preq.GetOriginatorSeqNumber (), preq.GetMetric ());
450  NS_LOG_DEBUG ("I am " << GetAddress () << ", Accepted preq from address" << from << ", preq:" << preq);
451  std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
452  //Add reactive path to originator:
453  if (
454  (freshInfo) ||
455  (
458  )
459  )
460  {
462  preq.GetOriginatorAddress (),
463  from,
464  interface,
465  preq.GetMetric (),
466  MicroSeconds (preq.GetLifetime () * 1024),
467  preq.GetOriginatorSeqNumber ()
468  );
469  // Notify trace source of routing change
470  struct RouteChange rChange;
471  rChange.type = "Add Reactive";
472  rChange.destination = preq.GetOriginatorAddress ();
473  rChange.retransmitter = from;
474  rChange.interface = interface;
475  rChange.metric = preq.GetMetric ();
476  rChange.lifetime = MicroSeconds (preq.GetLifetime () * 1024);
477  rChange.seqnum = preq.GetOriginatorSeqNumber ();
478  m_routeChangeTraceSource (rChange);
480  }
481  if (
483  (m_rtable->LookupReactive (fromMp).metric > metric)
484  )
485  {
487  fromMp,
488  from,
489  interface,
490  metric,
491  MicroSeconds (preq.GetLifetime () * 1024),
492  preq.GetOriginatorSeqNumber ()
493  );
494  // Notify trace source of routing change
495  struct RouteChange rChange;
496  rChange.type = "Add Reactive";
497  rChange.destination = fromMp;
498  rChange.retransmitter = from;
499  rChange.interface = interface;
500  rChange.metric = metric;
501  rChange.lifetime = MicroSeconds (preq.GetLifetime () * 1024);
502  rChange.seqnum = preq.GetOriginatorSeqNumber ();
503  m_routeChangeTraceSource (rChange);
504  ReactivePathResolved (fromMp);
505  }
506  for (std::vector<Ptr<DestinationAddressUnit> >::const_iterator i = destinations.begin (); i != destinations.end (); i++)
507  {
508  if ((*i)->GetDestinationAddress () == Mac48Address::GetBroadcast ())
509  {
510  //only proactive PREQ contains destination
511  //address as broadcast! Proactive preq MUST
512  //have destination count equal to 1 and
513  //per destination flags DO and RF
514  NS_ASSERT (preq.GetDestCount () == 1);
515  NS_ASSERT (((*i)->IsDo ()) && ((*i)->IsRf ()));
516  //Add proactive path only if it is the better then existed
517  //before
518  if (
519  ((m_rtable->LookupProactive ()).retransmitter == Mac48Address::GetBroadcast ()) ||
520  ((m_rtable->LookupProactive ()).metric > preq.GetMetric ())
521  )
522  {
524  preq.GetMetric (),
525  preq.GetOriginatorAddress (),
526  from,
527  interface,
528  MicroSeconds (preq.GetLifetime () * 1024),
529  preq.GetOriginatorSeqNumber ()
530  );
531  // Notify trace source of routing change
532  struct RouteChange rChange;
533  rChange.type = "Add Proactive";
534  rChange.destination = preq.GetOriginatorAddress ();
535  rChange.retransmitter = from;
536  rChange.interface = interface;
537  rChange.metric = preq.GetMetric ();
538  rChange.lifetime = MicroSeconds (preq.GetLifetime () * 1024);
539  rChange.seqnum = preq.GetOriginatorSeqNumber ();
540  m_routeChangeTraceSource (rChange);
542  }
543  if (!preq.IsNeedNotPrep ())
544  {
545  SendPrep (
546  GetAddress (),
547  preq.GetOriginatorAddress (),
548  from,
549  (uint32_t)0,
550  preq.GetOriginatorSeqNumber (),
551  GetNextHwmpSeqno (),
552  preq.GetLifetime (),
553  interface
554  );
555  }
556  break;
557  }
558  if ((*i)->GetDestinationAddress () == GetAddress ())
559  {
560  SendPrep (
561  GetAddress (),
562  preq.GetOriginatorAddress (),
563  from,
564  (uint32_t)0,
565  preq.GetOriginatorSeqNumber (),
566  GetNextHwmpSeqno (),
567  preq.GetLifetime (),
568  interface
569  );
571  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
572  continue;
573  }
574  //check if can answer:
575  HwmpRtable::LookupResult result = m_rtable->LookupReactive ((*i)->GetDestinationAddress ());
576  if ((!((*i)->IsDo ())) && (result.retransmitter != Mac48Address::GetBroadcast ()))
577  {
578  //have a valid information and can answer
579  uint32_t lifetime = result.lifetime.GetMicroSeconds () / 1024;
580  if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber ()) >= 0))
581  {
582  SendPrep (
583  (*i)->GetDestinationAddress (),
584  preq.GetOriginatorAddress (),
585  from,
586  result.metric,
587  preq.GetOriginatorSeqNumber (),
588  result.seqnum,
589  lifetime,
590  interface
591  );
592  m_rtable->AddPrecursor ((*i)->GetDestinationAddress (), interface, from,
593  MicroSeconds (preq.GetLifetime () * 1024));
594  if ((*i)->IsRf ())
595  {
596  (*i)->SetFlags (true, false, (*i)->IsUsn ()); //DO = 1, RF = 0
597  }
598  else
599  {
600  preq.DelDestinationAddressElement ((*i)->GetDestinationAddress ());
601  continue;
602  }
603  }
604  }
605  }
606  //check if must retransmit:
607  if (preq.GetDestCount () == 0)
608  {
609  return;
610  }
611  //Forward PREQ to all interfaces:
612  NS_LOG_DEBUG ("I am " << GetAddress () << "retransmitting PREQ:" << preq);
613  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
614  {
615  Time forwardingDelay = GetMeshPoint ()->GetForwardingDelay ();
616  NS_LOG_DEBUG ("Forwarding PREQ from " << from << " with delay " << forwardingDelay.As (Time::US));
617  Simulator::Schedule (forwardingDelay, &HwmpProtocolMac::SendPreq, i->second, preq);
618  }
619 }
620 void
621 HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
622 {
623  NS_LOG_FUNCTION (this << from << interface << fromMp << metric);
624  prep.IncrementMetric (metric);
625  //acceptance cretirea:
626  std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
627  prep.GetOriginatorAddress ());
628  bool freshInfo (true);
629  uint32_t sequence = prep.GetDestinationSeqNumber ();
630  if (i != m_hwmpSeqnoMetricDatabase.end ())
631  {
632  if ((int32_t)(i->second.first - sequence) > 0)
633  {
634  return;
635  }
636  if (i->second.first == sequence)
637  {
638  freshInfo = false;
639  }
640  }
641  m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (sequence, prep.GetMetric ());
642  //update routing info
643  //Now add a path to destination and add precursor to source
644  NS_LOG_DEBUG ("I am " << GetAddress () << ", received prep from " << prep.GetOriginatorAddress () << ", receiver was:" << from);
646  //Add a reactive path only if seqno is fresher or it improves the
647  //metric
648  if (
649  (freshInfo) ||
650  (
651  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).retransmitter == Mac48Address::GetBroadcast ()) ||
652  ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).metric > prep.GetMetric ())
653  )
654  )
655  {
657  prep.GetOriginatorAddress (),
658  from,
659  interface,
660  prep.GetMetric (),
661  MicroSeconds (prep.GetLifetime () * 1024),
662  sequence);
663  // Notify trace source of routing change
664  struct RouteChange rChange;
665  rChange.type = "Add Reactive";
666  rChange.destination = prep.GetOriginatorAddress ();
667  rChange.retransmitter = from;
668  rChange.interface = interface;
669  rChange.metric = prep.GetMetric ();
670  rChange.lifetime = MicroSeconds (prep.GetLifetime () * 1024);
671  rChange.seqnum = sequence;
672  m_routeChangeTraceSource (rChange);
673  m_rtable->AddPrecursor (prep.GetDestinationAddress (), interface, from,
674  MicroSeconds (prep.GetLifetime () * 1024));
675  if (result.retransmitter != Mac48Address::GetBroadcast ())
676  {
677  m_rtable->AddPrecursor (prep.GetOriginatorAddress (), interface, result.retransmitter,
678  result.lifetime);
679  }
681  }
682  if (
683  ((m_rtable->LookupReactive (fromMp)).retransmitter == Mac48Address::GetBroadcast ()) ||
684  ((m_rtable->LookupReactive (fromMp)).metric > metric)
685  )
686  {
688  fromMp,
689  from,
690  interface,
691  metric,
692  MicroSeconds (prep.GetLifetime () * 1024),
693  sequence);
694  // Notify trace source of routing change
695  struct RouteChange rChange;
696  rChange.type = "Add Reactive";
697  rChange.destination = fromMp;
698  rChange.retransmitter = from;
699  rChange.interface = interface;
700  rChange.metric = metric;
701  rChange.lifetime = MicroSeconds (prep.GetLifetime () * 1024);
702  rChange.seqnum = sequence;
703  m_routeChangeTraceSource (rChange);
704  ReactivePathResolved (fromMp);
705  }
706  if (prep.GetDestinationAddress () == GetAddress ())
707  {
708  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", resolved "<<prep.GetOriginatorAddress ());
709  return;
710  }
711  if (result.retransmitter == Mac48Address::GetBroadcast ())
712  {
713  return;
714  }
715  //Forward PREP
716  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (result.ifIndex);
717  NS_ASSERT (prep_sender != m_interfaces.end ());
718  Time forwardingDelay = GetMeshPoint ()->GetForwardingDelay ();
719  NS_LOG_DEBUG ("Forwarding PREP from " << from << " with delay " << forwardingDelay.As (Time::US));
720  Simulator::Schedule (forwardingDelay, &HwmpProtocolMac::SendPrep, prep_sender->second, prep, result.retransmitter);
721 }
722 void
723 HwmpProtocol::ReceivePerr (std::vector<FailedDestination> destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
724 {
725  NS_LOG_FUNCTION (this << from << interface << fromMp);
726  //Acceptance cretirea:
727  NS_LOG_DEBUG ("I am "<<GetAddress ()<<", received PERR from "<<from);
728  std::vector<FailedDestination> retval;
730  for (unsigned int i = 0; i < destinations.size (); i++)
731  {
732  result = m_rtable->LookupReactiveExpired (destinations[i].destination);
733  if (!(
734  (result.retransmitter != from) ||
735  (result.ifIndex != interface) ||
736  ((int32_t)(result.seqnum - destinations[i].seqnum) > 0)
737  ))
738  {
739  retval.push_back (destinations[i]);
740  }
741  }
742  if (retval.size () == 0)
743  {
744  return;
745  }
746  ForwardPathError (MakePathError (retval));
747 }
748 void
750  Mac48Address src,
751  Mac48Address dst,
752  Mac48Address retransmitter,
753  uint32_t initMetric,
754  uint32_t originatorDsn,
755  uint32_t destinationSN,
756  uint32_t lifetime,
757  uint32_t interface)
758 {
759  IePrep prep;
760  prep.SetHopcount (0);
761  prep.SetTtl (m_maxTtl);
762  prep.SetDestinationAddress (dst);
763  prep.SetDestinationSeqNumber (destinationSN);
764  prep.SetLifetime (lifetime);
765  prep.SetMetric (initMetric);
766  prep.SetOriginatorAddress (src);
767  prep.SetOriginatorSeqNumber (originatorDsn);
768  HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (interface);
769  NS_ASSERT (prep_sender != m_interfaces.end ());
770  prep_sender->second->SendPrep (prep, retransmitter);
772 }
773 bool
775 {
776  NS_LOG_FUNCTION (this << mp);
777  m_mp = mp;
778  std::vector<Ptr<NetDevice> > interfaces = mp->GetInterfaces ();
779  for (std::vector<Ptr<NetDevice> >::const_iterator i = interfaces.begin (); i != interfaces.end (); i++)
780  {
781  // Checking for compatible net device
782  Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice> ();
783  if (wifiNetDev == 0)
784  {
785  return false;
786  }
787  Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
788  if (mac == 0)
789  {
790  return false;
791  }
792  // Installing plugins:
793  Ptr<HwmpProtocolMac> hwmpMac = Create<HwmpProtocolMac> (wifiNetDev->GetIfIndex (), this);
794  m_interfaces[wifiNetDev->GetIfIndex ()] = hwmpMac;
795  mac->InstallPlugin (hwmpMac);
796  //Installing airtime link metric:
797  Ptr<AirtimeLinkMetricCalculator> metric = CreateObject <AirtimeLinkMetricCalculator> ();
798  mac->SetLinkMetricCallback (MakeCallback (&AirtimeLinkMetricCalculator::CalculateMetric, metric));
799  }
800  mp->SetRoutingProtocol (this);
801  // Mesh point aggregates all installed protocols
802  mp->AggregateObject (this);
803  m_address = Mac48Address::ConvertFrom (mp->GetAddress ()); // address;
804  return true;
805 }
806 void
807 HwmpProtocol::PeerLinkStatus (Mac48Address meshPointAddress, Mac48Address peerAddress, uint32_t interface, bool status)
808 {
809  NS_LOG_FUNCTION (this << meshPointAddress << peerAddress << interface << status);
810  if (status)
811  {
812  return;
813  }
814  std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations (peerAddress);
815  NS_LOG_DEBUG (destinations.size () << " failed destinations for peer address " << peerAddress);
816  InitiatePathError (MakePathError (destinations));
817 }
818 void
819 HwmpProtocol::SetNeighboursCallback (Callback<std::vector<Mac48Address>, uint32_t> cb)
820 {
822 }
823 bool
825 {
826  NS_LOG_FUNCTION (this << seqno << source);
827  if (source == GetAddress ())
828  {
829  NS_LOG_DEBUG ("Dropping seqno " << seqno << "; from self");
830  return true;
831  }
832  std::map<Mac48Address, uint32_t,std::less<Mac48Address> >::const_iterator i = m_lastDataSeqno.find (source);
833  if (i == m_lastDataSeqno.end ())
834  {
835  m_lastDataSeqno[source] = seqno;
836  }
837  else
838  {
839  if ((int32_t)(i->second - seqno) >= 0)
840  {
841  NS_LOG_DEBUG ("Dropping seqno " << seqno << "; stale frame");
842  return true;
843  }
844  m_lastDataSeqno[source] = seqno;
845  }
846  return false;
847 }
849 HwmpProtocol::MakePathError (std::vector<FailedDestination> destinations)
850 {
851  NS_LOG_FUNCTION (this);
852  PathError retval;
853  //HwmpRtable increments a sequence number as written in 11B.9.7.2
854  retval.receivers = GetPerrReceivers (destinations);
855  if (retval.receivers.size () == 0)
856  {
857  return retval;
858  }
860  for (unsigned int i = 0; i < destinations.size (); i++)
861  {
862  retval.destinations.push_back (destinations[i]);
863  m_rtable->DeleteReactivePath (destinations[i].destination);
864  // Notify trace source of routing change
865  struct RouteChange rChange;
866  rChange.type = "Delete Reactive";
867  rChange.destination = destinations[i].destination;
868  rChange.seqnum = destinations[i].seqnum;
869  m_routeChangeTraceSource (rChange);
870  }
871  return retval;
872 }
873 void
875 {
876  NS_LOG_FUNCTION (this);
877  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
878  {
879  std::vector<Mac48Address> receivers_for_interface;
880  for (unsigned int j = 0; j < perr.receivers.size (); j++)
881  {
882  if (i->first == perr.receivers[j].first)
883  {
884  receivers_for_interface.push_back (perr.receivers[j].second);
885  }
886  }
887  i->second->InitiatePerr (perr.destinations, receivers_for_interface);
888  }
889 }
890 void
892 {
893  NS_LOG_FUNCTION (this);
894  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
895  {
896  std::vector<Mac48Address> receivers_for_interface;
897  for (unsigned int j = 0; j < perr.receivers.size (); j++)
898  {
899  if (i->first == perr.receivers[j].first)
900  {
901  receivers_for_interface.push_back (perr.receivers[j].second);
902  }
903  }
904  Time forwardingDelay = GetMeshPoint ()->GetForwardingDelay ();
905  NS_LOG_DEBUG ("Forwarding PERR with delay " << forwardingDelay.As (Time::US));
906  Simulator::Schedule (forwardingDelay, &HwmpProtocolMac::ForwardPerr, i->second, perr.destinations, receivers_for_interface);
907  i->second->ForwardPerr (perr.destinations, receivers_for_interface);
908  }
909 }
910 
911 std::vector<std::pair<uint32_t, Mac48Address> >
912 HwmpProtocol::GetPerrReceivers (std::vector<FailedDestination> failedDest)
913 {
914  NS_LOG_FUNCTION (this);
916  for (unsigned int i = 0; i < failedDest.size (); i++)
917  {
918  HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors (failedDest[i].destination);
919  m_rtable->DeleteReactivePath (failedDest[i].destination);
920  // Notify trace source of routing change
921  struct RouteChange rChange;
922  rChange.type = "Delete Reactive";
923  rChange.destination = failedDest[i].destination;
924  rChange.seqnum = failedDest[i].seqnum;
925  m_routeChangeTraceSource (rChange);
926  m_rtable->DeleteProactivePath (failedDest[i].destination);
927  // Notify trace source of routing change
928  struct RouteChange rChangePro;
929  rChangePro.type = "Delete Proactive";
930  rChangePro.destination = failedDest[i].destination;
931  rChangePro.seqnum = failedDest[i].seqnum;
932  m_routeChangeTraceSource (rChangePro);
933  for (unsigned int j = 0; j < precursors.size (); j++)
934  {
935  retval.push_back (precursors[j]);
936  }
937  }
938  //Check if we have duplicates in retval and precursors:
939  for (unsigned int i = 0; i < retval.size (); i++)
940  {
941  for (unsigned int j = i+1; j < retval.size (); j++)
942  {
943  if (retval[i].second == retval[j].second)
944  {
945  retval.erase (retval.begin () + j);
946  }
947  }
948  }
949  return retval;
950 }
951 std::vector<Mac48Address>
952 HwmpProtocol::GetPreqReceivers (uint32_t interface)
953 {
954  NS_LOG_FUNCTION (this << interface);
955  std::vector<Mac48Address> retval;
956  if (!m_neighboursCallback.IsNull ())
957  {
958  retval = m_neighboursCallback (interface);
959  }
960  if ((retval.size () >= m_unicastPreqThreshold) || (retval.size () == 0))
961  {
962  retval.clear ();
963  retval.push_back (Mac48Address::GetBroadcast ());
964  }
965  return retval;
966 }
967 std::vector<Mac48Address>
969 {
970  NS_LOG_FUNCTION (this << interface);
971  std::vector<Mac48Address> retval;
972  if (!m_neighboursCallback.IsNull ())
973  {
974  retval = m_neighboursCallback (interface);
975  }
976  if ((retval.size () >= m_unicastDataThreshold) || (retval.size () == 0))
977  {
978  retval.clear ();
979  retval.push_back (Mac48Address::GetBroadcast ());
980  }
981  return retval;
982 }
983 
984 bool
986 {
987  NS_LOG_FUNCTION (this);
988  if (m_rqueue.size () > m_maxQueueSize)
989  {
990  return false;
991  }
992  m_rqueue.push_back (packet);
993  return true;
994 }
995 
998 {
999  NS_LOG_FUNCTION (this << dst);
1000  QueuedPacket retval;
1001  retval.pkt = 0;
1002  for (std::vector<QueuedPacket>::iterator i = m_rqueue.begin (); i != m_rqueue.end (); i++)
1003  {
1004  if ((*i).dst == dst)
1005  {
1006  retval = (*i);
1007  m_rqueue.erase (i);
1008  break;
1009  }
1010  }
1011  return retval;
1012 }
1013 
1016 {
1017  NS_LOG_FUNCTION (this);
1018  QueuedPacket retval;
1019  retval.pkt = 0;
1020  if (m_rqueue.size () != 0)
1021  {
1022  retval = m_rqueue[0];
1023  m_rqueue.erase (m_rqueue.begin ());
1024  }
1025  return retval;
1026 }
1027 
1028 void
1030 {
1031  NS_LOG_FUNCTION (this << dst);
1032  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1033  if (i != m_preqTimeouts.end ())
1034  {
1035  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
1036  }
1037 
1039  NS_ASSERT (result.retransmitter != Mac48Address::GetBroadcast ());
1040  //Send all packets stored for this destination
1041  QueuedPacket packet = DequeueFirstPacketByDst (dst);
1042  while (packet.pkt != 0)
1043  {
1044  //set RA tag for retransmitter:
1045  HwmpTag tag;
1046  packet.pkt->RemovePacketTag (tag);
1047  tag.SetAddress (result.retransmitter);
1048  packet.pkt->AddPacketTag (tag);
1049  m_stats.txUnicast++;
1050  m_stats.txBytes += packet.pkt->GetSize ();
1051  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1052 
1053  packet = DequeueFirstPacketByDst (dst);
1054  }
1055 }
1056 void
1058 {
1059  NS_LOG_FUNCTION (this);
1060  //send all packets to root
1062  NS_ASSERT (result.retransmitter != Mac48Address::GetBroadcast ());
1063  QueuedPacket packet = DequeueFirstPacket ();
1064  while (packet.pkt != 0)
1065  {
1066  //set RA tag for retransmitter:
1067  HwmpTag tag;
1068  if (!packet.pkt->RemovePacketTag (tag))
1069  {
1070  NS_FATAL_ERROR ("HWMP tag must be present at this point");
1071  }
1072  tag.SetAddress (result.retransmitter);
1073  packet.pkt->AddPacketTag (tag);
1074  m_stats.txUnicast++;
1075  m_stats.txBytes += packet.pkt->GetSize ();
1076  packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1077 
1078  packet = DequeueFirstPacket ();
1079  }
1080 }
1081 
1082 bool
1084 {
1085  NS_LOG_FUNCTION (this << dst);
1086  std::map<Mac48Address, PreqEvent>::const_iterator i = m_preqTimeouts.find (dst);
1087  if (i == m_preqTimeouts.end ())
1088  {
1089  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
1091  &HwmpProtocol::RetryPathDiscovery, this, dst, 1);
1092  m_preqTimeouts[dst].whenScheduled = Simulator::Now ();
1093  return true;
1094  }
1095  return false;
1096 }
1097 void
1099 {
1100  NS_LOG_FUNCTION (this << dst << (uint16_t) numOfRetry);
1102  if (result.retransmitter == Mac48Address::GetBroadcast ())
1103  {
1105  }
1106  if (result.retransmitter != Mac48Address::GetBroadcast ())
1107  {
1108  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1109  NS_ASSERT (i != m_preqTimeouts.end ());
1110  m_preqTimeouts.erase (i);
1111  return;
1112  }
1113  if (numOfRetry > m_dot11MeshHWMPmaxPREQretries)
1114  {
1115  QueuedPacket packet = DequeueFirstPacketByDst (dst);
1116  //purge queue and delete entry from retryDatabase
1117  while (packet.pkt != 0)
1118  {
1120  packet.reply (false, packet.pkt, packet.src, packet.dst, packet.protocol, HwmpRtable::MAX_METRIC);
1121  packet = DequeueFirstPacketByDst (dst);
1122  }
1123  std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
1124  NS_ASSERT (i != m_preqTimeouts.end ());
1125  m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
1126  m_preqTimeouts.erase (i);
1127  return;
1128  }
1129  numOfRetry++;
1130  uint32_t originator_seqno = GetNextHwmpSeqno ();
1131  uint32_t dst_seqno = m_rtable->LookupReactiveExpired (dst).seqnum;
1132  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1133  {
1134  i->second->RequestDestination (dst, originator_seqno, dst_seqno);
1135  }
1136  m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
1137  Time ((2 * (numOfRetry + 1)) * m_dot11MeshHWMPnetDiameterTraversalTime),
1138  &HwmpProtocol::RetryPathDiscovery, this, dst, numOfRetry);
1139 }
1140 //Proactive PREQ routines:
1141 void
1143 {
1144  NS_LOG_FUNCTION (this);
1145  NS_LOG_DEBUG ("ROOT IS: " << m_address);
1146  m_isRoot = true;
1147 }
1148 void
1150 {
1151  NS_LOG_FUNCTION (this);
1153 }
1154 void
1156 {
1157  NS_LOG_FUNCTION (this);
1158  IePreq preq;
1159  //By default: must answer
1160  preq.SetHopcount (0);
1161  preq.SetTTL (m_maxTtl);
1163  //\attention: do not forget to set originator address, sequence
1164  //number and preq ID in HWMP-MAC plugin
1166  preq.SetOriginatorAddress (GetAddress ());
1167  preq.SetPreqID (GetNextPreqId ());
1169  for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1170  {
1171  i->second->SendPreq (preq);
1172  }
1174 }
1175 bool
1177 {
1178  return m_doFlag;
1179 }
1180 bool
1182 {
1183  return m_rfFlag;
1184 }
1185 Time
1187 {
1189 }
1190 Time
1192 {
1194 }
1195 uint8_t
1197 {
1198  return m_maxTtl;
1199 }
1200 uint32_t
1202 {
1203  m_preqId++;
1204  return m_preqId;
1205 }
1206 uint32_t
1208 {
1209  m_hwmpSeqno++;
1210  return m_hwmpSeqno;
1211 }
1212 uint32_t
1214 {
1216 }
1217 uint8_t
1219 {
1220  return m_unicastPerrThreshold;
1221 }
1224 {
1225  return m_address;
1226 }
1227 //Statistics:
1229  txUnicast (0),
1230  txBroadcast (0),
1231  txBytes (0),
1232  droppedTtl (0),
1233  totalQueued (0),
1234  totalDropped (0),
1235  initiatedPreq (0),
1236  initiatedPrep (0),
1237  initiatedPerr (0)
1238 {
1239 }
1240 void HwmpProtocol::Statistics::Print (std::ostream & os) const
1241 {
1242  os << "<Statistics "
1243  "txUnicast=\"" << txUnicast << "\" "
1244  "txBroadcast=\"" << txBroadcast << "\" "
1245  "txBytes=\"" << txBytes << "\" "
1246  "droppedTtl=\"" << droppedTtl << "\" "
1247  "totalQueued=\"" << totalQueued << "\" "
1248  "totalDropped=\"" << totalDropped << "\" "
1249  "initiatedPreq=\"" << initiatedPreq << "\" "
1250  "initiatedPrep=\"" << initiatedPrep << "\" "
1251  "initiatedPerr=\"" << initiatedPerr << "\"/>" << std::endl;
1252 }
1253 void
1254 HwmpProtocol::Report (std::ostream & os) const
1255 {
1256  os << "<Hwmp "
1257  "address=\"" << m_address << "\"" << std::endl <<
1258  "maxQueueSize=\"" << m_maxQueueSize << "\"" << std::endl <<
1259  "Dot11MeshHWMPmaxPREQretries=\"" << (uint16_t)m_dot11MeshHWMPmaxPREQretries << "\"" << std::endl <<
1260  "Dot11MeshHWMPnetDiameterTraversalTime=\"" << m_dot11MeshHWMPnetDiameterTraversalTime.GetSeconds () << "\"" << std::endl <<
1261  "Dot11MeshHWMPpreqMinInterval=\"" << m_dot11MeshHWMPpreqMinInterval.GetSeconds () << "\"" << std::endl <<
1262  "Dot11MeshHWMPperrMinInterval=\"" << m_dot11MeshHWMPperrMinInterval.GetSeconds () << "\"" << std::endl <<
1263  "Dot11MeshHWMPactiveRootTimeout=\"" << m_dot11MeshHWMPactiveRootTimeout.GetSeconds () << "\"" << std::endl <<
1264  "Dot11MeshHWMPactivePathTimeout=\"" << m_dot11MeshHWMPactivePathTimeout.GetSeconds () << "\"" << std::endl <<
1265  "Dot11MeshHWMPpathToRootInterval=\"" << m_dot11MeshHWMPpathToRootInterval.GetSeconds () << "\"" << std::endl <<
1266  "Dot11MeshHWMPrannInterval=\"" << m_dot11MeshHWMPrannInterval.GetSeconds () << "\"" << std::endl <<
1267  "isRoot=\"" << m_isRoot << "\"" << std::endl <<
1268  "maxTtl=\"" << (uint16_t)m_maxTtl << "\"" << std::endl <<
1269  "unicastPerrThreshold=\"" << (uint16_t)m_unicastPerrThreshold << "\"" << std::endl <<
1270  "unicastPreqThreshold=\"" << (uint16_t)m_unicastPreqThreshold << "\"" << std::endl <<
1271  "unicastDataThreshold=\"" << (uint16_t)m_unicastDataThreshold << "\"" << std::endl <<
1272  "doFlag=\"" << m_doFlag << "\"" << std::endl <<
1273  "rfFlag=\"" << m_rfFlag << "\">" << std::endl;
1274  m_stats.Print (os);
1275  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
1276  {
1277  plugin->second->Report (os);
1278  }
1279  os << "</Hwmp>" << std::endl;
1280 }
1281 void
1283 {
1284  NS_LOG_FUNCTION (this);
1285  m_stats = Statistics ();
1286  for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin++)
1287  {
1288  plugin->second->ResetStats ();
1289  }
1290 }
1291 
1292 int64_t
1294 {
1295  NS_LOG_FUNCTION (this << stream);
1296  m_coefficient->SetStream (stream);
1297  return 1;
1298 }
1299 
1302 {
1303  return m_rtable;
1304 }
1305 
1307  pkt (0),
1308  protocol (0),
1309  inInterface (0)
1310 {
1311 }
1312 } // namespace dot11s
1313 } // namespace ns3
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Callback template class.
Definition: callback.h:1279
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
an EUI-48 address
Definition: mac48-address.h:44
static Mac48Address GetBroadcast(void)
static Mac48Address ConvertFrom(const Address &address)
Interface for L2 mesh routing protocol and mesh point communication.
Ptr< MeshPointDevice > GetMeshPoint() const
Each mesh protocol must be installed on the mesh point to work.
Ptr< MeshPointDevice > m_mp
Host mesh point.
Basic MAC of mesh point Wi-Fi interface.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:256
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:963
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:956
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:978
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:387
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
@ US
microsecond
Definition: nstime.h:116
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:418
AttributeValue implementation for Time.
Definition: nstime.h:1308
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
Hold together all Wifi-related objects.
Ptr< WifiMac > GetMac(void) const
uint32_t GetIfIndex(void) const override
Hybrid wireless mesh protocol – a mesh routing protocol defined in IEEE 802.11-2012 standard.
Definition: hwmp-protocol.h:64
void SetRoot()
Unset the current node as root.
std::vector< Mac48Address > GetPreqReceivers(uint32_t interface)
Get PREQ receivers.
QueuedPacket DequeueFirstPacket()
Dequeue the first packet in the queue.
Ptr< HwmpRtable > m_rtable
Routing table.
uint8_t m_unicastDataThreshold
Maximum number of broadcast receivers, when we send a broadcast as a chain of unicasts.
void ReceivePrep(IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
Handler for receiving Path Reply.
void Report(std::ostream &os) const
Statistics:
uint32_t GetNextHwmpSeqno()
Get next HWMP sequence no function.
PathError MakePathError(std::vector< FailedDestination > destinations)
forms a path error information element when list of destination fails on a given interface
Time m_dot11MeshHWMPrannInterval
Lifetime of proactive routing information.
Time GetPerrMinInterval()
Get PERR minimum interval function.
uint8_t m_unicastPreqThreshold
Maximum number of PREQ receivers, when we send a PREQ as a chain of unicasts.
void UnsetRoot()
Unset the current node as root.
uint32_t m_dataSeqno
data sequence no
Time m_dot11MeshHWMPnetDiameterTraversalTime
Time we suppose the packet to go from one edge of the network to another.
Time m_dot11MeshHWMPactivePathTimeout
Lifetime of reactive routing information.
bool QueuePacket(QueuedPacket packet)
Queue a packet.
bool m_isRoot
True if the node is a root.
Statistics m_stats
statistics
uint32_t m_hwmpSeqno
HWMP sequence no.
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 m_randomStart
Random start in Proactive PREQ propagation.
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.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
virtual void DoInitialize()
Initialize() implementation.
TracedCallback< Time > m_routeDiscoveryTimeCallback
Route discovery time:
static TypeId GetTypeId()
Get the type ID.
bool GetRfFlag()
Get rf flag function.
bool ShouldSendPreq(Mac48Address dst)
checks when the last path discovery procedure was started for a given destination.
void PeerLinkStatus(Mac48Address meshPontAddress, Mac48Address peerAddress, uint32_t interface, bool status)
Peer link status function.
void ReceivePerr(std::vector< FailedDestination > destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
Handler for receiving Path Error.
std::map< Mac48Address, PreqEvent > m_preqTimeouts
PREQ timeouts.
Time m_dot11MeshHWMPperrMinInterval
Minimal interval between to successive PREQs.
bool m_rfFlag
Reply and forward flag.
bool GetDoFlag()
Get do flag function.
Time GetPreqMinInterval()
Get PREQ minimum interval function.
QueuedPacket DequeueFirstPacketByDst(Mac48Address dst)
Dequeue the first packet for a given destination.
EventId m_proactivePreqTimer
proactive PREQ timer
Ptr< UniformRandomVariable > m_coefficient
Random variable for random start time.
uint32_t GetNextPreqId()
Get next period function.
void InitiatePathError(PathError perr)
Passes a self-generated PERR to interface-plugin.
uint8_t GetUnicastPerrThreshold()
Get unicast PERR threshold function.
void SendProactivePreq()
Proactive Preq routines:
void ForwardPathError(PathError perr)
Forwards a received path error.
void DoDispose()
Destructor implementation.
Time m_dot11MeshHWMPpathToRootInterval
Interval between two successive proactive PREQs.
void RetryPathDiscovery(Mac48Address dst, uint8_t numOfRetry)
Generates PREQ retry when retry timeout has expired and route is still unresolved.
bool m_doFlag
Destination only HWMP flag.
Mac48Address m_address
address
Time m_dot11MeshHWMPactiveRootTimeout
Lifetime of proactive routing information.
void ReceivePreq(IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
Handler for receiving Path Request.
Time m_dot11MeshHWMPpreqMinInterval
Minimal interval between to successive PREQs.
uint8_t GetMaxTtl()
Get maximum TTL function.
void ReactivePathResolved(Mac48Address dst)
Signal the protocol that the reactive path toward a destination is now available.
std::vector< Mac48Address > GetBroadcastReceivers(uint32_t interface)
Get broadcast receivers.
bool Install(Ptr< MeshPointDevice > mp)
Install HWMP on given mesh point.
uint32_t GetActivePathLifetime()
Get active path lifetime function.
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.
void ProactivePathResolved()
Signal the protocol that the proactive path is now available.
void SetNeighboursCallback(Callback< std::vector< Mac48Address >, uint32_t > cb)
This callback is used to obtain active neighbours on a given interface.
std::vector< QueuedPacket > m_rqueue
Packet Queue.
Callback< std::vector< Mac48Address >, uint32_t > m_neighboursCallback
neighbors callback
std::vector< std::pair< uint32_t, Mac48Address > > GetPerrReceivers(std::vector< FailedDestination > failedDest)
Get PERR receivers.
HwmpProtocolMacMap m_interfaces
interfaces
Ptr< HwmpRtable > GetRoutingTable(void) const
Get pointer to HWMP routing table.
uint16_t m_maxQueueSize
Maximum number of packets we can store when resolving route.
uint8_t m_maxTtl
Initial value of Time To Live field.
std::map< Mac48Address, uint32_t > m_lastDataSeqno
keeps HWMP seqno (first in pair) and HWMP metric (second in pair) for each address
void ResetStats()
Reset Statistics:
bool DropDataFrame(uint32_t seqno, Mac48Address source)
MAC-plugin asks whether the frame can be dropped.
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.
uint8_t m_unicastPerrThreshold
Maximum number of PERR receivers, when we send a PERR as a chain of unicasts.
uint32_t m_preqId
PREQ ID.
uint8_t m_dot11MeshHWMPmaxPREQretries
Maximum number of retries before we suppose the destination to be unreachable.
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
TracedCallback< struct RouteChange > m_routeChangeTraceSource
Route change trace source.
void SendPreq(IePreq preq)
Send PREQ function.
void SendPrep(IePrep prep, Mac48Address receiver)
Send PREP function.
void ForwardPerr(std::vector< HwmpProtocol::FailedDestination > destinations, std::vector< Mac48Address > receivers)
Forward a path error.
Routing table for HWMP – 802.11s routing protocol.
Definition: hwmp-rtable.h:36
void DeleteReactivePath(Mac48Address destination)
Delete the reactive paths toward a destination.
Definition: hwmp-rtable.cc:140
static const uint32_t MAX_METRIC
Maximum (the best?) path metric.
Definition: hwmp-rtable.h:41
LookupResult LookupReactive(Mac48Address destination)
Lookup path to destination.
Definition: hwmp-rtable.cc:150
LookupResult LookupReactiveExpired(Mac48Address destination)
Return all reactive paths, including expired.
Definition: hwmp-rtable.cc:166
PrecursorList GetPrecursors(Mac48Address destination)
Get the precursors list.
Definition: hwmp-rtable.cc:223
void DeleteProactivePath()
Delete all the proactive paths.
Definition: hwmp-rtable.cc:120
LookupResult LookupProactiveExpired()
Return all proactive paths, including expired.
Definition: hwmp-rtable.cc:190
std::vector< std::pair< uint32_t, Mac48Address > > PrecursorList
Path precursor = {MAC, interface ID}.
Definition: hwmp-rtable.h:77
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
LookupResult LookupProactive()
Find proactive path to tree root.
Definition: hwmp-rtable.cc:179
void AddPrecursor(Mac48Address destination, uint32_t precursorInterface, Mac48Address precursorAddress, Time lifetime)
Add a precursor.
Definition: hwmp-rtable.cc:90
void AddProactivePath(uint32_t metric, Mac48Address root, Mac48Address retransmitter, uint32_t interface, Time lifetime, uint32_t seqnum)
Add a proactive path.
Definition: hwmp-rtable.cc:78
void AddReactivePath(Mac48Address destination, Mac48Address retransmitter, uint32_t interface, uint32_t metric, Time lifetime, uint32_t seqnum)
Add a reactive path.
Definition: hwmp-rtable.cc:59
Hwmp tag implements interaction between HWMP protocol and MeshWifiMac.
Definition: hwmp-tag.h:49
void SetTtl(uint8_t ttl)
Set the TTL value.
Definition: hwmp-tag.cc:51
void SetSeqno(uint32_t seqno)
Set sequence number.
Definition: hwmp-tag.cc:75
uint8_t GetTtl()
Get the TTL value.
Definition: hwmp-tag.cc:57
void SetAddress(Mac48Address retransmitter)
Set address.
Definition: hwmp-tag.cc:39
void DecrementTtl()
Decrement TTL.
Definition: hwmp-tag.cc:155
See 7.3.2.97 of 802.11s draft 2.07.
uint32_t GetMetric() const
Get metric function.
void SetTtl(uint8_t ttl)
Set TTL function.
void SetDestinationSeqNumber(uint32_t dest_seq_number)
Set destination sequence number function.
Mac48Address GetDestinationAddress() const
Get destination address function.
void SetHopcount(uint8_t hopcount)
Set hop count function.
void IncrementMetric(uint32_t metric)
Increment metric function.
uint32_t GetLifetime() const
Get lifetime function.
void SetOriginatorAddress(Mac48Address originator_address)
Set originator address function.
void SetMetric(uint32_t metric)
Set metric function.
void SetDestinationAddress(Mac48Address dest_address)
Set destination address function.
void SetLifetime(uint32_t lifetime)
Set lifetime function.
Mac48Address GetOriginatorAddress() const
Get originator address function.
void SetOriginatorSeqNumber(uint32_t originator_seq_number)
Set originator sequence number function.
uint32_t GetDestinationSeqNumber() const
Get destination sequence number function.
See 7.3.2.96 of 802.11s draft 2.07.
uint32_t GetOriginatorSeqNumber() const
Get originator sequence numnber value.
void DelDestinationAddressElement(Mac48Address dest_address)
Delete a destination address unit by destination.
void SetHopcount(uint8_t hopcount)
Set number of hops from originator to mesh STA transmitting this element.
uint8_t GetDestCount() const
Get destination count.
std::vector< Ptr< DestinationAddressUnit > > GetDestinationList()
Get all destinations, which are stored in PREQ:
void SetOriginatorSeqNumber(uint32_t originator_seq_number)
Set originator sequence number.
uint32_t GetMetric() const
Get metric value.
void SetTTL(uint8_t ttl)
Set remaining number of hops allowed for this element.
void SetOriginatorAddress(Mac48Address originator_address)
Set originator address value.
Mac48Address GetOriginatorAddress() const
Get originator address value.
void SetPreqID(uint32_t id)
Set path discovery id field.
void IncrementMetric(uint32_t metric)
Handle Metric:
uint32_t GetLifetime() const
Get lifetime value.
void AddDestinationAddressElement(bool doFlag, bool rfFlag, Mac48Address dest_address, uint32_t dest_seq_number)
Add a destination address unit: flags, destination and sequence number.
bool IsNeedNotPrep() const
Check whether Proactive PREP subfield to off.
void SetLifetime(uint32_t lifetime)
Set lifetime in TUs for the forwarding information to be considered valid.
#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
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
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:85
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:1309
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
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:576
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1260
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
address
Definition: first.py:44
interfaces
Definition: first.py:48
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:522
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
Definition: second.py:1
mac
Definition: third.py:99
Structure of path error: IePerr and list of receivers: interfaces and MAC address.
std::vector< FailedDestination > destinations
destination list: Mac48Address and sequence number
std::vector< std::pair< uint32_t, Mac48Address > > receivers
list of PathError receivers (in case of unicast PERR)
Packet waiting its routing information.
RouteReplyCallback reply
how to reply
uint32_t inInterface
incoming device interface ID. (if packet has come from upper layers, this is Mesh point ID)
void Print(std::ostream &os) const
Print function.
uint16_t initiatedPrep
initiated PREP
uint16_t txBroadcast
transmit broadcast
uint16_t txUnicast
transmit unicast
uint16_t initiatedPerr
initiated PERR
uint16_t initiatedPreq
initiated PREQ
Route lookup result, return type of LookupXXX methods.
Definition: hwmp-rtable.h:45
uint32_t seqnum
sequence number
Definition: hwmp-rtable.h:49
Mac48Address retransmitter
retransmitter
Definition: hwmp-rtable.h:46
Structure to encapsulate route change information.
Definition: hwmp-protocol.h:48
Time lifetime
lifetime of route
Definition: hwmp-protocol.h:54
Mac48Address retransmitter
route source
Definition: hwmp-protocol.h:51
uint32_t seqnum
sequence number of route
Definition: hwmp-protocol.h:55
uint32_t metric
metric of route
Definition: hwmp-protocol.h:53
Mac48Address destination
route destination
Definition: hwmp-protocol.h:50
std::string type
type of change
Definition: hwmp-protocol.h:49
uint32_t interface
interface index
Definition: hwmp-protocol.h:52