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 (std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.begin();
205 i != m_preqTimeouts.end();
206 i++)
207 {
208 i->second.preqTimeout.Cancel();
209 }
211 m_preqTimeouts.clear();
212 m_lastDataSeqno.clear();
214 m_interfaces.clear();
215 m_rqueue.clear();
216 m_rtable = nullptr;
217 m_mp = nullptr;
218}
219
220bool
222 const Mac48Address source,
223 const Mac48Address destination,
224 Ptr<const Packet> constPacket,
225 uint16_t protocolType, // ethrnet 'Protocol' field
227{
228 NS_LOG_FUNCTION(this << sourceIface << source << destination << constPacket << protocolType);
229 Ptr<Packet> packet = constPacket->Copy();
230 HwmpTag tag;
231 if (sourceIface == GetMeshPoint()->GetIfIndex())
232 {
233 // packet from level 3
234 if (packet->PeekPacketTag(tag))
235 {
237 "HWMP tag has come with a packet from upper layer. This must not occur...");
238 }
239 // Filling TAG:
240 if (destination == Mac48Address::GetBroadcast())
241 {
242 tag.SetSeqno(m_dataSeqno++);
243 }
244 tag.SetTtl(m_maxTtl);
245 }
246 else
247 {
248 if (!packet->RemovePacketTag(tag))
249 {
250 NS_FATAL_ERROR("HWMP tag is supposed to be here at this point.");
251 }
252 tag.DecrementTtl();
253 if (tag.GetTtl() == 0)
254 {
255 NS_LOG_DEBUG("Dropping frame due to TTL expiry");
257 return false;
258 }
259 }
260 if (destination == Mac48Address::GetBroadcast())
261 {
263 m_stats.txBytes += packet->GetSize();
264 // channel IDs where we have already sent broadcast:
265 std::vector<uint16_t> channels;
266 for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin();
267 plugin != m_interfaces.end();
268 plugin++)
269 {
270 bool shouldSend = true;
271 for (std::vector<uint16_t>::const_iterator chan = channels.begin();
272 chan != channels.end();
273 chan++)
274 {
275 if ((*chan) == plugin->second->GetChannelId())
276 {
277 shouldSend = false;
278 }
279 }
280 if (!shouldSend)
281 {
282 continue;
283 }
284 channels.push_back(plugin->second->GetChannelId());
285 std::vector<Mac48Address> receivers = GetBroadcastReceivers(plugin->first);
286 for (std::vector<Mac48Address>::const_iterator i = receivers.begin();
287 i != receivers.end();
288 i++)
289 {
290 Ptr<Packet> packetCopy = packet->Copy();
291 //
292 // 64-bit Intel valgrind complains about tag.SetAddress (*i). It
293 // likes this just fine.
294 //
295 Mac48Address address = *i;
296 tag.SetAddress(address);
297 packetCopy->AddPacketTag(tag);
298 NS_LOG_DEBUG("Sending route reply for broadcast; address " << address);
299 routeReply(true, packetCopy, source, destination, protocolType, plugin->first);
300 }
301 }
302 }
303 else
304 {
305 return ForwardUnicast(sourceIface,
306 source,
307 destination,
308 packet,
309 protocolType,
310 routeReply,
311 tag.GetTtl());
312 }
313 return true;
314}
315
316bool
318 const Mac48Address source,
319 const Mac48Address destination,
320 Ptr<Packet> packet,
321 uint16_t& protocolType)
322{
323 HwmpTag tag;
324 if (!packet->RemovePacketTag(tag))
325 {
326 NS_FATAL_ERROR("HWMP tag must exist when packet received from the network");
327 }
328 return true;
329}
330
331bool
333 const Mac48Address source,
334 const Mac48Address destination,
335 Ptr<Packet> packet,
336 uint16_t protocolType,
337 RouteReplyCallback routeReply,
338 uint32_t ttl)
339{
340 NS_LOG_FUNCTION(this << sourceIface << source << destination << packet << protocolType << ttl);
341 NS_ASSERT(destination != Mac48Address::GetBroadcast());
342 HwmpRtable::LookupResult result = m_rtable->LookupReactive(destination);
343 NS_LOG_DEBUG("Requested src = " << source << ", dst = " << destination << ", I am "
344 << GetAddress() << ", RA = " << result.retransmitter);
346 {
347 result = m_rtable->LookupProactive();
348 }
349 HwmpTag tag;
350 tag.SetAddress(result.retransmitter);
351 tag.SetTtl(ttl);
352 // seqno and metric is not used;
353 packet->AddPacketTag(tag);
355 {
356 // reply immediately:
357 routeReply(true, packet, source, destination, protocolType, result.ifIndex);
359 m_stats.txBytes += packet->GetSize();
360 return true;
361 }
362 if (sourceIface != GetMeshPoint()->GetIfIndex())
363 {
364 // Start path error procedure:
365 NS_LOG_DEBUG("Must Send PERR");
366 result = m_rtable->LookupReactiveExpired(destination);
367 NS_LOG_DEBUG("Path error " << result.retransmitter);
368 // 1. Lookup expired reactive path. If exists - start path error
369 // procedure towards a next hop of this path
370 // 2. If there was no reactive path, we lookup expired proactive
371 // path. If exist - start path error procedure towards path to
372 // root
374 {
375 NS_LOG_DEBUG("Path error, lookup expired proactive path");
377 }
379 {
380 NS_LOG_DEBUG("Path error, initiate reactive path error");
381 std::vector<FailedDestination> destinations =
383 InitiatePathError(MakePathError(destinations));
384 }
386 return false;
387 }
388 // Request a destination:
389 result = m_rtable->LookupReactiveExpired(destination);
390 if (ShouldSendPreq(destination))
391 {
392 uint32_t originator_seqno = GetNextHwmpSeqno();
393 uint32_t dst_seqno = 0;
395 {
396 dst_seqno = result.seqnum;
397 }
399 for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin(); i != m_interfaces.end();
400 i++)
401 {
402 i->second->RequestDestination(destination, originator_seqno, dst_seqno);
403 }
404 }
405 QueuedPacket pkt;
406 pkt.pkt = packet;
407 pkt.dst = destination;
408 pkt.src = source;
409 pkt.protocol = protocolType;
410 pkt.reply = routeReply;
411 pkt.inInterface = sourceIface;
412 if (QueuePacket(pkt))
413 {
415 return true;
416 }
417 else
418 {
420 NS_LOG_DEBUG("Dropping packet from " << source << " to " << destination
421 << " due to queue overflow");
422 return false;
423 }
424}
425
426void
428 Mac48Address from,
429 uint32_t interface,
430 Mac48Address fromMp,
431 uint32_t metric)
432{
433 NS_LOG_FUNCTION(this << from << interface << fromMp << metric);
434 preq.IncrementMetric(metric);
435 // acceptance cretirea:
436 std::map<Mac48Address, std::pair<uint32_t, uint32_t>>::const_iterator i =
438 bool freshInfo(true);
439 if (i != m_hwmpSeqnoMetricDatabase.end())
440 {
441 if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber()) > 0)
442 {
443 return;
444 }
445 if (i->second.first == preq.GetOriginatorSeqNumber())
446 {
447 freshInfo = false;
448 if (i->second.second <= preq.GetMetric())
449 {
450 return;
451 }
452 }
453 }
455 std::make_pair(preq.GetOriginatorSeqNumber(), preq.GetMetric());
456 NS_LOG_DEBUG("I am " << GetAddress() << ", Accepted preq from address" << from
457 << ", preq:" << preq);
458 std::vector<Ptr<DestinationAddressUnit>> destinations = preq.GetDestinationList();
459 // Add reactive path to originator:
460 if ((freshInfo) ||
464 {
466 from,
467 interface,
468 preq.GetMetric(),
469 MicroSeconds(preq.GetLifetime() * 1024),
471 // Notify trace source of routing change
472 RouteChange rChange;
473 rChange.type = "Add Reactive";
474 rChange.destination = preq.GetOriginatorAddress();
475 rChange.retransmitter = from;
476 rChange.interface = interface;
477 rChange.metric = preq.GetMetric();
478 rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
479 rChange.seqnum = preq.GetOriginatorSeqNumber();
482 }
484 (m_rtable->LookupReactive(fromMp).metric > metric))
485 {
487 from,
488 interface,
489 metric,
490 MicroSeconds(preq.GetLifetime() * 1024),
492 // Notify trace source of routing change
493 RouteChange rChange;
494 rChange.type = "Add Reactive";
495 rChange.destination = fromMp;
496 rChange.retransmitter = from;
497 rChange.interface = interface;
498 rChange.metric = metric;
499 rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
500 rChange.seqnum = preq.GetOriginatorSeqNumber();
502 ReactivePathResolved(fromMp);
503 }
504 for (std::vector<Ptr<DestinationAddressUnit>>::const_iterator i = destinations.begin();
505 i != destinations.end();
506 i++)
507 {
508 if ((*i)->GetDestinationAddress() == Mac48Address::GetBroadcast())
509 {
510 // only proactive PREQ contains destination
511 // address as broadcast! Proactive preq MUST
512 // have destination count equal to 1 and
513 // per destination flags DO and RF
514 NS_ASSERT(preq.GetDestCount() == 1);
515 NS_ASSERT(((*i)->IsDo()) && ((*i)->IsRf()));
516 // Add proactive path only if it is the better then existed
517 // before
518 if (((m_rtable->LookupProactive()).retransmitter == Mac48Address::GetBroadcast()) ||
519 ((m_rtable->LookupProactive()).metric > preq.GetMetric()))
520 {
523 from,
524 interface,
525 MicroSeconds(preq.GetLifetime() * 1024),
527 // Notify trace source of routing change
528 RouteChange rChange;
529 rChange.type = "Add Proactive";
530 rChange.destination = preq.GetOriginatorAddress();
531 rChange.retransmitter = from;
532 rChange.interface = interface;
533 rChange.metric = preq.GetMetric();
534 rChange.lifetime = MicroSeconds(preq.GetLifetime() * 1024);
535 rChange.seqnum = preq.GetOriginatorSeqNumber();
538 }
539 if (!preq.IsNeedNotPrep())
540 {
543 from,
544 (uint32_t)0,
547 preq.GetLifetime(),
548 interface);
549 }
550 break;
551 }
552 if ((*i)->GetDestinationAddress() == GetAddress())
553 {
556 from,
557 (uint32_t)0,
560 preq.GetLifetime(),
561 interface);
564 preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
565 continue;
566 }
567 // check if can answer:
568 HwmpRtable::LookupResult result = m_rtable->LookupReactive((*i)->GetDestinationAddress());
569 if ((!((*i)->IsDo())) && (result.retransmitter != Mac48Address::GetBroadcast()))
570 {
571 // have a valid information and can answer
572 uint32_t lifetime = result.lifetime.GetMicroSeconds() / 1024;
573 if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber()) >= 0))
574 {
575 SendPrep((*i)->GetDestinationAddress(),
577 from,
578 result.metric,
580 result.seqnum,
581 lifetime,
582 interface);
583 m_rtable->AddPrecursor((*i)->GetDestinationAddress(),
584 interface,
585 from,
586 MicroSeconds(preq.GetLifetime() * 1024));
587 if ((*i)->IsRf())
588 {
589 (*i)->SetFlags(true, false, (*i)->IsUsn()); // DO = 1, RF = 0
590 }
591 else
592 {
593 preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
594 continue;
595 }
596 }
597 }
598 }
599 // check if must retransmit:
600 if (preq.GetDestCount() == 0)
601 {
602 return;
603 }
604 // Forward PREQ to all interfaces:
605 NS_LOG_DEBUG("I am " << GetAddress() << "retransmitting PREQ:" << preq);
606 for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin(); i != m_interfaces.end(); i++)
607 {
608 Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
609 NS_LOG_DEBUG("Forwarding PREQ from " << from << " with delay "
610 << forwardingDelay.As(Time::US));
611 Simulator::Schedule(forwardingDelay, &HwmpProtocolMac::SendPreq, i->second, preq);
612 }
613}
614
615void
617 Mac48Address from,
618 uint32_t interface,
619 Mac48Address fromMp,
620 uint32_t metric)
621{
622 NS_LOG_FUNCTION(this << from << interface << fromMp << metric);
623 prep.IncrementMetric(metric);
624 // acceptance cretirea:
625 std::map<Mac48Address, std::pair<uint32_t, uint32_t>>::const_iterator i =
627 bool freshInfo(true);
628 uint32_t sequence = prep.GetDestinationSeqNumber();
629 if (i != m_hwmpSeqnoMetricDatabase.end())
630 {
631 if ((int32_t)(i->second.first - sequence) > 0)
632 {
633 return;
634 }
635 if (i->second.first == sequence)
636 {
637 freshInfo = false;
638 }
639 }
641 std::make_pair(sequence, prep.GetMetric());
642 // update routing info
643 // Now add a path to destination and add precursor to source
644 NS_LOG_DEBUG("I am " << GetAddress() << ", received prep from " << prep.GetOriginatorAddress()
645 << ", receiver was:" << from);
647 // Add a reactive path only if seqno is fresher or it improves the
648 // metric
649 if ((freshInfo) ||
650 (((m_rtable->LookupReactive(prep.GetOriginatorAddress())).retransmitter ==
652 ((m_rtable->LookupReactive(prep.GetOriginatorAddress())).metric > prep.GetMetric())))
653 {
655 from,
656 interface,
657 prep.GetMetric(),
658 MicroSeconds(prep.GetLifetime() * 1024),
659 sequence);
660 // Notify trace source of routing change
661 RouteChange rChange;
662 rChange.type = "Add Reactive";
663 rChange.destination = prep.GetOriginatorAddress();
664 rChange.retransmitter = from;
665 rChange.interface = interface;
666 rChange.metric = prep.GetMetric();
667 rChange.lifetime = MicroSeconds(prep.GetLifetime() * 1024);
668 rChange.seqnum = sequence;
671 interface,
672 from,
673 MicroSeconds(prep.GetLifetime() * 1024));
675 {
677 interface,
678 result.retransmitter,
679 result.lifetime);
680 }
682 }
683 if (((m_rtable->LookupReactive(fromMp)).retransmitter == Mac48Address::GetBroadcast()) ||
684 ((m_rtable->LookupReactive(fromMp)).metric > metric))
685 {
687 from,
688 interface,
689 metric,
690 MicroSeconds(prep.GetLifetime() * 1024),
691 sequence);
692 // Notify trace source of routing change
693 RouteChange rChange;
694 rChange.type = "Add Reactive";
695 rChange.destination = fromMp;
696 rChange.retransmitter = from;
697 rChange.interface = interface;
698 rChange.metric = metric;
699 rChange.lifetime = MicroSeconds(prep.GetLifetime() * 1024);
700 rChange.seqnum = sequence;
702 ReactivePathResolved(fromMp);
703 }
704 if (prep.GetDestinationAddress() == GetAddress())
705 {
706 NS_LOG_DEBUG("I am " << GetAddress() << ", resolved " << prep.GetOriginatorAddress());
707 return;
708 }
710 {
711 return;
712 }
713 // Forward PREP
714 HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find(result.ifIndex);
715 NS_ASSERT(prep_sender != m_interfaces.end());
716 Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
717 NS_LOG_DEBUG("Forwarding PREP from " << from << " with delay " << forwardingDelay.As(Time::US));
718 Simulator::Schedule(forwardingDelay,
720 prep_sender->second,
721 prep,
722 result.retransmitter);
723}
724
725void
726HwmpProtocol::ReceivePerr(std::vector<FailedDestination> destinations,
727 Mac48Address from,
728 uint32_t interface,
729 Mac48Address fromMp)
730{
731 NS_LOG_FUNCTION(this << from << interface << fromMp);
732 // Acceptance cretirea:
733 NS_LOG_DEBUG("I am " << GetAddress() << ", received PERR from " << from);
734 std::vector<FailedDestination> retval;
736 for (unsigned int i = 0; i < destinations.size(); i++)
737 {
738 result = m_rtable->LookupReactiveExpired(destinations[i].destination);
739 if (!((result.retransmitter != from) || (result.ifIndex != interface) ||
740 ((int32_t)(result.seqnum - destinations[i].seqnum) > 0)))
741 {
742 retval.push_back(destinations[i]);
743 }
744 }
745 if (retval.empty())
746 {
747 return;
748 }
750}
751
752void
754 Mac48Address dst,
755 Mac48Address retransmitter,
756 uint32_t initMetric,
757 uint32_t originatorDsn,
758 uint32_t destinationSN,
759 uint32_t lifetime,
760 uint32_t interface)
761{
762 IePrep prep;
763 prep.SetHopcount(0);
764 prep.SetTtl(m_maxTtl);
765 prep.SetDestinationAddress(dst);
766 prep.SetDestinationSeqNumber(destinationSN);
767 prep.SetLifetime(lifetime);
768 prep.SetMetric(initMetric);
769 prep.SetOriginatorAddress(src);
770 prep.SetOriginatorSeqNumber(originatorDsn);
771 HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find(interface);
772 NS_ASSERT(prep_sender != m_interfaces.end());
773 prep_sender->second->SendPrep(prep, retransmitter);
775}
776
777bool
779{
780 NS_LOG_FUNCTION(this << mp);
781 m_mp = mp;
782 std::vector<Ptr<NetDevice>> interfaces = mp->GetInterfaces();
783 for (std::vector<Ptr<NetDevice>>::const_iterator i = interfaces.begin(); i != interfaces.end();
784 i++)
785 {
786 // Checking for compatible net device
787 Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice>();
788 if (!wifiNetDev)
789 {
790 return false;
791 }
792 Ptr<MeshWifiInterfaceMac> mac = wifiNetDev->GetMac()->GetObject<MeshWifiInterfaceMac>();
793 if (!mac)
794 {
795 return false;
796 }
797 // Installing plugins:
798 Ptr<HwmpProtocolMac> hwmpMac = Create<HwmpProtocolMac>(wifiNetDev->GetIfIndex(), this);
799 m_interfaces[wifiNetDev->GetIfIndex()] = hwmpMac;
800 mac->InstallPlugin(hwmpMac);
801 // Installing airtime link metric:
802 Ptr<AirtimeLinkMetricCalculator> metric = CreateObject<AirtimeLinkMetricCalculator>();
803 mac->SetLinkMetricCallback(
805 }
806 mp->SetRoutingProtocol(this);
807 // Mesh point aggregates all installed protocols
808 mp->AggregateObject(this);
809 m_address = Mac48Address::ConvertFrom(mp->GetAddress()); // address;
810 return true;
811}
812
813void
815 Mac48Address peerAddress,
816 uint32_t interface,
817 bool status)
818{
819 NS_LOG_FUNCTION(this << meshPointAddress << peerAddress << interface << status);
820 if (status)
821 {
822 return;
823 }
824 std::vector<FailedDestination> destinations = m_rtable->GetUnreachableDestinations(peerAddress);
825 NS_LOG_DEBUG(destinations.size() << " failed destinations for peer address " << peerAddress);
826 InitiatePathError(MakePathError(destinations));
827}
828
829void
831{
833}
834
835bool
837{
838 NS_LOG_FUNCTION(this << seqno << source);
839 if (source == GetAddress())
840 {
841 NS_LOG_DEBUG("Dropping seqno " << seqno << "; from self");
842 return true;
843 }
844 std::map<Mac48Address, uint32_t, std::less<Mac48Address>>::const_iterator i =
845 m_lastDataSeqno.find(source);
846 if (i == m_lastDataSeqno.end())
847 {
848 m_lastDataSeqno[source] = seqno;
849 }
850 else
851 {
852 if ((int32_t)(i->second - seqno) >= 0)
853 {
854 NS_LOG_DEBUG("Dropping seqno " << seqno << "; stale frame");
855 return true;
856 }
857 m_lastDataSeqno[source] = seqno;
858 }
859 return false;
860}
861
863HwmpProtocol::MakePathError(std::vector<FailedDestination> destinations)
864{
865 NS_LOG_FUNCTION(this);
866 PathError retval;
867 // HwmpRtable increments a sequence number as written in 11B.9.7.2
868 retval.receivers = GetPerrReceivers(destinations);
869 if (retval.receivers.empty())
870 {
871 return retval;
872 }
874 for (unsigned int i = 0; i < destinations.size(); i++)
875 {
876 retval.destinations.push_back(destinations[i]);
877 m_rtable->DeleteReactivePath(destinations[i].destination);
878 // Notify trace source of routing change
879 RouteChange rChange;
880 rChange.type = "Delete Reactive";
881 rChange.destination = destinations[i].destination;
882 rChange.seqnum = destinations[i].seqnum;
884 }
885 return retval;
886}
887
888void
890{
891 NS_LOG_FUNCTION(this);
892 for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin(); i != m_interfaces.end(); i++)
893 {
894 std::vector<Mac48Address> receivers_for_interface;
895 for (unsigned int j = 0; j < perr.receivers.size(); j++)
896 {
897 if (i->first == perr.receivers[j].first)
898 {
899 receivers_for_interface.push_back(perr.receivers[j].second);
900 }
901 }
902 i->second->InitiatePerr(perr.destinations, receivers_for_interface);
903 }
904}
905
906void
908{
909 NS_LOG_FUNCTION(this);
910 for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin(); i != m_interfaces.end(); i++)
911 {
912 std::vector<Mac48Address> receivers_for_interface;
913 for (unsigned int j = 0; j < perr.receivers.size(); j++)
914 {
915 if (i->first == perr.receivers[j].first)
916 {
917 receivers_for_interface.push_back(perr.receivers[j].second);
918 }
919 }
920 Time forwardingDelay = GetMeshPoint()->GetForwardingDelay();
921 NS_LOG_DEBUG("Forwarding PERR with delay " << forwardingDelay.As(Time::US));
922 Simulator::Schedule(forwardingDelay,
924 i->second,
925 perr.destinations,
926 receivers_for_interface);
927 i->second->ForwardPerr(perr.destinations, receivers_for_interface);
928 }
929}
930
931std::vector<std::pair<uint32_t, Mac48Address>>
932HwmpProtocol::GetPerrReceivers(std::vector<FailedDestination> failedDest)
933{
934 NS_LOG_FUNCTION(this);
936 for (unsigned int i = 0; i < failedDest.size(); i++)
937 {
938 HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors(failedDest[i].destination);
939 m_rtable->DeleteReactivePath(failedDest[i].destination);
940 // Notify trace source of routing change
941 RouteChange rChange;
942 rChange.type = "Delete Reactive";
943 rChange.destination = failedDest[i].destination;
944 rChange.seqnum = failedDest[i].seqnum;
946 m_rtable->DeleteProactivePath(failedDest[i].destination);
947 // Notify trace source of routing change
948 RouteChange rChangePro;
949 rChangePro.type = "Delete Proactive";
950 rChangePro.destination = failedDest[i].destination;
951 rChangePro.seqnum = failedDest[i].seqnum;
952 m_routeChangeTraceSource(rChangePro);
953 for (unsigned int j = 0; j < precursors.size(); j++)
954 {
955 retval.push_back(precursors[j]);
956 }
957 }
958 // Check if we have duplicates in retval and precursors:
959 for (unsigned int i = 0; i < retval.size(); i++)
960 {
961 for (unsigned int j = i + 1; j < retval.size(); j++)
962 {
963 if (retval[i].second == retval[j].second)
964 {
965 retval.erase(retval.begin() + j);
966 }
967 }
968 }
969 return retval;
970}
971
972std::vector<Mac48Address>
974{
975 NS_LOG_FUNCTION(this << interface);
976 std::vector<Mac48Address> retval;
977 if (!m_neighboursCallback.IsNull())
978 {
979 retval = m_neighboursCallback(interface);
980 }
981 if (retval.size() >= m_unicastPreqThreshold || retval.empty())
982 {
983 retval.clear();
984 retval.push_back(Mac48Address::GetBroadcast());
985 }
986 return retval;
987}
988
989std::vector<Mac48Address>
991{
992 NS_LOG_FUNCTION(this << interface);
993 std::vector<Mac48Address> retval;
994 if (!m_neighboursCallback.IsNull())
995 {
996 retval = m_neighboursCallback(interface);
997 }
998 if (retval.size() >= m_unicastDataThreshold || retval.empty())
999 {
1000 retval.clear();
1001 retval.push_back(Mac48Address::GetBroadcast());
1002 }
1003 return retval;
1004}
1005
1006bool
1008{
1009 NS_LOG_FUNCTION(this);
1010 if (m_rqueue.size() > m_maxQueueSize)
1011 {
1012 return false;
1013 }
1014 m_rqueue.push_back(packet);
1015 return true;
1016}
1017
1020{
1021 NS_LOG_FUNCTION(this << dst);
1022 QueuedPacket retval;
1023 retval.pkt = nullptr;
1024 for (std::vector<QueuedPacket>::iterator i = m_rqueue.begin(); i != m_rqueue.end(); i++)
1025 {
1026 if ((*i).dst == dst)
1027 {
1028 retval = (*i);
1029 m_rqueue.erase(i);
1030 break;
1031 }
1032 }
1033 return retval;
1034}
1035
1038{
1039 NS_LOG_FUNCTION(this);
1040 QueuedPacket retval;
1041 retval.pkt = nullptr;
1042 if (!m_rqueue.empty())
1043 {
1044 retval = m_rqueue[0];
1045 m_rqueue.erase(m_rqueue.begin());
1046 }
1047 return retval;
1048}
1049
1050void
1052{
1053 NS_LOG_FUNCTION(this << dst);
1054 std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find(dst);
1055 if (i != m_preqTimeouts.end())
1056 {
1057 m_routeDiscoveryTimeCallback(Simulator::Now() - i->second.whenScheduled);
1058 }
1059
1062 // Send all packets stored for this destination
1064 while (packet.pkt)
1065 {
1066 // set RA tag for retransmitter:
1067 HwmpTag tag;
1068 packet.pkt->RemovePacketTag(tag);
1069 tag.SetAddress(result.retransmitter);
1070 packet.pkt->AddPacketTag(tag);
1072 m_stats.txBytes += packet.pkt->GetSize();
1073 packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1074
1075 packet = DequeueFirstPacketByDst(dst);
1076 }
1077}
1078
1079void
1081{
1082 NS_LOG_FUNCTION(this);
1083 // send all packets to root
1087 while (packet.pkt)
1088 {
1089 // set RA tag for retransmitter:
1090 HwmpTag tag;
1091 if (!packet.pkt->RemovePacketTag(tag))
1092 {
1093 NS_FATAL_ERROR("HWMP tag must be present at this point");
1094 }
1095 tag.SetAddress(result.retransmitter);
1096 packet.pkt->AddPacketTag(tag);
1098 m_stats.txBytes += packet.pkt->GetSize();
1099 packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
1100
1101 packet = DequeueFirstPacket();
1102 }
1103}
1104
1105bool
1107{
1108 NS_LOG_FUNCTION(this << dst);
1109 std::map<Mac48Address, PreqEvent>::const_iterator i = m_preqTimeouts.find(dst);
1110 if (i == m_preqTimeouts.end())
1111 {
1112 m_preqTimeouts[dst].preqTimeout =
1115 this,
1116 dst,
1117 1);
1118 m_preqTimeouts[dst].whenScheduled = Simulator::Now();
1119 return true;
1120 }
1121 return false;
1122}
1123
1124void
1126{
1127 NS_LOG_FUNCTION(this << dst << (uint16_t)numOfRetry);
1130 {
1131 result = m_rtable->LookupProactive();
1132 }
1134 {
1135 std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find(dst);
1136 NS_ASSERT(i != m_preqTimeouts.end());
1137 m_preqTimeouts.erase(i);
1138 return;
1139 }
1140 if (numOfRetry > m_dot11MeshHWMPmaxPREQretries)
1141 {
1143 // purge queue and delete entry from retryDatabase
1144 while (packet.pkt)
1145 {
1147 packet.reply(false,
1148 packet.pkt,
1149 packet.src,
1150 packet.dst,
1151 packet.protocol,
1153 packet = DequeueFirstPacketByDst(dst);
1154 }
1155 std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find(dst);
1156 NS_ASSERT(i != m_preqTimeouts.end());
1157 m_routeDiscoveryTimeCallback(Simulator::Now() - i->second.whenScheduled);
1158 m_preqTimeouts.erase(i);
1159 return;
1160 }
1161 numOfRetry++;
1162 uint32_t originator_seqno = GetNextHwmpSeqno();
1164 for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin(); i != m_interfaces.end(); i++)
1165 {
1166 i->second->RequestDestination(dst, originator_seqno, dst_seqno);
1167 }
1168 m_preqTimeouts[dst].preqTimeout =
1171 this,
1172 dst,
1173 numOfRetry);
1174}
1175
1176// Proactive PREQ routines:
1177void
1179{
1180 NS_LOG_FUNCTION(this);
1181 NS_LOG_DEBUG("ROOT IS: " << m_address);
1182 m_isRoot = true;
1183}
1184
1185void
1187{
1188 NS_LOG_FUNCTION(this);
1190}
1191
1192void
1194{
1195 NS_LOG_FUNCTION(this);
1196 IePreq preq;
1197 // By default: must answer
1198 preq.SetHopcount(0);
1199 preq.SetTTL(m_maxTtl);
1201 //\attention: do not forget to set originator address, sequence
1202 // number and preq ID in HWMP-MAC plugin
1205 preq.SetPreqID(GetNextPreqId());
1207 for (HwmpProtocolMacMap::const_iterator i = m_interfaces.begin(); i != m_interfaces.end(); i++)
1208 {
1209 i->second->SendPreq(preq);
1210 }
1213 this);
1214}
1215
1216bool
1218{
1219 return m_doFlag;
1220}
1221
1222bool
1224{
1225 return m_rfFlag;
1226}
1227
1228Time
1230{
1232}
1233
1234Time
1236{
1238}
1239
1240uint8_t
1242{
1243 return m_maxTtl;
1244}
1245
1248{
1249 m_preqId++;
1250 return m_preqId;
1251}
1252
1255{
1256 m_hwmpSeqno++;
1257 return m_hwmpSeqno;
1258}
1259
1262{
1264}
1265
1266uint8_t
1268{
1270}
1271
1274{
1275 return m_address;
1276}
1277
1278// Statistics:
1280 : txUnicast(0),
1281 txBroadcast(0),
1282 txBytes(0),
1283 droppedTtl(0),
1284 totalQueued(0),
1285 totalDropped(0),
1286 initiatedPreq(0),
1287 initiatedPrep(0),
1288 initiatedPerr(0)
1289{
1290}
1291
1292void
1293HwmpProtocol::Statistics::Print(std::ostream& os) const
1294{
1295 os << "<Statistics "
1296 "txUnicast=\""
1297 << txUnicast
1298 << "\" "
1299 "txBroadcast=\""
1300 << txBroadcast
1301 << "\" "
1302 "txBytes=\""
1303 << txBytes
1304 << "\" "
1305 "droppedTtl=\""
1306 << droppedTtl
1307 << "\" "
1308 "totalQueued=\""
1309 << totalQueued
1310 << "\" "
1311 "totalDropped=\""
1312 << totalDropped
1313 << "\" "
1314 "initiatedPreq=\""
1315 << initiatedPreq
1316 << "\" "
1317 "initiatedPrep=\""
1318 << initiatedPrep
1319 << "\" "
1320 "initiatedPerr=\""
1321 << initiatedPerr << "\"/>" << std::endl;
1322}
1323
1324void
1325HwmpProtocol::Report(std::ostream& os) const
1326{
1327 os << "<Hwmp "
1328 "address=\""
1329 << m_address << "\"" << std::endl
1330 << "maxQueueSize=\"" << m_maxQueueSize << "\"" << std::endl
1331 << "Dot11MeshHWMPmaxPREQretries=\"" << (uint16_t)m_dot11MeshHWMPmaxPREQretries << "\""
1332 << std::endl
1333 << "Dot11MeshHWMPnetDiameterTraversalTime=\""
1334 << m_dot11MeshHWMPnetDiameterTraversalTime.GetSeconds() << "\"" << std::endl
1335 << "Dot11MeshHWMPpreqMinInterval=\"" << m_dot11MeshHWMPpreqMinInterval.GetSeconds() << "\""
1336 << std::endl
1337 << "Dot11MeshHWMPperrMinInterval=\"" << m_dot11MeshHWMPperrMinInterval.GetSeconds() << "\""
1338 << std::endl
1339 << "Dot11MeshHWMPactiveRootTimeout=\"" << m_dot11MeshHWMPactiveRootTimeout.GetSeconds()
1340 << "\"" << std::endl
1341 << "Dot11MeshHWMPactivePathTimeout=\"" << m_dot11MeshHWMPactivePathTimeout.GetSeconds()
1342 << "\"" << std::endl
1343 << "Dot11MeshHWMPpathToRootInterval=\"" << m_dot11MeshHWMPpathToRootInterval.GetSeconds()
1344 << "\"" << std::endl
1345 << "Dot11MeshHWMPrannInterval=\"" << m_dot11MeshHWMPrannInterval.GetSeconds() << "\""
1346 << std::endl
1347 << "isRoot=\"" << m_isRoot << "\"" << std::endl
1348 << "maxTtl=\"" << (uint16_t)m_maxTtl << "\"" << std::endl
1349 << "unicastPerrThreshold=\"" << (uint16_t)m_unicastPerrThreshold << "\"" << std::endl
1350 << "unicastPreqThreshold=\"" << (uint16_t)m_unicastPreqThreshold << "\"" << std::endl
1351 << "unicastDataThreshold=\"" << (uint16_t)m_unicastDataThreshold << "\"" << std::endl
1352 << "doFlag=\"" << m_doFlag << "\"" << std::endl
1353 << "rfFlag=\"" << m_rfFlag << "\">" << std::endl;
1354 m_stats.Print(os);
1355 for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin();
1356 plugin != m_interfaces.end();
1357 plugin++)
1358 {
1359 plugin->second->Report(os);
1360 }
1361 os << "</Hwmp>" << std::endl;
1362}
1363
1364void
1366{
1367 NS_LOG_FUNCTION(this);
1368 m_stats = Statistics();
1369 for (HwmpProtocolMacMap::const_iterator plugin = m_interfaces.begin();
1370 plugin != m_interfaces.end();
1371 plugin++)
1372 {
1373 plugin->second->ResetStats();
1374 }
1375}
1376
1377int64_t
1379{
1380 NS_LOG_FUNCTION(this << stream);
1381 m_coefficient->SetStream(stream);
1382 return 1;
1383}
1384
1387{
1388 return m_rtable;
1389}
1390
1392 : pkt(nullptr),
1393 protocol(0),
1394 inInterface(0)
1395{
1396}
1397} // namespace dot11s
1398} // namespace ns3
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Callback template class.
Definition: callback.h:443
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:200
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:986
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:979
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
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:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
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:417
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:402
@ 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:412
AttributeValue implementation for Time.
Definition: nstime.h:1423
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
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.
QueuedPacket DequeueFirstPacket()
Dequeue the first packet in the queue.
Ptr< HwmpRtable > m_rtable
Routing table.
uint8_t m_unicastDataThreshold
Maximum number of broadcast receivers, when we send a broadcast as a chain of unicasts.
void ReceivePrep(IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric)
Handler for receiving Path Reply.
void Report(std::ostream &os) const
Statistics:
uint32_t GetNextHwmpSeqno()
Get next HWMP sequence no function.
PathError MakePathError(std::vector< FailedDestination > destinations)
forms a path error information element when list of destination fails on a given interface
Time m_dot11MeshHWMPrannInterval
Lifetime of proactive routing information.
Time GetPerrMinInterval()
Get PERR minimum interval function.
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 PeerLinkStatus(Mac48Address meshPontAddress, Mac48Address peerAddress, uint32_t interface, bool status)
Peer link status function.
void ReceivePerr(std::vector< FailedDestination > destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
Handler for receiving Path Error.
std::map< Mac48Address, PreqEvent > m_preqTimeouts
PREQ timeouts.
Time m_dot11MeshHWMPperrMinInterval
Minimal interval between to successive PREQs.
bool m_rfFlag
Reply and forward flag.
bool 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
TracedCallback< struct RouteChange > m_routeChangeTraceSource
Route change trace source.
void SendPreq(IePreq preq)
Send PREQ function.
void SendPrep(IePrep prep, Mac48Address receiver)
Send PREP function.
void ForwardPerr(std::vector< HwmpProtocol::FailedDestination > destinations, std::vector< Mac48Address > receivers)
Forward a path error.
Routing table for HWMP – 802.11s routing protocol.
Definition: hwmp-rtable.h:39
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:44
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:257
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:81
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:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1444
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1424
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:579
#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:1360
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
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:707
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:48
uint32_t seqnum
sequence number
Definition: hwmp-rtable.h:52
Mac48Address retransmitter
retransmitter
Definition: hwmp-rtable.h:49
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