A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
hwmp-protocol.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008,2009 IITP RAS
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Kirill Andreev <andreev@iitp.ru>
7 */
8
9#include "hwmp-protocol.h"
10
11#include "airtime-metric.h"
12#include "hwmp-protocol-mac.h"
13#include "hwmp-rtable.h"
14#include "hwmp-tag.h"
15#include "ie-dot11s-perr.h"
16#include "ie-dot11s-prep.h"
17#include "ie-dot11s-preq.h"
18
19#include "ns3/log.h"
20#include "ns3/mesh-point-device.h"
21#include "ns3/mesh-wifi-interface-mac.h"
22#include "ns3/packet.h"
23#include "ns3/pointer.h"
24#include "ns3/random-variable-stream.h"
25#include "ns3/simulator.h"
26#include "ns3/string.h"
27#include "ns3/trace-source-accessor.h"
28#include "ns3/wifi-net-device.h"
29
30namespace ns3
31{
32
33NS_LOG_COMPONENT_DEFINE("HwmpProtocol");
34
35namespace dot11s
36{
37
38NS_OBJECT_ENSURE_REGISTERED(HwmpProtocol);
39
40TypeId
42{
43 static TypeId tid =
44 TypeId("ns3::dot11s::HwmpProtocol")
46 .SetGroupName("Mesh")
47 .AddConstructor<HwmpProtocol>()
48 .AddAttribute("RandomStart",
49 "Random delay at first proactive PREQ",
50 TimeValue(Seconds(0.1)),
53 .AddAttribute("MaxQueueSize",
54 "Maximum number of packets we can store when resolving route",
55 UintegerValue(255),
58 .AddAttribute(
59 "Dot11MeshHWMPmaxPREQretries",
60 "Maximum number of retries before we suppose the destination to be unreachable",
64 .AddAttribute(
65 "Dot11MeshHWMPnetDiameterTraversalTime",
66 "Time we suppose the packet to go from one edge of the network to another",
67 TimeValue(MicroSeconds(1024 * 100)),
70 .AddAttribute("Dot11MeshHWMPpreqMinInterval",
71 "Minimal interval between to successive PREQs",
72 TimeValue(MicroSeconds(1024 * 100)),
75 .AddAttribute("Dot11MeshHWMPperrMinInterval",
76 "Minimal interval between to successive PREQs",
77 TimeValue(MicroSeconds(1024 * 100)),
80 .AddAttribute("Dot11MeshHWMPactiveRootTimeout",
81 "Lifetime of proactive routing information",
82 TimeValue(MicroSeconds(1024 * 5000)),
85 .AddAttribute("Dot11MeshHWMPactivePathTimeout",
86 "Lifetime of reactive routing information",
87 TimeValue(MicroSeconds(1024 * 5000)),
90 .AddAttribute("Dot11MeshHWMPpathToRootInterval",
91 "Interval between two successive proactive PREQs",
92 TimeValue(MicroSeconds(1024 * 2000)),
95 .AddAttribute("Dot11MeshHWMPrannInterval",
96 "Lifetime of proactive routing information",
97 TimeValue(MicroSeconds(1024 * 5000)),
100 .AddAttribute("MaxTtl",
101 "Initial value of Time To Live field",
102 UintegerValue(32),
105 .AddAttribute(
106 "UnicastPerrThreshold",
107 "Maximum number of PERR receivers, when we send a PERR as a chain of unicasts",
108 UintegerValue(32),
111 .AddAttribute(
112 "UnicastPreqThreshold",
113 "Maximum number of PREQ receivers, when we send a PREQ as a chain of unicasts",
114 UintegerValue(1),
117 .AddAttribute("UnicastDataThreshold",
118 "Maximum number of broadcast receivers, when we send a broadcast as a "
119 "chain of unicasts",
120 UintegerValue(1),
123 .AddAttribute("DoFlag",
124 "Destination only HWMP flag",
125 BooleanValue(false),
128 .AddAttribute("RfFlag",
129 "Reply and forward flag",
130 BooleanValue(true),
133 .AddTraceSource("RouteDiscoveryTime",
134 "The time of route discovery procedure",
136 "ns3::Time::TracedCallback")
137 .AddTraceSource("RouteChange",
138 "Routing table changed",
140 "ns3::HwmpProtocol::RouteChangeTracedCallback");
141 return tid;
142}
143
145 : m_dataSeqno(1),
146 m_hwmpSeqno(1),
147 m_preqId(0),
148 m_rtable(CreateObject<HwmpRtable>()),
149 m_randomStart(Seconds(0.1)),
150 m_maxQueueSize(255),
151 m_dot11MeshHWMPmaxPREQretries(3),
152 m_dot11MeshHWMPnetDiameterTraversalTime(MicroSeconds(1024 * 100)),
153 m_dot11MeshHWMPpreqMinInterval(MicroSeconds(1024 * 100)),
154 m_dot11MeshHWMPperrMinInterval(MicroSeconds(1024 * 100)),
155 m_dot11MeshHWMPactiveRootTimeout(MicroSeconds(1024 * 5000)),
156 m_dot11MeshHWMPactivePathTimeout(MicroSeconds(1024 * 5000)),
157 m_dot11MeshHWMPpathToRootInterval(MicroSeconds(1024 * 2000)),
158 m_dot11MeshHWMPrannInterval(MicroSeconds(1024 * 5000)),
159 m_isRoot(false),
160 m_maxTtl(32),
161 m_unicastPerrThreshold(32),
162 m_unicastPreqThreshold(1),
163 m_unicastDataThreshold(1),
164 m_doFlag(false),
165 m_rfFlag(false)
166{
167 NS_LOG_FUNCTION(this);
169}
170
175
176void
178{
179 NS_LOG_FUNCTION(this);
180 m_coefficient->SetAttribute("Max", DoubleValue(m_randomStart.GetSeconds()));
181 if (m_isRoot)
182 {
183 Time randomStart = Seconds(m_coefficient->GetValue());
186 }
187}
188
189void
191{
192 NS_LOG_FUNCTION(this);
193 for (auto i = m_preqTimeouts.begin(); i != m_preqTimeouts.end(); i++)
194 {
195 i->second.preqTimeout.Cancel();
196 }
198 m_preqTimeouts.clear();
199 m_lastDataSeqno.clear();
201 m_interfaces.clear();
202 m_rqueue.clear();
203 m_rtable = nullptr;
204 m_mp = nullptr;
205}
206
207bool
209 const Mac48Address source,
210 const Mac48Address destination,
211 Ptr<const Packet> constPacket,
212 uint16_t protocolType, // ethrnet 'Protocol' field
214{
215 NS_LOG_FUNCTION(this << sourceIface << source << destination << constPacket << protocolType);
216 Ptr<Packet> packet = constPacket->Copy();
217 HwmpTag tag;
218 if (sourceIface == GetMeshPoint()->GetIfIndex())
219 {
220 // packet from level 3
221 if (packet->PeekPacketTag(tag))
222 {
224 "HWMP tag has come with a packet from upper layer. This must not occur...");
225 }
226 // Filling TAG:
227 if (destination == Mac48Address::GetBroadcast())
228 {
229 tag.SetSeqno(m_dataSeqno++);
230 }
231 tag.SetTtl(m_maxTtl);
232 }
233 else
234 {
235 if (!packet->RemovePacketTag(tag))
236 {
237 NS_FATAL_ERROR("HWMP tag is supposed to be here at this point.");
238 }
239 tag.DecrementTtl();
240 if (tag.GetTtl() == 0)
241 {
242 NS_LOG_DEBUG("Dropping frame due to TTL expiry");
244 return false;
245 }
246 }
247 if (destination == Mac48Address::GetBroadcast())
248 {
250 m_stats.txBytes += packet->GetSize();
251 // channel IDs where we have already sent broadcast:
252 std::vector<uint16_t> channels;
253 for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
254 {
255 bool shouldSend = true;
256 for (auto chan = channels.begin(); chan != channels.end(); chan++)
257 {
258 if ((*chan) == plugin->second->GetChannelId())
259 {
260 shouldSend = false;
261 }
262 }
263 if (!shouldSend)
264 {
265 continue;
266 }
267 channels.push_back(plugin->second->GetChannelId());
268 std::vector<Mac48Address> receivers = GetBroadcastReceivers(plugin->first);
269 for (auto i = receivers.begin(); i != receivers.end(); i++)
270 {
271 Ptr<Packet> packetCopy = packet->Copy();
272 //
273 // 64-bit Intel valgrind complains about tag.SetAddress (*i). It
274 // likes this just fine.
275 //
276 Mac48Address address = *i;
277 tag.SetAddress(address);
278 packetCopy->AddPacketTag(tag);
279 NS_LOG_DEBUG("Sending route reply for broadcast; address " << address);
280 routeReply(true, packetCopy, source, destination, protocolType, plugin->first);
281 }
282 }
283 }
284 else
285 {
286 return ForwardUnicast(sourceIface,
287 source,
288 destination,
289 packet,
290 protocolType,
291 routeReply,
292 tag.GetTtl());
293 }
294 return true;
295}
296
297bool
299 const Mac48Address source,
300 const Mac48Address destination,
301 Ptr<Packet> packet,
302 uint16_t& protocolType)
303{
304 HwmpTag tag;
305 if (!packet->RemovePacketTag(tag))
306 {
307 NS_FATAL_ERROR("HWMP tag must exist when packet received from the network");
308 }
309 return true;
310}
311
312bool
314 const Mac48Address source,
315 const Mac48Address destination,
316 Ptr<Packet> packet,
317 uint16_t protocolType,
318 RouteReplyCallback routeReply,
319 uint32_t ttl)
320{
321 NS_LOG_FUNCTION(this << sourceIface << source << destination << packet << protocolType << ttl);
322 NS_ASSERT(destination != Mac48Address::GetBroadcast());
323 HwmpRtable::LookupResult result = m_rtable->LookupReactive(destination);
324 NS_LOG_DEBUG("Requested src = " << source << ", dst = " << destination << ", I am "
325 << GetAddress() << ", RA = " << result.retransmitter);
327 {
328 result = m_rtable->LookupProactive();
329 }
330 HwmpTag tag;
331 tag.SetAddress(result.retransmitter);
332 tag.SetTtl(ttl);
333 // seqno and metric is not used;
334 packet->AddPacketTag(tag);
336 {
337 // reply immediately:
338 routeReply(true, packet, source, destination, protocolType, result.ifIndex);
340 m_stats.txBytes += packet->GetSize();
341 return true;
342 }
343 if (sourceIface != GetMeshPoint()->GetIfIndex())
344 {
345 // Start path error procedure:
346 NS_LOG_DEBUG("Must Send PERR");
347 result = m_rtable->LookupReactiveExpired(destination);
348 NS_LOG_DEBUG("Path error " << result.retransmitter);
349 // 1. Lookup expired reactive path. If exists - start path error
350 // procedure towards a next hop of this path
351 // 2. If there was no reactive path, we lookup expired proactive
352 // path. If exist - start path error procedure towards path to
353 // root
355 {
356 NS_LOG_DEBUG("Path error, lookup expired proactive path");
357 result = m_rtable->LookupProactiveExpired();
358 }
360 {
361 NS_LOG_DEBUG("Path error, initiate reactive path error");
362 std::vector<FailedDestination> destinations =
363 m_rtable->GetUnreachableDestinations(result.retransmitter);
364 InitiatePathError(MakePathError(destinations));
365 }
367 return false;
368 }
369 // Request a destination:
370 result = m_rtable->LookupReactiveExpired(destination);
371 if (ShouldSendPreq(destination))
372 {
373 uint32_t originator_seqno = GetNextHwmpSeqno();
374 uint32_t dst_seqno = 0;
376 {
377 dst_seqno = result.seqnum;
378 }
380 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
381 {
382 i->second->RequestDestination(destination, originator_seqno, dst_seqno);
383 }
384 }
385 QueuedPacket pkt;
386 pkt.pkt = packet;
387 pkt.dst = destination;
388 pkt.src = source;
389 pkt.protocol = protocolType;
390 pkt.reply = routeReply;
391 pkt.inInterface = sourceIface;
392 if (QueuePacket(pkt))
393 {
395 return true;
396 }
397 else
398 {
400 NS_LOG_DEBUG("Dropping packet from " << source << " to " << destination
401 << " due to queue overflow");
402 return false;
403 }
404}
405
406void
408 Mac48Address from,
409 uint32_t interface,
410 Mac48Address fromMp,
411 uint32_t metric)
412{
413 NS_LOG_FUNCTION(this << from << interface << fromMp << metric);
414 preq.IncrementMetric(metric);
415 // acceptance cretirea:
417 bool freshInfo(true);
418 if (i != m_hwmpSeqnoMetricDatabase.end())
419 {
420 if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber()) > 0)
421 {
422 return;
423 }
424 if (i->second.first == preq.GetOriginatorSeqNumber())
425 {
426 freshInfo = false;
427 if (i->second.second <= preq.GetMetric())
428 {
429 return;
430 }
431 }
432 }
434 std::make_pair(preq.GetOriginatorSeqNumber(), preq.GetMetric());
435 NS_LOG_DEBUG("I am " << GetAddress() << ", Accepted preq from address" << from
436 << ", preq:" << preq);
437 std::vector<Ptr<DestinationAddressUnit>> destinations = preq.GetDestinationList();
438 // Add reactive path to originator:
439 if ((freshInfo) ||
440 ((m_rtable->LookupReactive(preq.GetOriginatorAddress()).retransmitter ==
442 (m_rtable->LookupReactive(preq.GetOriginatorAddress()).metric > preq.GetMetric())))
443 {
444 m_rtable->AddReactivePath(preq.GetOriginatorAddress(),
445 from,
446 interface,
447 preq.GetMetric(),
448 MicroSeconds(preq.GetLifetime() * 1024),
450 // Notify trace source of routing change
451 RouteChange rChange;
452 rChange.type = "Add Reactive";
453 rChange.destination = preq.GetOriginatorAddress();
454 rChange.retransmitter = from;
455 rChange.interface = interface;
456 rChange.metric = preq.GetMetric();
457 rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
458 rChange.seqnum = preq.GetOriginatorSeqNumber();
461 }
462 if ((m_rtable->LookupReactive(fromMp).retransmitter == Mac48Address::GetBroadcast()) ||
463 (m_rtable->LookupReactive(fromMp).metric > metric))
464 {
465 m_rtable->AddReactivePath(fromMp,
466 from,
467 interface,
468 metric,
469 MicroSeconds(preq.GetLifetime() * 1024),
471 // Notify trace source of routing change
472 RouteChange rChange;
473 rChange.type = "Add Reactive";
474 rChange.destination = fromMp;
475 rChange.retransmitter = from;
476 rChange.interface = interface;
477 rChange.metric = metric;
478 rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
479 rChange.seqnum = preq.GetOriginatorSeqNumber();
481 ReactivePathResolved(fromMp);
482 }
483 for (auto i = destinations.begin(); i != destinations.end(); i++)
484 {
485 if ((*i)->GetDestinationAddress() == Mac48Address::GetBroadcast())
486 {
487 // only proactive PREQ contains destination
488 // address as broadcast! Proactive preq MUST
489 // have destination count equal to 1 and
490 // per destination flags DO and RF
491 NS_ASSERT(preq.GetDestCount() == 1);
492 NS_ASSERT(((*i)->IsDo()) && ((*i)->IsRf()));
493 // Add proactive path only if it is the better then existed
494 // before
495 if (((m_rtable->LookupProactive()).retransmitter == Mac48Address::GetBroadcast()) ||
496 ((m_rtable->LookupProactive()).metric > preq.GetMetric()))
497 {
498 m_rtable->AddProactivePath(preq.GetMetric(),
500 from,
501 interface,
502 MicroSeconds(preq.GetLifetime() * 1024),
504 // Notify trace source of routing change
505 RouteChange rChange;
506 rChange.type = "Add Proactive";
507 rChange.destination = preq.GetOriginatorAddress();
508 rChange.retransmitter = from;
509 rChange.interface = interface;
510 rChange.metric = preq.GetMetric();
511 rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
512 rChange.seqnum = preq.GetOriginatorSeqNumber();
515 }
516 if (!preq.IsNeedNotPrep())
517 {
520 from,
521 (uint32_t)0,
524 preq.GetLifetime(),
525 interface);
526 }
527 break;
528 }
529 if ((*i)->GetDestinationAddress() == GetAddress())
530 {
533 from,
534 (uint32_t)0,
537 preq.GetLifetime(),
538 interface);
539 NS_ASSERT(m_rtable->LookupReactive(preq.GetOriginatorAddress()).retransmitter !=
541 preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
542 continue;
543 }
544 // check if can answer:
545 HwmpRtable::LookupResult result = m_rtable->LookupReactive((*i)->GetDestinationAddress());
546 if ((!((*i)->IsDo())) && (result.retransmitter != Mac48Address::GetBroadcast()))
547 {
548 // have a valid information and can answer
549 uint32_t lifetime = result.lifetime.GetMicroSeconds() / 1024;
550 if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber()) >= 0))
551 {
552 SendPrep((*i)->GetDestinationAddress(),
554 from,
555 result.metric,
557 result.seqnum,
558 lifetime,
559 interface);
560 m_rtable->AddPrecursor((*i)->GetDestinationAddress(),
561 interface,
562 from,
563 MicroSeconds(preq.GetLifetime() * 1024));
564 if ((*i)->IsRf())
565 {
566 (*i)->SetFlags(true, false, (*i)->IsUsn()); // DO = 1, RF = 0
567 }
568 else
569 {
570 preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
571 continue;
572 }
573 }
574 }
575 }
576 // check if must retransmit:
577 if (preq.GetDestCount() == 0)
578 {
579 return;
580 }
581 // Forward PREQ to all interfaces:
582 NS_LOG_DEBUG("I am " << GetAddress() << "retransmitting PREQ:" << preq);
583 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
584 {
585 Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
586 NS_LOG_DEBUG("Forwarding PREQ from " << from << " with delay "
587 << forwardingDelay.As(Time::US));
588 Simulator::Schedule(forwardingDelay, &HwmpProtocolMac::SendPreq, i->second, preq);
589 }
590}
591
592void
594 Mac48Address from,
595 uint32_t interface,
596 Mac48Address fromMp,
597 uint32_t metric)
598{
599 NS_LOG_FUNCTION(this << from << interface << fromMp << metric);
600 prep.IncrementMetric(metric);
601 // acceptance cretirea:
603 bool freshInfo(true);
604 uint32_t sequence = prep.GetDestinationSeqNumber();
605 if (i != m_hwmpSeqnoMetricDatabase.end())
606 {
607 if ((int32_t)(i->second.first - sequence) > 0)
608 {
609 return;
610 }
611 if (i->second.first == sequence)
612 {
613 freshInfo = false;
614 }
615 }
617 std::make_pair(sequence, prep.GetMetric());
618 // update routing info
619 // Now add a path to destination and add precursor to source
620 NS_LOG_DEBUG("I am " << GetAddress() << ", received prep from " << prep.GetOriginatorAddress()
621 << ", receiver was:" << from);
622 HwmpRtable::LookupResult result = m_rtable->LookupReactive(prep.GetDestinationAddress());
623 // Add a reactive path only if seqno is fresher or it improves the
624 // metric
625 if ((freshInfo) ||
626 (((m_rtable->LookupReactive(prep.GetOriginatorAddress())).retransmitter ==
628 ((m_rtable->LookupReactive(prep.GetOriginatorAddress())).metric > prep.GetMetric())))
629 {
630 m_rtable->AddReactivePath(prep.GetOriginatorAddress(),
631 from,
632 interface,
633 prep.GetMetric(),
634 MicroSeconds(prep.GetLifetime() * 1024),
635 sequence);
636 // Notify trace source of routing change
637 RouteChange rChange;
638 rChange.type = "Add Reactive";
639 rChange.destination = prep.GetOriginatorAddress();
640 rChange.retransmitter = from;
641 rChange.interface = interface;
642 rChange.metric = prep.GetMetric();
643 rChange.lifetime = MicroSeconds(prep.GetLifetime() * 1024);
644 rChange.seqnum = sequence;
646 m_rtable->AddPrecursor(prep.GetDestinationAddress(),
647 interface,
648 from,
649 MicroSeconds(prep.GetLifetime() * 1024));
651 {
652 m_rtable->AddPrecursor(prep.GetOriginatorAddress(),
653 interface,
654 result.retransmitter,
655 result.lifetime);
656 }
658 }
659 if (((m_rtable->LookupReactive(fromMp)).retransmitter == Mac48Address::GetBroadcast()) ||
660 ((m_rtable->LookupReactive(fromMp)).metric > metric))
661 {
662 m_rtable->AddReactivePath(fromMp,
663 from,
664 interface,
665 metric,
666 MicroSeconds(prep.GetLifetime() * 1024),
667 sequence);
668 // Notify trace source of routing change
669 RouteChange rChange;
670 rChange.type = "Add Reactive";
671 rChange.destination = fromMp;
672 rChange.retransmitter = from;
673 rChange.interface = interface;
674 rChange.metric = metric;
675 rChange.lifetime = MicroSeconds(prep.GetLifetime() * 1024);
676 rChange.seqnum = sequence;
678 ReactivePathResolved(fromMp);
679 }
680 if (prep.GetDestinationAddress() == GetAddress())
681 {
682 NS_LOG_DEBUG("I am " << GetAddress() << ", resolved " << prep.GetOriginatorAddress());
683 return;
684 }
686 {
687 return;
688 }
689 // Forward PREP
690 auto prep_sender = m_interfaces.find(result.ifIndex);
691 NS_ASSERT(prep_sender != m_interfaces.end());
692 Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
693 NS_LOG_DEBUG("Forwarding PREP from " << from << " with delay " << forwardingDelay.As(Time::US));
694 Simulator::Schedule(forwardingDelay,
696 prep_sender->second,
697 prep,
698 result.retransmitter);
699}
700
701void
702HwmpProtocol::ReceivePerr(std::vector<FailedDestination> destinations,
703 Mac48Address from,
704 uint32_t interface,
705 Mac48Address fromMp)
706{
707 NS_LOG_FUNCTION(this << from << interface << fromMp);
708 // Acceptance cretirea:
709 NS_LOG_DEBUG("I am " << GetAddress() << ", received PERR from " << from);
710 std::vector<FailedDestination> retval;
712 for (unsigned int i = 0; i < destinations.size(); i++)
713 {
714 result = m_rtable->LookupReactiveExpired(destinations[i].destination);
715 if (!((result.retransmitter != from) || (result.ifIndex != interface) ||
716 ((int32_t)(result.seqnum - destinations[i].seqnum) > 0)))
717 {
718 retval.push_back(destinations[i]);
719 }
720 }
721 if (retval.empty())
722 {
723 return;
724 }
726}
727
728void
730 Mac48Address dst,
731 Mac48Address retransmitter,
732 uint32_t initMetric,
733 uint32_t originatorDsn,
734 uint32_t destinationSN,
735 uint32_t lifetime,
736 uint32_t interface)
737{
738 IePrep prep;
739 prep.SetHopcount(0);
740 prep.SetTtl(m_maxTtl);
741 prep.SetDestinationAddress(dst);
742 prep.SetDestinationSeqNumber(destinationSN);
743 prep.SetLifetime(lifetime);
744 prep.SetMetric(initMetric);
745 prep.SetOriginatorAddress(src);
746 prep.SetOriginatorSeqNumber(originatorDsn);
747 auto prep_sender = m_interfaces.find(interface);
748 NS_ASSERT(prep_sender != m_interfaces.end());
749 prep_sender->second->SendPrep(prep, retransmitter);
751}
752
753bool
755{
756 NS_LOG_FUNCTION(this << mp);
757 m_mp = mp;
758 std::vector<Ptr<NetDevice>> interfaces = mp->GetInterfaces();
759 for (auto i = interfaces.begin(); i != interfaces.end(); i++)
760 {
761 // Checking for compatible net device
762 Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice>();
763 if (!wifiNetDev)
764 {
765 return false;
766 }
767 Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac()->GetObject<MeshWifiInterfaceMac>();
768 if (!mac)
769 {
770 return false;
771 }
772 // Installing plugins:
773 Ptr<HwmpProtocolMac> hwmpMac = Create<HwmpProtocolMac>(wifiNetDev->GetIfIndex(), this);
774 m_interfaces[wifiNetDev->GetIfIndex()] = hwmpMac;
775 mac->InstallPlugin(hwmpMac);
776 // Installing airtime link metric:
778 mac->SetLinkMetricCallback(
780 }
781 mp->SetRoutingProtocol(this);
782 // Mesh point aggregates all installed protocols
783 mp->AggregateObject(this);
784 m_address = Mac48Address::ConvertFrom(mp->GetAddress()); // address;
785 return true;
786}
787
788void
790 Mac48Address peerAddress,
791 uint32_t interface,
792 bool status)
793{
794 NS_LOG_FUNCTION(this << meshPointAddress << peerAddress << interface << status);
795 if (status)
796 {
797 return;
798 }
799 std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations(peerAddress);
800 NS_LOG_DEBUG(destinations.size() << " failed destinations for peer address " << peerAddress);
801 InitiatePathError(MakePathError(destinations));
802}
803
804void
806{
808}
809
810bool
812{
813 NS_LOG_FUNCTION(this << seqno << source);
814 if (source == GetAddress())
815 {
816 NS_LOG_DEBUG("Dropping seqno " << seqno << "; from self");
817 return true;
818 }
819 const auto i = m_lastDataSeqno.find(source);
820 if (i == m_lastDataSeqno.end())
821 {
822 m_lastDataSeqno[source] = seqno;
823 }
824 else
825 {
826 if ((int32_t)(i->second - seqno) >= 0)
827 {
828 NS_LOG_DEBUG("Dropping seqno " << seqno << "; stale frame");
829 return true;
830 }
831 m_lastDataSeqno[source] = seqno;
832 }
833 return false;
834}
835
837HwmpProtocol::MakePathError(std::vector<FailedDestination> destinations)
838{
839 NS_LOG_FUNCTION(this);
840 PathError retval;
841 // HwmpRtable increments a sequence number as written in 11B.9.7.2
842 retval.receivers = GetPerrReceivers(destinations);
843 if (retval.receivers.empty())
844 {
845 return retval;
846 }
848 for (unsigned int i = 0; i < destinations.size(); i++)
849 {
850 retval.destinations.push_back(destinations[i]);
851 m_rtable->DeleteReactivePath(destinations[i].destination);
852 // Notify trace source of routing change
853 RouteChange rChange;
854 rChange.type = "Delete Reactive";
855 rChange.destination = destinations[i].destination;
856 rChange.seqnum = destinations[i].seqnum;
858 }
859 return retval;
860}
861
862void
864{
865 NS_LOG_FUNCTION(this);
866 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
867 {
868 std::vector<Mac48Address> receivers_for_interface;
869 for (unsigned int j = 0; j < perr.receivers.size(); j++)
870 {
871 if (i->first == perr.receivers[j].first)
872 {
873 receivers_for_interface.push_back(perr.receivers[j].second);
874 }
875 }
876 i->second->InitiatePerr(perr.destinations, receivers_for_interface);
877 }
878}
879
880void
882{
883 NS_LOG_FUNCTION(this);
884 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
885 {
886 std::vector<Mac48Address> receivers_for_interface;
887 for (unsigned int j = 0; j < perr.receivers.size(); j++)
888 {
889 if (i->first == perr.receivers[j].first)
890 {
891 receivers_for_interface.push_back(perr.receivers[j].second);
892 }
893 }
894 Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
895 NS_LOG_DEBUG("Forwarding PERR with delay " << forwardingDelay.As(Time::US));
896 Simulator::Schedule(forwardingDelay,
898 i->second,
899 perr.destinations,
900 receivers_for_interface);
901 i->second->ForwardPerr(perr.destinations, receivers_for_interface);
902 }
903}
904
905std::vector<std::pair<uint32_t, Mac48Address>>
906HwmpProtocol::GetPerrReceivers(std::vector<FailedDestination> failedDest)
907{
908 NS_LOG_FUNCTION(this);
910 for (unsigned int i = 0; i < failedDest.size(); i++)
911 {
912 HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors(failedDest[i].destination);
913 m_rtable->DeleteReactivePath(failedDest[i].destination);
914 // Notify trace source of routing change
915 RouteChange rChange;
916 rChange.type = "Delete Reactive";
917 rChange.destination = failedDest[i].destination;
918 rChange.seqnum = failedDest[i].seqnum;
920 m_rtable->DeleteProactivePath(failedDest[i].destination);
921 // Notify trace source of routing change
922 RouteChange rChangePro;
923 rChangePro.type = "Delete Proactive";
924 rChangePro.destination = failedDest[i].destination;
925 rChangePro.seqnum = failedDest[i].seqnum;
926 m_routeChangeTraceSource(rChangePro);
927 for (unsigned int j = 0; j < precursors.size(); j++)
928 {
929 retval.push_back(precursors[j]);
930 }
931 }
932 // Check if we have duplicates in retval and precursors:
933 for (unsigned int i = 0; i < retval.size(); i++)
934 {
935 for (unsigned int j = i + 1; j < retval.size(); j++)
936 {
937 if (retval[i].second == retval[j].second)
938 {
939 retval.erase(retval.begin() + j);
940 }
941 }
942 }
943 return retval;
944}
945
946std::vector<Mac48Address>
948{
949 NS_LOG_FUNCTION(this << interface);
950 std::vector<Mac48Address> retval;
951 if (!m_neighboursCallback.IsNull())
952 {
953 retval = m_neighboursCallback(interface);
954 }
955 if (retval.size() >= m_unicastPreqThreshold || retval.empty())
956 {
957 retval.clear();
958 retval.push_back(Mac48Address::GetBroadcast());
959 }
960 return retval;
961}
962
963std::vector<Mac48Address>
965{
966 NS_LOG_FUNCTION(this << interface);
967 std::vector<Mac48Address> retval;
968 if (!m_neighboursCallback.IsNull())
969 {
970 retval = m_neighboursCallback(interface);
971 }
972 if (retval.size() >= m_unicastDataThreshold || retval.empty())
973 {
974 retval.clear();
975 retval.push_back(Mac48Address::GetBroadcast());
976 }
977 return retval;
978}
979
980bool
982{
983 NS_LOG_FUNCTION(this);
984 if (m_rqueue.size() > m_maxQueueSize)
985 {
986 return false;
987 }
988 m_rqueue.push_back(packet);
989 return true;
990}
991
994{
995 NS_LOG_FUNCTION(this << dst);
996 QueuedPacket retval;
997 retval.pkt = nullptr;
998 for (auto i = m_rqueue.begin(); i != m_rqueue.end(); i++)
999 {
1000 if ((*i).dst == dst)
1001 {
1002 retval = (*i);
1003 m_rqueue.erase(i);
1004 break;
1005 }
1006 }
1007 return retval;
1008}
1009
1012{
1013 NS_LOG_FUNCTION(this);
1014 QueuedPacket retval;
1015 retval.pkt = nullptr;
1016 if (!m_rqueue.empty())
1017 {
1018 retval = m_rqueue[0];
1019 m_rqueue.erase(m_rqueue.begin());
1020 }
1021 return retval;
1022}
1023
1024void
1026{
1027 NS_LOG_FUNCTION(this << dst);
1028 auto i = m_preqTimeouts.find(dst);
1029 if (i != m_preqTimeouts.end())
1030 {
1031 m_routeDiscoveryTimeCallback(Simulator::Now() - i->second.whenScheduled);
1032 }
1033
1034 HwmpRtable::LookupResult result = m_rtable->LookupReactive(dst);
1036 // Send all packets stored for this destination
1038 while (packet.pkt)
1039 {
1040 // set RA tag for retransmitter:
1041 HwmpTag tag;
1042 packet.pkt->RemovePacketTag(tag);
1043 tag.SetAddress(result.retransmitter);
1044 packet.pkt->AddPacketTag(tag);
1046 m_stats.txBytes += packet.pkt->GetSize();
1047 packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1048
1049 packet = DequeueFirstPacketByDst(dst);
1050 }
1051}
1052
1053void
1055{
1056 NS_LOG_FUNCTION(this);
1057 // send all packets to root
1058 HwmpRtable::LookupResult result = m_rtable->LookupProactive();
1061 while (packet.pkt)
1062 {
1063 // set RA tag for retransmitter:
1064 HwmpTag tag;
1065 if (!packet.pkt->RemovePacketTag(tag))
1066 {
1067 NS_FATAL_ERROR("HWMP tag must be present at this point");
1068 }
1069 tag.SetAddress(result.retransmitter);
1070 packet.pkt->AddPacketTag(tag);
1072 m_stats.txBytes += packet.pkt->GetSize();
1073 packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1074
1075 packet = DequeueFirstPacket();
1076 }
1077}
1078
1079bool
1081{
1082 NS_LOG_FUNCTION(this << dst);
1083 auto i = m_preqTimeouts.find(dst);
1084 if (i == m_preqTimeouts.end())
1085 {
1086 m_preqTimeouts[dst].preqTimeout =
1089 this,
1090 dst,
1091 1);
1092 m_preqTimeouts[dst].whenScheduled = Simulator::Now();
1093 return true;
1094 }
1095 return false;
1096}
1097
1098void
1100{
1101 NS_LOG_FUNCTION(this << dst << (uint16_t)numOfRetry);
1102 HwmpRtable::LookupResult result = m_rtable->LookupReactive(dst);
1104 {
1105 result = m_rtable->LookupProactive();
1106 }
1108 {
1109 auto i = m_preqTimeouts.find(dst);
1110 NS_ASSERT(i != m_preqTimeouts.end());
1111 m_preqTimeouts.erase(i);
1112 return;
1113 }
1114 if (numOfRetry > m_dot11MeshHWMPmaxPREQretries)
1115 {
1117 // purge queue and delete entry from retryDatabase
1118 while (packet.pkt)
1119 {
1121 packet.reply(false,
1122 packet.pkt,
1123 packet.src,
1124 packet.dst,
1125 packet.protocol,
1127 packet = DequeueFirstPacketByDst(dst);
1128 }
1129 auto i = m_preqTimeouts.find(dst);
1130 NS_ASSERT(i != m_preqTimeouts.end());
1131 m_routeDiscoveryTimeCallback(Simulator::Now() - i->second.whenScheduled);
1132 m_preqTimeouts.erase(i);
1133 return;
1134 }
1135 numOfRetry++;
1136 uint32_t originator_seqno = GetNextHwmpSeqno();
1137 uint32_t dst_seqno = m_rtable->LookupReactiveExpired(dst).seqnum;
1138 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
1139 {
1140 i->second->RequestDestination(dst, originator_seqno, dst_seqno);
1141 }
1142 m_preqTimeouts[dst].preqTimeout =
1145 this,
1146 dst,
1147 numOfRetry);
1148}
1149
1150// Proactive PREQ routines:
1151void
1153{
1154 NS_LOG_FUNCTION(this);
1155 NS_LOG_DEBUG("ROOT IS: " << m_address);
1156 m_isRoot = true;
1157}
1158
1159void
1165
1166void
1168{
1169 NS_LOG_FUNCTION(this);
1170 IePreq preq;
1171 // By default: must answer
1172 preq.SetHopcount(0);
1173 preq.SetTTL(m_maxTtl);
1175 //\attention: do not forget to set originator address, sequence
1176 // number and preq ID in HWMP-MAC plugin
1179 preq.SetPreqID(GetNextPreqId());
1181 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
1182 {
1183 i->second->SendPreq(preq);
1184 }
1187 this);
1188}
1189
1190bool
1192{
1193 return m_doFlag;
1194}
1195
1196bool
1198{
1199 return m_rfFlag;
1200}
1201
1202Time
1207
1208Time
1213
1214uint8_t
1216{
1217 return m_maxTtl;
1218}
1219
1222{
1223 m_preqId++;
1224 return m_preqId;
1225}
1226
1229{
1230 m_hwmpSeqno++;
1231 return m_hwmpSeqno;
1232}
1233
1239
1240uint8_t
1245
1248{
1249 return m_address;
1250}
1251
1252// Statistics:
1254 : txUnicast(0),
1255 txBroadcast(0),
1256 txBytes(0),
1257 droppedTtl(0),
1258 totalQueued(0),
1259 totalDropped(0),
1260 initiatedPreq(0),
1261 initiatedPrep(0),
1262 initiatedPerr(0)
1263{
1264}
1265
1266void
1267HwmpProtocol::Statistics::Print(std::ostream& os) const
1268{
1269 os << "<Statistics "
1270 "txUnicast=\""
1271 << txUnicast
1272 << "\" "
1273 "txBroadcast=\""
1274 << txBroadcast
1275 << "\" "
1276 "txBytes=\""
1277 << txBytes
1278 << "\" "
1279 "droppedTtl=\""
1280 << droppedTtl
1281 << "\" "
1282 "totalQueued=\""
1283 << totalQueued
1284 << "\" "
1285 "totalDropped=\""
1286 << totalDropped
1287 << "\" "
1288 "initiatedPreq=\""
1289 << initiatedPreq
1290 << "\" "
1291 "initiatedPrep=\""
1292 << initiatedPrep
1293 << "\" "
1294 "initiatedPerr=\""
1295 << initiatedPerr << "\"/>" << std::endl;
1296}
1297
1298void
1299HwmpProtocol::Report(std::ostream& os) const
1300{
1301 os << "<Hwmp "
1302 "address=\""
1303 << m_address << "\"" << std::endl
1304 << "maxQueueSize=\"" << m_maxQueueSize << "\"" << std::endl
1305 << "Dot11MeshHWMPmaxPREQretries=\"" << (uint16_t)m_dot11MeshHWMPmaxPREQretries << "\""
1306 << std::endl
1307 << "Dot11MeshHWMPnetDiameterTraversalTime=\""
1308 << m_dot11MeshHWMPnetDiameterTraversalTime.GetSeconds() << "\"" << std::endl
1309 << "Dot11MeshHWMPpreqMinInterval=\"" << m_dot11MeshHWMPpreqMinInterval.GetSeconds() << "\""
1310 << std::endl
1311 << "Dot11MeshHWMPperrMinInterval=\"" << m_dot11MeshHWMPperrMinInterval.GetSeconds() << "\""
1312 << std::endl
1313 << "Dot11MeshHWMPactiveRootTimeout=\"" << m_dot11MeshHWMPactiveRootTimeout.GetSeconds()
1314 << "\"" << std::endl
1315 << "Dot11MeshHWMPactivePathTimeout=\"" << m_dot11MeshHWMPactivePathTimeout.GetSeconds()
1316 << "\"" << std::endl
1317 << "Dot11MeshHWMPpathToRootInterval=\"" << m_dot11MeshHWMPpathToRootInterval.GetSeconds()
1318 << "\"" << std::endl
1319 << "Dot11MeshHWMPrannInterval=\"" << m_dot11MeshHWMPrannInterval.GetSeconds() << "\""
1320 << std::endl
1321 << "isRoot=\"" << m_isRoot << "\"" << std::endl
1322 << "maxTtl=\"" << (uint16_t)m_maxTtl << "\"" << std::endl
1323 << "unicastPerrThreshold=\"" << (uint16_t)m_unicastPerrThreshold << "\"" << std::endl
1324 << "unicastPreqThreshold=\"" << (uint16_t)m_unicastPreqThreshold << "\"" << std::endl
1325 << "unicastDataThreshold=\"" << (uint16_t)m_unicastDataThreshold << "\"" << std::endl
1326 << "doFlag=\"" << m_doFlag << "\"" << std::endl
1327 << "rfFlag=\"" << m_rfFlag << "\">" << std::endl;
1328 m_stats.Print(os);
1329 for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
1330 {
1331 plugin->second->Report(os);
1332 }
1333 os << "</Hwmp>" << std::endl;
1334}
1335
1336void
1338{
1339 NS_LOG_FUNCTION(this);
1340 m_stats = Statistics();
1341 for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
1342 {
1343 plugin->second->ResetStats();
1344 }
1345}
1346
1347int64_t
1349{
1350 NS_LOG_FUNCTION(this << stream);
1351 m_coefficient->SetStream(stream);
1352 return 1;
1353}
1354
1357{
1358 return m_rtable;
1359}
1360
1362 : pkt(nullptr),
1363 protocol(0),
1364 inInterface(0)
1365{
1366}
1367} // namespace dot11s
1368} // namespace ns3
AttributeValue implementation for Boolean.
Definition boolean.h:26
Callback template class.
Definition callback.h:422
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition event-id.cc:44
an EUI-48 address
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address GetBroadcast()
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.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition packet.cc:956
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition packet.h:850
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition packet.cc:949
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:404
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
@ US
microsecond
Definition nstime.h:107
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:402
AttributeValue implementation for Time.
Definition nstime.h:1431
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
Hold together all Wifi-related objects.
Hybrid wireless mesh protocol – a mesh routing protocol defined in IEEE 802.11-2012 standard.
std::vector< Mac48Address > GetPreqReceivers(uint32_t interface)
Get PREQ receivers.
void PeerLinkStatus(Mac48Address meshPointAddress, Mac48Address peerAddress, uint32_t interface, bool status)
Peer link status function.
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.
TracedCallback< RouteChange > m_routeChangeTraceSource
Route change trace source.
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.
Ptr< HwmpRtable > GetRoutingTable() const
Get pointer to HWMP routing table.
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.
uint8_t GetMaxTtl() const
Get maximum TTL function.
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.
bool GetDoFlag() const
Get do flag function.
TracedCallback< Time > m_routeDiscoveryTimeCallback
Route discovery time:
static TypeId GetTypeId()
Get the type ID.
bool ShouldSendPreq(Mac48Address dst)
checks when the last path discovery procedure was started for a given destination.
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 RequestRoute(uint32_t sourceIface, const Mac48Address source, const Mac48Address destination, Ptr< const Packet > packet, uint16_t protocolType, RouteReplyCallback routeReply) override
Route request, inherited from MeshL2RoutingProtocol.
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.
void SendProactivePreq()
Proactive Preq routines:
void ForwardPathError(PathError perr)
Forwards a received path error.
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 RemoveRoutingStuff(uint32_t fromIface, const Mac48Address source, const Mac48Address destination, Ptr< Packet > packet, uint16_t &protocolType) override
Clean HWMP packet tag from packet; only the packet parameter is used.
bool m_doFlag
Destination only HWMP flag.
Mac48Address m_address
address
void DoInitialize() override
Initialize() implementation.
Time m_dot11MeshHWMPactiveRootTimeout
Lifetime of proactive routing information.
void DoDispose() override
Destructor implementation.
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 GetUnicastPerrThreshold() const
Get unicast PERR threshold 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 GetRfFlag() const
Get rf flag function.
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
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
void ResetStats()
Reset Statistics:
bool DropDataFrame(uint32_t seqno, Mac48Address source)
MAC-plugin asks whether the frame can be dropped.
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
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:29
static const uint32_t MAX_METRIC
Maximum (the best?) path metric.
Definition hwmp-rtable.h:34
std::vector< std::pair< uint32_t, Mac48Address > > PrecursorList
Path precursor = {MAC, interface ID}.
Definition hwmp-rtable.h:71
Hwmp tag implements interaction between HWMP protocol and MeshWifiMac.
Definition hwmp-tag.h:40
void SetTtl(uint8_t ttl)
Set the TTL value.
Definition hwmp-tag.cc:44
void SetSeqno(uint32_t seqno)
Set sequence number.
Definition hwmp-tag.cc:68
uint8_t GetTtl() const
Get the TTL value.
Definition hwmp-tag.cc:50
void SetAddress(Mac48Address retransmitter)
Set address.
Definition hwmp-tag.cc:32
void DecrementTtl()
Decrement TTL.
Definition hwmp-tag.cc:148
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 number 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:55
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
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:70
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:1432
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1452
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
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:35
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#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:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1368
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
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.
void Print(std::ostream &os) const
Print function.
uint16_t txBroadcast
transmit broadcast
uint16_t txUnicast
transmit unicast
Route lookup result, return type of LookupXXX methods.
Definition hwmp-rtable.h:38
uint32_t seqnum
sequence number
Definition hwmp-rtable.h:42
Mac48Address retransmitter
retransmitter
Definition hwmp-rtable.h:39
Structure to encapsulate route change information.
Time lifetime
lifetime of route
Mac48Address retransmitter
route source
uint32_t seqnum
sequence number of route
uint32_t metric
metric of route
Mac48Address destination
route destination
std::string type
type of change
uint32_t interface
interface index