diff --git a/src/devices/mesh/dot11s/hwmp-protocol-mac.cc b/src/devices/mesh/dot11s/hwmp-protocol-mac.cc index 0e0a8bae2..c999831f2 100644 --- a/src/devices/mesh/dot11s/hwmp-protocol-mac.cc +++ b/src/devices/mesh/dot11s/hwmp-protocol-mac.cc @@ -102,11 +102,11 @@ HwmpProtocolMac::ReceiveAction (Ptr packet, const WifiMacHeader & header IePreq preq; IePrep prep; IePerr perr; - while (packet->RemoveHeader(rann)) + while (packet->RemoveHeader (rann)) { NS_LOG_WARN("RANN is not supported!"); } - while (packet->RemoveHeader(preq)) + while (packet->RemoveHeader (preq)) { m_stats.rxPreq ++; if (preq.GetOriginatorAddress () == m_protocol->GetAddress ()) @@ -116,7 +116,7 @@ HwmpProtocolMac::ReceiveAction (Ptr packet, const WifiMacHeader & header preq.DecrementTtl (); m_protocol->ReceivePreq (preq, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (), m_parent->GetLinkMetric(header.GetAddr2 ())); } - while (packet->RemoveHeader(prep)) + while (packet->RemoveHeader (prep)) { m_stats.rxPrep ++; if (prep.GetTtl () == 0) @@ -124,11 +124,17 @@ HwmpProtocolMac::ReceiveAction (Ptr packet, const WifiMacHeader & header prep.DecrementTtl (); m_protocol->ReceivePrep (prep, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (), m_parent->GetLinkMetric(header.GetAddr2 ())); } - while(packet->RemoveHeader(perr)) + std::vector failedDestinations; + while (packet->RemoveHeader (perr)) { m_stats.rxPerr ++; - m_protocol->ReceivePerr (perr, header.GetAddr2 (), m_ifIndex, header.GetAddr3 ()); + 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; } @@ -156,10 +162,10 @@ 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 @@ -175,8 +181,18 @@ void HwmpProtocolMac::SendPreq(IePreq preq) { NS_LOG_FUNCTION_NOARGS (); + std::vector preq_vector; + preq_vector.push_back(preq); + SendPreq(preq_vector); +} +void +HwmpProtocolMac::SendPreq(std::vector preq) +{ Ptr packet = Create (); - packet->AddHeader(preq); + for(std::vector::const_iterator i = preq.begin (); i != preq.end (); i ++) + { + packet->AddHeader (*i); + } packet->AddHeader (GetWifiMeshActionHeader ()); //create 802.11 header: WifiMacHeader hdr; @@ -200,16 +216,22 @@ void HwmpProtocolMac::RequestDestination (Mac48Address dst, uint32_t originator_seqno, uint32_t dst_seqno) { NS_LOG_FUNCTION_NOARGS (); - if(m_myPreq.GetDestCount () == 0) + for(std::vector::iterator i = m_myPreq.begin (); i != m_myPreq.end(); i ++) { - m_myPreq.SetHopcount (0); - m_myPreq.SetTTL (m_protocol->GetMaxTtl ()); - m_myPreq.SetPreqID (m_protocol->GetNextPreqId ()); - m_myPreq.SetOriginatorAddress (m_protocol->GetAddress ()); - m_myPreq.SetOriginatorSeqNumber (originator_seqno); - m_myPreq.SetLifetime (m_protocol->GetActivePathLifetime ()); + if(i->IsFull ()) + continue; + NS_ASSERT (i->GetDestCount () > 0); + i->AddDestinationAddressElement (m_protocol->GetDoFlag(), m_protocol->GetRfFlag(), dst, dst_seqno); } - m_myPreq.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 @@ -218,13 +240,13 @@ HwmpProtocolMac::SendMyPreq () NS_LOG_FUNCTION_NOARGS (); if(m_preqTimer.IsRunning ()) return; - if(m_myPreq.GetDestCount () == 0) + 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.ClearDestinationAddressElements (); + m_myPreq.clear (); } void HwmpProtocolMac::SendPrep (IePrep prep, Mac48Address receiver) @@ -232,7 +254,7 @@ HwmpProtocolMac::SendPrep (IePrep prep, Mac48Address receiver) NS_LOG_FUNCTION_NOARGS (); //Create packet Ptr packet = Create (); - packet->AddHeader(prep); + packet->AddHeader (prep); packet->AddHeader (GetWifiMeshActionHeader ()); //create 802.11 header: WifiMacHeader hdr; @@ -249,11 +271,23 @@ HwmpProtocolMac::SendPrep (IePrep prep, Mac48Address receiver) m_parent->SendManagementFrame(packet, hdr); } void -HwmpProtocolMac::ForwardPerr(IePerr perr, std::vector receivers) +HwmpProtocolMac::ForwardPerr(std::vector failedDestinations, std::vector receivers) { NS_LOG_FUNCTION_NOARGS (); Ptr packet = Create (); - packet->AddHeader(perr); + IePerr perr; + for(std::vector::const_iterator i = failedDestinations.begin (); i != failedDestinations.end (); i ++) + { + if(!perr.IsFull ()) + perr.AddAddressUnit (*i); + else + { + packet->AddHeader (perr); + perr.ResetPerr (); + } + } + if(perr.GetNumOfDest () > 0) + packet->AddHeader (perr); packet->AddHeader (GetWifiMeshActionHeader ()); //create 802.11 header: WifiMacHeader hdr; @@ -278,17 +312,37 @@ HwmpProtocolMac::ForwardPerr(IePerr perr, std::vector receivers) } } void -HwmpProtocolMac::InitiatePerr (IePerr perr, std::vector receivers) +HwmpProtocolMac::InitiatePerr (std::vector failedDestinations, std::vector receivers) { - m_myPerr.perr.Merge(perr); - for(unsigned int i = 0; i < receivers.size (); i ++) + //All duplicates in PERR are checked here, and there is no reason to + //check it at any athoer place { - bool should_add = true; - for (unsigned int j = 0; j < m_myPerr.receivers.size (); j ++) - if(receivers[i] == m_myPerr.receivers[j]) - should_add = false; - if(should_add) - m_myPerr.receivers.push_back(receivers[i]); + 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 (); } @@ -299,8 +353,8 @@ HwmpProtocolMac::SendMyPerr() if(m_perrTimer.IsRunning ()) return; m_perrTimer = Simulator::Schedule (m_protocol->GetPerrMinInterval (), &HwmpProtocolMac::SendMyPerr, this); - ForwardPerr (m_myPerr.perr, m_myPerr.receivers); - m_myPerr.perr.ResetPerr (); + ForwardPerr (m_myPerr.destinations, m_myPerr.receivers); + m_myPerr.destinations.clear (); m_myPerr.receivers.clear (); } uint32_t diff --git a/src/devices/mesh/dot11s/hwmp-protocol-mac.h b/src/devices/mesh/dot11s/hwmp-protocol-mac.h index 3e4f7c5fe..8ea1c4d65 100644 --- a/src/devices/mesh/dot11s/hwmp-protocol-mac.h +++ b/src/devices/mesh/dot11s/hwmp-protocol-mac.h @@ -63,12 +63,13 @@ private: static WifiMeshActionHeader GetWifiMeshActionHeader (); ///\name Intercation with HWMP: //\{ - void SendPreq(IePreq preq); - void SendPrep(IePrep prep, Mac48Address receiver); + void SendPreq (IePreq preq); + void SendPreq (std::vector preq); + void SendPrep (IePrep prep, Mac48Address receiver); //Forward a peth error - void ForwardPerr(IePerr perr, std::vector receivers); + void ForwardPerr(std::vector destinations, std::vector receivers); // initiate my own path error - void InitiatePerr(IePerr perr, std::vector receivers); + 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 @@ -96,13 +97,13 @@ private: ///\name my PREQ and PREQ timer: //\{ EventId m_preqTimer; - IePreq m_myPreq; + 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 422e3ee93..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"); @@ -559,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; - ForwardPathError (MakePathError (destinations)); + ForwardPathError (MakePathError (retval)); } void HwmpProtocol::SendPrep ( @@ -675,7 +671,7 @@ HwmpProtocol::MakePathError (std::vector destinations m_stats.initiatedPerr ++; for(unsigned int i = 0; i < destinations.size (); i ++) { - retval.perr.AddAddressUnit(destinations[i]); + retval.destinations.push_back(destinations[i]); m_rtable->DeleteReactivePath(destinations[i].destination); } return retval; @@ -689,7 +685,7 @@ HwmpProtocol::InitiatePathError(PathError perr) 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.perr, receivers_for_interface); + i->second->InitiatePerr (perr.destinations, receivers_for_interface); } } void @@ -701,7 +697,7 @@ HwmpProtocol::ForwardPathError(PathError perr) 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.perr, receivers_for_interface); + i->second->ForwardPerr (perr.destinations, receivers_for_interface); } } diff --git a/src/devices/mesh/dot11s/hwmp-protocol.h b/src/devices/mesh/dot11s/hwmp-protocol.h index c9f8e3ba9..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, @@ -106,7 +106,7 @@ private: */ struct PathError { - IePerr perr; + std::vector destinations; /// interface-address std::vector > receivers; }; diff --git a/src/devices/mesh/dot11s/ie-dot11s-perr.cc b/src/devices/mesh/dot11s/ie-dot11s-perr.cc index 1c7c17430..8264f134d 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-perr.cc +++ b/src/devices/mesh/dot11s/ie-dot11s-perr.cc @@ -119,20 +119,6 @@ IePerr::DeleteAddressUnit (Mac48Address address) } } 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_addressUnits.clear (); @@ -178,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 b1220d850..99606900a 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-perr.h +++ b/src/devices/mesh/dot11s/ie-dot11s-perr.h @@ -47,7 +47,6 @@ public: bool IsFull () const; std::vector GetAddressUnitVector () const; void DeleteAddressUnit (Mac48Address address); - void Merge(const IePerr perr); void ResetPerr (); private: WifiElementId ElementId () const{ 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 a39f6fe37..dc39904eb 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-preq.cc +++ b/src/devices/mesh/dot11s/ie-dot11s-preq.cc @@ -410,10 +410,15 @@ IePreq::MayAddAddress (Mac48Address originator) return false; if(m_destinations[0]->GetDestinationAddress () == Mac48Address::GetBroadcast ()) return false; - if(GetInformationSize () + 11 > 255) + 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 f5c93695f..6ee625ce4 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-preq.h +++ b/src/devices/mesh/dot11s/ie-dot11s-preq.h @@ -118,7 +118,7 @@ public: * this preq is not proactive */ bool MayAddAddress(Mac48Address originator); - + bool IsFull () const; private: WifiElementId ElementId () const{ return IE11S_PREQ;