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
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
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());
184 NS_LOG_INFO("Root is starting proactive PREQ timer to expire at "
185 << randomStart.As(Time::S));
188 }
189}
190
191void
193{
194 NS_LOG_FUNCTION(this);
195 for (auto i = m_preqTimeouts.begin(); i != m_preqTimeouts.end(); i++)
196 {
197 i->second.preqTimeout.Cancel();
198 }
199 m_proactivePreqTimer.Cancel();
200 m_preqTimeouts.clear();
201 m_lastDataSeqno.clear();
203 m_interfaces.clear();
204 m_rqueue.clear();
205 m_rtable = nullptr;
206 m_mp = nullptr;
207}
208
209bool
211 const Mac48Address source,
212 const Mac48Address destination,
213 Ptr<const Packet> constPacket,
214 uint16_t protocolType, // ethrnet 'Protocol' field
216{
217 NS_LOG_FUNCTION(this << sourceIface << source << destination << constPacket << protocolType);
218 Ptr<Packet> packet = constPacket->Copy();
219 HwmpTag tag;
220 if (sourceIface == GetMeshPoint()->GetIfIndex())
221 {
222 // packet from level 3
223 if (packet->PeekPacketTag(tag))
224 {
226 "HWMP tag has come with a packet from upper layer. This must not occur...");
227 }
228 // Filling TAG:
229 if (destination == Mac48Address::GetBroadcast())
230 {
231 tag.SetSeqno(m_dataSeqno++);
232 }
233 tag.SetTtl(m_maxTtl);
234 }
235 else
236 {
237 if (!packet->RemovePacketTag(tag))
238 {
239 NS_FATAL_ERROR("HWMP tag is supposed to be here at this point.");
240 }
241 tag.DecrementTtl();
242 if (tag.GetTtl() == 0)
243 {
244 NS_LOG_DEBUG("Dropping frame due to TTL expiry");
245 m_stats.droppedTtl++;
246 return false;
247 }
248 }
249 if (destination == Mac48Address::GetBroadcast())
250 {
251 m_stats.txBroadcast++;
252 m_stats.txBytes += packet->GetSize();
253 // channel IDs where we have already sent broadcast:
254 std::vector<uint16_t> channels;
255 for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
256 {
257 bool shouldSend = true;
258 for (auto chan = channels.begin(); chan != channels.end(); chan++)
259 {
260 if ((*chan) == plugin->second->GetChannelId())
261 {
262 shouldSend = false;
263 }
264 }
265 if (!shouldSend)
266 {
267 continue;
268 }
269 channels.push_back(plugin->second->GetChannelId());
270 std::vector<Mac48Address> receivers = GetBroadcastReceivers(plugin->first);
271 for (auto i = receivers.begin(); i != receivers.end(); i++)
272 {
273 Ptr<Packet> packetCopy = packet->Copy();
274 //
275 // 64-bit Intel valgrind complains about tag.SetAddress (*i). It
276 // likes this just fine.
277 //
278 Mac48Address address = *i;
279 tag.SetAddress(address);
280 packetCopy->AddPacketTag(tag);
281 NS_LOG_DEBUG("Sending route reply for broadcast; address " << address);
282 routeReply(true, packetCopy, source, destination, protocolType, plugin->first);
283 }
284 }
285 }
286 else
287 {
288 return ForwardUnicast(sourceIface,
289 source,
290 destination,
291 packet,
292 protocolType,
293 routeReply,
294 tag.GetTtl());
295 }
296 return true;
297}
298
299bool
301 const Mac48Address source,
302 const Mac48Address destination,
303 Ptr<Packet> packet,
304 uint16_t& protocolType)
305{
306 HwmpTag tag;
307 if (!packet->RemovePacketTag(tag))
308 {
309 NS_FATAL_ERROR("HWMP tag must exist when packet received from the network");
310 }
311 return true;
312}
313
314bool
316 const Mac48Address source,
317 const Mac48Address destination,
318 Ptr<Packet> packet,
319 uint16_t protocolType,
320 RouteReplyCallback routeReply,
321 uint32_t ttl)
322{
323 NS_LOG_FUNCTION(this << sourceIface << source << destination << packet << protocolType << ttl);
324 NS_ASSERT(destination != Mac48Address::GetBroadcast());
325 HwmpRtable::LookupResult result = m_rtable->LookupReactive(destination);
326 NS_LOG_DEBUG("Requested src = " << source << ", dst = " << destination << ", I am "
327 << GetAddress() << ", RA = " << result.retransmitter);
329 {
330 result = m_rtable->LookupProactive();
331 }
332 HwmpTag tag;
333 tag.SetAddress(result.retransmitter);
334 tag.SetTtl(ttl);
335 // seqno and metric is not used;
336 packet->AddPacketTag(tag);
338 {
339 // reply immediately:
340 routeReply(true, packet, source, destination, protocolType, result.ifIndex);
341 m_stats.txUnicast++;
342 m_stats.txBytes += packet->GetSize();
343 return true;
344 }
345 if (sourceIface != GetMeshPoint()->GetIfIndex())
346 {
347 // Start path error procedure:
348 NS_LOG_DEBUG("Must Send PERR");
349 result = m_rtable->LookupReactiveExpired(destination);
350 NS_LOG_DEBUG("Path error " << result.retransmitter);
351 // 1. Lookup expired reactive path. If exists - start path error
352 // procedure towards a next hop of this path
353 // 2. If there was no reactive path, we lookup expired proactive
354 // path. If exist - start path error procedure towards path to
355 // root
357 {
358 NS_LOG_DEBUG("Path error, lookup expired proactive path");
359 result = m_rtable->LookupProactiveExpired();
360 }
362 {
363 NS_LOG_DEBUG("Path error, initiate reactive path error");
364 std::vector<FailedDestination> destinations =
365 m_rtable->GetUnreachableDestinations(result.retransmitter);
366 InitiatePathError(MakePathError(destinations));
367 }
368 m_stats.totalDropped++;
369 return false;
370 }
371 // Request a destination:
372 result = m_rtable->LookupReactiveExpired(destination);
373 if (ShouldSendPreq(destination))
374 {
375 uint32_t originator_seqno = GetNextHwmpSeqno();
376 uint32_t dst_seqno = 0;
378 {
379 dst_seqno = result.seqnum;
380 }
381 m_stats.initiatedPreq++;
382 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
383 {
384 i->second->RequestDestination(destination, originator_seqno, dst_seqno);
385 }
386 }
387 QueuedPacket pkt;
388 pkt.pkt = packet;
389 pkt.dst = destination;
390 pkt.src = source;
391 pkt.protocol = protocolType;
392 pkt.reply = routeReply;
393 pkt.inInterface = sourceIface;
394 if (QueuePacket(pkt))
395 {
396 m_stats.totalQueued++;
397 return true;
398 }
399 else
400 {
401 m_stats.totalDropped++;
402 NS_LOG_DEBUG("Dropping packet from " << source << " to " << destination
403 << " due to queue overflow");
404 return false;
405 }
406}
407
408void
410 Mac48Address from,
411 uint32_t interface,
412 Mac48Address fromMp,
413 uint32_t metric)
414{
415 NS_LOG_FUNCTION(this << from << interface << fromMp << metric);
416 preq.IncrementMetric(metric);
417 // acceptance criteria:
419 bool freshInfo(true);
420 if (i != m_hwmpSeqnoMetricDatabase.end())
421 {
422 if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber()) > 0)
423 {
424 return;
425 }
426 if (i->second.first == preq.GetOriginatorSeqNumber())
427 {
428 freshInfo = false;
429 if (i->second.second <= preq.GetMetric())
430 {
431 return;
432 }
433 }
434 }
436 std::make_pair(preq.GetOriginatorSeqNumber(), preq.GetMetric());
437 NS_LOG_DEBUG("I am " << GetAddress() << ", Accepted preq from address" << from
438 << ", preq:" << preq);
439 std::vector<Ptr<DestinationAddressUnit>> destinations = preq.GetDestinationList();
440 // Add reactive path to originator:
441 if ((freshInfo) ||
442 ((m_rtable->LookupReactive(preq.GetOriginatorAddress()).retransmitter ==
444 (m_rtable->LookupReactive(preq.GetOriginatorAddress()).metric > preq.GetMetric())))
445 {
446 m_rtable->AddReactivePath(preq.GetOriginatorAddress(),
447 from,
448 interface,
449 preq.GetMetric(),
450 MicroSeconds(preq.GetLifetime() * 1024),
452 // Notify trace source of routing change
453 RouteChange rChange;
454 rChange.type = "Add Reactive";
455 rChange.destination = preq.GetOriginatorAddress();
456 rChange.retransmitter = from;
457 rChange.interface = interface;
458 rChange.metric = preq.GetMetric();
459 rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
460 rChange.seqnum = preq.GetOriginatorSeqNumber();
463 }
464 if ((m_rtable->LookupReactive(fromMp).retransmitter == Mac48Address::GetBroadcast()) ||
465 (m_rtable->LookupReactive(fromMp).metric > metric))
466 {
467 m_rtable->AddReactivePath(fromMp,
468 from,
469 interface,
470 metric,
471 MicroSeconds(preq.GetLifetime() * 1024),
473 // Notify trace source of routing change
474 RouteChange rChange;
475 rChange.type = "Add Reactive";
476 rChange.destination = fromMp;
477 rChange.retransmitter = from;
478 rChange.interface = interface;
479 rChange.metric = metric;
480 rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
481 rChange.seqnum = preq.GetOriginatorSeqNumber();
483 ReactivePathResolved(fromMp);
484 }
485 for (auto i = destinations.begin(); i != destinations.end(); i++)
486 {
487 if ((*i)->GetDestinationAddress() == Mac48Address::GetBroadcast())
488 {
489 // only proactive PREQ contains destination
490 // address as broadcast! Proactive preq MUST
491 // have destination count equal to 1 and
492 // per destination flags DO and RF
493 NS_ASSERT(preq.GetDestCount() == 1);
494 NS_ASSERT(((*i)->IsDo()) && ((*i)->IsRf()));
495 // Add proactive path only if it is the better then existed
496 // before
497 if (((m_rtable->LookupProactive()).retransmitter == Mac48Address::GetBroadcast()) ||
498 ((m_rtable->LookupProactive()).metric > preq.GetMetric()))
499 {
500 m_rtable->AddProactivePath(preq.GetMetric(),
502 from,
503 interface,
504 MicroSeconds(preq.GetLifetime() * 1024),
506 // Notify trace source of routing change
507 RouteChange rChange;
508 rChange.type = "Add Proactive";
509 rChange.destination = preq.GetOriginatorAddress();
510 rChange.retransmitter = from;
511 rChange.interface = interface;
512 rChange.metric = preq.GetMetric();
513 rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
514 rChange.seqnum = preq.GetOriginatorSeqNumber();
517 }
518 if (!preq.IsNeedNotPrep())
519 {
522 from,
523 (uint32_t)0,
526 preq.GetLifetime(),
527 interface);
528 }
529 break;
530 }
531 if ((*i)->GetDestinationAddress() == GetAddress())
532 {
535 from,
536 (uint32_t)0,
539 preq.GetLifetime(),
540 interface);
541 NS_ASSERT(m_rtable->LookupReactive(preq.GetOriginatorAddress()).retransmitter !=
543 preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
544 continue;
545 }
546 // check if can answer:
547 HwmpRtable::LookupResult result = m_rtable->LookupReactive((*i)->GetDestinationAddress());
548 if ((!((*i)->IsDo())) && (result.retransmitter != Mac48Address::GetBroadcast()))
549 {
550 // have a valid information and can answer
551 uint32_t lifetime = result.lifetime.GetMicroSeconds() / 1024;
552 if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber()) >= 0))
553 {
554 SendPrep((*i)->GetDestinationAddress(),
556 from,
557 result.metric,
559 result.seqnum,
560 lifetime,
561 interface);
562 m_rtable->AddPrecursor((*i)->GetDestinationAddress(),
563 interface,
564 from,
565 MicroSeconds(preq.GetLifetime() * 1024));
566 if ((*i)->IsRf())
567 {
568 (*i)->SetFlags(true, false, (*i)->IsUsn()); // DO = 1, RF = 0
569 }
570 else
571 {
572 preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
573 continue;
574 }
575 }
576 }
577 }
578 // check if must retransmit:
579 if (preq.GetDestCount() == 0)
580 {
581 return;
582 }
583 // Forward PREQ to all interfaces:
584 NS_LOG_DEBUG("I am " << GetAddress() << "retransmitting PREQ:" << preq);
585 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
586 {
587 Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
588 NS_LOG_DEBUG("Forwarding PREQ from " << from << " with delay "
589 << forwardingDelay.As(Time::US));
590 Simulator::Schedule(forwardingDelay, &HwmpProtocolMac::SendPreq, i->second, preq);
591 }
592}
593
594void
596 Mac48Address from,
597 uint32_t interface,
598 Mac48Address fromMp,
599 uint32_t metric)
600{
601 NS_LOG_FUNCTION(this << from << interface << fromMp << metric);
602 prep.IncrementMetric(metric);
603 // acceptance criteria:
605 bool freshInfo(true);
606 uint32_t sequence = prep.GetDestinationSeqNumber();
607 if (i != m_hwmpSeqnoMetricDatabase.end())
608 {
609 if ((int32_t)(i->second.first - sequence) > 0)
610 {
611 return;
612 }
613 if (i->second.first == sequence)
614 {
615 freshInfo = false;
616 }
617 }
619 std::make_pair(sequence, prep.GetMetric());
620 // update routing info
621 // Now add a path to destination and add precursor to source
622 NS_LOG_DEBUG("I am " << GetAddress() << ", received prep from " << prep.GetOriginatorAddress()
623 << ", receiver was:" << from);
624 HwmpRtable::LookupResult result = m_rtable->LookupReactive(prep.GetDestinationAddress());
625 // Add a reactive path only if seqno is fresher or it improves the
626 // metric
627 if ((freshInfo) ||
628 (((m_rtable->LookupReactive(prep.GetOriginatorAddress())).retransmitter ==
630 ((m_rtable->LookupReactive(prep.GetOriginatorAddress())).metric > prep.GetMetric())))
631 {
632 m_rtable->AddReactivePath(prep.GetOriginatorAddress(),
633 from,
634 interface,
635 prep.GetMetric(),
636 MicroSeconds(prep.GetLifetime() * 1024),
637 sequence);
638 // Notify trace source of routing change
639 RouteChange rChange;
640 rChange.type = "Add Reactive";
641 rChange.destination = prep.GetOriginatorAddress();
642 rChange.retransmitter = from;
643 rChange.interface = interface;
644 rChange.metric = prep.GetMetric();
645 rChange.lifetime = MicroSeconds(prep.GetLifetime() * 1024);
646 rChange.seqnum = sequence;
648 m_rtable->AddPrecursor(prep.GetDestinationAddress(),
649 interface,
650 from,
651 MicroSeconds(prep.GetLifetime() * 1024));
653 {
654 m_rtable->AddPrecursor(prep.GetOriginatorAddress(),
655 interface,
656 result.retransmitter,
657 result.lifetime);
658 }
660 }
661 if (((m_rtable->LookupReactive(fromMp)).retransmitter == Mac48Address::GetBroadcast()) ||
662 ((m_rtable->LookupReactive(fromMp)).metric > metric))
663 {
664 m_rtable->AddReactivePath(fromMp,
665 from,
666 interface,
667 metric,
668 MicroSeconds(prep.GetLifetime() * 1024),
669 sequence);
670 // Notify trace source of routing change
671 RouteChange rChange;
672 rChange.type = "Add Reactive";
673 rChange.destination = fromMp;
674 rChange.retransmitter = from;
675 rChange.interface = interface;
676 rChange.metric = metric;
677 rChange.lifetime = MicroSeconds(prep.GetLifetime() * 1024);
678 rChange.seqnum = sequence;
680 ReactivePathResolved(fromMp);
681 }
682 if (prep.GetDestinationAddress() == GetAddress())
683 {
684 NS_LOG_DEBUG("I am " << GetAddress() << ", resolved " << prep.GetOriginatorAddress());
685 return;
686 }
688 {
689 return;
690 }
691 // Forward PREP
692 auto prep_sender = m_interfaces.find(result.ifIndex);
693 NS_ASSERT(prep_sender != m_interfaces.end());
694 Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
695 NS_LOG_DEBUG("Forwarding PREP from " << from << " with delay " << forwardingDelay.As(Time::US));
696 Simulator::Schedule(forwardingDelay,
698 prep_sender->second,
699 prep,
700 result.retransmitter);
701}
702
703void
704HwmpProtocol::ReceivePerr(std::vector<FailedDestination> destinations,
705 Mac48Address from,
706 uint32_t interface,
707 Mac48Address fromMp)
708{
709 NS_LOG_FUNCTION(this << from << interface << fromMp);
710 // Acceptance criteria:
711 NS_LOG_DEBUG("I am " << GetAddress() << ", received PERR from " << from);
712 std::vector<FailedDestination> retval;
714 for (unsigned int i = 0; i < destinations.size(); i++)
715 {
716 result = m_rtable->LookupReactiveExpired(destinations[i].destination);
717 if (!((result.retransmitter != from) || (result.ifIndex != interface) ||
718 ((int32_t)(result.seqnum - destinations[i].seqnum) > 0)))
719 {
720 retval.push_back(destinations[i]);
721 }
722 }
723 if (retval.empty())
724 {
725 return;
726 }
728}
729
730void
732 Mac48Address dst,
733 Mac48Address retransmitter,
734 uint32_t initMetric,
735 uint32_t originatorDsn,
736 uint32_t destinationSN,
737 uint32_t lifetime,
738 uint32_t interface)
739{
740 NS_LOG_FUNCTION(this << src << dst << retransmitter << initMetric << originatorDsn
741 << destinationSN << lifetime << interface);
742 IePrep prep;
743 prep.SetHopcount(0);
744 prep.SetTtl(m_maxTtl);
745 prep.SetDestinationAddress(dst);
746 prep.SetDestinationSeqNumber(destinationSN);
747 prep.SetLifetime(lifetime);
748 prep.SetMetric(initMetric);
749 prep.SetOriginatorAddress(src);
750 prep.SetOriginatorSeqNumber(originatorDsn);
751 auto prep_sender = m_interfaces.find(interface);
752 NS_ASSERT(prep_sender != m_interfaces.end());
753 prep_sender->second->SendPrep(prep, retransmitter);
754 m_stats.initiatedPrep++;
755}
756
757bool
759{
760 NS_LOG_FUNCTION(this << mp);
761 m_mp = mp;
762 std::vector<Ptr<NetDevice>> interfaces = mp->GetInterfaces();
763 for (auto i = interfaces.begin(); i != interfaces.end(); i++)
764 {
765 // Checking for compatible net device
766 Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice>();
767 if (!wifiNetDev)
768 {
769 return false;
770 }
771 Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac()->GetObject<MeshWifiInterfaceMac>();
772 if (!mac)
773 {
774 return false;
775 }
776 // Installing plugins:
777 Ptr<HwmpProtocolMac> hwmpMac = Create<HwmpProtocolMac>(wifiNetDev->GetIfIndex(), this);
778 m_interfaces[wifiNetDev->GetIfIndex()] = hwmpMac;
779 mac->InstallPlugin(hwmpMac);
780 // Installing airtime link metric:
782 mac->SetLinkMetricCallback(
784 }
785 mp->SetRoutingProtocol(this);
786 // Mesh point aggregates all installed protocols
787 mp->AggregateObject(this);
788 m_address = Mac48Address::ConvertFrom(mp->GetAddress()); // address;
789 return true;
790}
791
792void
794 Mac48Address peerAddress,
795 uint32_t interface,
796 bool status)
797{
798 NS_LOG_FUNCTION(this << meshPointAddress << peerAddress << interface << status);
799 if (status)
800 {
801 return;
802 }
803 std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations(peerAddress);
804 NS_LOG_DEBUG(destinations.size() << " failed destinations for peer address " << peerAddress);
805 InitiatePathError(MakePathError(destinations));
806}
807
808void
810{
812}
813
814bool
816{
817 NS_LOG_FUNCTION(this << seqno << source);
818 if (source == GetAddress())
819 {
820 NS_LOG_DEBUG("Dropping seqno " << seqno << "; from self");
821 return true;
822 }
823 const auto i = m_lastDataSeqno.find(source);
824 if (i == m_lastDataSeqno.end())
825 {
826 m_lastDataSeqno[source] = seqno;
827 }
828 else
829 {
830 if ((int32_t)(i->second - seqno) >= 0)
831 {
832 NS_LOG_DEBUG("Dropping seqno " << seqno << "; stale frame");
833 return true;
834 }
835 m_lastDataSeqno[source] = seqno;
836 }
837 return false;
838}
839
841HwmpProtocol::MakePathError(std::vector<FailedDestination> destinations)
842{
843 NS_LOG_FUNCTION(this);
844 PathError retval;
845 // HwmpRtable increments a sequence number as written in 11B.9.7.2
846 retval.receivers = GetPerrReceivers(destinations);
847 if (retval.receivers.empty())
848 {
849 return retval;
850 }
851 m_stats.initiatedPerr++;
852 for (unsigned int i = 0; i < destinations.size(); i++)
853 {
854 retval.destinations.push_back(destinations[i]);
855 m_rtable->DeleteReactivePath(destinations[i].destination);
856 // Notify trace source of routing change
857 RouteChange rChange;
858 rChange.type = "Delete Reactive";
859 rChange.destination = destinations[i].destination;
860 rChange.seqnum = destinations[i].seqnum;
862 }
863 return retval;
864}
865
866void
868{
869 NS_LOG_FUNCTION(this);
870 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
871 {
872 std::vector<Mac48Address> receivers_for_interface;
873 for (unsigned int j = 0; j < perr.receivers.size(); j++)
874 {
875 if (i->first == perr.receivers[j].first)
876 {
877 receivers_for_interface.push_back(perr.receivers[j].second);
878 }
879 }
880 i->second->InitiatePerr(perr.destinations, receivers_for_interface);
881 }
882}
883
884void
886{
887 NS_LOG_FUNCTION(this);
888 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
889 {
890 std::vector<Mac48Address> receivers_for_interface;
891 for (unsigned int j = 0; j < perr.receivers.size(); j++)
892 {
893 if (i->first == perr.receivers[j].first)
894 {
895 receivers_for_interface.push_back(perr.receivers[j].second);
896 }
897 }
898 Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
899 NS_LOG_DEBUG("Forwarding PERR with delay " << forwardingDelay.As(Time::US));
900 Simulator::Schedule(forwardingDelay,
902 i->second,
903 perr.destinations,
904 receivers_for_interface);
905 i->second->ForwardPerr(perr.destinations, receivers_for_interface);
906 }
907}
908
909std::vector<std::pair<uint32_t, Mac48Address>>
910HwmpProtocol::GetPerrReceivers(std::vector<FailedDestination> failedDest)
911{
912 NS_LOG_FUNCTION(this);
914 for (unsigned int i = 0; i < failedDest.size(); i++)
915 {
916 HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors(failedDest[i].destination);
917 m_rtable->DeleteReactivePath(failedDest[i].destination);
918 // Notify trace source of routing change
919 RouteChange rChange;
920 rChange.type = "Delete Reactive";
921 rChange.destination = failedDest[i].destination;
922 rChange.seqnum = failedDest[i].seqnum;
924 m_rtable->DeleteProactivePath(failedDest[i].destination);
925 // Notify trace source of routing change
926 RouteChange rChangePro;
927 rChangePro.type = "Delete Proactive";
928 rChangePro.destination = failedDest[i].destination;
929 rChangePro.seqnum = failedDest[i].seqnum;
930 m_routeChangeTraceSource(rChangePro);
931 for (unsigned int j = 0; j < precursors.size(); j++)
932 {
933 retval.push_back(precursors[j]);
934 }
935 }
936 // Check if we have duplicates in retval and precursors:
937 for (unsigned int i = 0; i < retval.size(); i++)
938 {
939 for (unsigned int j = i + 1; j < retval.size(); j++)
940 {
941 if (retval[i].second == retval[j].second)
942 {
943 retval.erase(retval.begin() + j);
944 }
945 }
946 }
947 return retval;
948}
949
950std::vector<Mac48Address>
952{
953 NS_LOG_FUNCTION(this << interface);
954 std::vector<Mac48Address> retval;
955 if (!m_neighboursCallback.IsNull())
956 {
957 retval = m_neighboursCallback(interface);
958 }
959 if (retval.size() >= m_unicastPreqThreshold || retval.empty())
960 {
961 retval.clear();
962 retval.push_back(Mac48Address::GetBroadcast());
963 }
964 return retval;
965}
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.empty())
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 = nullptr;
1002 for (auto 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 = nullptr;
1020 if (!m_rqueue.empty())
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 auto i = m_preqTimeouts.find(dst);
1033 if (i != m_preqTimeouts.end())
1034 {
1035 m_routeDiscoveryTimeCallback(Simulator::Now() - i->second.whenScheduled);
1036 }
1037
1038 HwmpRtable::LookupResult result = m_rtable->LookupReactive(dst);
1040 // Send all packets stored for this destination
1042 while (packet.pkt)
1043 {
1044 // set RA tag for retransmitter:
1045 HwmpTag tag;
1046 packet.pkt->RemovePacketTag(tag);
1047 tag.SetAddress(result.retransmitter);
1048 packet.pkt->AddPacketTag(tag);
1049 m_stats.txUnicast++;
1050 m_stats.txBytes += packet.pkt->GetSize();
1051 packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1052
1053 packet = DequeueFirstPacketByDst(dst);
1054 }
1055}
1056
1057void
1059{
1060 NS_LOG_FUNCTION(this);
1061 // send all packets to root
1062 HwmpRtable::LookupResult result = m_rtable->LookupProactive();
1065 while (packet.pkt)
1066 {
1067 // set RA tag for retransmitter:
1068 HwmpTag tag;
1069 if (!packet.pkt->RemovePacketTag(tag))
1070 {
1071 NS_FATAL_ERROR("HWMP tag must be present at this point");
1072 }
1073 tag.SetAddress(result.retransmitter);
1074 packet.pkt->AddPacketTag(tag);
1075 m_stats.txUnicast++;
1076 m_stats.txBytes += packet.pkt->GetSize();
1077 packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1078
1079 packet = DequeueFirstPacket();
1080 }
1081}
1082
1083bool
1085{
1086 NS_LOG_FUNCTION(this << dst);
1087 auto i = m_preqTimeouts.find(dst);
1088 if (i == m_preqTimeouts.end())
1089 {
1090 m_preqTimeouts[dst].preqTimeout =
1093 this,
1094 dst,
1095 1);
1096 m_preqTimeouts[dst].whenScheduled = Simulator::Now();
1097 return true;
1098 }
1099 return false;
1100}
1101
1102void
1104{
1105 NS_LOG_FUNCTION(this << dst << (uint16_t)numOfRetry);
1106 HwmpRtable::LookupResult result = m_rtable->LookupReactive(dst);
1108 {
1109 result = m_rtable->LookupProactive();
1110 }
1112 {
1113 auto i = m_preqTimeouts.find(dst);
1114 NS_ASSERT(i != m_preqTimeouts.end());
1115 m_preqTimeouts.erase(i);
1116 return;
1117 }
1118 if (numOfRetry > m_dot11MeshHWMPmaxPREQretries)
1119 {
1121 // purge queue and delete entry from retryDatabase
1122 while (packet.pkt)
1123 {
1124 m_stats.totalDropped++;
1125 packet.reply(false,
1126 packet.pkt,
1127 packet.src,
1128 packet.dst,
1129 packet.protocol,
1131 packet = DequeueFirstPacketByDst(dst);
1132 }
1133 auto i = m_preqTimeouts.find(dst);
1134 NS_ASSERT(i != m_preqTimeouts.end());
1135 m_routeDiscoveryTimeCallback(Simulator::Now() - i->second.whenScheduled);
1136 m_preqTimeouts.erase(i);
1137 return;
1138 }
1139 numOfRetry++;
1140 uint32_t originator_seqno = GetNextHwmpSeqno();
1141 uint32_t dst_seqno = m_rtable->LookupReactiveExpired(dst).seqnum;
1142 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
1143 {
1144 i->second->RequestDestination(dst, originator_seqno, dst_seqno);
1145 }
1146 m_preqTimeouts[dst].preqTimeout =
1149 this,
1150 dst,
1151 numOfRetry);
1152}
1153
1154// Proactive PREQ routines:
1155void
1157{
1158 NS_LOG_FUNCTION(this);
1159 NS_LOG_DEBUG("ROOT IS: " << m_address);
1160 m_isRoot = true;
1161}
1162
1163void
1165{
1166 NS_LOG_FUNCTION(this);
1167 m_proactivePreqTimer.Cancel();
1168}
1169
1170void
1172{
1173 NS_LOG_FUNCTION(this);
1174 IePreq preq;
1175 // By default: must answer
1176 preq.SetHopcount(0);
1177 preq.SetTTL(m_maxTtl);
1178 preq.SetLifetime(m_dot11MeshHWMPactiveRootTimeout.GetMicroSeconds() / 1024);
1179 //\attention: do not forget to set originator address, sequence
1180 // number and preq ID in HWMP-MAC plugin
1183 preq.SetPreqID(GetNextPreqId());
1185 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
1186 {
1187 i->second->SendPreq(preq);
1188 }
1191 this);
1192}
1193
1194bool
1196{
1197 return m_doFlag;
1198}
1199
1200bool
1202{
1203 return m_rfFlag;
1204}
1205
1206Time
1211
1212Time
1217
1218uint8_t
1220{
1221 return m_maxTtl;
1222}
1223
1226{
1227 m_preqId++;
1228 return m_preqId;
1229}
1230
1233{
1234 m_hwmpSeqno++;
1235 return m_hwmpSeqno;
1236}
1237
1240{
1241 return m_dot11MeshHWMPactivePathTimeout.GetMicroSeconds() / 1024;
1242}
1243
1244uint8_t
1249
1252{
1253 return m_address;
1254}
1255
1256// Statistics:
1258 : txUnicast(0),
1259 txBroadcast(0),
1260 txBytes(0),
1261 droppedTtl(0),
1262 totalQueued(0),
1263 totalDropped(0),
1264 initiatedPreq(0),
1265 initiatedPrep(0),
1266 initiatedPerr(0)
1267{
1268}
1269
1270void
1271HwmpProtocol::Statistics::Print(std::ostream& os) const
1272{
1273 os << "<Statistics "
1274 "txUnicast=\""
1275 << txUnicast
1276 << "\" "
1277 "txBroadcast=\""
1278 << txBroadcast
1279 << "\" "
1280 "txBytes=\""
1281 << txBytes
1282 << "\" "
1283 "droppedTtl=\""
1284 << droppedTtl
1285 << "\" "
1286 "totalQueued=\""
1287 << totalQueued
1288 << "\" "
1289 "totalDropped=\""
1290 << totalDropped
1291 << "\" "
1292 "initiatedPreq=\""
1293 << initiatedPreq
1294 << "\" "
1295 "initiatedPrep=\""
1296 << initiatedPrep
1297 << "\" "
1298 "initiatedPerr=\""
1299 << initiatedPerr << "\"/>" << std::endl;
1300}
1301
1302void
1303HwmpProtocol::Report(std::ostream& os) const
1304{
1305 os << "<Hwmp "
1306 "address=\""
1307 << m_address << "\"" << std::endl
1308 << "maxQueueSize=\"" << m_maxQueueSize << "\"" << std::endl
1309 << "Dot11MeshHWMPmaxPREQretries=\"" << (uint16_t)m_dot11MeshHWMPmaxPREQretries << "\""
1310 << std::endl
1311 << "Dot11MeshHWMPnetDiameterTraversalTime=\""
1312 << m_dot11MeshHWMPnetDiameterTraversalTime.GetSeconds() << "\"" << std::endl
1313 << "Dot11MeshHWMPpreqMinInterval=\"" << m_dot11MeshHWMPpreqMinInterval.GetSeconds() << "\""
1314 << std::endl
1315 << "Dot11MeshHWMPperrMinInterval=\"" << m_dot11MeshHWMPperrMinInterval.GetSeconds() << "\""
1316 << std::endl
1317 << "Dot11MeshHWMPactiveRootTimeout=\"" << m_dot11MeshHWMPactiveRootTimeout.GetSeconds()
1318 << "\"" << std::endl
1319 << "Dot11MeshHWMPactivePathTimeout=\"" << m_dot11MeshHWMPactivePathTimeout.GetSeconds()
1320 << "\"" << std::endl
1321 << "Dot11MeshHWMPpathToRootInterval=\"" << m_dot11MeshHWMPpathToRootInterval.GetSeconds()
1322 << "\"" << std::endl
1323 << "Dot11MeshHWMPrannInterval=\"" << m_dot11MeshHWMPrannInterval.GetSeconds() << "\""
1324 << std::endl
1325 << "isRoot=\"" << m_isRoot << "\"" << std::endl
1326 << "maxTtl=\"" << (uint16_t)m_maxTtl << "\"" << std::endl
1327 << "unicastPerrThreshold=\"" << (uint16_t)m_unicastPerrThreshold << "\"" << std::endl
1328 << "unicastPreqThreshold=\"" << (uint16_t)m_unicastPreqThreshold << "\"" << std::endl
1329 << "unicastDataThreshold=\"" << (uint16_t)m_unicastDataThreshold << "\"" << std::endl
1330 << "doFlag=\"" << m_doFlag << "\"" << std::endl
1331 << "rfFlag=\"" << m_rfFlag << "\">" << std::endl;
1332 m_stats.Print(os);
1333 for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
1334 {
1335 plugin->second->Report(os);
1336 }
1337 os << "</Hwmp>" << std::endl;
1338}
1339
1340void
1342{
1343 NS_LOG_FUNCTION(this);
1344 m_stats = Statistics();
1345 for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
1346 {
1347 plugin->second->ResetStats();
1348 }
1349}
1350
1351int64_t
1353{
1354 NS_LOG_FUNCTION(this << stream);
1355 m_coefficient->SetStream(stream);
1356 return 1;
1357}
1358
1361{
1362 return m_rtable;
1363}
1364
1366 : pkt(nullptr),
1367 protocol(0),
1368 inInterface(0)
1369{
1370}
1371} // namespace dot11s
1372} // 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
an EUI-48 address
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address GetBroadcast()
Interface for L2 mesh routing protocol and mesh point communication.
Callback< void, bool, Ptr< Packet >, Mac48Address, Mac48Address, uint16_t, uint32_t > RouteReplyCallback
Callback to be invoked when route discovery procedure is completed.
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.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:67
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:561
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
Simulation virtual time values and global simulation resolution.
Definition nstime.h:96
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:409
@ US
microsecond
Definition nstime.h:109
@ S
second
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:404
AttributeValue implementation for Time.
Definition nstime.h:1456
a unique identifier for an interface.
Definition type-id.h:49
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:114
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:1457
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1477
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 ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
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:439
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1393
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
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