From a593d80a98c98327039cd18199a2ce82241b6c7a Mon Sep 17 00:00:00 2001 From: Kirill Andreev Date: Fri, 10 Apr 2009 12:41:10 +0400 Subject: [PATCH] Resturctured peer link frame - removed unneeded field "subtype", added unit test to it --- .../mesh/dot11s/ie-dot11s-peer-management.cc | 7 +- src/devices/mesh/dot11s/peer-link-frame.cc | 159 +++++++++++++++--- src/devices/mesh/dot11s/peer-link-frame.h | 22 ++- .../mesh/dot11s/peer-management-plugin.cc | 45 ++--- 4 files changed, 177 insertions(+), 56 deletions(-) diff --git a/src/devices/mesh/dot11s/ie-dot11s-peer-management.cc b/src/devices/mesh/dot11s/ie-dot11s-peer-management.cc index 6e1e36b8e..90f4e089a 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-peer-management.cc +++ b/src/devices/mesh/dot11s/ie-dot11s-peer-management.cc @@ -141,7 +141,12 @@ IePeerManagement::DeserializeInformation (Buffer::Iterator start, uint8_t length void IePeerManagement::PrintInformation (std::ostream& os) const { - //TODO + + os << " Subtype: = " << (uint16_t)m_subtype << "\n"; + os << " Length: = " << (uint16_t)m_length << "\n"; + os << " LocalLinkId: = " << m_localLinkId << "\n"; + os << " PeerLinkId: = " << m_peerLinkId << "\n"; + os << " ReasonCode: = " << m_reasonCode << "\n"; } bool operator== (const IePeerManagement & a, const IePeerManagement & b) { diff --git a/src/devices/mesh/dot11s/peer-link-frame.cc b/src/devices/mesh/dot11s/peer-link-frame.cc index b957e99fb..37d2de94d 100644 --- a/src/devices/mesh/dot11s/peer-link-frame.cc +++ b/src/devices/mesh/dot11s/peer-link-frame.cc @@ -20,37 +20,58 @@ #include "peer-link-frame.h" #include "ns3/mesh-wifi-interface-mac.h" +#include "ns3/test.h" +#include "ns3/packet.h" namespace ns3 { namespace dot11s { NS_OBJECT_ENSURE_REGISTERED (PeerLinkFrameStart); -PeerLinkFrameStart::PeerLinkFrameStart () +PeerLinkFrameStart::PeerLinkFrameStart (): + m_subtype (255), + m_aid (0), + m_rates (SupportedRates()), + m_meshId (Ssid()) { - m_fields.subtype = IePeerManagement::PEER_OPEN; - m_fields.aid = 0; - m_fields.rates = SupportedRates(); - m_fields.meshId = Ssid(); +} +void +PeerLinkFrameStart::SetPlinkFrameSubtype(uint8_t subtype) +{ + m_subtype = subtype; } void PeerLinkFrameStart::SetPlinkFrameStart(PeerLinkFrameStart::PlinkFrameStartFields fields) { - m_fields = fields; + m_subtype = fields.subtype; + if(m_subtype == (uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM)) + m_aid = fields.aid; + if(m_subtype != (uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_CLOSE)) + { + m_rates = fields.rates; + m_meshId = fields.meshId; + } + else + m_reasonCode = fields.reasonCode; } PeerLinkFrameStart::PlinkFrameStartFields PeerLinkFrameStart::GetFields () { - return m_fields; + PlinkFrameStartFields retval; + retval.subtype = m_subtype; + retval.aid = m_aid; + retval.rates = m_rates; + retval.meshId = m_meshId; + return retval; } bool PeerLinkFrameStart::CheckPlinkFrameStart(Ptr mac) { bool retval; - retval = mac->CheckSupportedRates(m_fields.rates); + retval = mac->CheckSupportedRates(m_rates); if(! retval) return retval; - retval = mac->CheckMeshId(m_fields.meshId); + retval = mac->CheckMeshId(m_meshId); return true; } @@ -73,21 +94,27 @@ PeerLinkFrameStart::GetInstanceTypeId () const void PeerLinkFrameStart::Print (std::ostream &os) const { - //TODO:fill this method + os << "subtype = " << (uint16_t)m_subtype + << "\naid = " << (uint16_t)m_aid + << "\nrates = " << m_rates + << "\nmeshId = " << m_meshId; } uint32_t PeerLinkFrameStart::GetSerializedSize () const { - uint32_t size = 1; //Subtype - if (IePeerManagement::PEER_CONFIRM == m_fields.subtype) + uint32_t size = 0; + NS_ASSERT(m_subtype < 3); + if ((uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM) == m_subtype) size += 2; //AID of remote peer - if (IePeerManagement::PEER_CLOSE != m_fields.subtype) + if ((uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_CLOSE) != m_subtype) { - size += m_fields.rates.GetSerializedSize (); + size += m_rates.GetSerializedSize (); size += 2; - size += m_fields.meshId.GetSerializedSize (); + size += m_meshId.GetSerializedSize (); } + else + size += 2; //reasonCode return size; } @@ -95,33 +122,109 @@ void PeerLinkFrameStart::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; - i.WriteU8 (m_fields.subtype); //Like a Category in Standart - if (IePeerManagement::PEER_CONFIRM == m_fields.subtype) - i.WriteHtonU16 (m_fields.aid); - if (IePeerManagement::PEER_CLOSE != m_fields.subtype) + NS_ASSERT(m_subtype < 3); + //i.WriteU8 (m_subtype); + if ((uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM) == m_subtype) + i.WriteHtonU16 (m_aid); + if ((uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_CLOSE) != m_subtype) { - i = m_fields.rates.Serialize (i); + i = m_rates.Serialize (i); i.Next(2); //QoS - i = m_fields.meshId.Serialize (i); + i = m_meshId.Serialize (i); } + else + i.WriteHtonU16(m_reasonCode); } uint32_t PeerLinkFrameStart::Deserialize (Buffer::Iterator start) { Buffer::Iterator i = start; - m_fields.subtype = (IePeerManagement::Subtype)i.ReadU8 (); - if (IePeerManagement::PEER_CONFIRM == m_fields.subtype) - m_fields.aid = i.ReadNtohU16 (); - if (IePeerManagement::PEER_CLOSE != m_fields.subtype) + NS_ASSERT(m_subtype < 3); + //m_subtype = (IePeerManagement::Subtype)i.ReadU8 (); + if ((uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM) == m_subtype) + m_aid = i.ReadNtohU16 (); + if ((uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_CLOSE) != m_subtype) { - i = m_fields.rates.Deserialize (i); + i = m_rates.Deserialize (i); i.Next(2); //QoS - i = m_fields.meshId.Deserialize (i); + i = m_meshId.Deserialize (i); } + else + m_reasonCode = i.ReadNtohU16(); return i.GetDistanceFrom (start); } - +bool operator== (const PeerLinkFrameStart & a, const PeerLinkFrameStart & b) +{ + return ( + (a.m_subtype == b.m_subtype) && + (a.m_aid == b.m_aid) && + (a.m_meshId.IsEqual(b.m_meshId)) + ); +} +#ifdef RUN_SELF_TESTS + +/// Built-in self test for PeerLinkFrameStart +struct PeerLinkFrameStartBist : public Test +{ + PeerLinkFrameStartBist () : Test ("Mesh/802.11s/IE/PeerLinkFrameStart") {} + virtual bool RunTests(); +}; + +/// Test instance +static PeerLinkFrameStartBist g_PeerLinkFrameStartBist; + +bool PeerLinkFrameStartBist::RunTests () +{ + bool result (true); + { + PeerLinkFrameStart a; + PeerLinkFrameStart::PlinkFrameStartFields fields; + fields.subtype = (uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_OPEN); + fields.aid = 101; + fields.reasonCode = 12; + fields.meshId = Ssid("qwertyuiop"); + a.SetPlinkFrameStart(fields); + Ptr packet = Create (); + packet->AddHeader (a); + PeerLinkFrameStart b; + b.SetPlinkFrameSubtype((uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_OPEN)); + packet->RemoveHeader (b); + NS_TEST_ASSERT_EQUAL (a, b); + } + { + PeerLinkFrameStart a; + PeerLinkFrameStart::PlinkFrameStartFields fields; + fields.subtype = (uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM); + fields.aid = 1234; + fields.reasonCode = 12; + fields.meshId = Ssid("qwerty"); + a.SetPlinkFrameStart(fields); + Ptr packet = Create (); + packet->AddHeader (a); + PeerLinkFrameStart b; + b.SetPlinkFrameSubtype((uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM)); + packet->RemoveHeader (b); + NS_TEST_ASSERT_EQUAL (a, b); + } + { + PeerLinkFrameStart a; + PeerLinkFrameStart::PlinkFrameStartFields fields; + fields.subtype = (uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_CLOSE); + fields.aid = 10; + fields.meshId = Ssid("qqq"); + fields.reasonCode = 12; + a.SetPlinkFrameStart(fields); + Ptr packet = Create (); + packet->AddHeader (a); + PeerLinkFrameStart b; + b.SetPlinkFrameSubtype((uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_CLOSE)); + packet->RemoveHeader (b); + NS_TEST_ASSERT_EQUAL (a, b); + } + return result; +} +#endif } // namespace dot11s } //namespace ns3 diff --git a/src/devices/mesh/dot11s/peer-link-frame.h b/src/devices/mesh/dot11s/peer-link-frame.h index 2756e5bda..c9866fc84 100644 --- a/src/devices/mesh/dot11s/peer-link-frame.h +++ b/src/devices/mesh/dot11s/peer-link-frame.h @@ -23,7 +23,7 @@ #include "ns3/header.h" #include "ns3/supported-rates.h" #include "ns3/ssid.h" -#include "ie-dot11s-peer-management.h" +#include "dot11s-mac-header.h" namespace ns3 { class MeshWifiInterfaceMac; namespace dot11s { @@ -46,10 +46,14 @@ public: struct PlinkFrameStartFields { uint8_t subtype; - uint16_t aid; - SupportedRates rates; - Ssid meshId; + uint16_t reasonCode; //close only + uint16_t aid; //confirm only + SupportedRates rates; //open and confirm + Ssid meshId; //open and confirm }; + ///\attention: must be set before deserialize, before only multihop + //action header knows about subtype + void SetPlinkFrameSubtype(uint8_t subtype); void SetPlinkFrameStart(PlinkFrameStartFields); PlinkFrameStartFields GetFields (); bool CheckPlinkFrameStart(Ptr mac); @@ -66,9 +70,15 @@ public: * \} */ private: - PlinkFrameStartFields m_fields; -}; + uint8_t m_subtype; + uint16_t m_reasonCode; + uint16_t m_aid; + SupportedRates m_rates; + Ssid m_meshId; + friend bool operator== (const PeerLinkFrameStart & a, const PeerLinkFrameStart & b); +}; +bool operator== (const PeerLinkFrameStart & a, const PeerLinkFrameStart & b); } //namespace dot11s } //namespace ns3 #endif diff --git a/src/devices/mesh/dot11s/peer-management-plugin.cc b/src/devices/mesh/dot11s/peer-management-plugin.cc index 354d4208d..673dcb9d7 100644 --- a/src/devices/mesh/dot11s/peer-management-plugin.cc +++ b/src/devices/mesh/dot11s/peer-management-plugin.cc @@ -90,8 +90,10 @@ PeerManagerMacPlugin::Receive (Ptr const_packet, const WifiMacHeader & h PeerLinkFrameStart::PlinkFrameStartFields fields; { PeerLinkFrameStart peerFrame; + peerFrame.SetPlinkFrameSubtype((uint8_t)actionValue.peerLink); packet->RemoveHeader (peerFrame); fields = peerFrame.GetFields(); + NS_ASSERT(fields.subtype == actionValue.peerLink); } if (actionValue.peerLink != WifiMeshMultihopActionHeader::PEER_LINK_CLOSE) { @@ -105,32 +107,30 @@ PeerManagerMacPlugin::Receive (Ptr const_packet, const WifiMacHeader & h { m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress); // Broken peer link frame - drop it - return true; + return false; } } // MeshConfiguration Element - exists in all peer link management // frames except CLOSE IeConfiguration meshConfig; - if(fields.subtype != IePeerManagement::PEER_CLOSE) + if(fields.subtype != (uint8_t)(WifiMeshMultihopActionHeader::PEER_LINK_CLOSE)) + { packet->RemoveHeader(meshConfig); + } IePeerManagement peerElement; packet->RemoveHeader(peerElement); - // Check the correspondance betwee action valuse and peer link - // management element subtypes: - switch (actionValue.peerLink) + //Check taht frame subtype corresponds peer link subtype + if(peerElement.SubtypeIsOpen ()) { - case WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM: - NS_ASSERT(fields.subtype == IePeerManagement::PEER_CONFIRM); - break; - case WifiMeshMultihopActionHeader::PEER_LINK_OPEN: - NS_ASSERT(fields.subtype == IePeerManagement::PEER_OPEN); - break; - case WifiMeshMultihopActionHeader::PEER_LINK_CLOSE: - NS_ASSERT(fields.subtype == IePeerManagement::PEER_CLOSE); - break; - default: - // Protocol can not define which frame is it - pass further - return true; + NS_ASSERT(actionValue.peerLink == WifiMeshMultihopActionHeader::PEER_LINK_OPEN); + } + if(peerElement.SubtypeIsConfirm ()) + { + NS_ASSERT(actionValue.peerLink == WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM); + } + if(peerElement.SubtypeIsClose ()) + { + NS_ASSERT(actionValue.peerLink == WifiMeshMultihopActionHeader::PEER_LINK_CLOSE); } //Deliver Peer link management frame to protocol: m_protocol->ReceivePeerLinkFrame(m_ifIndex, peerAddress, peerMpAddress, fields.aid, peerElement, meshConfig); @@ -168,13 +168,9 @@ PeerManagerMacPlugin::SendPeerLinkManagementFrame( if(!peerElement.SubtypeIsClose()) packet->AddHeader (meshConfig); PeerLinkFrameStart::PlinkFrameStartFields fields; - fields.subtype = peerElement.GetSubtype(); - fields.aid = aid; fields.rates = m_parent->GetSupportedRates (); fields.meshId = m_parent->GetSsid (); PeerLinkFrameStart plinkFrame; - plinkFrame.SetPlinkFrameStart(fields); - packet->AddHeader (plinkFrame); //Create an 802.11 frame header: //Send management frame to MAC: WifiMeshMultihopActionHeader multihopHdr; @@ -182,20 +178,27 @@ PeerManagerMacPlugin::SendPeerLinkManagementFrame( { WifiMeshMultihopActionHeader::ACTION_VALUE action; action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_OPEN; + fields.subtype = WifiMeshMultihopActionHeader::PEER_LINK_OPEN; multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action); } if (peerElement.SubtypeIsConfirm ()) { WifiMeshMultihopActionHeader::ACTION_VALUE action; action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM; + fields.aid = aid; + fields.subtype = WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM; multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action); } if (peerElement.SubtypeIsClose ()) { WifiMeshMultihopActionHeader::ACTION_VALUE action; action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_CLOSE; + fields.subtype = WifiMeshMultihopActionHeader::PEER_LINK_CLOSE; + fields.reasonCode = peerElement.GetReasonCode (); multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action); } + plinkFrame.SetPlinkFrameStart(fields); + packet->AddHeader (plinkFrame); packet->AddHeader (multihopHdr); //mesh header: Dot11sMacHeader meshHdr;