diff --git a/src/devices/mesh/dot11s/dot11s-mac-header.cc b/src/devices/mesh/dot11s/dot11s-mac-header.cc index 835db8588..d267a0841 100644 --- a/src/devices/mesh/dot11s/dot11s-mac-header.cc +++ b/src/devices/mesh/dot11s/dot11s-mac-header.cc @@ -258,17 +258,8 @@ WifiMeshActionHeader::GetAction () case MESH_PATH_SELECTION: switch (m_actionValue) { - case PATH_REQUEST: - retval.pathSelection = PATH_REQUEST; - return retval; - case PATH_REPLY: - retval.pathSelection = PATH_REPLY; - return retval; - case PATH_ERROR: - retval.pathSelection = PATH_ERROR; - return retval; - case ROOT_ANNOUNCEMENT: - retval.pathSelection = ROOT_ANNOUNCEMENT; + case PATH_SELECTION: + retval.pathSelection = PATH_SELECTION; return retval; default: NS_FATAL_ERROR ("Unknown mesh path selection action code"); diff --git a/src/devices/mesh/dot11s/dot11s-mac-header.h b/src/devices/mesh/dot11s/dot11s-mac-header.h index 48d7bdf4f..936208845 100644 --- a/src/devices/mesh/dot11s/dot11s-mac-header.h +++ b/src/devices/mesh/dot11s/dot11s-mac-header.h @@ -111,10 +111,7 @@ public: /* Compatible with open80211s implementation */ enum PathSelectionActionValue { - PATH_REQUEST = 0, - PATH_REPLY = 1, - PATH_ERROR = 2, - ROOT_ANNOUNCEMENT = 3, + PATH_SELECTION = 0, }; enum InterworkActionValue { diff --git a/src/devices/mesh/dot11s/hwmp-protocol-mac.cc b/src/devices/mesh/dot11s/hwmp-protocol-mac.cc index fc8986a27..c999831f2 100644 --- a/src/devices/mesh/dot11s/hwmp-protocol-mac.cc +++ b/src/devices/mesh/dot11s/hwmp-protocol-mac.cc @@ -29,6 +29,7 @@ #include "hwmp-tag.h" #include "ie-dot11s-preq.h" #include "ie-dot11s-prep.h" +#include "ie-dot11s-rann.h" namespace ns3 { namespace dot11s { @@ -97,44 +98,44 @@ HwmpProtocolMac::ReceiveAction (Ptr packet, const WifiMacHeader & header WifiMeshActionHeader::ActionValue actionValue = actionHdr.GetAction (); if(actionHdr.GetCategory () != WifiMeshActionHeader::MESH_PATH_SELECTION) return true; - switch (actionValue.pathSelection) + IeRann rann; + IePreq preq; + IePrep prep; + IePerr perr; + while (packet->RemoveHeader (rann)) { - case WifiMeshActionHeader::PATH_REQUEST: - { - IePreq preq; - m_stats.rxPreq ++; - packet->RemoveHeader (preq); - if(preq.GetOriginatorAddress () == m_protocol->GetAddress ()) - return false; - if (preq.GetTtl () == 0) - return false; - preq.DecrementTtl (); - m_protocol->ReceivePreq (preq, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (), m_parent->GetLinkMetric(header.GetAddr2 ())); - return false; - } - case WifiMeshActionHeader::PATH_REPLY: - { - IePrep prep; - m_stats.rxPrep ++; - packet->RemoveHeader (prep); - if(prep.GetTtl () == 0) - return false; - prep.DecrementTtl (); - m_protocol->ReceivePrep (prep, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (), m_parent->GetLinkMetric(header.GetAddr2 ())); - return false; - } - case WifiMeshActionHeader::PATH_ERROR: - { - IePerr perr; - m_stats.rxPerr ++; - packet->RemoveHeader (perr); - m_protocol->ReceivePerr (perr, header.GetAddr2 (), m_ifIndex, header.GetAddr3 ()); - return false; - } - case WifiMeshActionHeader::ROOT_ANNOUNCEMENT: - return false; + NS_LOG_WARN("RANN is not supported!"); } - return true; + while (packet->RemoveHeader (preq)) + { + m_stats.rxPreq ++; + if (preq.GetOriginatorAddress () == m_protocol->GetAddress ()) + continue; + if (preq.GetTtl () == 0) + continue; + preq.DecrementTtl (); + m_protocol->ReceivePreq (preq, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (), m_parent->GetLinkMetric(header.GetAddr2 ())); + } + while (packet->RemoveHeader (prep)) + { + m_stats.rxPrep ++; + if (prep.GetTtl () == 0) + continue; + prep.DecrementTtl (); + m_protocol->ReceivePrep (prep, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (), m_parent->GetLinkMetric(header.GetAddr2 ())); + } + std::vector failedDestinations; + while (packet->RemoveHeader (perr)) + { + m_stats.rxPerr ++; + std::vector destinations = perr.GetAddressUnitVector (); + for(std::vector::const_iterator i = destinations.begin (); i != destinations.end (); i ++) + failedDestinations.push_back (*i); + } + if (failedDestinations.size () > 0) + m_protocol->ReceivePerr (failedDestinations, header.GetAddr2 (), m_ifIndex, header.GetAddr3 ()); + NS_ASSERT(packet->GetSize () == 0); + return false; } bool @@ -161,58 +162,38 @@ HwmpProtocolMac::UpdateOutcomingFrame (Ptr packet, WifiMacHeader & heade m_stats.txData ++; m_stats.txDataBytes += packet->GetSize (); MeshHeader meshHdr; - meshHdr.SetMeshSeqno(tag.GetSeqno()); - meshHdr.SetMeshTtl(tag.GetTtl()); - packet->AddHeader(meshHdr); - header.SetAddr1(tag.GetAddress()); + meshHdr.SetMeshSeqno (tag.GetSeqno()); + meshHdr.SetMeshTtl (tag.GetTtl()); + packet->AddHeader (meshHdr); + header.SetAddr1 (tag.GetAddress()); return true; } +WifiMeshActionHeader +HwmpProtocolMac::GetWifiMeshActionHeader () +{ + WifiMeshActionHeader actionHdr; + WifiMeshActionHeader::ActionValue action; + action.pathSelection = WifiMeshActionHeader::PATH_SELECTION; + actionHdr.SetAction (WifiMeshActionHeader::MESH_PATH_SELECTION, action); + return actionHdr; +} void HwmpProtocolMac::SendPreq(IePreq preq) { - m_preqQueue.push_back (preq); - SendOnePreq (); + NS_LOG_FUNCTION_NOARGS (); + std::vector preq_vector; + preq_vector.push_back(preq); + SendPreq(preq_vector); } void -HwmpProtocolMac::RequestDestination (Mac48Address dst, uint32_t originator_seqno, uint32_t dst_seqno) +HwmpProtocolMac::SendPreq(std::vector preq) { - for(std::vector::iterator i = m_preqQueue.begin (); i != m_preqQueue.end (); i ++) - if(i->MayAddAddress(m_protocol->GetAddress ())) - { - i->AddDestinationAddressElement (m_protocol->GetDoFlag(), m_protocol->GetRfFlag(), dst, dst_seqno); - return; - } - IePreq preq; - //fill PREQ: - preq.SetHopcount (0); - preq.SetTTL (m_protocol->GetMaxTtl ()); - preq.SetPreqID (m_protocol->GetNextPreqId ()); - preq.SetOriginatorAddress (m_protocol->GetAddress ()); - preq.SetOriginatorSeqNumber (originator_seqno); - preq.SetLifetime (m_protocol->GetActivePathLifetime ()); - preq.AddDestinationAddressElement (m_protocol->GetDoFlag (), m_protocol->GetRfFlag (), dst, dst_seqno); - m_preqQueue.push_back (preq); - //set iterator position to my preq: - SendOnePreq (); -} -void -HwmpProtocolMac::SendOnePreq () -{ - if(m_preqTimer.IsRunning ()) - return; - if (m_preqQueue.size () == 0) - return; - //reschedule sending PREQ - NS_ASSERT (!m_preqTimer.IsRunning()); - m_preqTimer = Simulator::Schedule (m_protocol->GetPreqMinInterval (), &HwmpProtocolMac::SendOnePreq, this); - Ptr packet = Create (); - packet->AddHeader(m_preqQueue[0]); - //Action header: - WifiMeshActionHeader actionHdr; - WifiMeshActionHeader::ActionValue action; - action.pathSelection = WifiMeshActionHeader::PATH_REQUEST; - actionHdr.SetAction (WifiMeshActionHeader::MESH_PATH_SELECTION, action); - packet->AddHeader (actionHdr); + Ptr packet = Create (); + for(std::vector::const_iterator i = preq.begin (); i != preq.end (); i ++) + { + packet->AddHeader (*i); + } + packet->AddHeader (GetWifiMeshActionHeader ()); //create 802.11 header: WifiMacHeader hdr; hdr.SetAction (); @@ -230,60 +211,51 @@ HwmpProtocolMac::SendOnePreq () m_stats.txMgtBytes += packet->GetSize (); m_parent->SendManagementFrame(packet, hdr); } - //erase queue - m_preqQueue.erase (m_preqQueue.begin()); } void -HwmpProtocolMac::SendOnePerr() +HwmpProtocolMac::RequestDestination (Mac48Address dst, uint32_t originator_seqno, uint32_t dst_seqno) { - if(m_perrTimer.IsRunning ()) + NS_LOG_FUNCTION_NOARGS (); + for(std::vector::iterator i = m_myPreq.begin (); i != m_myPreq.end(); i ++) + { + if(i->IsFull ()) + continue; + NS_ASSERT (i->GetDestCount () > 0); + i->AddDestinationAddressElement (m_protocol->GetDoFlag(), m_protocol->GetRfFlag(), dst, dst_seqno); + } + IePreq preq; + preq.SetHopcount (0); + preq.SetTTL (m_protocol->GetMaxTtl ()); + preq.SetPreqID (m_protocol->GetNextPreqId ()); + preq.SetOriginatorAddress (m_protocol->GetAddress ()); + preq.SetOriginatorSeqNumber (originator_seqno); + preq.SetLifetime (m_protocol->GetActivePathLifetime ()); + preq.AddDestinationAddressElement (m_protocol->GetDoFlag(), m_protocol->GetRfFlag(), dst, dst_seqno); + m_myPreq.push_back(preq); + SendMyPreq (); +} +void +HwmpProtocolMac::SendMyPreq () +{ + NS_LOG_FUNCTION_NOARGS (); + if(m_preqTimer.IsRunning ()) return; - if(m_myPerr.receivers.size () >= m_protocol->GetUnicastPerrThreshold ()) - { - m_myPerr.receivers.clear (); - m_myPerr.receivers.push_back (Mac48Address::GetBroadcast ()); - } - m_perrTimer = Simulator::Schedule (m_protocol->GetPerrMinInterval (), &HwmpProtocolMac::SendOnePerr, this); -//Create packet - Ptr packet = Create (); - packet->AddHeader(m_myPerr.perr); - //Action header: - WifiMeshActionHeader actionHdr; - WifiMeshActionHeader::ActionValue action; - action.pathSelection = WifiMeshActionHeader::PATH_ERROR; - actionHdr.SetAction (WifiMeshActionHeader::MESH_PATH_SELECTION, action); - packet->AddHeader (actionHdr); - //create 802.11 header: - WifiMacHeader hdr; - hdr.SetAction (); - hdr.SetDsNotFrom (); - hdr.SetDsNotTo (); - hdr.SetAddr2 (m_parent->GetAddress ()); - hdr.SetAddr3 (m_protocol->GetAddress ()); - //Send Management frame - for(std::vector::const_iterator i = m_myPerr.receivers.begin (); i != m_myPerr.receivers.end (); i ++) - { - hdr.SetAddr1 (*i); - m_stats.txPerr ++; - m_stats.txMgt ++; - m_stats.txMgtBytes += packet->GetSize (); - m_parent->SendManagementFrame(packet, hdr); - } - m_myPerr.perr.ResetPerr (); - m_myPerr.receivers.clear (); + if(m_myPreq.size () == 0) + return; + //reschedule sending PREQ + NS_ASSERT (!m_preqTimer.IsRunning()); + m_preqTimer = Simulator::Schedule (m_protocol->GetPreqMinInterval (), &HwmpProtocolMac::SendMyPreq, this); + SendPreq (m_myPreq); + m_myPreq.clear (); } void HwmpProtocolMac::SendPrep (IePrep prep, Mac48Address receiver) { + NS_LOG_FUNCTION_NOARGS (); //Create packet Ptr packet = Create (); - packet->AddHeader(prep); - //Action header: - WifiMeshActionHeader actionHdr; - WifiMeshActionHeader::ActionValue action; - action.pathSelection = WifiMeshActionHeader::PATH_REPLY; - actionHdr.SetAction (WifiMeshActionHeader::MESH_PATH_SELECTION, action); - packet->AddHeader (actionHdr); + packet->AddHeader (prep); + packet->AddHeader (GetWifiMeshActionHeader ()); //create 802.11 header: WifiMacHeader hdr; hdr.SetAction (); @@ -299,19 +271,91 @@ HwmpProtocolMac::SendPrep (IePrep prep, Mac48Address receiver) m_parent->SendManagementFrame(packet, hdr); } void -HwmpProtocolMac::SendPerr(IePerr perr, std::vector receivers) +HwmpProtocolMac::ForwardPerr(std::vector failedDestinations, std::vector receivers) { - m_myPerr.perr.Merge(perr); - for(unsigned int i = 0; i < receivers.size (); i ++) + NS_LOG_FUNCTION_NOARGS (); + Ptr packet = Create (); + IePerr perr; + for(std::vector::const_iterator i = failedDestinations.begin (); i != failedDestinations.end (); i ++) { - bool should_add = true; - for (unsigned int j = 0; j < m_myPerr.receivers.size (); j ++) - if(receivers[j] == m_myPerr.receivers[i]) - should_add = false; - if(should_add) - m_myPerr.receivers.push_back(receivers[i]); + if(!perr.IsFull ()) + perr.AddAddressUnit (*i); + else + { + packet->AddHeader (perr); + perr.ResetPerr (); + } } - SendOnePerr (); + if(perr.GetNumOfDest () > 0) + packet->AddHeader (perr); + packet->AddHeader (GetWifiMeshActionHeader ()); + //create 802.11 header: + WifiMacHeader hdr; + hdr.SetAction (); + hdr.SetDsNotFrom (); + hdr.SetDsNotTo (); + hdr.SetAddr2 (m_parent->GetAddress ()); + hdr.SetAddr3 (m_protocol->GetAddress ()); + if(receivers.size () >= m_protocol->GetUnicastPerrThreshold ()) + { + receivers.clear (); + receivers.push_back (Mac48Address::GetBroadcast ()); + } + //Send Management frame + for(std::vector::const_iterator i = m_myPerr.receivers.begin (); i != m_myPerr.receivers.end (); i ++) + { + hdr.SetAddr1 (*i); + m_stats.txPerr ++; + m_stats.txMgt ++; + m_stats.txMgtBytes += packet->GetSize (); + m_parent->SendManagementFrame(packet, hdr); + } +} +void +HwmpProtocolMac::InitiatePerr (std::vector failedDestinations, std::vector receivers) +{ + //All duplicates in PERR are checked here, and there is no reason to + //check it at any athoer place + { + std::vector::const_iterator end = receivers.end(); + for(std::vector::const_iterator i = receivers.begin (); i != end; i ++) + { + bool should_add = true; + for (std::vector::const_iterator j = m_myPerr.receivers.begin (); j != m_myPerr.receivers.end (); j ++) + if ((*i) == (*j)) + should_add = false; + if (should_add) + m_myPerr.receivers.push_back(*i); + } + } + { + std::vector::const_iterator end = failedDestinations.end (); + for(std::vector::const_iterator i = failedDestinations.begin (); i != end; i ++) + { + bool should_add = true; + for + ( + std::vector::const_iterator j = m_myPerr.destinations.begin (); + j != m_myPerr.destinations.end (); + j ++) + if ( ((*i).destination == (*j).destination) && ((*j).seqnum > (*i).seqnum) ) + should_add = false; + if (should_add) + m_myPerr.destinations.push_back(*i); + } + } + SendMyPerr (); +} +void +HwmpProtocolMac::SendMyPerr() +{ + NS_LOG_FUNCTION_NOARGS (); + if(m_perrTimer.IsRunning ()) + return; + m_perrTimer = Simulator::Schedule (m_protocol->GetPerrMinInterval (), &HwmpProtocolMac::SendMyPerr, this); + ForwardPerr (m_myPerr.destinations, m_myPerr.receivers); + m_myPerr.destinations.clear (); + m_myPerr.receivers.clear (); } uint32_t HwmpProtocolMac::GetLinkMetric(Mac48Address peerAddress) const diff --git a/src/devices/mesh/dot11s/hwmp-protocol-mac.h b/src/devices/mesh/dot11s/hwmp-protocol-mac.h index 97c37a757..8ea1c4d65 100644 --- a/src/devices/mesh/dot11s/hwmp-protocol-mac.h +++ b/src/devices/mesh/dot11s/hwmp-protocol-mac.h @@ -23,6 +23,7 @@ #define HWMP_STATE_H #include "ns3/mesh-wifi-interface-mac-plugin.h" +#include "ie-dot11s-preq.h" #include "ie-dot11s-perr.h" namespace ns3 { @@ -32,6 +33,7 @@ class MeshWifiInterfaceMac; namespace dot11s { class HwmpProtocol; +class WifiMeshActionHeader; class IePreq; class IePrep; class IePerr; @@ -57,12 +59,17 @@ public: private: friend class HwmpProtocol; - + ///\returns a path selection action header + static WifiMeshActionHeader GetWifiMeshActionHeader (); ///\name Intercation with HWMP: //\{ - void SendPreq(IePreq preq); - void SendPrep(IePrep prep, Mac48Address receiver); - void SendPerr(IePerr perr, std::vector receivers); + void SendPreq (IePreq preq); + void SendPreq (std::vector preq); + void SendPrep (IePrep prep, Mac48Address receiver); + //Forward a peth error + void ForwardPerr(std::vector destinations, std::vector receivers); + // initiate my own path error + void InitiatePerr (std::vector destinations, std::vector receivers); /** \brief Request a destination. If can not send preq immediately - * add a destination to exisying PREQ generated by me and stored in * PREQ queue @@ -73,8 +80,8 @@ private: //\} /// Sends one PREQ when PreqMinInterval after last PREQ expires (if any PREQ exists in rhe queue) - void SendOnePreq (); - void SendOnePerr (); + void SendMyPreq (); + void SendMyPerr (); /// \return metric to HWMP protocol, needed only by metrics to add //peer as routing entry uint32_t GetLinkMetric (Mac48Address peerAddress) const; @@ -87,16 +94,16 @@ private: uint32_t m_ifIndex; Ptr m_protocol; - ///\name PREQ queue and PREQ timer: + ///\name my PREQ and PREQ timer: //\{ - EventId m_preqTimer; - std::vector m_preqQueue; + EventId m_preqTimer; + std::vector m_myPreq; //\} ///\name PERR timer and stored path error //\{ EventId m_perrTimer; struct MyPerr { - IePerr perr; + std::vector destinations; std::vector receivers; }; MyPerr m_myPerr; diff --git a/src/devices/mesh/dot11s/hwmp-protocol.cc b/src/devices/mesh/dot11s/hwmp-protocol.cc index eac08ce0f..bc0add153 100644 --- a/src/devices/mesh/dot11s/hwmp-protocol.cc +++ b/src/devices/mesh/dot11s/hwmp-protocol.cc @@ -34,7 +34,6 @@ #include "airtime-metric.h" #include "ie-dot11s-preq.h" #include "ie-dot11s-prep.h" -#include "ie-dot11s-perr.h" NS_LOG_COMPONENT_DEFINE ("HwmpProtocol"); @@ -304,7 +303,7 @@ HwmpProtocol::ForwardUnicast(uint32_t sourceIface, const Mac48Address source, c if(result.retransmitter != Mac48Address::GetBroadcast ()) { std::vector destinations = m_rtable->GetUnreachableDestinations (result.retransmitter); - MakePathError (destinations); + InitiatePathError (MakePathError (destinations)); } m_stats.totalDropped ++; return false; @@ -317,6 +316,7 @@ HwmpProtocol::ForwardUnicast(uint32_t sourceIface, const Mac48Address source, c uint32_t dst_seqno = 0; if(result.retransmitter != Mac48Address::GetBroadcast ()) dst_seqno = result.seqnum; + m_stats.initiatedPreq ++; for(HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i ++) i->second->RequestDestination(destination, originator_seqno, dst_seqno); } @@ -558,28 +558,25 @@ HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface, M prep_sender->second->SendPrep (prep, result.retransmitter); } void -HwmpProtocol::ReceivePerr (IePerr perr, Mac48Address from, uint32_t interface, Mac48Address fromMp) +HwmpProtocol::ReceivePerr (std::vector destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp) { //Acceptance cretirea: NS_LOG_DEBUG("I am "< destinations = perr.GetAddressUnitVector (); + std::vector retval; HwmpRtable::LookupResult result; for(unsigned int i = 0; i < destinations.size (); i ++) { result = m_rtable->LookupReactive (destinations[i].destination); - if ( + if (!( (result.retransmitter != from) || (result.ifIndex != interface) || (result.seqnum > destinations[i].seqnum) - ) - { - perr.DeleteAddressUnit(destinations[i].destination); - continue; - } + )) + retval.push_back(destinations[i]); } - if(perr.GetNumOfDest () == 0) + if(retval.size() == 0) return; - MakePathError (destinations); + ForwardPathError (MakePathError (retval)); } void HwmpProtocol::SendPrep ( @@ -604,8 +601,7 @@ HwmpProtocol::SendPrep ( HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (interface); NS_ASSERT(prep_sender != m_interfaces.end ()); prep_sender->second->SendPrep (prep, retransmitter); - //m_prepCallback (prep, retransmitter); - + m_stats.initiatedPrep ++; } bool HwmpProtocol::Install (Ptr mp) @@ -641,7 +637,7 @@ HwmpProtocol::PeerLinkStatus(Mac48Address meshPointAddress, Mac48Address peerAdd if(status) return; std::vector destinations = m_rtable->GetUnreachableDestinations (peerAddress); - MakePathError (destinations); + InitiatePathError (MakePathError (destinations)); } void HwmpProtocol::SetNeighboursCallback(Callback, uint32_t> cb) @@ -664,28 +660,47 @@ HwmpProtocol::DropDataFrame(uint32_t seqno, Mac48Address source) } return false; } -void +HwmpProtocol::PathError HwmpProtocol::MakePathError (std::vector destinations) { + PathError retval; //HwmpRtable increments a sequence number as written in 11B.9.7.2 - std::vector > receivers = GetPerrReceivers (destinations); - if(receivers.size () == 0) - return; - IePerr perr; + retval.receivers = GetPerrReceivers (destinations); + if(retval.receivers.size () == 0) + return retval; + m_stats.initiatedPerr ++; for(unsigned int i = 0; i < destinations.size (); i ++) { - perr.AddAddressUnit(destinations[i]); + retval.destinations.push_back(destinations[i]); m_rtable->DeleteReactivePath(destinations[i].destination); } + return retval; +} +void +HwmpProtocol::InitiatePathError(PathError perr) +{ for(HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i ++) { std::vector receivers_for_interface; - for(unsigned int j = 0; j < receivers.size(); j ++) - if(i->first == receivers[j].first) - receivers_for_interface.push_back(receivers[j].second); - i->second->SendPerr (perr, receivers_for_interface); + for(unsigned int j = 0; j < perr.receivers.size(); j ++) + if(i->first == perr.receivers[j].first) + receivers_for_interface.push_back(perr.receivers[j].second); + i->second->InitiatePerr (perr.destinations, receivers_for_interface); } } +void +HwmpProtocol::ForwardPathError(PathError perr) +{ + for(HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i ++) + { + std::vector receivers_for_interface; + for(unsigned int j = 0; j < perr.receivers.size(); j ++) + if(i->first == perr.receivers[j].first) + receivers_for_interface.push_back(perr.receivers[j].second); + i->second->ForwardPerr (perr.destinations, receivers_for_interface); + } +} + std::vector > HwmpProtocol::GetPerrReceivers (std::vector failedDest) { @@ -964,7 +979,10 @@ void HwmpProtocol::Statistics::Print (std::ostream & os) const "txBytes=\"" << txBytes << "\" " "droppedTtl=\"" << droppedTtl << "\" " "totalQueued=\"" << totalQueued << "\" " - "totalDropped=\"" << totalDropped << "\"/>\n"; + "totalDropped=\"" << totalDropped << "\" " + "initiatedPreq=\"" << initiatedPreq << "\" " + "initiatedPrep=\"" << initiatedPrep << "\" " + "initiatedPerr=\"" << initiatedPerr << "\"\n"; } void HwmpProtocol::Report (std::ostream & os) const diff --git a/src/devices/mesh/dot11s/hwmp-protocol.h b/src/devices/mesh/dot11s/hwmp-protocol.h index 4abeb9aef..6128e6079 100644 --- a/src/devices/mesh/dot11s/hwmp-protocol.h +++ b/src/devices/mesh/dot11s/hwmp-protocol.h @@ -90,7 +90,7 @@ private: //\{ void ReceivePreq(IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric); void ReceivePrep(IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric); - void ReceivePerr(IePerr perr, Mac48Address from, uint32_t interface, Mac48Address fromMp); + void ReceivePerr(std::vector, Mac48Address from, uint32_t interface, Mac48Address fromMp); void SendPrep ( Mac48Address src, Mac48Address dst, @@ -100,9 +100,25 @@ private: uint32_t destinationSN, uint32_t lifetime, uint32_t interface); - - ///\brief forms a path error information element when list of destination fails on a given interface - void MakePathError (std::vector destinations); + /** + * \brief Structure of path error: IePerr and list of receivers: + * interfaces and MAC address + */ + struct PathError + { + std::vector destinations; + /// interface-address + std::vector > receivers; + }; + /** + * \brief forms a path error information element when list of destination fails on a given interface + * \attention removes all entries from routing table! + */ + PathError MakePathError (std::vector destinations); + ///\brief Forwards a received path error + void ForwardPathError (PathError perr); + ///\brief Pasess a selg-generated PERR to interface-plugin + void InitiatePathError (PathError perr); /// \return list of addresses where a PERR should be sent to std::vector > GetPerrReceivers (std::vector failedDest); @@ -151,9 +167,12 @@ private: uint16_t droppedTtl; uint16_t totalQueued; uint16_t totalDropped; + uint16_t initiatedPreq; + uint16_t initiatedPrep; + uint16_t initiatedPerr; void Print (std::ostream & os) const; - Statistics () : txUnicast (0), txBroadcast (0), txBytes (0), droppedTtl (0), totalQueued (0), totalDropped (0) {} + Statistics () : txUnicast (0), txBroadcast (0), txBytes (0), droppedTtl (0), totalQueued (0), totalDropped (0), initiatedPreq (0), initiatedPrep (0), initiatedPerr (0) {} }; Statistics m_stats; ///\} diff --git a/src/devices/mesh/dot11s/ie-dot11s-perr.cc b/src/devices/mesh/dot11s/ie-dot11s-perr.cc index cea8ac281..8264f134d 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-perr.cc +++ b/src/devices/mesh/dot11s/ie-dot11s-perr.cc @@ -32,9 +32,8 @@ IePerr::~IePerr () void IePerr::PrintInformation (std::ostream &os) const { - os << "Number of failed destinations: = " << m_numOfDest; - NS_ASSERT (m_numOfDest == m_addressUnits.size ()); - for (unsigned int j = 0; j < m_numOfDest; j++) + os << "Number of failed destinations: = " << m_addressUnits.size (); + for (unsigned int j = 0; j < m_addressUnits.size (); j++) { os << "Failed destination address: = "<< m_addressUnits[j].destination << ", sequence number = " << m_addressUnits[j].seqnum; @@ -42,22 +41,20 @@ IePerr::PrintInformation (std::ostream &os) const os << "\n"; } -IePerr::IePerr (): - m_numOfDest (0) +IePerr::IePerr () { } uint8_t IePerr::GetNumOfDest () { - return m_numOfDest; + return m_addressUnits.size (); } void IePerr::SerializeInformation (Buffer::Iterator i) const { i.WriteU8 (0); - i.WriteU8 (m_numOfDest); - NS_ASSERT (m_numOfDest == m_addressUnits.size ()); - for (unsigned int j = 0; j < m_numOfDest; j++) + i.WriteU8 (m_addressUnits.size ()); + for (unsigned int j = 0; j < m_addressUnits.size (); j++) { WriteTo (i, m_addressUnits[j].destination); i.WriteHtolsbU32 (m_addressUnits[j].seqnum); @@ -68,10 +65,10 @@ IePerr::DeserializeInformation (Buffer::Iterator start, uint8_t length) { Buffer::Iterator i = start; i.Next (1); //Mode flags is not used now - m_numOfDest = i.ReadU8 (); - NS_ASSERT ((2+10*m_numOfDest) == length); + uint8_t numOfDest = i.ReadU8 (); + NS_ASSERT ((2+10*numOfDest) == length); length = 0; //to avoid compiler warning in optimized builds - for (unsigned int j = 0; j < m_numOfDest; j++) + for (unsigned int j = 0; j < numOfDest; j++) { FailedDestination unit; ReadFrom (i,unit.destination); @@ -87,8 +84,7 @@ IePerr::GetInformationSize () const uint8_t retval = 1 //ModeFlags +1 //NumOfDests - +6*m_numOfDest - +4*m_numOfDest; + +(6+4) * m_addressUnits.size (); return retval; } @@ -98,10 +94,15 @@ IePerr::AddAddressUnit (FailedDestination unit) for (unsigned int i = 0; i < m_addressUnits.size (); i ++) if (m_addressUnits[i].destination == unit.destination) return; + if((m_addressUnits.size () + 1) * 10 + 2 > 255) + return; m_addressUnits.push_back (unit); - m_numOfDest++; } - +bool +IePerr::IsFull () const +{ + return (GetSerializedSize () + 10 > 255); +} std::vector IePerr::GetAddressUnitVector () const { @@ -113,34 +114,18 @@ IePerr::DeleteAddressUnit (Mac48Address address) for (std::vector::iterator i = m_addressUnits.begin (); i != m_addressUnits.end(); i ++) if (i->destination == address) { - m_numOfDest --; m_addressUnits.erase (i); break; } } void -IePerr::Merge(const IePerr perr) -{ - std::vector to_merge = perr.GetAddressUnitVector (); - for (std::vector::iterator i = to_merge.begin (); i != to_merge.end(); i ++) - { - bool should_add = true; - for (std::vector::iterator j = m_addressUnits.begin (); j != m_addressUnits.end(); j ++) - if ((i->destination == j->destination) && (i->seqnum <= j->seqnum)) - should_add = false; - if(should_add) - AddAddressUnit (*i); - } -} -void IePerr::ResetPerr () { - m_numOfDest = 0; m_addressUnits.clear (); } bool operator== (const IePerr & a, const IePerr & b) { - if(a.m_numOfDest != b.m_numOfDest) + if(a.m_addressUnits.size () != b.m_addressUnits.size ()) return false; for(unsigned int i = 0; i < a.m_addressUnits.size(); i ++) { @@ -179,10 +164,6 @@ bool IePerrBist::RunTests () dest.seqnum = 3; a.AddAddressUnit(dest); - IePerr b = a; - b.Merge(a); - NS_TEST_ASSERT_EQUAL (a, b); - result = result && TestRoundtripSerialization (a); return result; } diff --git a/src/devices/mesh/dot11s/ie-dot11s-perr.h b/src/devices/mesh/dot11s/ie-dot11s-perr.h index 0e836071c..99606900a 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-perr.h +++ b/src/devices/mesh/dot11s/ie-dot11s-perr.h @@ -44,9 +44,9 @@ public: uint8_t GetNumOfDest (); void AddAddressUnit (struct FailedDestination unit); + bool IsFull () const; std::vector GetAddressUnitVector () const; void DeleteAddressUnit (Mac48Address address); - void Merge(const IePerr perr); void ResetPerr (); private: WifiElementId ElementId () const{ @@ -57,7 +57,6 @@ private: void PrintInformation (std::ostream& os) const; uint8_t GetInformationSize () const; private: - uint8_t m_numOfDest; std::vector m_addressUnits; friend bool operator== (const IePerr & a, const IePerr & b); }; diff --git a/src/devices/mesh/dot11s/ie-dot11s-prep.cc b/src/devices/mesh/dot11s/ie-dot11s-prep.cc index ea4357a10..1b043c1c7 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-prep.cc +++ b/src/devices/mesh/dot11s/ie-dot11s-prep.cc @@ -188,8 +188,7 @@ IePrep::GetInformationSize () const +4 //Lifetime +4 //metric +6 //Originator address - +4 //Originator seqno - +1; //destination count + +4; //Originator seqno return retval; }; void diff --git a/src/devices/mesh/dot11s/ie-dot11s-preq.cc b/src/devices/mesh/dot11s/ie-dot11s-preq.cc index c095f97d4..dc39904eb 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-preq.cc +++ b/src/devices/mesh/dot11s/ie-dot11s-preq.cc @@ -336,6 +336,7 @@ IePreq::AddDestinationAddressElement ( for (std::vector >::const_iterator i = m_destinations.begin (); i != m_destinations.end(); i++ ) if ((*i)->GetDestinationAddress () == dest_address) return; + //TODO: check overflow Ptrnew_element = Create (); new_element->SetFlags (doFlag, rfFlag, false); new_element->SetDestinationAddress (dest_address); @@ -355,7 +356,7 @@ IePreq::DelDestinationAddressElement (Mac48Address dest_address) } } void -IePreq::ClearDestinationAddressElement () +IePreq::ClearDestinationAddressElements () { int i; for (std::vector >::iterator j = m_destinations.begin (); j != m_destinations.end(); j++) @@ -363,6 +364,7 @@ IePreq::ClearDestinationAddressElement () for (i = 0; i < m_destCount; i ++) m_destinations.pop_back (); m_destinations.clear (); + m_destCount = 0; } bool operator== (const DestinationAddressUnit & a, const DestinationAddressUnit & b) { @@ -408,8 +410,15 @@ IePreq::MayAddAddress (Mac48Address originator) return false; if(m_destinations[0]->GetDestinationAddress () == Mac48Address::GetBroadcast ()) return false; + if((GetInformationSize () + 11) > 255) + return false; return true; } +bool +IePreq::IsFull () const +{ + return ((GetInformationSize () + 11) > 255); +} #ifdef RUN_SELF_TESTS /// Built-in self test for IePreq diff --git a/src/devices/mesh/dot11s/ie-dot11s-preq.h b/src/devices/mesh/dot11s/ie-dot11s-preq.h index cb7cf9c19..6ee625ce4 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-preq.h +++ b/src/devices/mesh/dot11s/ie-dot11s-preq.h @@ -64,20 +64,30 @@ class IePreq : public WifiInformationElement public: IePreq (); ~IePreq (); + /** + * Add a destination address unit: flags, destination and sequence + * number + */ void AddDestinationAddressElement ( bool doFlag, bool rfFlag, Mac48Address dest_address, uint32_t dest_seq_number ); + /// Delete a destination address unit by destination void DelDestinationAddressElement (Mac48Address dest_address); - void ClearDestinationAddressElement (); + /// Clear PREQ: remove all destinations + void ClearDestinationAddressElements (); + /// Get all destinations, which are stored in PREQ: std::vector > GetDestinationList (); + /// SetProper flags which indicate that PREQ is unicast void SetUnicastPreq (); /* * \brief In proactive case: need we send PREP */ void SetNeedNotPrep (); + ///\name Setters for fields: + ///\{ void SetHopcount (uint8_t hopcount); void SetTTL (uint8_t ttl); void SetPreqID (uint32_t id); @@ -86,7 +96,9 @@ public: void SetLifetime (uint32_t lifetime); void SetMetric (uint32_t metric); void SetDestCount (uint8_t dest_count); - + ///\} + ///\name Getters for fields: + ///\{ bool IsUnicastPreq () const; bool IsNeedNotPrep () const; uint8_t GetHopCount () const; @@ -97,6 +109,8 @@ public: uint32_t GetLifetime () const; uint32_t GetMetric () const; uint8_t GetDestCount () const; + ///\} + /// Handle TTL and Metric: void DecrementTtl (); void IncrementMetric (uint32_t metric); /* @@ -104,7 +118,7 @@ public: * this preq is not proactive */ bool MayAddAddress(Mac48Address originator); - + bool IsFull () const; private: WifiElementId ElementId () const{ return IE11S_PREQ; diff --git a/src/devices/mesh/flame/flame-installer.cc b/src/devices/mesh/flame/flame-installer.cc index 5313ad048..13f9fa3ed 100644 --- a/src/devices/mesh/flame/flame-installer.cc +++ b/src/devices/mesh/flame/flame-installer.cc @@ -52,11 +52,18 @@ FlameStack::Report (const Ptr mp, std::ostream& os) { mp->Report (os); // TODO report flame counters + Ptr flame = mp->GetObject (); + NS_ASSERT(flame != 0); + flame->Report (os); } void FlameStack::ResetStats (const Ptr mp) { mp->ResetStats (); // TODO reset flame counters + Ptr flame = mp->GetObject (); + NS_ASSERT(flame != 0); + + flame->ResetStats (); } } //namespace ns3 diff --git a/src/devices/mesh/flame/flame-protocol-mac.cc b/src/devices/mesh/flame/flame-protocol-mac.cc index 7f3ddca1b..13d45ffc8 100644 --- a/src/devices/mesh/flame/flame-protocol-mac.cc +++ b/src/devices/mesh/flame/flame-protocol-mac.cc @@ -51,6 +51,11 @@ FlameProtocolMac::Receive (Ptr packet, const WifiMacHeader & header) } tag.receiver = header.GetAddr1 (); tag.transmitter = header.GetAddr2 (); + if(tag.receiver == Mac48Address::GetBroadcast ()) + m_stats.rxBroadcast ++; + else + m_stats.rxUnicast ++; + m_stats.rxBytes += packet->GetSize (); packet->AddPacketTag (tag); return true; } @@ -65,6 +70,11 @@ FlameProtocolMac::UpdateOutcomingFrame (Ptr packet, WifiMacHeader & head NS_FATAL_ERROR ("FLAME tag must exist here"); } header.SetAddr1 (tag.receiver); + if(tag.receiver == Mac48Address::GetBroadcast ()) + m_stats.txBroadcast ++; + else + m_stats.txUnicast ++; + m_stats.txBytes += packet->GetSize (); return true; } uint16_t @@ -73,12 +83,29 @@ FlameProtocolMac::GetChannelId () const return m_parent->GetFrequencyChannel (); } void +FlameProtocolMac::Statistics::Print (std::ostream &os) const +{ + os << "\n"; +} +void FlameProtocolMac::Report (std::ostream & os) const { + os << "GetAddress () <<"\">\n"; + m_stats.Print(os); + os << "\n"; + } void FlameProtocolMac::ResetStats () { + m_stats = Statistics (); } } //namespace flame diff --git a/src/devices/mesh/flame/flame-protocol-mac.h b/src/devices/mesh/flame/flame-protocol-mac.h index 40bcac3c5..9f9c2ebaa 100644 --- a/src/devices/mesh/flame/flame-protocol-mac.h +++ b/src/devices/mesh/flame/flame-protocol-mac.h @@ -57,6 +57,23 @@ private: uint32_t m_ifIndex; Ptr m_parent; ///\} + ///\name Statistics: + ///\{ + struct Statistics + { + uint16_t txUnicast; + uint16_t txBroadcast; + uint32_t txBytes; + uint16_t rxUnicast; + uint16_t rxBroadcast; + uint32_t rxBytes; + + void Print (std::ostream & os) const; + Statistics () : txUnicast (0), txBroadcast (0), txBytes (0), rxUnicast (0), rxBroadcast (0), rxBytes (0) {} + }; + Statistics m_stats; + ///\} + }; } //namespace flame } //namespace ns3 diff --git a/src/devices/mesh/flame/flame-protocol.cc b/src/devices/mesh/flame/flame-protocol.cc index 85f053908..40813d621 100644 --- a/src/devices/mesh/flame/flame-protocol.cc +++ b/src/devices/mesh/flame/flame-protocol.cc @@ -157,8 +157,13 @@ FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, c flameHdr.SetProtocol (protocolType); flameHdr.SetOrigDst (destination); flameHdr.SetOrigSrc (source); + m_stats.txBytes += packet->GetSize (); packet->AddHeader (flameHdr); tag.receiver = result.retransmitter; + if(result.retransmitter == Mac48Address::GetBroadcast ()) + m_stats.txBroadcast ++; + else + m_stats.txUnicast ++; NS_LOG_DEBUG("Source: send packet with RA = " << tag.receiver); packet->AddPacketTag (tag); routeReply (true, packet, source, destination, FLAME_PROTOCOL, result.ifIndex); @@ -179,6 +184,7 @@ FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, c "received packet with SA = GetAddress (), RA = " << tag.receiver << ", TA = " << tag.transmitter << ", I am "<GetSize (); packet->AddHeader (flameHdr); packet->AddPacketTag (tag); routeReply (true, packet, source, destination, FLAME_PROTOCOL, FlameRtable::INTERFACE_ANY); + m_stats.txBroadcast ++; return true; } else @@ -204,10 +212,16 @@ FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, c NS_LOG_DEBUG("unicast packet dropped, because no route! I am "<\n"; +} + +void +FlameProtocol::Report (std::ostream & os) const +{ + os << "\n"; + m_stats.Print (os); + for(FlamePluginMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin ++) + plugin->second->Report(os); + os << "\n"; +} +void +FlameProtocol::ResetStats () +{ + m_stats = Statistics (); + for(FlamePluginMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin ++) + plugin->second->ResetStats (); +} } //namespace flame } //namespace ns3 diff --git a/src/devices/mesh/flame/flame-protocol.h b/src/devices/mesh/flame/flame-protocol.h index 71d19a333..476d8a8f4 100644 --- a/src/devices/mesh/flame/flame-protocol.h +++ b/src/devices/mesh/flame/flame-protocol.h @@ -33,9 +33,16 @@ * \ingroup mesh * \defgroup flame FLAME * - * \brief Forwarding LAyer for Meshing protocol + * \brief Forwarding LAyer for MEshing protocol * - * TODO add relevant references + * Simple L2.5 mesh routing protocol developed by + * Herman Elfrink and presented in + * "Easy Wireless: broadband ad-hoc networking for emergency services" + * by Maurits de Graaf et. al. at The Sixth Annual Mediterranean Ad Hoc + * Networking WorkShop, Corfu, Greece, June 12-15, 2007 + * + * see also Linux kernel mailing list discussion at + * http://lkml.org/lkml/2006/5/23/82 */ namespace ns3 { namespace flame { @@ -126,6 +133,21 @@ private: uint16_t m_myLastSeqno; /// Routing table: Ptr m_rtable; + ///\name Statistics: + ///\{ + struct Statistics + { + uint16_t txUnicast; + uint16_t txBroadcast; + uint32_t txBytes; + uint16_t droppedTtl; + uint16_t totalDropped; + void Print (std::ostream & os) const; + Statistics () : txUnicast (0), txBroadcast (0), txBytes (0), droppedTtl (0), totalDropped (0) {} + }; + Statistics m_stats; + ///\} + }; } //namespace flame } //namespace ns3 diff --git a/src/devices/mesh/mesh-wifi-interface-mac.cc b/src/devices/mesh/mesh-wifi-interface-mac.cc index f1d8e06e5..b0601a845 100644 --- a/src/devices/mesh/mesh-wifi-interface-mac.cc +++ b/src/devices/mesh/mesh-wifi-interface-mac.cc @@ -31,6 +31,7 @@ #include "ns3/simulator.h" #include "ns3/yans-wifi-phy.h" #include "ns3/pointer.h" +#include "ns3/qos-tag.h" NS_LOG_COMPONENT_DEFINE ("MeshWifiInterfaceMac"); @@ -62,18 +63,7 @@ MeshWifiInterfaceMac::GetTypeId () &MeshWifiInterfaceMac::GetBeaconGeneration ), MakeBooleanChecker () - ) - - .AddAttribute ("BE", "The DcaTxop object", - PointerValue (), - MakePointerAccessor (&MeshWifiInterfaceMac::GetBE, - &MeshWifiInterfaceMac::SetBE), - MakePointerChecker ()) - .AddAttribute ("VO", "The DcaTxop object", - PointerValue (), - MakePointerAccessor (&MeshWifiInterfaceMac::GetVO, - &MeshWifiInterfaceMac::SetVO), - MakePointerChecker ()); + ); return tid; } @@ -199,10 +189,8 @@ MeshWifiInterfaceMac::SetWifiRemoteStationManager (Ptr { NS_LOG_FUNCTION (this << stationManager); m_stationManager = stationManager; - NS_ASSERT(m_BE != 0); - m_BE->SetWifiRemoteStationManager (stationManager); - NS_ASSERT(m_VO != 0); - m_VO->SetWifiRemoteStationManager (stationManager); + for (Queues::const_iterator i = m_queues.begin (); i != m_queues.end (); i ++) + i->second->SetWifiRemoteStationManager (stationManager); m_beaconDca->SetWifiRemoteStationManager (stationManager); m_low->SetWifiRemoteStationManager (stationManager); } @@ -293,8 +281,7 @@ MeshWifiInterfaceMac::DoDispose () m_low = 0; m_dcfManager = 0; m_phy = 0; - m_BE = 0; - m_VO = 0; + m_queues.clear (); m_beaconSendEvent.Cancel (); m_beaconDca = 0; @@ -387,6 +374,11 @@ MeshWifiInterfaceMac::ForwardDown (Ptr const_packet, Mac48Address hdr.SetAddr4 (from); hdr.SetDsFrom (); hdr.SetDsTo (); + // Fill QoS fields: + hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK); + hdr.SetQosNoEosp (); + hdr.SetQosNoAmsdu (); + hdr.SetQosTxopLimit (0); // Address 1 is unknwon here. Routing plugin is responsible to correctly set it. hdr.SetAddr1 (Mac48Address ()); @@ -414,9 +406,16 @@ MeshWifiInterfaceMac::ForwardDown (Ptr const_packet, Mac48Address } destination->RecordDisassociated (); } + //Classify: application sets a tag, which is removed here + // Get Qos tag: + AccessClass ac = AC_BE; + QosTag tag; + if(packet->RemovePacketTag (tag)) + ac = QosUtilsMapTidToAc (tag.Get ()); m_stats.sentFrames ++; m_stats.sentBytes += packet->GetSize (); - m_BE->Queue (packet, hdr); + NS_ASSERT(m_queues.find(ac) != m_queues.end ()); + m_queues[ac]->Queue (packet, hdr); } void @@ -431,7 +430,12 @@ MeshWifiInterfaceMac::SendManagementFrame (Ptr packet, const WifiMacHead } m_stats.sentFrames ++; m_stats.sentBytes += packet->GetSize (); - m_VO->Queue (packet, header); + Queues::iterator i = m_queues.find (AC_VO); + if (i == m_queues.end ()) + { + NS_FATAL_ERROR("Voice queue is not set up!"); + } + m_queues[AC_VO]->Queue (packet, header); } SupportedRates @@ -606,6 +610,9 @@ MeshWifiInterfaceMac::Receive (Ptr packet, WifiMacHeader const *hdr) if (drop) return; // plugin drops frame } + // Check if QoS tag exists and add it: + if (hdr->IsQosData ()) + packet->AddPacketTag (QosTag (hdr->GetQosTid ())); // Forward data up if (hdr->IsData ()) ForwardUp (packet, hdr->GetAddr4(), hdr->GetAddr3()); @@ -671,28 +678,28 @@ MeshWifiInterfaceMac::ResetStats () m_stats = Statistics::Statistics (); } void -MeshWifiInterfaceMac::SetBE (Ptr dcaTxop) +MeshWifiInterfaceMac::SetQueue (Ptr queue, AccessClass ac) { - m_BE = dcaTxop; - m_BE->SetLow (m_low); - m_BE->SetManager (m_dcfManager); -} -void -MeshWifiInterfaceMac::SetVO (Ptr dcaTxop) -{ - m_VO = dcaTxop; - m_VO->SetLow (m_low); - m_VO->SetManager (m_dcfManager); + Queues::iterator i = m_queues.find(ac); + if(i != m_queues.end ()) + { + NS_LOG_WARN("Queue is already set!"); + return; + } + m_queues.insert (std::make_pair(ac, queue)); + m_queues[ac]->SetLow (m_low); + m_queues[ac]->SetManager (m_dcfManager); } Ptr -MeshWifiInterfaceMac::GetBE () const +MeshWifiInterfaceMac::GetQueue (AccessClass ac) { - return m_BE; -} -Ptr -MeshWifiInterfaceMac::GetVO () const -{ - return m_VO; + Queues::iterator i = m_queues.find(ac); + if(i != m_queues.end ()) + { + NS_LOG_WARN("Queue is not found! Check access class!"); + return 0; + } + return i->second; } } // namespace ns3 diff --git a/src/devices/mesh/mesh-wifi-interface-mac.h b/src/devices/mesh/mesh-wifi-interface-mac.h index 0fafd04b8..a0b0db406 100644 --- a/src/devices/mesh/mesh-wifi-interface-mac.h +++ b/src/devices/mesh/mesh-wifi-interface-mac.h @@ -33,7 +33,7 @@ #include "ns3/wifi-mac.h" #include "ns3/mesh-wifi-interface-mac-plugin.h" #include "ns3/event-id.h" - +#include "qos-utils.h" namespace ns3 { class WifiMacHeader; @@ -160,11 +160,9 @@ public: void ResetStats (); /// Enable/disable beacons void SetBeaconGeneration (bool enable); + void SetQueue (Ptr queue, AccessClass ac); private: - Ptr GetBE(void) const; - void SetBE (Ptr dcaTxop); - Ptr GetVO(void) const; - void SetVO (Ptr dcaTxop); + Ptr GetQueue (AccessClass ac); /// Frame receive handler void Receive (Ptr packet, WifiMacHeader const *hdr); /// Forward frame to mesh point @@ -183,10 +181,8 @@ private: private: ///\name Wifi MAC internals //\{ - Ptr m_BE; - Ptr m_BK; - Ptr m_VI; - Ptr m_VO; + typedef std::map > Queues; + Queues m_queues; Ptr m_beaconDca; Ptr m_stationManager; Ptr m_phy; diff --git a/src/devices/wifi/qos-tag.cc b/src/devices/wifi/qos-tag.cc index 98bed65b6..2010be3c1 100644 --- a/src/devices/wifi/qos-tag.cc +++ b/src/devices/wifi/qos-tag.cc @@ -43,7 +43,11 @@ QosTag::GetInstanceTypeId (void) const return GetTypeId (); } -QosTag::QosTag() +QosTag::QosTag (): + m_tid (0) +{} +QosTag::QosTag (uint8_t tid): + m_tid (tid) {} uint32_t diff --git a/src/devices/wifi/qos-tag.h b/src/devices/wifi/qos-tag.h index 51f13a908..1e8ab9dac 100644 --- a/src/devices/wifi/qos-tag.h +++ b/src/devices/wifi/qos-tag.h @@ -33,6 +33,7 @@ public: virtual TypeId GetInstanceTypeId (void) const; QosTag (); + QosTag (uint8_t tid); virtual void Serialize (TagBuffer i) const; virtual void Deserialize (TagBuffer i); virtual uint32_t GetSerializedSize () const; diff --git a/src/devices/wifi/qos-utils.cc b/src/devices/wifi/qos-utils.cc index 8effbe1ab..ff6c3a102 100644 --- a/src/devices/wifi/qos-utils.cc +++ b/src/devices/wifi/qos-utils.cc @@ -28,30 +28,23 @@ QosUtilsMapTidToAc (uint8_t tid) switch (tid) { case 0 : return AC_BE; - break; case 1 : return AC_BK; - break; case 2 : return AC_BK; - break; case 3 : return AC_BE; - break; case 4 : return AC_VI; - break; case 5 : return AC_VI; - break; case 6 : return AC_VO; - break; case 7 : return AC_VO; - break; + default: + return AC_BE; } - return AC_UNDEF; } uint8_t diff --git a/src/helper/mesh-interface-helper.cc b/src/helper/mesh-interface-helper.cc index a9b90719d..0064f887a 100644 --- a/src/helper/mesh-interface-helper.cc +++ b/src/helper/mesh-interface-helper.cc @@ -28,8 +28,15 @@ namespace ns3 { MeshInterfaceHelper::MeshInterfaceHelper () { - m_Be.SetTypeId ("ns3::DcaTxop"); - m_Vo.SetTypeId ("ns3::DcaTxop"); + m_queues.insert (std::make_pair (AC_VO, ObjectFactory ())); + m_queues.insert (std::make_pair (AC_VI, ObjectFactory ())); + m_queues.insert (std::make_pair (AC_BE, ObjectFactory ())); + m_queues.insert (std::make_pair (AC_BK, ObjectFactory ())); + + m_queues[AC_VO].SetTypeId ("ns3::DcaTxop"); + m_queues[AC_VI].SetTypeId ("ns3::DcaTxop"); + m_queues[AC_BE].SetTypeId ("ns3::DcaTxop"); + m_queues[AC_BK].SetTypeId ("ns3::DcaTxop"); } MeshInterfaceHelper::~MeshInterfaceHelper () @@ -40,14 +47,6 @@ MeshInterfaceHelper::Default (void) { MeshInterfaceHelper helper; helper.SetType (); - helper.SetBeParameters ( - "MinCw", UintegerValue (15), - "MaxCw", UintegerValue (255), - "Aifsn", UintegerValue (2)); - helper.SetVoParameters ( - "MinCw", UintegerValue (3), - "MaxCw", UintegerValue (7), - "Aifsn", UintegerValue (2)); helper.SetRemoteStationManager ("ns3::ArfWifiManager"); return helper; } @@ -73,26 +72,24 @@ MeshInterfaceHelper::SetType (std::string n0, const AttributeValue &v0, m_mac.Set (n7, v7); } void -MeshInterfaceHelper::SetBeParameters (std::string n0, const AttributeValue &v0, - std::string n1, const AttributeValue &v1, - std::string n2, const AttributeValue &v2, - std::string n3, const AttributeValue &v3) +MeshInterfaceHelper::SetQueueParameters ( AccessClass ac, + std::string n0, const AttributeValue &v0, + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3) { - m_Be.Set (n0, v0); - m_Be.Set (n1, v1); - m_Be.Set (n2, v2); - m_Be.Set (n3, v3); -} -void -MeshInterfaceHelper::SetVoParameters (std::string n0, const AttributeValue &v0, - std::string n1, const AttributeValue &v1, - std::string n2, const AttributeValue &v2, - std::string n3, const AttributeValue &v3) -{ - m_Vo.Set (n0, v0); - m_Vo.Set (n1, v1); - m_Vo.Set (n2, v2); - m_Vo.Set (n3, v3); + std::map::iterator queue = m_queues.find (ac); + if (queue != m_queues.end ()) + { + queue->second.Set (n0, v0); + queue->second.Set (n1, v1); + queue->second.Set (n2, v2); + queue->second.Set (n3, v3); + } + else + { + NS_FATAL_ERROR ("Queue is not set!"); + } } void MeshInterfaceHelper::SetRemoteStationManager (std::string type, @@ -137,11 +134,12 @@ MeshInterfaceHelper::CreateInterface (const WifiPhyHelper &phyHelper, Ptr Ptr MeshInterfaceHelper::Create (void) const { - Ptr mac = m_mac.Create (); - Ptr be = m_Be.Create (); - Ptr vo = m_Vo.Create (); - mac->SetAttribute ("BE", PointerValue (be)); - mac->SetAttribute ("VO", PointerValue (vo)); + Ptr mac = m_mac.Create (); + for (std::map::const_iterator i = m_queues.begin (); i != m_queues.end (); i ++) + { + //Ptr dca = i->second->Create (); + mac->SetQueue(i->second.Create (), i->first); + } return mac; } void diff --git a/src/helper/mesh-interface-helper.h b/src/helper/mesh-interface-helper.h index a67b8664e..57dada134 100644 --- a/src/helper/mesh-interface-helper.h +++ b/src/helper/mesh-interface-helper.h @@ -23,6 +23,7 @@ #include "ns3/wifi-helper.h" #include "ns3/wifi-net-device.h" #include "ns3/mesh-wifi-interface-mac.h" +#include "ns3/qos-utils.h" namespace ns3 { class MeshInterfaceHelper : public WifiMacHelper @@ -51,23 +52,16 @@ public: std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); /** + * \param ac is access class of the queue to be adjusted * \param type the type of ns3::WifiMac to create. * \param n%d the name of the attribute to set * \param v%d the value of the attribute to set */ - void SetBeParameters ( std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), - std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), - std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), - std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue ()); - /** - * \param type the type of ns3::WifiMac to create. - * \param n%d the name of the attribute to set - * \param v%d the value of the attribute to set - */ - void SetVoParameters ( std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), - std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), - std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), - std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue ()); + void SetQueueParameters (AccessClass ac, + std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), + std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), + std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), + std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue ()); /** * \param type the type of ns3::WifiRemoteStationManager to create. * \param n%d the name of the attribute to set @@ -104,8 +98,7 @@ private: Ptr Create (void) const; ObjectFactory m_mac; - ObjectFactory m_Be; - ObjectFactory m_Vo; + std::map m_queues; ObjectFactory m_stationManager; };