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: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: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:861
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:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
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: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:702
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