From 39bf7627614a104aa0b010c1fb60b5e54afabc81 Mon Sep 17 00:00:00 2001 From: Kirill Andreev Date: Wed, 1 Apr 2009 16:21:24 +0400 Subject: [PATCH] Reactive HWMP is ported! --- src/devices/mesh/dot11s/hwmp-mac-plugin.cc | 167 ++++++++------------- src/devices/mesh/dot11s/hwmp-mac-plugin.h | 84 ++--------- src/devices/mesh/dot11s/hwmp-protocol.cc | 54 ++++++- src/devices/mesh/dot11s/hwmp-protocol.h | 3 +- src/devices/mesh/dot11s/ie-dot11s-perr.cc | 19 ++- src/devices/mesh/dot11s/ie-dot11s-perr.h | 9 +- 6 files changed, 144 insertions(+), 192 deletions(-) diff --git a/src/devices/mesh/dot11s/hwmp-mac-plugin.cc b/src/devices/mesh/dot11s/hwmp-mac-plugin.cc index 8ec1504f8..0ee3df431 100644 --- a/src/devices/mesh/dot11s/hwmp-mac-plugin.cc +++ b/src/devices/mesh/dot11s/hwmp-mac-plugin.cc @@ -30,13 +30,13 @@ #include "hwmp-tag.h" #include "ie-dot11s-preq.h" #include "ie-dot11s-prep.h" -#include "ie-dot11s-perr.h" namespace ns3 { namespace dot11s { NS_LOG_COMPONENT_DEFINE ("HwmpMacPlugin"); -HwmpMacPlugin::HwmpMacPlugin (uint32_t ifIndex, Ptr protocol) +HwmpMacPlugin::HwmpMacPlugin (uint32_t ifIndex, Ptr protocol): + m_myPreq (m_preqQueue.end()) { m_ifIndex = ifIndex; m_protocol = protocol; @@ -144,7 +144,6 @@ HwmpMacPlugin::UpdateOutcomingFrame (Ptr packet, WifiMacHeader & header, } #if 0 HwmpMacPlugin::HwmpMacPlugin (): - m_myPreq (m_preqQueue.end()), { } @@ -243,53 +242,6 @@ HwmpMacPlugin::SendPathError (std::vector destina m_perrTimer = Simulator::Schedule (dot11sParameters::dot11MeshHWMPperrMinInterval,&HwmpMacPlugin::SendOnePerr,this); } } -//needed to fill routing information structure - -void -HwmpMacPlugin::ReceivePrep (IeDot11sPrep& prep, const Mac48Address& from, const uint32_t& metric) -{ - if (m_disabled) - return; - prep.DecrementTtl (); - prep.IncrementMetric (metric); - //acceptance cretirea: - std::map::iterator i = m_dsnDatabase.find (prep.GetDestinationAddress()); - if (i == m_dsnDatabase.end ()) - { - m_dsnDatabase[prep.GetDestinationAddress ()] = prep.GetDestinationSeqNumber(); - } - else - if (i->second > prep.GetDestinationSeqNumber ()) - return; - //update routing info - HwmpRtable::LookupResult result = m_requestRouteCallback (prep.GetDestinationAddress()); - if (result.retransmitter == Mac48Address::GetBroadcast ()) - //try to look for default route - result = m_requestRootPathCallback (m_ifIndex); - if ((result.retransmitter == Mac48Address::GetBroadcast ())&&(m_address != prep.GetDestinationAddress())) - return; - INFO newInfo; - newInfo.me = m_address; - newInfo.destination = prep.GetOriginatorAddress (); - newInfo.source = prep.GetDestinationAddress (); - newInfo.nextHop = from; - newInfo.metric = prep.GetMetric (); - newInfo.lifetime = TU_TO_TIME (prep.GetLifetime()); - newInfo.outPort = m_ifIndex; - newInfo.dsn = prep.GetOriginatorSeqNumber (); - newInfo.prevHop = result.retransmitter; - newInfo.type = INFO_PREP; - NS_LOG_DEBUG ("Path to "<GetPreqMinInterval (), &HwmpMacPlugin::SendOnePreq, this); } void +HwmpMacPlugin::SendPerr() +{ + if(m_perrTimer.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 (), &HwmpMacPlugin::SendPerr, this); +//Create packet + Ptr packet = Create (); + packet->AddHeader(m_myPerr.perr); + //Multihop action header: + WifiMeshMultihopActionHeader multihopHdr; + WifiMeshMultihopActionHeader::ACTION_VALUE action; + action.pathSelection = WifiMeshMultihopActionHeader::PATH_ERROR; + multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PATH_SELECTION, action); + packet->AddHeader (multihopHdr); + //Mesh header + WifiMeshHeader meshHdr; + meshHdr.SetMeshTtl (m_protocol->GetMaxTtl ()); + //TODO: should seqno be here? + meshHdr.SetMeshSeqno (0); + meshHdr.SetAddressExt(1); + meshHdr.SetAddr4(m_protocol->GetAddress ()); + packet->AddHeader (meshHdr); + //create 802.11 header: + WifiMacHeader hdr; + hdr.SetMultihopAction (); + hdr.SetDsNotFrom (); + hdr.SetDsNotTo (); + hdr.SetAddr2 (m_parent->GetAddress ()); + hdr.SetAddr3 (Mac48Address::GetBroadcast ()); + //Send Management frame + for(std::vector::iterator i = m_myPerr.receivers.begin (); i != m_myPerr.receivers.end (); i ++) + { + hdr.SetAddr1 (*i); + m_parent->SendManagementFrame(packet, hdr); + } + m_myPerr.perr.ResetPerr (); + m_myPerr.receivers.clear (); +} +void HwmpMacPlugin::SendPrep (IePrep prep, Mac48Address receiver) { //Create packet @@ -393,41 +360,25 @@ HwmpMacPlugin::SendPrep (IePrep prep, Mac48Address receiver) hdr.SetDsNotTo (); hdr.SetAddr1 (receiver); hdr.SetAddr2 (m_parent->GetAddress ()); - hdr.SetAddr3 (Mac48Address::GetBroadcast ()); + hdr.SetAddr3 (prep.GetDestinationAddress ()); //Send Management frame NS_LOG_UNCOND("Sending PREP"); m_parent->SendManagementFrame(packet, hdr); } -#if 0 void -HwmpMacPlugin::SendPrep (Mac48Address dst, - Mac48Address src, - Mac48Address retransmitter, - uint32_t initMetric, - uint32_t dsn, - uint32_t originatorDsn, - uint32_t lifetime) +HwmpMacPlugin::SendOnePerr(IePerr perr, std::vector receivers) { - IeDot11sPrep prep; - prep.SetHopcount (0); - prep.SetTTL (m_maxTtl); - prep.SetDestinationAddress (dst); - prep.SetDestinationSeqNumber (dsn); - prep.SetLifetime (lifetime); - prep.SetMetric (0); - prep.SetOriginatorAddress (src); - prep.SetOriginatorSeqNumber (originatorDsn); - //m_prepCallback (prep, retransmitter); + m_myPerr.perr.Merge(perr); + for(unsigned int i = 0; i < receivers.size (); 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]); + } + SendPerr (); } - -void -HwmpMacPlugin::SendOnePerr () -{ - if (m_myPerr.GetNumOfDest () == 0) - return; - m_perrCallback (m_myPerr, m_myPerrReceivers); - m_myPerr.ResetPerr (); -} -#endif } //namespace dot11s }//namespace ns3 diff --git a/src/devices/mesh/dot11s/hwmp-mac-plugin.h b/src/devices/mesh/dot11s/hwmp-mac-plugin.h index dc06c1501..d4516b7bb 100644 --- a/src/devices/mesh/dot11s/hwmp-mac-plugin.h +++ b/src/devices/mesh/dot11s/hwmp-mac-plugin.h @@ -23,6 +23,7 @@ #define HWMP_STATE_H #include "ns3/mesh-wifi-interface-mac-plugin.h" +#include "ie-dot11s-perr.h" namespace ns3 { @@ -61,13 +62,13 @@ private: //\{ void SendPreq(IePreq preq); void SendPrep(IePrep prep, Mac48Address receiver); - void SendPerr(IePerr perr, std::vector receivers); + void SendOnePerr(IePerr perr, std::vector receivers); void RequestDestination (Mac48Address dest); //\} /// Sends one PREQ when PreqMinInterval after last PREQ expires (if any PREQ exists in rhe queue) void SendOnePreq (); - + void SendPerr (); private: Ptr m_parent; uint32_t m_ifIndex; @@ -79,66 +80,20 @@ private: std::vector m_preqQueue; std::vector::iterator m_myPreq; //\} + ///\name PERR timer and stored path error + //{ + EventId m_perrTimer; + struct MyPerr { + IePerr perr; + std::vector receivers; + }; + MyPerr m_myPerr; }; #if 0 class HwmpMacPlugin : public MeshWifiInterfaceMacPlugin { public: - static TypeId GetTypeId (); - HwmpMacPlugin (); - ~HwmpMacPlugin (); - - /** - * \brief Interface with HWMP - Hwmp can only - * request address and collect routing - * information - */ - void SetRequestRouteCallback ( - Callback cb); - void SetRequestRootPathCallback ( - Callback cb); - - enum InfoType { - INFO_PREQ, - INFO_PREP, - INFO_PERR, - INFO_PROACTIVE, - INFO_NEW_PEER, - INFO_FAILED_PEER - }; - typedef struct RoutingInfo { - Mac48Address me; - Mac48Address destination; - Mac48Address source; - Mac48Address nextHop; - Mac48Address prevHop; - uint32_t outPort; - uint32_t metric; - std::vector failedDestinations; - uint32_t dsn; - Time lifetime; - enum InfoType type; - } INFO; - void SetRoutingInfoCallback ( - Callback cb - ); - void SetRetransmittersOfPerrCallback ( - Callback, std::vector, uint32_t> cb); - void SendPathError (std::vector destinations); - void SetAssociatedIfaceId (uint32_t interface); - uint32_t GetAssociatedIfaceId (); - //Mac interaction: - void SetMac (Ptr mac); - void SetSendPreqCallback ( - Callback cb); - void SetSendPrepCallback ( - Callback cb); - void SetSendPerrCallback ( - Callback > cb); - void ReceivePreq (IeDot11sPreq&, const Mac48Address& from, const uint32_t& metric); - void ReceivePrep (IeDot11sPrep&, const Mac48Address& from, const uint32_t& metric); - void ReceivePerr (IeDot11sPerr&, const Mac48Address& from); -private: + private: //true means that we can add a destination to //existing PREQ element //False means that we must send @@ -171,22 +126,9 @@ private: //Proactive PREQ mechanism: EventId m_proactivePreqTimer; void SendProactivePreq (); - /** - * \brief Two PERRs may not be sent closer to - * each other than - * dot11MeshHWMPperrMinInterval, so, each HWMP - * state collects all unreachable destinations - * and once in dot11MeshHWMPperrMinInterval - * should send PERR, and PERR element should - * be cleared - */ - IeDot11sPerr m_myPerr; - std::vector m_myPerrReceivers; - void AddPerrReceiver (Mac48Address receiver); + IeDot11sPerr m_myPerr; EventId m_perrTimer; void SendOnePerr (); - //Configurable parameters: - uint8_t m_maxTtl; }; #endif } //namespace dot11s diff --git a/src/devices/mesh/dot11s/hwmp-protocol.cc b/src/devices/mesh/dot11s/hwmp-protocol.cc index 9489de557..5b00d2950 100644 --- a/src/devices/mesh/dot11s/hwmp-protocol.cc +++ b/src/devices/mesh/dot11s/hwmp-protocol.cc @@ -225,7 +225,8 @@ HwmpProtocol::ForwardUnicast(uint32_t sourceIface, const Mac48Address source, c result = m_rtable->LookupProactiveExpired (); if((result.retransmitter == Mac48Address::GetBroadcast ()) && (!m_isRoot)) return false; - MakePathError (result.retransmitter); + std::vector destinations = m_rtable->GetUnreachableDestinations (result.retransmitter); + MakePathError (destinations); if(!m_isRoot) return false; } @@ -421,6 +422,28 @@ HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface) void HwmpProtocol::ReceivePerr (IePerr perr, Mac48Address from, uint32_t interface) { + //Acceptance cretirea: + NS_LOG_UNCOND("I am "< destinations = perr.GetAddressUnitVector (); + HwmpRtable::LookupResult result; + for(unsigned int i = 0; i < destinations.size (); i ++) + { + result = m_rtable->LookupReactive (destinations[i].destination); + NS_LOG_UNCOND("Destination = "< destinations = m_rtable->GetUnreachableDestinations (retransmitter); //HwmpRtable increments a sequence number as written in 11B.9.7.2 NS_LOG_UNCOND("Number of unreachable destinations:"<::iterator i = destinations.begin (); i != destinations.end (); i ++) @@ -604,7 +629,20 @@ HwmpProtocol::MakePathError (Mac48Address retransmitter) NS_LOG_UNCOND("Address:"<second<<", interface:"<first); //form a path error and send it to proper ports IePerr perr; - NS_ASSERT(false); + for(unsigned int i = 0; i < destinations.size (); i ++) + { + perr.AddAddressUnit(destinations[i]); + m_rtable->DeleteReactivePath(destinations[i].destination); + } + for(HwmpPluginMap::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->SendOnePerr (perr, receivers_for_interface); + } + } std::vector > HwmpProtocol::GetPerrReceivers (std::vector failedDest) @@ -766,6 +804,7 @@ HwmpProtocol::RetryPathDiscovery (Mac48Address dst, uint8_t numOfRetry) { i->second->RequestDestination(dst); i->second->RequestDestination(Mac48Address("00:00:00:00:00:10")); + i->second->RequestDestination(Mac48Address("00:00:00:00:00:24")); } m_preqTimeouts[dst] = Simulator::Schedule ( MilliSeconds (2*(m_dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())), @@ -847,6 +886,11 @@ HwmpProtocol::GetActivePathLifetime () { return m_dot11MeshHWMPactivePathTimeout.GetMicroSeconds () / 1024; } +uint8_t +HwmpProtocol::GetUnicastPerrThreshold() +{ + return m_unicastPerrThreshold; +} Mac48Address HwmpProtocol::GetAddress () { diff --git a/src/devices/mesh/dot11s/hwmp-protocol.h b/src/devices/mesh/dot11s/hwmp-protocol.h index 8d99812a0..21ff18de3 100644 --- a/src/devices/mesh/dot11s/hwmp-protocol.h +++ b/src/devices/mesh/dot11s/hwmp-protocol.h @@ -92,7 +92,7 @@ private: uint32_t interface); ///\brief forms a path error information element when list of destination fails on a given interface - void MakePathError (Mac48Address peerAddress); + void MakePathError (std::vector destinations); /// \return list of addresses where a PERR should be sent to std::vector > GetPerrReceivers (std::vector failedDest); @@ -204,6 +204,7 @@ private: uint32_t GetNextPreqId (); uint32_t GetNextHwmpSeqno (); uint32_t GetActivePathLifetime (); + uint8_t GetUnicastPerrThreshold (); //\} Callback , uint32_t> m_neighboursCallback; }; diff --git a/src/devices/mesh/dot11s/ie-dot11s-perr.cc b/src/devices/mesh/dot11s/ie-dot11s-perr.cc index b015769aa..0cc1f9203 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-perr.cc +++ b/src/devices/mesh/dot11s/ie-dot11s-perr.cc @@ -107,7 +107,7 @@ IePerr::AddAddressUnit (FailedDestination unit) } std::vector -IePerr::GetAddressUnitVector () +IePerr::GetAddressUnitVector () const { return m_addressUnits; } @@ -115,14 +115,27 @@ void IePerr::DeleteAddressUnit (Mac48Address address) { for (std::vector::iterator i = m_addressUnits.begin (); i != m_addressUnits.end(); i ++) - if ((*i).destination == address) + 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 () { diff --git a/src/devices/mesh/dot11s/ie-dot11s-perr.h b/src/devices/mesh/dot11s/ie-dot11s-perr.h index 2b3a28e87..77f1155e0 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-perr.h +++ b/src/devices/mesh/dot11s/ie-dot11s-perr.h @@ -45,10 +45,11 @@ public: }; uint8_t GetNumOfDest (); - void AddAddressUnit (struct FailedDestination unit); - std::vector GetAddressUnitVector (); - void DeleteAddressUnit (Mac48Address address); - void ResetPerr (); + void AddAddressUnit (struct FailedDestination unit); + std::vector GetAddressUnitVector () const; + void DeleteAddressUnit (Mac48Address address); + void Merge(const IePerr perr); + void ResetPerr (); private: WifiElementId ElementId () const{ return IE11S_PERR;