A Discrete-Event Network Simulator
API
hwmp-protocol-mac.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2008,2009 IITP RAS
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Kirill Andreev <andreev@iitp.ru>
19 */
20
21#include "ns3/mesh-wifi-interface-mac.h"
22#include "ns3/packet.h"
23#include "ns3/simulator.h"
24#include "ns3/nstime.h"
25#include "ns3/log.h"
26#include "ns3/wifi-mac-header.h"
27#include "dot11s-mac-header.h"
28#include "hwmp-protocol-mac.h"
29#include "hwmp-tag.h"
30#include "ie-dot11s-preq.h"
31#include "ie-dot11s-prep.h"
32#include "ie-dot11s-rann.h"
33#include "ie-dot11s-perr.h"
34
35namespace ns3 {
36
37NS_LOG_COMPONENT_DEFINE ("HwmpProtocolMac");
38
39namespace dot11s {
40
42 m_ifIndex (ifIndex), m_protocol (protocol)
43{
44 NS_LOG_FUNCTION (this << ifIndex << protocol);
45}
47{
48}
49void
51{
52 NS_LOG_FUNCTION (this << parent);
53 m_parent = parent;
54}
55
56bool
58{
59 NS_LOG_FUNCTION (this << packet << header);
60 NS_ASSERT (header.IsData ());
61
62 MeshHeader meshHdr;
63 HwmpTag tag;
64 if (packet->PeekPacketTag (tag))
65 {
66 NS_FATAL_ERROR ("HWMP tag is not supposed to be received by network");
67 }
68
69 packet->RemoveHeader (meshHdr);
71 m_stats.rxDataBytes += packet->GetSize ();
72
74 Mac48Address destination;
75 Mac48Address source;
76 switch (meshHdr.GetAddressExt ())
77 {
78 case 0:
79 source = header.GetAddr4 ();
80 destination = header.GetAddr3 ();
81 break;
82 default:
84 "6-address scheme is not yet supported and 4-address extension is not supposed to be used for data frames.");
85 }
86 tag.SetSeqno (meshHdr.GetMeshSeqno ());
87 tag.SetTtl (meshHdr.GetMeshTtl ());
88 packet->AddPacketTag (tag);
89
90 if ((destination == Mac48Address::GetBroadcast ()) && (m_protocol->DropDataFrame (meshHdr.GetMeshSeqno (),
91 source)))
92 {
93 NS_LOG_DEBUG ("Dropping frame; source " << source << " dest " << destination << " seqno " << meshHdr.GetMeshSeqno ());
94 return false;
95 }
96 return true;
97}
98
99bool
101{
102 NS_LOG_FUNCTION (this << packet << header);
103 m_stats.rxMgt++;
104 m_stats.rxMgtBytes += packet->GetSize ();
105 WifiActionHeader actionHdr;
106 packet->RemoveHeader (actionHdr);
107 if (actionHdr.GetCategory () != WifiActionHeader::MESH)
108 {
109 return true;
110 }
112 // To determine header size here, we can rely on the knowledge that
113 // this is the last header to remove.
114 packet->RemoveHeader (elements, packet->GetSize ());
115 std::vector<HwmpProtocol::FailedDestination> failedDestinations;
116 for (MeshInformationElementVector::Iterator i = elements.Begin (); i != elements.End (); i++)
117 {
118 if ((*i)->ElementId () == IE_RANN)
119 {
120 NS_LOG_WARN ("RANN is not supported!");
121 }
122 if ((*i)->ElementId () == IE_PREQ)
123 {
124 Ptr<IePreq> preq = DynamicCast<IePreq> (*i);
125 NS_ASSERT (preq != 0);
126 m_stats.rxPreq++;
127 if (preq->GetOriginatorAddress () == m_protocol->GetAddress ())
128 {
129 continue;
130 }
131 if (preq->GetTtl () == 0)
132 {
133 continue;
134 }
135 preq->DecrementTtl ();
136 m_protocol->ReceivePreq (*preq, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (),
137 m_parent->GetLinkMetric (header.GetAddr2 ()));
138 }
139 if ((*i)->ElementId () == IE_PREP)
140 {
141 Ptr<IePrep> prep = DynamicCast<IePrep> (*i);
142 NS_ASSERT (prep != 0);
143 m_stats.rxPrep++;
144 if (prep->GetTtl () == 0)
145 {
146 continue;
147 }
148 prep->DecrementTtl ();
149 m_protocol->ReceivePrep (*prep, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (),
150 m_parent->GetLinkMetric (header.GetAddr2 ()));
151 }
152 if ((*i)->ElementId () == IE_PERR)
153 {
154 Ptr<IePerr> perr = DynamicCast<IePerr> (*i);
155 NS_ASSERT (perr != 0);
156 m_stats.rxPerr++;
157 std::vector<HwmpProtocol::FailedDestination> destinations = perr->GetAddressUnitVector ();
158 for (std::vector<HwmpProtocol::FailedDestination>::const_iterator i = destinations.begin (); i
159 != destinations.end (); i++)
160 {
161 failedDestinations.push_back (*i);
162 }
163 }
164 }
165 if (failedDestinations.size () > 0)
166 {
167 m_protocol->ReceivePerr (failedDestinations, header.GetAddr2 (), m_ifIndex, header.GetAddr3 ());
168 }
169 NS_ASSERT (packet->GetSize () == 0);
170 return false;
171}
172
173bool
175{
176 NS_LOG_FUNCTION (this << packet << header);
177 if (header.IsData ())
178 {
179 return ReceiveData (packet, header);
180 }
181 else
182 {
183 if (header.IsAction ())
184 {
185 return ReceiveAction (packet, header);
186 }
187 else
188 {
189 return true; // don't care
190 }
191 }
192}
193bool
195 Mac48Address to)
196{
197 NS_LOG_FUNCTION (this << packet << header << from << to);
198 if (!header.IsData ())
199 {
200 return true;
201 }
202 HwmpTag tag;
203 bool tagExists = packet->RemovePacketTag (tag);
204 if (!tagExists)
205 {
206 NS_FATAL_ERROR ("HWMP tag must exist at this point");
207 }
208 m_stats.txData++;
209 m_stats.txDataBytes += packet->GetSize ();
210 MeshHeader meshHdr;
211 meshHdr.SetMeshSeqno (tag.GetSeqno ());
212 meshHdr.SetMeshTtl (tag.GetTtl ());
213 packet->AddHeader (meshHdr);
214 header.SetAddr1 (tag.GetAddress ());
215 header.SetQosMeshControlPresent ();
216 return true;
217}
220{
221 WifiActionHeader actionHdr;
224 actionHdr.SetAction (WifiActionHeader::MESH, action);
225 return actionHdr;
226}
227void
229{
230 NS_LOG_FUNCTION (this);
231 std::vector<IePreq> preq_vector;
232 preq_vector.push_back (preq);
233 SendPreqVector (preq_vector);
234}
235void
236HwmpProtocolMac::SendPreqVector (std::vector<IePreq> preq)
237{
238 NS_LOG_FUNCTION (this);
239 Ptr<Packet> packet = Create<Packet> ();
241 for (std::vector<IePreq>::iterator i = preq.begin (); i != preq.end (); i++)
242 {
243 elements.AddInformationElement (Ptr<IePreq> (&(*i)));
244 }
245 packet->AddHeader (elements);
246 packet->AddHeader (GetWifiActionHeader ());
247 //create 802.11 header:
248 WifiMacHeader hdr;
250 hdr.SetDsNotFrom ();
251 hdr.SetDsNotTo ();
252 hdr.SetAddr2 (m_parent->GetAddress ());
253 hdr.SetAddr3 (m_protocol->GetAddress ());
254 //Send Management frame
255 std::vector<Mac48Address> receivers = m_protocol->GetPreqReceivers (m_ifIndex);
256 for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i++)
257 {
258 hdr.SetAddr1 (*i);
259 m_stats.txPreq++;
260 m_stats.txMgt++;
261 m_stats.txMgtBytes += packet->GetSize ();
262 m_parent->SendManagementFrame (packet, hdr);
263 }
264}
265void
267{
268 NS_LOG_FUNCTION (this << dst << originator_seqno << dst_seqno);
269 for (std::vector<IePreq>::iterator i = m_myPreq.begin (); i != m_myPreq.end (); i++)
270 {
271 if (i->IsFull ())
272 {
273 continue;
274 }
275 NS_ASSERT (i->GetDestCount () > 0);
276 i->AddDestinationAddressElement (m_protocol->GetDoFlag (), m_protocol->GetRfFlag (), dst, dst_seqno);
277 }
278 IePreq preq;
279 preq.SetHopcount (0);
280 preq.SetTTL (m_protocol->GetMaxTtl ());
281 preq.SetPreqID (m_protocol->GetNextPreqId ());
282 preq.SetOriginatorAddress (m_protocol->GetAddress ());
283 preq.SetOriginatorSeqNumber (originator_seqno);
284 preq.SetLifetime (m_protocol->GetActivePathLifetime ());
285 preq.AddDestinationAddressElement (m_protocol->GetDoFlag (), m_protocol->GetRfFlag (), dst, dst_seqno);
286 m_myPreq.push_back (preq);
287 SendMyPreq ();
288}
289void
291{
292 NS_LOG_FUNCTION (this);
293 if (m_preqTimer.IsRunning ())
294 {
295 return;
296 }
297 if (m_myPreq.size () == 0)
298 {
299 return;
300 }
301 //reschedule sending PREQ
305 m_myPreq.clear ();
306}
307void
309{
310 NS_LOG_FUNCTION (this << receiver);
311 //Create packet
312 Ptr<Packet> packet = Create<Packet> ();
314 elements.AddInformationElement (Ptr<IePrep> (&prep));
315 packet->AddHeader (elements);
316 packet->AddHeader (GetWifiActionHeader ());
317 //create 802.11 header:
318 WifiMacHeader hdr;
320 hdr.SetDsNotFrom ();
321 hdr.SetDsNotTo ();
322 hdr.SetAddr1 (receiver);
323 hdr.SetAddr2 (m_parent->GetAddress ());
324 hdr.SetAddr3 (m_protocol->GetAddress ());
325 //Send Management frame
326 m_stats.txPrep++;
327 m_stats.txMgt++;
328 m_stats.txMgtBytes += packet->GetSize ();
329 m_parent->SendManagementFrame (packet, hdr);
330}
331void
332HwmpProtocolMac::ForwardPerr (std::vector<HwmpProtocol::FailedDestination> failedDestinations, std::vector<
333 Mac48Address> receivers)
334{
335 NS_LOG_FUNCTION (this);
336 Ptr<Packet> packet = Create<Packet> ();
337 Ptr<IePerr> perr = Create <IePerr> ();
339 for (std::vector<HwmpProtocol::FailedDestination>::const_iterator i = failedDestinations.begin (); i
340 != failedDestinations.end (); i++)
341 {
342 if (!perr->IsFull ())
343 {
344 perr->AddAddressUnit (*i);
345 }
346 else
347 {
348 elements.AddInformationElement (perr);
349 perr->ResetPerr ();
350 }
351 }
352 if (perr->GetNumOfDest () > 0)
353 {
354 elements.AddInformationElement (perr);
355 }
356 packet->AddHeader (elements);
357 packet->AddHeader (GetWifiActionHeader ());
358 //create 802.11 header:
359 WifiMacHeader hdr;
361 hdr.SetDsNotFrom ();
362 hdr.SetDsNotTo ();
363 hdr.SetAddr2 (m_parent->GetAddress ());
364 hdr.SetAddr3 (m_protocol->GetAddress ());
365 if (receivers.size () >= m_protocol->GetUnicastPerrThreshold ())
366 {
367 receivers.clear ();
368 receivers.push_back (Mac48Address::GetBroadcast ());
369 }
370 //Send Management frame
371 for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i++)
372 {
373 //
374 // 64-bit Intel valgrind complains about hdr.SetAddr1 (*i). It likes this
375 // just fine.
376 //
378 hdr.SetAddr1 (address);
379 m_stats.txPerr++;
380 m_stats.txMgt++;
381 m_stats.txMgtBytes += packet->GetSize ();
382 m_parent->SendManagementFrame (packet, hdr);
383 }
384}
385void
386HwmpProtocolMac::InitiatePerr (std::vector<HwmpProtocol::FailedDestination> failedDestinations, std::vector<
387 Mac48Address> receivers)
388{
389 NS_LOG_FUNCTION (this);
390 //All duplicates in PERR are checked here, and there is no reason to
391 //check it at any other place
392 {
393 std::vector<Mac48Address>::const_iterator end = receivers.end ();
394 for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != end; i++)
395 {
396 bool should_add = true;
397 for (std::vector<Mac48Address>::const_iterator j = m_myPerr.receivers.begin (); j
398 != m_myPerr.receivers.end (); j++)
399 {
400 if ((*i) == (*j))
401 {
402 should_add = false;
403 }
404 }
405 if (should_add)
406 {
407 m_myPerr.receivers.push_back (*i);
408 NS_LOG_DEBUG ("Initiate PERR: Adding receiver: " << (*i));
409 }
410 }
411 }
412 {
413 std::vector<HwmpProtocol::FailedDestination>::const_iterator end = failedDestinations.end ();
414 for (std::vector<HwmpProtocol::FailedDestination>::const_iterator i = failedDestinations.begin (); i != end; i++)
415 {
416 bool should_add = true;
417 for (std::vector<HwmpProtocol::FailedDestination>::const_iterator j = m_myPerr.destinations.begin (); j
418 != m_myPerr.destinations.end (); j++)
419 {
420 if (((*i).destination == (*j).destination) && ((*j).seqnum > (*i).seqnum))
421 {
422 should_add = false;
423 }
424 }
425 if (should_add)
426 {
427 m_myPerr.destinations.push_back (*i);
428 NS_LOG_DEBUG ("Initiate PERR: Adding failed destination: " << (*i).destination);
429 }
430 }
431 }
432 SendMyPerr ();
433}
434void
436{
437 NS_LOG_FUNCTION (this);
438 if (m_perrTimer.IsRunning ())
439 {
440 return;
441 }
444 m_myPerr.destinations.clear ();
445 m_myPerr.receivers.clear ();
446}
449{
450 return m_parent->GetLinkMetric (peerAddress);
451}
452uint16_t
454{
455 return m_parent->GetFrequencyChannel ();
456}
458 txPreq (0), rxPreq (0), txPrep (0), rxPrep (0), txPerr (0), rxPerr (0), txMgt (0), txMgtBytes (0),
459 rxMgt (0), rxMgtBytes (0), txData (0), txDataBytes (0), rxData (0), rxDataBytes (0)
460{
461}
462void
463HwmpProtocolMac::Statistics::Print (std::ostream & os) const
464{
465 os << "<Statistics "
466 "txPreq= \"" << txPreq << "\"" << std::endl <<
467 "txPrep=\"" << txPrep << "\"" << std::endl <<
468 "txPerr=\"" << txPerr << "\"" << std::endl <<
469 "rxPreq=\"" << rxPreq << "\"" << std::endl <<
470 "rxPrep=\"" << rxPrep << "\"" << std::endl <<
471 "rxPerr=\"" << rxPerr << "\"" << std::endl <<
472 "txMgt=\"" << txMgt << "\"" << std::endl <<
473 "txMgtBytes=\"" << txMgtBytes << "\"" << std::endl <<
474 "rxMgt=\"" << rxMgt << "\"" << std::endl <<
475 "rxMgtBytes=\"" << rxMgtBytes << "\"" << std::endl <<
476 "txData=\"" << txData << "\"" << std::endl <<
477 "txDataBytes=\"" << txDataBytes << "\"" << std::endl <<
478 "rxData=\"" << rxData << "\"" << std::endl <<
479 "rxDataBytes=\"" << rxDataBytes << "\"/>" << std::endl;
480}
481void
482HwmpProtocolMac::Report (std::ostream & os) const
483{
484 os << "<HwmpProtocolMac" << std::endl <<
485 "address =\"" << m_parent->GetAddress () << "\">" << std::endl;
486 m_stats.Print (os);
487 os << "</HwmpProtocolMac>" << std::endl;
488}
489void
491{
492 NS_LOG_FUNCTION (this);
493 m_stats = Statistics ();
494}
495
496int64_t
498{
499 return m_protocol->AssignStreams (stream);
500}
501
502
503} // namespace dot11s
504} // namespace ns3
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
an EUI-48 address
Definition: mac48-address.h:44
static Mac48Address GetBroadcast(void)
Introspection did not find any typical Config paths.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:963
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:956
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:978
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
Definition: mgt-headers.h:885
CategoryValue GetCategory()
Return the category value.
void SetAction(CategoryValue type, ActionValue action)
Set action for this Action header.
Iterator End()
Returns End of the vector.
Iterator Begin()
Returns Begin of the vector.
std::vector< Ptr< WifiInformationElement > >::iterator Iterator
As soon as this is a vector, we define an Iterator.
bool AddInformationElement(Ptr< WifiInformationElement > element)
add an IE, if maxSize has exceeded, returns false
Implements the IEEE 802.11 MAC header.
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
Mac48Address GetAddr3(void) const
Return the address in the Address 3 field.
Mac48Address GetAddr4(void) const
Return the address in the Address 4 field.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
bool IsAction(void) const
Return true if the header is an Action header.
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
bool IsData(void) const
Return true if the Type is DATA.
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
void SetQosMeshControlPresent()
Set the Mesh Control Present flag for the QoS header.
static WifiActionHeader GetWifiActionHeader()
void SendMyPreq()
Sends one PREQ when PreqMinInterval after last PREQ expires (if any PREQ exists in rhe queue)
void SendPreq(IePreq preq)
Send PREQ function.
HwmpProtocolMac(uint32_t ifIndex, Ptr< HwmpProtocol > protocol)
Constructor.
void SendPreqVector(std::vector< IePreq > preq)
Send PREQ function for vector of PREQ.
void SendPrep(IePrep prep, Mac48Address receiver)
Send PREP function.
void SendMyPerr()
Send PERR function.
uint16_t GetChannelId() const
Get the channel ID.
void ForwardPerr(std::vector< HwmpProtocol::FailedDestination > destinations, std::vector< Mac48Address > receivers)
Forward a path error.
Ptr< HwmpProtocol > m_protocol
protocol
bool ReceiveData(Ptr< Packet > packet, const WifiMacHeader &header)
Receive data frame.
Statistics m_stats
statistics
bool Receive(Ptr< Packet > packet, const WifiMacHeader &header)
Process received frame.
EventId m_preqTimer
Timer for PREQs.
void ResetStats()
Reset statistics.
uint32_t GetLinkMetric(Mac48Address peerAddress) const
bool ReceiveAction(Ptr< Packet > packet, const WifiMacHeader &header)
Receive action management frame.
void InitiatePerr(std::vector< HwmpProtocol::FailedDestination > destinations, std::vector< Mac48Address > receivers)
initiate my own path error
std::vector< IePreq > m_myPreq
container of PREQs
void SetParent(Ptr< MeshWifiInterfaceMac > parent)
Each plugin must be installed on an interface to work.
void Report(std::ostream &os) const
Report statistics.
bool UpdateOutcomingFrame(Ptr< Packet > packet, WifiMacHeader &header, Mac48Address from, Mac48Address to)
Update frame before it will be forwarded down.
Ptr< MeshWifiInterfaceMac > m_parent
parent
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
void RequestDestination(Mac48Address dest, uint32_t originator_seqno, uint32_t dst_seqno)
Request a destination.
Hwmp tag implements interaction between HWMP protocol and MeshWifiMac.
Definition: hwmp-tag.h:49
void SetTtl(uint8_t ttl)
Set the TTL value.
Definition: hwmp-tag.cc:51
uint32_t GetSeqno()
Get the sequence number.
Definition: hwmp-tag.cc:81
void SetSeqno(uint32_t seqno)
Set sequence number.
Definition: hwmp-tag.cc:75
Mac48Address GetAddress()
Get address from tag.
Definition: hwmp-tag.cc:45
uint8_t GetTtl()
Get the TTL value.
Definition: hwmp-tag.cc:57
See 7.3.2.97 of 802.11s draft 2.07.
See 7.3.2.96 of 802.11s draft 2.07.
void SetHopcount(uint8_t hopcount)
Set number of hops from originator to mesh STA transmitting this element.
void SetOriginatorSeqNumber(uint32_t originator_seq_number)
Set originator sequence number.
void SetTTL(uint8_t ttl)
Set remaining number of hops allowed for this element.
void SetOriginatorAddress(Mac48Address originator_address)
Set originator address value.
void SetPreqID(uint32_t id)
Set path discovery id field.
void AddDestinationAddressElement(bool doFlag, bool rfFlag, Mac48Address dest_address, uint32_t dest_seq_number)
Add a destination address unit: flags, destination and sequence number.
void SetLifetime(uint32_t lifetime)
Set lifetime in TUs for the forwarding information to be considered valid.
Mesh Control field, see Section 8.2.4.7.3 IEEE 802.11-2012.
void SetMeshSeqno(uint32_t seqno)
Set four-byte mesh sequence number.
uint32_t GetMeshSeqno() const
Get the four-byte mesh sequence number.
void SetMeshTtl(uint8_t TTL)
Set mesh TTL subfield corresponding to the remaining number of hops the MSDU/MMPDU is forwarded.
uint8_t GetAddressExt() const
Get Address Extension Mode.
uint8_t GetMeshTtl() const
Get mesh TTL function subfield value.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
address
Definition: first.py:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.
@ WIFI_MAC_MGT_ACTION
std::vector< HwmpProtocol::FailedDestination > destinations
destinations
std::vector< Mac48Address > receivers
receivers
uint32_t txMgtBytes
transmit management bytes
void Print(std::ostream &os) const
Print function.
uint32_t txDataBytes
transmit data bytes
uint32_t rxMgtBytes
receive management bytes
typedef for union of different ActionValues
Definition: mgt-headers.h:956
MeshActionValue meshAction
mesh action
Definition: mgt-headers.h:957
#define IE_PREQ
#define IE_RANN
#define IE_PREP
#define IE_PERR