21 #include "ns3/mesh-wifi-interface-mac.h"
22 #include "ns3/packet.h"
23 #include "ns3/simulator.h"
24 #include "ns3/nstime.h"
26 #include "ns3/mgt-headers.h"
27 #include "dot11s-mac-header.h"
28 #include "hwmp-protocol-mac.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"
39 HwmpProtocolMac::HwmpProtocolMac (uint32_t ifIndex, Ptr<HwmpProtocol> protocol) :
40 m_ifIndex (ifIndex), m_protocol (protocol)
43 HwmpProtocolMac::~HwmpProtocolMac ()
61 NS_FATAL_ERROR (
"HWMP tag is not supposed to be received by network");
66 m_stats.rxDataBytes += packet->
GetSize ();
71 switch (meshHdr.GetAddressExt ())
74 source = header.GetAddr4 ();
75 destination = header.GetAddr3 ();
79 "6-address scheme is not yet supported and 4-address extension is not supposed to be used for data frames.");
81 tag.SetSeqno (meshHdr.GetMeshSeqno ());
82 tag.SetTtl (meshHdr.GetMeshTtl ());
97 m_stats.rxMgtBytes += packet->
GetSize ();
100 if (actionHdr.GetCategory () != WifiActionHeader::MESH_PATH_SELECTION)
106 std::vector<HwmpProtocol::FailedDestination> failedDestinations;
109 if ((*i)->ElementId () == IE11S_RANN)
113 if ((*i)->ElementId () == IE11S_PREQ)
118 if (preq->GetOriginatorAddress () == m_protocol->GetAddress ())
122 if (preq->GetTtl () == 0)
126 preq->DecrementTtl ();
127 m_protocol->ReceivePreq (*preq, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (),
128 m_parent->GetLinkMetric (header.GetAddr2 ()));
130 if ((*i)->ElementId () == IE11S_PREP)
135 if (prep->GetTtl () == 0)
139 prep->DecrementTtl ();
140 m_protocol->ReceivePrep (*prep, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (),
141 m_parent->GetLinkMetric (header.GetAddr2 ()));
143 if ((*i)->ElementId () == IE11S_PERR)
148 std::vector<HwmpProtocol::FailedDestination> destinations = perr->GetAddressUnitVector ();
149 for (std::vector<HwmpProtocol::FailedDestination>::const_iterator i = destinations.begin (); i
150 != destinations.end (); i++)
152 failedDestinations.push_back (*i);
156 if (failedDestinations.size () > 0)
158 m_protocol->ReceivePerr (failedDestinations, header.GetAddr2 (), m_ifIndex, header.GetAddr3 ());
167 if (header.IsData ())
173 if (header.IsAction ())
187 if (!header.IsData ())
198 m_stats.txDataBytes += packet->
GetSize ();
200 meshHdr.SetMeshSeqno (tag.GetSeqno ());
201 meshHdr.SetMeshTtl (tag.GetTtl ());
203 header.SetAddr1 (tag.GetAddress ());
211 action.pathSelection = WifiActionHeader::PATH_SELECTION;
212 actionHdr.SetAction (WifiActionHeader::MESH_PATH_SELECTION, action);
216 HwmpProtocolMac::SendPreq (
IePreq preq)
219 std::vector<IePreq> preq_vector;
220 preq_vector.push_back (preq);
221 SendPreq (preq_vector);
224 HwmpProtocolMac::SendPreq (std::vector<IePreq> preq)
228 for (std::vector<IePreq>::iterator i = preq.begin (); i != preq.end (); i++)
239 hdr.SetAddr2 (m_parent->GetAddress ());
240 hdr.SetAddr3 (m_protocol->GetAddress ());
242 std::vector<Mac48Address> receivers = m_protocol->GetPreqReceivers (m_ifIndex);
243 for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i++)
248 m_stats.txMgtBytes += packet->
GetSize ();
249 m_parent->SendManagementFrame (packet, hdr);
256 for (std::vector<IePreq>::iterator i = m_myPreq.begin (); i != m_myPreq.end (); i++)
263 i->AddDestinationAddressElement (m_protocol->GetDoFlag (), m_protocol->GetRfFlag (), dst, dst_seqno);
266 preq.SetHopcount (0);
267 preq.SetTTL (m_protocol->GetMaxTtl ());
268 preq.SetPreqID (m_protocol->GetNextPreqId ());
269 preq.SetOriginatorAddress (m_protocol->GetAddress ());
270 preq.SetOriginatorSeqNumber (originator_seqno);
271 preq.SetLifetime (m_protocol->GetActivePathLifetime ());
273 m_myPreq.push_back (preq);
284 if (m_myPreq.size () == 0)
309 hdr.SetAddr1 (receiver);
310 hdr.SetAddr2 (m_parent->GetAddress ());
311 hdr.SetAddr3 (m_protocol->GetAddress ());
315 m_stats.txMgtBytes += packet->
GetSize ();
316 m_parent->SendManagementFrame (packet, hdr);
319 HwmpProtocolMac::ForwardPerr (std::vector<HwmpProtocol::FailedDestination> failedDestinations, std::vector<
326 for (std::vector<HwmpProtocol::FailedDestination>::const_iterator i = failedDestinations.begin (); i
327 != failedDestinations.end (); i++)
329 if (!perr->IsFull ())
331 perr->AddAddressUnit (*i);
339 if (perr->GetNumOfDest () > 0)
341 elements.AddInformationElement (perr);
350 hdr.SetAddr2 (m_parent->GetAddress ());
351 hdr.SetAddr3 (m_protocol->GetAddress ());
352 if (receivers.size () >= m_protocol->GetUnicastPerrThreshold ())
358 for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i++)
364 Mac48Address address = *i;
365 hdr.SetAddr1 (address);
368 m_stats.txMgtBytes += packet->
GetSize ();
369 m_parent->SendManagementFrame (packet, hdr);
373 HwmpProtocolMac::InitiatePerr (std::vector<HwmpProtocol::FailedDestination> failedDestinations, std::vector<
374 Mac48Address> receivers)
379 std::vector<Mac48Address>::const_iterator end = receivers.end ();
380 for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != end; i++)
382 bool should_add =
true;
383 for (std::vector<Mac48Address>::const_iterator j = m_myPerr.receivers.begin (); j
384 != m_myPerr.receivers.end (); j++)
393 m_myPerr.receivers.push_back (*i);
398 std::vector<HwmpProtocol::FailedDestination>::const_iterator end = failedDestinations.end ();
399 for (std::vector<HwmpProtocol::FailedDestination>::const_iterator i = failedDestinations.begin (); i != end; i++)
401 bool should_add =
true;
402 for (std::vector<HwmpProtocol::FailedDestination>::const_iterator j = m_myPerr.destinations.begin (); j
403 != m_myPerr.destinations.end (); j++)
405 if (((*i).destination == (*j).destination) && ((*j).seqnum > (*i).seqnum))
412 m_myPerr.destinations.push_back (*i);
419 HwmpProtocolMac::SendMyPerr ()
426 m_perrTimer =
Simulator::Schedule (m_protocol->GetPerrMinInterval (), &HwmpProtocolMac::SendMyPerr,
this);
427 ForwardPerr (m_myPerr.destinations, m_myPerr.receivers);
428 m_myPerr.destinations.clear ();
429 m_myPerr.receivers.clear ();
434 return m_parent->GetLinkMetric (peerAddress);
437 HwmpProtocolMac::GetChannelId ()
const
439 return m_parent->GetFrequencyChannel ();
441 HwmpProtocolMac::Statistics::Statistics () :
442 txPreq (0), rxPreq (0), txPrep (0), rxPrep (0), txPerr (0), rxPerr (0), txMgt (0), txMgtBytes (0),
443 rxMgt (0), rxMgtBytes (0), txData (0), txDataBytes (0), rxData (0), rxDataBytes (0)
447 HwmpProtocolMac::Statistics::Print (std::ostream & os)
const
450 "txPreq= \"" << txPreq <<
"\"" << std::endl <<
451 "txPrep=\"" << txPrep <<
"\"" << std::endl <<
452 "txPerr=\"" << txPerr <<
"\"" << std::endl <<
453 "rxPreq=\"" << rxPreq <<
"\"" << std::endl <<
454 "rxPrep=\"" << rxPrep <<
"\"" << std::endl <<
455 "rxPerr=\"" << rxPerr <<
"\"" << std::endl <<
456 "txMgt=\"" << txMgt <<
"\"" << std::endl <<
457 "txMgtBytes=\"" << txMgtBytes <<
"\"" << std::endl <<
458 "rxMgt=\"" << rxMgt <<
"\"" << std::endl <<
459 "rxMgtBytes=\"" << rxMgtBytes <<
"\"" << std::endl <<
460 "txData=\"" << txData <<
"\"" << std::endl <<
461 "txDataBytes=\"" << txDataBytes <<
"\"" << std::endl <<
462 "rxData=\"" << rxData <<
"\"" << std::endl <<
463 "rxDataBytes=\"" << rxDataBytes <<
"\"/>" << std::endl;
468 os <<
"<HwmpProtocolMac" << std::endl <<
469 "address =\"" << m_parent->GetAddress () <<
"\">" << std::endl;
471 os <<
"</HwmpProtocolMac>" << std::endl;
474 HwmpProtocolMac::ResetStats ()
476 m_stats = Statistics ();
482 return m_protocol->AssignStreams (stream);
uint32_t RemoveHeader(Header &header)
bool ReceiveAction(Ptr< Packet > packet, const WifiMacHeader &header)
Receive action management frame.
uint32_t GetLinkMetric(Mac48Address peerAddress) const
smart pointer class similar to boost::intrusive_ptr
void SetParent(Ptr< MeshWifiInterfaceMac > parent)
Each plugin must be installed on interface to work.
void SendMyPreq()
Sends one PREQ when PreqMinInterval after last PREQ expires (if any PREQ exists in rhe queue) ...
Hwmp tag implements interaction between HWMP protocol and MeshWifiMac.
void RequestDestination(Mac48Address dest, uint32_t originator_seqno, uint32_t dst_seqno)
Request a destination. If can not send preq immediately - add a destination to existing PREQ generate...
void AddPacketTag(const Tag &tag) const
#define NS_ASSERT(condition)
#define NS_LOG_COMPONENT_DEFINE(name)
See 7.3.2.97 of 802.11s draft 2.07.
uint32_t GetSize(void) const
bool IsRunning(void) const
#define NS_LOG_FUNCTION_NOARGS()
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
#define NS_FATAL_ERROR(msg)
fatal error handling
bool PeekPacketTag(Tag &tag) const
static WifiActionHeader GetWifiActionHeader()
See 7.3.2.96 of 802.11s draft 2.07.
static Mac48Address GetBroadcast(void)
void AddDestinationAddressElement(bool doFlag, bool rfFlag, Mac48Address dest_address, uint32_t dest_seq_number)
bool UpdateOutcomingFrame(Ptr< Packet > packet, WifiMacHeader &header, Mac48Address from, Mac48Address to)
Update frame before it will be forwarded down.
int64_t AssignStreams(int64_t stream)
bool ReceiveData(Ptr< Packet > packet, const WifiMacHeader &header)
Receive data frame.
bool RemovePacketTag(Tag &tag)
bool Receive(Ptr< Packet > packet, const WifiMacHeader &header)
Process received frame.
void Report(std::ostream &) const
Report statistics.
void AddHeader(const Header &header)