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 
35 namespace ns3 {
36 
37 NS_LOG_COMPONENT_DEFINE ("HwmpProtocolMac");
38 
39 namespace dot11s {
40 
42  m_ifIndex (ifIndex), m_protocol (protocol)
43 {
44  NS_LOG_FUNCTION (this << ifIndex << protocol);
45 }
47 {
48 }
49 void
51 {
52  NS_LOG_FUNCTION (this << parent);
53  m_parent = parent;
54 }
55 
56 bool
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);
70  m_stats.rxData++;
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 
99 bool
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 
173 bool
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 }
193 bool
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 }
227 void
229 {
230  NS_LOG_FUNCTION (this);
231  std::vector<IePreq> preq_vector;
232  preq_vector.push_back (preq);
233  SendPreqVector (preq_vector);
234 }
235 void
236 HwmpProtocolMac::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 }
265 void
266 HwmpProtocolMac::RequestDestination (Mac48Address dst, uint32_t originator_seqno, uint32_t dst_seqno)
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 }
289 void
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
303  m_preqTimer = Simulator::Schedule (m_protocol->GetPreqMinInterval (), &HwmpProtocolMac::SendMyPreq, this);
305  m_myPreq.clear ();
306 }
307 void
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 }
331 void
332 HwmpProtocolMac::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  //
377  Mac48Address address = *i;
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 }
385 void
386 HwmpProtocolMac::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 }
434 void
436 {
437  NS_LOG_FUNCTION (this);
438  if (m_perrTimer.IsRunning ())
439  {
440  return;
441  }
442  m_perrTimer = Simulator::Schedule (m_protocol->GetPerrMinInterval (), &HwmpProtocolMac::SendMyPerr, this);
444  m_myPerr.destinations.clear ();
445  m_myPerr.receivers.clear ();
446 }
447 uint32_t
449 {
450  return m_parent->GetLinkMetric (peerAddress);
451 }
452 uint16_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 }
462 void
463 HwmpProtocolMac::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 }
481 void
482 HwmpProtocolMac::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 }
489 void
491 {
492  NS_LOG_FUNCTION (this);
493  m_stats = Statistics ();
494 }
495 
496 int64_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.
std::vector< Ptr< WifiInformationElement > >::iterator Iterator
As soon as this is a vector, we define an Iterator.
Iterator End()
Returns End of the vector.
Iterator Begin()
Returns Begin of the vector.
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