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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Authors: Kirill Andreev <andreev@iitp.ru>
18 */
19
20#include "hwmp-protocol.h"
21
22#include "airtime-metric.h"
23#include "hwmp-protocol-mac.h"
24#include "hwmp-rtable.h"
25#include "hwmp-tag.h"
26#include "ie-dot11s-perr.h"
27#include "ie-dot11s-prep.h"
28#include "ie-dot11s-preq.h"
29
30#include "ns3/log.h"
31#include "ns3/mesh-point-device.h"
32#include "ns3/mesh-wifi-interface-mac.h"
33#include "ns3/packet.h"
34#include "ns3/pointer.h"
35#include "ns3/random-variable-stream.h"
36#include "ns3/simulator.h"
37#include "ns3/string.h"
38#include "ns3/trace-source-accessor.h"
39#include "ns3/wifi-net-device.h"
40
41namespace ns3
42{
43
44NS_LOG_COMPONENT_DEFINE("HwmpProtocol");
45
46namespace dot11s
47{
48
49NS_OBJECT_ENSURE_REGISTERED(HwmpProtocol);
50
51TypeId
53{
54 static TypeId tid =
55 TypeId("ns3::dot11s::HwmpProtocol")
57 .SetGroupName("Mesh")
58 .AddConstructor<HwmpProtocol>()
59 .AddAttribute("RandomStart",
60 "Random delay at first proactive PREQ",
61 TimeValue(Seconds(0.1)),
64 .AddAttribute("MaxQueueSize",
65 "Maximum number of packets we can store when resolving route",
66 UintegerValue(255),
68 MakeUintegerChecker<uint16_t>(1))
69 .AddAttribute(
70 "Dot11MeshHWMPmaxPREQretries",
71 "Maximum number of retries before we suppose the destination to be unreachable",
74 MakeUintegerChecker<uint8_t>(1))
75 .AddAttribute(
76 "Dot11MeshHWMPnetDiameterTraversalTime",
77 "Time we suppose the packet to go from one edge of the network to another",
78 TimeValue(MicroSeconds(1024 * 100)),
81 .AddAttribute("Dot11MeshHWMPpreqMinInterval",
82 "Minimal interval between to successive PREQs",
83 TimeValue(MicroSeconds(1024 * 100)),
86 .AddAttribute("Dot11MeshHWMPperrMinInterval",
87 "Minimal interval between to successive PREQs",
88 TimeValue(MicroSeconds(1024 * 100)),
91 .AddAttribute("Dot11MeshHWMPactiveRootTimeout",
92 "Lifetime of proactive routing information",
93 TimeValue(MicroSeconds(1024 * 5000)),
96 .AddAttribute("Dot11MeshHWMPactivePathTimeout",
97 "Lifetime of reactive routing information",
98 TimeValue(MicroSeconds(1024 * 5000)),
101 .AddAttribute("Dot11MeshHWMPpathToRootInterval",
102 "Interval between two successive proactive PREQs",
103 TimeValue(MicroSeconds(1024 * 2000)),
106 .AddAttribute("Dot11MeshHWMPrannInterval",
107 "Lifetime of proactive routing information",
108 TimeValue(MicroSeconds(1024 * 5000)),
111 .AddAttribute("MaxTtl",
112 "Initial value of Time To Live field",
113 UintegerValue(32),
115 MakeUintegerChecker<uint8_t>(2))
116 .AddAttribute(
117 "UnicastPerrThreshold",
118 "Maximum number of PERR receivers, when we send a PERR as a chain of unicasts",
119 UintegerValue(32),
121 MakeUintegerChecker<uint8_t>(1))
122 .AddAttribute(
123 "UnicastPreqThreshold",
124 "Maximum number of PREQ receivers, when we send a PREQ as a chain of unicasts",
125 UintegerValue(1),
127 MakeUintegerChecker<uint8_t>(1))
128 .AddAttribute("UnicastDataThreshold",
129 "Maximum number of broadcast receivers, when we send a broadcast as a "
130 "chain of unicasts",
131 UintegerValue(1),
133 MakeUintegerChecker<uint8_t>(1))
134 .AddAttribute("DoFlag",
135 "Destination only HWMP flag",
136 BooleanValue(false),
139 .AddAttribute("RfFlag",
140 "Reply and forward flag",
141 BooleanValue(true),
144 .AddTraceSource("RouteDiscoveryTime",
145 "The time of route discovery procedure",
147 "ns3::Time::TracedCallback")
148 .AddTraceSource("RouteChange",
149 "Routing table changed",
151 "ns3::HwmpProtocol::RouteChangeTracedCallback");
152 return tid;
153}
154
156 : m_dataSeqno(1),
157 m_hwmpSeqno(1),
158 m_preqId(0),
159 m_rtable(CreateObject<HwmpRtable>()),
160 m_randomStart(Seconds(0.1)),
161 m_maxQueueSize(255),
162 m_dot11MeshHWMPmaxPREQretries(3),
163 m_dot11MeshHWMPnetDiameterTraversalTime(MicroSeconds(1024 * 100)),
164 m_dot11MeshHWMPpreqMinInterval(MicroSeconds(1024 * 100)),
165 m_dot11MeshHWMPperrMinInterval(MicroSeconds(1024 * 100)),
166 m_dot11MeshHWMPactiveRootTimeout(MicroSeconds(1024 * 5000)),
167 m_dot11MeshHWMPactivePathTimeout(MicroSeconds(1024 * 5000)),
168 m_dot11MeshHWMPpathToRootInterval(MicroSeconds(1024 * 2000)),
169 m_dot11MeshHWMPrannInterval(MicroSeconds(1024 * 5000)),
170 m_isRoot(false),
171 m_maxTtl(32),
172 m_unicastPerrThreshold(32),
173 m_unicastPreqThreshold(1),
174 m_unicastDataThreshold(1),
175 m_doFlag(false),
176 m_rfFlag(false)
177{
178 NS_LOG_FUNCTION(this);
179 m_coefficient = CreateObject<UniformRandomVariable>();
180}
181
183{
184 NS_LOG_FUNCTION(this);
185}
186
187void
189{
190 NS_LOG_FUNCTION(this);
192 if (m_isRoot)
193 {
194 Time randomStart = Seconds(m_coefficient->GetValue());
197 }
198}
199
200void
202{
203 NS_LOG_FUNCTION(this);
204 for (auto i = m_preqTimeouts.begin(); i != m_preqTimeouts.end(); i++)
205 {
206 i->second.preqTimeout.Cancel();
207 }
209 m_preqTimeouts.clear();
210 m_lastDataSeqno.clear();
212 m_interfaces.clear();
213 m_rqueue.clear();
214 m_rtable = nullptr;
215 m_mp = nullptr;
216}
217
218bool
220 const Mac48Address source,
221 const Mac48Address destination,
222 Ptr<const Packet> constPacket,
223 uint16_t protocolType, // ethrnet 'Protocol' field
225{
226 NS_LOG_FUNCTION(this << sourceIface << source << destination << constPacket << protocolType);
227 Ptr<Packet> packet = constPacket->Copy();
228 HwmpTag tag;
229 if (sourceIface == GetMeshPoint()->GetIfIndex())
230 {
231 // packet from level 3
232 if (packet->PeekPacketTag(tag))
233 {
235 "HWMP tag has come with a packet from upper layer. This must not occur...");
236 }
237 // Filling TAG:
238 if (destination == Mac48Address::GetBroadcast())
239 {
240 tag.SetSeqno(m_dataSeqno++);
241 }
242 tag.SetTtl(m_maxTtl);
243 }
244 else
245 {
246 if (!packet->RemovePacketTag(tag))
247 {
248 NS_FATAL_ERROR("HWMP tag is supposed to be here at this point.");
249 }
250 tag.DecrementTtl();
251 if (tag.GetTtl() == 0)
252 {
253 NS_LOG_DEBUG("Dropping frame due to TTL expiry");
255 return false;
256 }
257 }
258 if (destination == Mac48Address::GetBroadcast())
259 {
261 m_stats.txBytes += packet->GetSize();
262 // channel IDs where we have already sent broadcast:
263 std::vector<uint16_t> channels;
264 for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
265 {
266 bool shouldSend = true;
267 for (auto chan = channels.begin(); chan != channels.end(); chan++)
268 {
269 if ((*chan) == plugin->second->GetChannelId())
270 {
271 shouldSend = false;
272 }
273 }
274 if (!shouldSend)
275 {
276 continue;
277 }
278 channels.push_back(plugin->second->GetChannelId());
279 std::vector<Mac48Address> receivers = GetBroadcastReceivers(plugin->first);
280 for (auto i = receivers.begin(); i != receivers.end(); i++)
281 {
282 Ptr<Packet> packetCopy = packet->Copy();
283 //
284 // 64-bit Intel valgrind complains about tag.SetAddress (*i). It
285 // likes this just fine.
286 //
287 Mac48Address address = *i;
288 tag.SetAddress(address);
289 packetCopy->AddPacketTag(tag);
290 NS_LOG_DEBUG("Sending route reply for broadcast; address " << address);
291 routeReply(true, packetCopy, source, destination, protocolType, plugin->first);
292 }
293 }
294 }
295 else
296 {
297 return ForwardUnicast(sourceIface,
298 source,
299 destination,
300 packet,
301 protocolType,
302 routeReply,
303 tag.GetTtl());
304 }
305 return true;
306}
307
308bool
310 const Mac48Address source,
311 const Mac48Address destination,
312 Ptr<Packet> packet,
313 uint16_t& protocolType)
314{
315 HwmpTag tag;
316 if (!packet->RemovePacketTag(tag))
317 {
318 NS_FATAL_ERROR("HWMP tag must exist when packet received from the network");
319 }
320 return true;
321}
322
323bool
325 const Mac48Address source,
326 const Mac48Address destination,
327 Ptr<Packet> packet,
328 uint16_t protocolType,
329 RouteReplyCallback routeReply,
330 uint32_t ttl)
331{
332 NS_LOG_FUNCTION(this << sourceIface << source << destination << packet << protocolType << ttl);
333 NS_ASSERT(destination != Mac48Address::GetBroadcast());
334 HwmpRtable::LookupResult result = m_rtable->LookupReactive(destination);
335 NS_LOG_DEBUG("Requested src = " << source << ", dst = " << destination << ", I am "
336 << GetAddress() << ", RA = " << result.retransmitter);
338 {
339 result = m_rtable->LookupProactive();
340 }
341 HwmpTag tag;
342 tag.SetAddress(result.retransmitter);
343 tag.SetTtl(ttl);
344 // seqno and metric is not used;
345 packet->AddPacketTag(tag);
347 {
348 // reply immediately:
349 routeReply(true, packet, source, destination, protocolType, result.ifIndex);
351 m_stats.txBytes += packet->GetSize();
352 return true;
353 }
354 if (sourceIface != GetMeshPoint()->GetIfIndex())
355 {
356 // Start path error procedure:
357 NS_LOG_DEBUG("Must Send PERR");
358 result = m_rtable->LookupReactiveExpired(destination);
359 NS_LOG_DEBUG("Path error " << result.retransmitter);
360 // 1. Lookup expired reactive path. If exists - start path error
361 // procedure towards a next hop of this path
362 // 2. If there was no reactive path, we lookup expired proactive
363 // path. If exist - start path error procedure towards path to
364 // root
366 {
367 NS_LOG_DEBUG("Path error, lookup expired proactive path");
369 }
371 {
372 NS_LOG_DEBUG("Path error, initiate reactive path error");
373 std::vector<FailedDestination> destinations =
375 InitiatePathError(MakePathError(destinations));
376 }
378 return false;
379 }
380 // Request a destination:
381 result = m_rtable->LookupReactiveExpired(destination);
382 if (ShouldSendPreq(destination))
383 {
384 uint32_t originator_seqno = GetNextHwmpSeqno();
385 uint32_t dst_seqno = 0;
387 {
388 dst_seqno = result.seqnum;
389 }
391 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
392 {
393 i->second->RequestDestination(destination, originator_seqno, dst_seqno);
394 }
395 }
396 QueuedPacket pkt;
397 pkt.pkt = packet;
398 pkt.dst = destination;
399 pkt.src = source;
400 pkt.protocol = protocolType;
401 pkt.reply = routeReply;
402 pkt.inInterface = sourceIface;
403 if (QueuePacket(pkt))
404 {
406 return true;
407 }
408 else
409 {
411 NS_LOG_DEBUG("Dropping packet from " << source << " to " << destination
412 << " due to queue overflow");
413 return false;
414 }
415}
416
417void
419 Mac48Address from,
420 uint32_t interface,
421 Mac48Address fromMp,
422 uint32_t metric)
423{
424 NS_LOG_FUNCTION(this << from << interface << fromMp << metric);
425 preq.IncrementMetric(metric);
426 // acceptance cretirea:
428 bool freshInfo(true);
429 if (i != m_hwmpSeqnoMetricDatabase.end())
430 {
431 if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber()) > 0)
432 {
433 return;
434 }
435 if (i->second.first == preq.GetOriginatorSeqNumber())
436 {
437 freshInfo = false;
438 if (i->second.second <= preq.GetMetric())
439 {
440 return;
441 }
442 }
443 }
445 std::make_pair(preq.GetOriginatorSeqNumber(), preq.GetMetric());
446 NS_LOG_DEBUG("I am " << GetAddress() << ", Accepted preq from address" << from
447 << ", preq:" << preq);
448 std::vector<Ptr<DestinationAddressUnit>> destinations = preq.GetDestinationList();
449 // Add reactive path to originator:
450 if ((freshInfo) ||
454 {
456 from,
457 interface,
458 preq.GetMetric(),
459 MicroSeconds(preq.GetLifetime() * 1024),
461 // Notify trace source of routing change
462 RouteChange rChange;
463 rChange.type = "Add Reactive";
464 rChange.destination = preq.GetOriginatorAddress();
465 rChange.retransmitter = from;
466 rChange.interface = interface;
467 rChange.metric = preq.GetMetric();
468 rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
469 rChange.seqnum = preq.GetOriginatorSeqNumber();
472 }
474 (m_rtable->LookupReactive(fromMp).metric > metric))
475 {
477 from,
478 interface,
479 metric,
480 MicroSeconds(preq.GetLifetime() * 1024),
482 // Notify trace source of routing change
483 RouteChange rChange;
484 rChange.type = "Add Reactive";
485 rChange.destination = fromMp;
486 rChange.retransmitter = from;
487 rChange.interface = interface;
488 rChange.metric = metric;
489 rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
490 rChange.seqnum = preq.GetOriginatorSeqNumber();
492 ReactivePathResolved(fromMp);
493 }
494 for (auto i = destinations.begin(); i != destinations.end(); i++)
495 {
496 if ((*i)->GetDestinationAddress() == Mac48Address::GetBroadcast())
497 {
498 // only proactive PREQ contains destination
499 // address as broadcast! Proactive preq MUST
500 // have destination count equal to 1 and
501 // per destination flags DO and RF
502 NS_ASSERT(preq.GetDestCount() == 1);
503 NS_ASSERT(((*i)->IsDo()) && ((*i)->IsRf()));
504 // Add proactive path only if it is the better then existed
505 // before
506 if (((m_rtable->LookupProactive()).retransmitter == Mac48Address::GetBroadcast()) ||
507 ((m_rtable->LookupProactive()).metric > preq.GetMetric()))
508 {
511 from,
512 interface,
513 MicroSeconds(preq.GetLifetime() * 1024),
515 // Notify trace source of routing change
516 RouteChange rChange;
517 rChange.type = "Add Proactive";
518 rChange.destination = preq.GetOriginatorAddress();
519 rChange.retransmitter = from;
520 rChange.interface = interface;
521 rChange.metric = preq.GetMetric();
522 rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
523 rChange.seqnum = preq.GetOriginatorSeqNumber();
526 }
527 if (!preq.IsNeedNotPrep())
528 {
531 from,
532 (uint32_t)0,
535 preq.GetLifetime(),
536 interface);
537 }
538 break;
539 }
540 if ((*i)->GetDestinationAddress() == GetAddress())
541 {
544 from,
545 (uint32_t)0,
548 preq.GetLifetime(),
549 interface);
552 preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
553 continue;
554 }
555 // check if can answer:
556 HwmpRtable::LookupResult result = m_rtable->LookupReactive((*i)->GetDestinationAddress());
557 if ((!((*i)->IsDo())) && (result.retransmitter != Mac48Address::GetBroadcast()))
558 {
559 // have a valid information and can answer
560 uint32_t lifetime = result.lifetime.GetMicroSeconds() / 1024;
561 if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber()) >= 0))
562 {
563 SendPrep((*i)->GetDestinationAddress(),
565 from,
566 result.metric,
568 result.seqnum,
569 lifetime,
570 interface);
571 m_rtable->AddPrecursor((*i)->GetDestinationAddress(),
572 interface,
573 from,
574 MicroSeconds(preq.GetLifetime() * 1024));
575 if ((*i)->IsRf())
576 {
577 (*i)->SetFlags(true, false, (*i)->IsUsn()); // DO = 1, RF = 0
578 }
579 else
580 {
581 preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
582 continue;
583 }
584 }
585 }
586 }
587 // check if must retransmit:
588 if (preq.GetDestCount() == 0)
589 {
590 return;
591 }
592 // Forward PREQ to all interfaces:
593 NS_LOG_DEBUG("I am " << GetAddress() << "retransmitting PREQ:" << preq);
594 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
595 {
596 Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
597 NS_LOG_DEBUG("Forwarding PREQ from " << from << " with delay "
598 << forwardingDelay.As(Time::US));
599 Simulator::Schedule(forwardingDelay, &HwmpProtocolMac::SendPreq, i->second, preq);
600 }
601}
602
603void
605 Mac48Address from,
606 uint32_t interface,
607 Mac48Address fromMp,
608 uint32_t metric)
609{
610 NS_LOG_FUNCTION(this << from << interface << fromMp << metric);
611 prep.IncrementMetric(metric);
612 // acceptance cretirea:
614 bool freshInfo(true);
615 uint32_t sequence = prep.GetDestinationSeqNumber();
616 if (i != m_hwmpSeqnoMetricDatabase.end())
617 {
618 if ((int32_t)(i->second.first - sequence) > 0)
619 {
620 return;
621 }
622 if (i->second.first == sequence)
623 {
624 freshInfo = false;
625 }
626 }
628 std::make_pair(sequence, prep.GetMetric());
629 // update routing info
630 // Now add a path to destination and add precursor to source
631 NS_LOG_DEBUG("I am " << GetAddress() << ", received prep from " << prep.GetOriginatorAddress()
632 << ", receiver was:" << from);
634 // Add a reactive path only if seqno is fresher or it improves the
635 // metric
636 if ((freshInfo) ||
637 (((m_rtable->LookupReactive(prep.GetOriginatorAddress())).retransmitter ==
639 ((m_rtable->LookupReactive(prep.GetOriginatorAddress())).metric > prep.GetMetric())))
640 {
642 from,
643 interface,
644 prep.GetMetric(),
645 MicroSeconds(prep.GetLifetime() * 1024),
646 sequence);
647 // Notify trace source of routing change
648 RouteChange rChange;
649 rChange.type = "Add Reactive";
650 rChange.destination = prep.GetOriginatorAddress();
651 rChange.retransmitter = from;
652 rChange.interface = interface;
653 rChange.metric = prep.GetMetric();
654 rChange.lifetime = MicroSeconds(prep.GetLifetime() * 1024);
655 rChange.seqnum = sequence;
658 interface,
659 from,
660 MicroSeconds(prep.GetLifetime() * 1024));
662 {
664 interface,
665 result.retransmitter,
666 result.lifetime);
667 }
669 }
670 if (((m_rtable->LookupReactive(fromMp)).retransmitter == Mac48Address::GetBroadcast()) ||
671 ((m_rtable->LookupReactive(fromMp)).metric > metric))
672 {
674 from,
675 interface,
676 metric,
677 MicroSeconds(prep.GetLifetime() * 1024),
678 sequence);
679 // Notify trace source of routing change
680 RouteChange rChange;
681 rChange.type = "Add Reactive";
682 rChange.destination = fromMp;
683 rChange.retransmitter = from;
684 rChange.interface = interface;
685 rChange.metric = metric;
686 rChange.lifetime = MicroSeconds(prep.GetLifetime() * 1024);
687 rChange.seqnum = sequence;
689 ReactivePathResolved(fromMp);
690 }
691 if (prep.GetDestinationAddress() == GetAddress())
692 {
693 NS_LOG_DEBUG("I am " << GetAddress() << ", resolved " << prep.GetOriginatorAddress());
694 return;
695 }
697 {
698 return;
699 }
700 // Forward PREP
701 auto prep_sender = m_interfaces.find(result.ifIndex);
702 NS_ASSERT(prep_sender != m_interfaces.end());
703 Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
704 NS_LOG_DEBUG("Forwarding PREP from " << from << " with delay " << forwardingDelay.As(Time::US));
705 Simulator::Schedule(forwardingDelay,
707 prep_sender->second,
708 prep,
709 result.retransmitter);
710}
711
712void
713HwmpProtocol::ReceivePerr(std::vector<FailedDestination> destinations,
714 Mac48Address from,
715 uint32_t interface,
716 Mac48Address fromMp)
717{
718 NS_LOG_FUNCTION(this << from << interface << fromMp);
719 // Acceptance cretirea:
720 NS_LOG_DEBUG("I am " << GetAddress() << ", received PERR from " << from);
721 std::vector<FailedDestination> retval;
723 for (unsigned int i = 0; i < destinations.size(); i++)
724 {
725 result = m_rtable->LookupReactiveExpired(destinations[i].destination);
726 if (!((result.retransmitter != from) || (result.ifIndex != interface) ||
727 ((int32_t)(result.seqnum - destinations[i].seqnum) > 0)))
728 {
729 retval.push_back(destinations[i]);
730 }
731 }
732 if (retval.empty())
733 {
734 return;
735 }
737}
738
739void
741 Mac48Address dst,
742 Mac48Address retransmitter,
743 uint32_t initMetric,
744 uint32_t originatorDsn,
745 uint32_t destinationSN,
746 uint32_t lifetime,
747 uint32_t interface)
748{
749 IePrep prep;
750 prep.SetHopcount(0);
751 prep.SetTtl(m_maxTtl);
752 prep.SetDestinationAddress(dst);
753 prep.SetDestinationSeqNumber(destinationSN);
754 prep.SetLifetime(lifetime);
755 prep.SetMetric(initMetric);
756 prep.SetOriginatorAddress(src);
757 prep.SetOriginatorSeqNumber(originatorDsn);
758 auto prep_sender = m_interfaces.find(interface);
759 NS_ASSERT(prep_sender != m_interfaces.end());
760 prep_sender->second->SendPrep(prep, retransmitter);
762}
763
764bool
766{
767 NS_LOG_FUNCTION(this << mp);
768 m_mp = mp;
769 std::vector<Ptr<NetDevice>> interfaces = mp->GetInterfaces();
770 for (auto i = interfaces.begin(); i != interfaces.end(); i++)
771 {
772 // Checking for compatible net device
773 Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice>();
774 if (!wifiNetDev)
775 {
776 return false;
777 }
778 Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac()->GetObject<MeshWifiInterfaceMac>();
779 if (!mac)
780 {
781 return false;
782 }
783 // Installing plugins:
784 Ptr<HwmpProtocolMac> hwmpMac = Create<HwmpProtocolMac>(wifiNetDev->GetIfIndex(), this);
785 m_interfaces[wifiNetDev->GetIfIndex()] = hwmpMac;
786 mac->InstallPlugin(hwmpMac);
787 // Installing airtime link metric:
788 Ptr<AirtimeLinkMetricCalculator> metric = CreateObject<AirtimeLinkMetricCalculator>();
789 mac->SetLinkMetricCallback(
791 }
792 mp->SetRoutingProtocol(this);
793 // Mesh point aggregates all installed protocols
794 mp->AggregateObject(this);
795 m_address = Mac48Address::ConvertFrom(mp->GetAddress()); // address;
796 return true;
797}
798
799void
801 Mac48Address peerAddress,
802 uint32_t interface,
803 bool status)
804{
805 NS_LOG_FUNCTION(this << meshPointAddress << peerAddress << interface << status);
806 if (status)
807 {
808 return;
809 }
810 std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations(peerAddress);
811 NS_LOG_DEBUG(destinations.size() << " failed destinations for peer address " << peerAddress);
812 InitiatePathError(MakePathError(destinations));
813}
814
815void
817{
819}
820
821bool
823{
824 NS_LOG_FUNCTION(this << seqno << source);
825 if (source == GetAddress())
826 {
827 NS_LOG_DEBUG("Dropping seqno " << seqno << "; from self");
828 return true;
829 }
830 const auto i = m_lastDataSeqno.find(source);
831 if (i == m_lastDataSeqno.end())
832 {
833 m_lastDataSeqno[source] = seqno;
834 }
835 else
836 {
837 if ((int32_t)(i->second - seqno) >= 0)
838 {
839 NS_LOG_DEBUG("Dropping seqno " << seqno << "; stale frame");
840 return true;
841 }
842 m_lastDataSeqno[source] = seqno;
843 }
844 return false;
845}
846
848HwmpProtocol::MakePathError(std::vector<FailedDestination> destinations)
849{
850 NS_LOG_FUNCTION(this);
851 PathError retval;
852 // HwmpRtable increments a sequence number as written in 11B.9.7.2
853 retval.receivers = GetPerrReceivers(destinations);
854 if (retval.receivers.empty())
855 {
856 return retval;
857 }
859 for (unsigned int i = 0; i < destinations.size(); i++)
860 {
861 retval.destinations.push_back(destinations[i]);
862 m_rtable->DeleteReactivePath(destinations[i].destination);
863 // Notify trace source of routing change
864 RouteChange rChange;
865 rChange.type = "Delete Reactive";
866 rChange.destination = destinations[i].destination;
867 rChange.seqnum = destinations[i].seqnum;
869 }
870 return retval;
871}
872
873void
875{
876 NS_LOG_FUNCTION(this);
877 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
878 {
879 std::vector<Mac48Address> receivers_for_interface;
880 for (unsigned int j = 0; j < perr.receivers.size(); j++)
881 {
882 if (i->first == perr.receivers[j].first)
883 {
884 receivers_for_interface.push_back(perr.receivers[j].second);
885 }
886 }
887 i->second->InitiatePerr(perr.destinations, receivers_for_interface);
888 }
889}
890
891void
893{
894 NS_LOG_FUNCTION(this);
895 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
896 {
897 std::vector<Mac48Address> receivers_for_interface;
898 for (unsigned int j = 0; j < perr.receivers.size(); j++)
899 {
900 if (i->first == perr.receivers[j].first)
901 {
902 receivers_for_interface.push_back(perr.receivers[j].second);
903 }
904 }
905 Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
906 NS_LOG_DEBUG("Forwarding PERR with delay " << forwardingDelay.As(Time::US));
907 Simulator::Schedule(forwardingDelay,
909 i->second,
910 perr.destinations,
911 receivers_for_interface);
912 i->second->ForwardPerr(perr.destinations, receivers_for_interface);
913 }
914}
915
916std::vector<std::pair<uint32_t, Mac48Address>>
917HwmpProtocol::GetPerrReceivers(std::vector<FailedDestination> failedDest)
918{
919 NS_LOG_FUNCTION(this);
921 for (unsigned int i = 0; i < failedDest.size(); i++)
922 {
923 HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors(failedDest[i].destination);
924 m_rtable->DeleteReactivePath(failedDest[i].destination);
925 // Notify trace source of routing change
926 RouteChange rChange;
927 rChange.type = "Delete Reactive";
928 rChange.destination = failedDest[i].destination;
929 rChange.seqnum = failedDest[i].seqnum;
931 m_rtable->DeleteProactivePath(failedDest[i].destination);
932 // Notify trace source of routing change
933 RouteChange rChangePro;
934 rChangePro.type = "Delete Proactive";
935 rChangePro.destination = failedDest[i].destination;
936 rChangePro.seqnum = failedDest[i].seqnum;
937 m_routeChangeTraceSource(rChangePro);
938 for (unsigned int j = 0; j < precursors.size(); j++)
939 {
940 retval.push_back(precursors[j]);
941 }
942 }
943 // Check if we have duplicates in retval and precursors:
944 for (unsigned int i = 0; i < retval.size(); i++)
945 {
946 for (unsigned int j = i + 1; j < retval.size(); j++)
947 {
948 if (retval[i].second == retval[j].second)
949 {
950 retval.erase(retval.begin() + j);
951 }
952 }
953 }
954 return retval;
955}
956
957std::vector<Mac48Address>
959{
960 NS_LOG_FUNCTION(this << interface);
961 std::vector<Mac48Address> retval;
962 if (!m_neighboursCallback.IsNull())
963 {
964 retval = m_neighboursCallback(interface);
965 }
966 if (retval.size() >= m_unicastPreqThreshold || retval.empty())
967 {
968 retval.clear();
969 retval.push_back(Mac48Address::GetBroadcast());
970 }
971 return retval;
972}
973
974std::vector<Mac48Address>
976{
977 NS_LOG_FUNCTION(this << interface);
978 std::vector<Mac48Address> retval;
979 if (!m_neighboursCallback.IsNull())
980 {
981 retval = m_neighboursCallback(interface);
982 }
983 if (retval.size() >= m_unicastDataThreshold || retval.empty())
984 {
985 retval.clear();
986 retval.push_back(Mac48Address::GetBroadcast());
987 }
988 return retval;
989}
990
991bool
993{
994 NS_LOG_FUNCTION(this);
995 if (m_rqueue.size() > m_maxQueueSize)
996 {
997 return false;
998 }
999 m_rqueue.push_back(packet);
1000 return true;
1001}
1002
1005{
1006 NS_LOG_FUNCTION(this << dst);
1007 QueuedPacket retval;
1008 retval.pkt = nullptr;
1009 for (auto i = m_rqueue.begin(); i != m_rqueue.end(); i++)
1010 {
1011 if ((*i).dst == dst)
1012 {
1013 retval = (*i);
1014 m_rqueue.erase(i);
1015 break;
1016 }
1017 }
1018 return retval;
1019}
1020
1023{
1024 NS_LOG_FUNCTION(this);
1025 QueuedPacket retval;
1026 retval.pkt = nullptr;
1027 if (!m_rqueue.empty())
1028 {
1029 retval = m_rqueue[0];
1030 m_rqueue.erase(m_rqueue.begin());
1031 }
1032 return retval;
1033}
1034
1035void
1037{
1038 NS_LOG_FUNCTION(this << dst);
1039 auto i = m_preqTimeouts.find(dst);
1040 if (i != m_preqTimeouts.end())
1041 {
1042 m_routeDiscoveryTimeCallback(Simulator::Now() - i->second.whenScheduled);
1043 }
1044
1047 // Send all packets stored for this destination
1049 while (packet.pkt)
1050 {
1051 // set RA tag for retransmitter:
1052 HwmpTag tag;
1053 packet.pkt->RemovePacketTag(tag);
1054 tag.SetAddress(result.retransmitter);
1055 packet.pkt->AddPacketTag(tag);
1057 m_stats.txBytes += packet.pkt->GetSize();
1058 packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1059
1060 packet = DequeueFirstPacketByDst(dst);
1061 }
1062}
1063
1064void
1066{
1067 NS_LOG_FUNCTION(this);
1068 // send all packets to root
1072 while (packet.pkt)
1073 {
1074 // set RA tag for retransmitter:
1075 HwmpTag tag;
1076 if (!packet.pkt->RemovePacketTag(tag))
1077 {
1078 NS_FATAL_ERROR("HWMP tag must be present at this point");
1079 }
1080 tag.SetAddress(result.retransmitter);
1081 packet.pkt->AddPacketTag(tag);
1083 m_stats.txBytes += packet.pkt->GetSize();
1084 packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1085
1086 packet = DequeueFirstPacket();
1087 }
1088}
1089
1090bool
1092{
1093 NS_LOG_FUNCTION(this << dst);
1094 auto i = m_preqTimeouts.find(dst);
1095 if (i == m_preqTimeouts.end())
1096 {
1097 m_preqTimeouts[dst].preqTimeout =
1100 this,
1101 dst,
1102 1);
1103 m_preqTimeouts[dst].whenScheduled = Simulator::Now();
1104 return true;
1105 }
1106 return false;
1107}
1108
1109void
1111{
1112 NS_LOG_FUNCTION(this << dst << (uint16_t)numOfRetry);
1115 {
1116 result = m_rtable->LookupProactive();
1117 }
1119 {
1120 auto i = m_preqTimeouts.find(dst);
1121 NS_ASSERT(i != m_preqTimeouts.end());
1122 m_preqTimeouts.erase(i);
1123 return;
1124 }
1125 if (numOfRetry > m_dot11MeshHWMPmaxPREQretries)
1126 {
1128 // purge queue and delete entry from retryDatabase
1129 while (packet.pkt)
1130 {
1132 packet.reply(false,
1133 packet.pkt,
1134 packet.src,
1135 packet.dst,
1136 packet.protocol,
1138 packet = DequeueFirstPacketByDst(dst);
1139 }
1140 auto i = m_preqTimeouts.find(dst);
1141 NS_ASSERT(i != m_preqTimeouts.end());
1142 m_routeDiscoveryTimeCallback(Simulator::Now() - i->second.whenScheduled);
1143 m_preqTimeouts.erase(i);
1144 return;
1145 }
1146 numOfRetry++;
1147 uint32_t originator_seqno = GetNextHwmpSeqno();
1149 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
1150 {
1151 i->second->RequestDestination(dst, originator_seqno, dst_seqno);
1152 }
1153 m_preqTimeouts[dst].preqTimeout =
1156 this,
1157 dst,
1158 numOfRetry);
1159}
1160
1161// Proactive PREQ routines:
1162void
1164{
1165 NS_LOG_FUNCTION(this);
1166 NS_LOG_DEBUG("ROOT IS: " << m_address);
1167 m_isRoot = true;
1168}
1169
1170void
1172{
1173 NS_LOG_FUNCTION(this);
1175}
1176
1177void
1179{
1180 NS_LOG_FUNCTION(this);
1181 IePreq preq;
1182 // By default: must answer
1183 preq.SetHopcount(0);
1184 preq.SetTTL(m_maxTtl);
1186 //\attention: do not forget to set originator address, sequence
1187 // number and preq ID in HWMP-MAC plugin
1190 preq.SetPreqID(GetNextPreqId());
1192 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
1193 {
1194 i->second->SendPreq(preq);
1195 }
1198 this);
1199}
1200
1201bool
1203{
1204 return m_doFlag;
1205}
1206
1207bool
1209{
1210 return m_rfFlag;
1211}
1212
1213Time
1215{
1217}
1218
1219Time
1221{
1223}
1224
1225uint8_t
1227{
1228 return m_maxTtl;
1229}
1230
1233{
1234 m_preqId++;
1235 return m_preqId;
1236}
1237
1240{
1241 m_hwmpSeqno++;
1242 return m_hwmpSeqno;
1243}
1244
1247{
1249}
1250
1251uint8_t
1253{
1255}
1256
1259{
1260 return m_address;
1261}
1262
1263// Statistics:
1265 : txUnicast(0),
1266 txBroadcast(0),
1267 txBytes(0),
1268 droppedTtl(0),
1269 totalQueued(0),
1270 totalDropped(0),
1271 initiatedPreq(0),
1272 initiatedPrep(0),
1273 initiatedPerr(0)
1274{
1275}
1276
1277void
1278HwmpProtocol::Statistics::Print(std::ostream& os) const
1279{
1280 os << "<Statistics "
1281 "txUnicast=\""
1282 << txUnicast
1283 << "\" "
1284 "txBroadcast=\""
1285 << txBroadcast
1286 << "\" "
1287 "txBytes=\""
1288 << txBytes
1289 << "\" "
1290 "droppedTtl=\""
1291 << droppedTtl
1292 << "\" "
1293 "totalQueued=\""
1294 << totalQueued
1295 << "\" "
1296 "totalDropped=\""
1297 << totalDropped
1298 << "\" "
1299 "initiatedPreq=\""
1300 << initiatedPreq
1301 << "\" "
1302 "initiatedPrep=\""
1303 << initiatedPrep
1304 << "\" "
1305 "initiatedPerr=\""
1306 << initiatedPerr << "\"/>" << std::endl;
1307}
1308
1309void
1310HwmpProtocol::Report(std::ostream& os) const
1311{
1312 os << "<Hwmp "
1313 "address=\""
1314 << m_address << "\"" << std::endl
1315 << "maxQueueSize=\"" << m_maxQueueSize << "\"" << std::endl
1316 << "Dot11MeshHWMPmaxPREQretries=\"" << (uint16_t)m_dot11MeshHWMPmaxPREQretries << "\""
1317 << std::endl
1318 << "Dot11MeshHWMPnetDiameterTraversalTime=\""
1319 << m_dot11MeshHWMPnetDiameterTraversalTime.GetSeconds() << "\"" << std::endl
1320 << "Dot11MeshHWMPpreqMinInterval=\"" << m_dot11MeshHWMPpreqMinInterval.GetSeconds() << "\""
1321 << std::endl
1322 << "Dot11MeshHWMPperrMinInterval=\"" << m_dot11MeshHWMPperrMinInterval.GetSeconds() << "\""
1323 << std::endl
1324 << "Dot11MeshHWMPactiveRootTimeout=\"" << m_dot11MeshHWMPactiveRootTimeout.GetSeconds()
1325 << "\"" << std::endl
1326 << "Dot11MeshHWMPactivePathTimeout=\"" << m_dot11MeshHWMPactivePathTimeout.GetSeconds()
1327 << "\"" << std::endl
1328 << "Dot11MeshHWMPpathToRootInterval=\"" << m_dot11MeshHWMPpathToRootInterval.GetSeconds()
1329 << "\"" << std::endl
1330 << "Dot11MeshHWMPrannInterval=\"" << m_dot11MeshHWMPrannInterval.GetSeconds() << "\""
1331 << std::endl
1332 << "isRoot=\"" << m_isRoot << "\"" << std::endl
1333 << "maxTtl=\"" << (uint16_t)m_maxTtl << "\"" << std::endl
1334 << "unicastPerrThreshold=\"" << (uint16_t)m_unicastPerrThreshold << "\"" << std::endl
1335 << "unicastPreqThreshold=\"" << (uint16_t)m_unicastPreqThreshold << "\"" << std::endl
1336 << "unicastDataThreshold=\"" << (uint16_t)m_unicastDataThreshold << "\"" << std::endl
1337 << "doFlag=\"" << m_doFlag << "\"" << std::endl
1338 << "rfFlag=\"" << m_rfFlag << "\">" << std::endl;
1339 m_stats.Print(os);
1340 for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
1341 {
1342 plugin->second->Report(os);
1343 }
1344 os << "</Hwmp>" << std::endl;
1345}
1346
1347void
1349{
1350 NS_LOG_FUNCTION(this);
1351 m_stats = Statistics();
1352 for (auto plugin = m_interfaces.begin(); plugin != m_interfaces.end(); plugin++)
1353 {
1354 plugin->second->ResetStats();
1355 }
1356}
1357
1358int64_t
1360{
1361 NS_LOG_FUNCTION(this << stream);
1362 m_coefficient->SetStream(stream);
1363 return 1;
1364}
1365
1368{
1369 return m_rtable;
1370}
1371
1373 : pkt(nullptr),
1374 protocol(0),
1375 inInterface(0)
1376{
1377}
1378} // namespace dot11s
1379} // namespace ns3
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Callback template class.
Definition: callback.h:438
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
an EUI-48 address
Definition: mac48-address.h:46
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.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:211
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:967
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:960
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
@ US
microsecond
Definition: nstime.h:118
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:413
AttributeValue implementation for Time.
Definition: nstime.h:1413
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
Hold together all Wifi-related objects.
Hybrid wireless mesh protocol – a mesh routing protocol defined in IEEE 802.11-2012 standard.
Definition: hwmp-protocol.h:68
void SetRoot()
Unset the current node as root.
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
keeps HWMP seqno (first in pair) and HWMP metric (second in pair) for each address
void ResetStats()
Reset Statistics:
bool DropDataFrame(uint32_t seqno, Mac48Address source)
MAC-plugin asks whether the frame can be dropped.
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:40
void DeleteReactivePath(Mac48Address destination)
Delete the reactive paths toward a destination.
Definition: hwmp-rtable.cc:161
static const uint32_t MAX_METRIC
Maximum (the best?) path metric.
Definition: hwmp-rtable.h:45
LookupResult LookupReactive(Mac48Address destination)
Lookup path to destination.
Definition: hwmp-rtable.cc:172
LookupResult LookupReactiveExpired(Mac48Address destination)
Return all reactive paths, including expired.
Definition: hwmp-rtable.cc:189
PrecursorList GetPrecursors(Mac48Address destination)
Get the precursors list.
Definition: hwmp-rtable.cc:256
void DeleteProactivePath()
Delete all the proactive paths.
Definition: hwmp-rtable.cc:139
LookupResult LookupProactiveExpired()
Return all proactive paths, including expired.
Definition: hwmp-rtable.cc:218
std::vector< std::pair< uint32_t, Mac48Address > > PrecursorList
Path precursor = {MAC, interface ID}.
Definition: hwmp-rtable.h:82
std::vector< HwmpProtocol::FailedDestination > GetUnreachableDestinations(Mac48Address peerAddress)
When peer link with a given MAC-address fails - it returns list of unreachable destination addresses.
Definition: hwmp-rtable.cc:230
LookupResult LookupProactive()
Find proactive path to tree root.
Definition: hwmp-rtable.cc:206
void AddPrecursor(Mac48Address destination, uint32_t precursorInterface, Mac48Address precursorAddress, Time lifetime)
Add a precursor.
Definition: hwmp-rtable.cc:106
void AddProactivePath(uint32_t metric, Mac48Address root, Mac48Address retransmitter, uint32_t interface, Time lifetime, uint32_t seqnum)
Add a proactive path.
Definition: hwmp-rtable.cc:89
void AddReactivePath(Mac48Address destination, Mac48Address retransmitter, uint32_t interface, uint32_t metric, Time lifetime, uint32_t seqnum)
Add a reactive path.
Definition: hwmp-rtable.cc:64
Hwmp tag implements interaction between HWMP protocol and MeshWifiMac.
Definition: hwmp-tag.h:51
void SetTtl(uint8_t ttl)
Set the TTL value.
Definition: hwmp-tag.cc:55
void SetSeqno(uint32_t seqno)
Set sequence number.
Definition: hwmp-tag.cc:79
uint8_t GetTtl() const
Get the TTL value.
Definition: hwmp-tag.cc:61
void SetAddress(Mac48Address retransmitter)
Set address.
Definition: hwmp-tag.cc:43
void DecrementTtl()
Decrement TTL.
Definition: hwmp-tag.cc:159
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:66
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:81
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1434
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#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:630
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
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:704
Definition: second.py:1
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 initiatedPrep
initiated PREP
uint16_t txBroadcast
transmit broadcast
uint16_t txUnicast
transmit unicast
uint16_t initiatedPerr
initiated PERR
uint16_t initiatedPreq
initiated PREQ
Route lookup result, return type of LookupXXX methods.
Definition: hwmp-rtable.h:49
uint32_t seqnum
sequence number
Definition: hwmp-rtable.h:53
Mac48Address retransmitter
retransmitter
Definition: hwmp-rtable.h:50
Structure to encapsulate route change information.
Definition: hwmp-protocol.h:51
Time lifetime
lifetime of route
Definition: hwmp-protocol.h:57
Mac48Address retransmitter
route source
Definition: hwmp-protocol.h:54
uint32_t seqnum
sequence number of route
Definition: hwmp-protocol.h:58
uint32_t metric
metric of route
Definition: hwmp-protocol.h:56
Mac48Address destination
route destination
Definition: hwmp-protocol.h:53
std::string type
type of change
Definition: hwmp-protocol.h:52
uint32_t interface
interface index
Definition: hwmp-protocol.h:55