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
41namespace ns3 {
42
43NS_LOG_COMPONENT_DEFINE ("HwmpProtocol");
44
45namespace dot11s {
46
47NS_OBJECT_ENSURE_REGISTERED (HwmpProtocol);
48
49TypeId
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)),
103 )
104 .AddAttribute ( "Dot11MeshHWMPactivePathTimeout",
105 "Lifetime of reactive routing information",
106 TimeValue (MicroSeconds (1024*5000)),
110 )
111 .AddAttribute ( "Dot11MeshHWMPpathToRootInterval",
112 "Interval between two successive proactive PREQs",
113 TimeValue (MicroSeconds (1024*2000)),
117 )
118 .AddAttribute ( "Dot11MeshHWMPrannInterval",
119 "Lifetime of proactive routing information",
120 TimeValue (MicroSeconds (1024*5000)),
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
214void
216{
217 NS_LOG_FUNCTION (this);
219 if (m_isRoot)
220 {
221 Time randomStart = Seconds (m_coefficient->GetValue ());
223 }
224}
225
226void
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 ();
238 m_interfaces.clear ();
239 m_rqueue.clear ();
240 m_rtable = 0;
241 m_mp = 0;
242}
243
244bool
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 //
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}
328bool
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}
339bool
340HwmpProtocol::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);
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}
424void
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),
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),
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),
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,
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,
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,
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}
620void
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}
722void
723HwmpProtocol::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 }
747}
748void
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}
773bool
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}
806void
807HwmpProtocol::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}
818void
820{
822}
823bool
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}
849HwmpProtocol::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}
873void
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}
890void
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
911std::vector<std::pair<uint32_t, Mac48Address> >
912HwmpProtocol::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}
951std::vector<Mac48Address>
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}
967std::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
984bool
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
1028void
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
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);
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}
1056void
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);
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
1082bool
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}
1097void
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 {
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:
1141void
1143{
1144 NS_LOG_FUNCTION (this);
1145 NS_LOG_DEBUG ("ROOT IS: " << m_address);
1146 m_isRoot = true;
1147}
1148void
1150{
1151 NS_LOG_FUNCTION (this);
1153}
1154void
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
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}
1175bool
1177{
1178 return m_doFlag;
1179}
1180bool
1182{
1183 return m_rfFlag;
1184}
1185Time
1187{
1189}
1190Time
1192{
1194}
1195uint8_t
1197{
1198 return m_maxTtl;
1199}
1202{
1203 m_preqId++;
1204 return m_preqId;
1205}
1208{
1209 m_hwmpSeqno++;
1210 return m_hwmpSeqno;
1211}
1214{
1216}
1217uint8_t
1219{
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}
1240void 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}
1253void
1254HwmpProtocol::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}
1281void
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
1292int64_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:432
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)
Definition: boolean.h:85
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1309
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
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:536
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:96
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