bug 1482: split PeerLinkFrameStart header into different header types, avoiding the need to set the header type before deserializing

This commit is contained in:
Tom Henderson committed 2015-08-17 14:29:51 -07:00
1 parent 134aadf85e
commit 7e6ca121d6
4 files changed
+631 -82

No files matched your search

+404 -21
View File
@@ -26,20 +26,15 @@
namespace ns3 {
namespace dot11s {
NS_OBJECT_ENSURE_REGISTERED (PeerLinkFrameStart);
NS_OBJECT_ENSURE_REGISTERED (PeerLinkOpenStart);
PeerLinkFrameStart::PeerLinkFrameStart () :
m_subtype (255), m_capability (0), m_aid (0), m_rates (SupportedRates ()), m_meshId (),
PeerLinkOpenStart::PeerLinkOpenStart () :
m_subtype ((uint8_t)(WifiActionHeader::PEER_LINK_OPEN)), m_capability (0), m_aid (0), m_rates (SupportedRates ()), m_meshId (),
m_config (IeConfiguration ())
{
}
void
PeerLinkFrameStart::SetPlinkFrameSubtype (uint8_t subtype)
{
m_subtype = subtype;
}
void
PeerLinkFrameStart::SetPlinkFrameStart (PeerLinkFrameStart::PlinkFrameStartFields fields)
PeerLinkOpenStart::SetPlinkOpenStart (PeerLinkOpenStart::PlinkOpenStartFields fields)
{
m_subtype = fields.subtype;
@@ -68,10 +63,10 @@ PeerLinkFrameStart::SetPlinkFrameStart (PeerLinkFrameStart::PlinkFrameStartField
//reasonCode not used here
}
}
PeerLinkFrameStart::PlinkFrameStartFields
PeerLinkFrameStart::GetFields () const
PeerLinkOpenStart::PlinkOpenStartFields
PeerLinkOpenStart::GetFields () const
{
PlinkFrameStartFields retval;
PlinkOpenStartFields retval;
/// \todo protocol version:
retval.subtype = m_subtype;
retval.capability = m_capability;
@@ -83,22 +78,22 @@ PeerLinkFrameStart::GetFields () const
return retval;
}
TypeId
PeerLinkFrameStart::GetTypeId ()
PeerLinkOpenStart::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::dot11s::PeerLinkFrameStart")
static TypeId tid = TypeId ("ns3::dot11s::PeerLinkOpenStart")
.SetParent<Header> ()
.SetGroupName ("Mesh")
.AddConstructor<PeerLinkFrameStart> ()
.AddConstructor<PeerLinkOpenStart> ()
;
return tid;
}
TypeId
PeerLinkFrameStart::GetInstanceTypeId () const
PeerLinkOpenStart::GetInstanceTypeId () const
{
return GetTypeId ();
}
void
PeerLinkFrameStart::Print (std::ostream &os) const
PeerLinkOpenStart::Print (std::ostream &os) const
{
os << "subtype = " << (uint16_t) m_subtype << std::endl << "capability = " << m_capability << std::endl << "laid = "
<< (uint16_t) m_aid << std::endl << "rates = " << m_rates << std::endl << "meshId = ";
@@ -108,7 +103,7 @@ PeerLinkFrameStart::Print (std::ostream &os) const
os << std::endl << "reason code = " << m_reasonCode;
}
uint32_t
PeerLinkFrameStart::GetSerializedSize () const
PeerLinkOpenStart::GetSerializedSize () const
{
uint32_t size =0; //Peering protocol
NS_ASSERT (m_subtype < 4);
@@ -140,7 +135,7 @@ PeerLinkFrameStart::GetSerializedSize () const
return size;
}
void
PeerLinkFrameStart::Serialize (Buffer::Iterator start) const
PeerLinkOpenStart::Serialize (Buffer::Iterator start) const
{
Buffer::Iterator i = start;
NS_ASSERT (m_subtype < 4);
@@ -172,7 +167,7 @@ PeerLinkFrameStart::Serialize (Buffer::Iterator start) const
}
}
uint32_t
PeerLinkFrameStart::Deserialize (Buffer::Iterator start)
PeerLinkOpenStart::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
NS_ASSERT (m_subtype < 4);
@@ -219,7 +214,395 @@ PeerLinkFrameStart::Deserialize (Buffer::Iterator start)
return i.GetDistanceFrom (start);
}
bool
operator== (const PeerLinkFrameStart & a, const PeerLinkFrameStart & b)
operator== (const PeerLinkOpenStart & a, const PeerLinkOpenStart & b)
{
return ((a.m_subtype == b.m_subtype) && (a.m_capability == b.m_capability) && (a.m_aid == b.m_aid)
&& (a.m_meshId.IsEqual (b.m_meshId)) && (a.m_config == b.m_config));
}
NS_OBJECT_ENSURE_REGISTERED (PeerLinkCloseStart);
PeerLinkCloseStart::PeerLinkCloseStart () :
m_subtype ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE)), m_capability (0), m_aid (0), m_rates (SupportedRates ()), m_meshId (),
m_config (IeConfiguration ())
{
}
void
PeerLinkCloseStart::SetPlinkCloseStart (PeerLinkCloseStart::PlinkCloseStartFields fields)
{
m_subtype = fields.subtype;
if (m_subtype != (uint8_t)(WifiActionHeader::PEER_LINK_CLOSE))
{
m_capability = fields.capability;
}
if (m_subtype == (uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM))
{
m_aid = fields.aid;
}
if (m_subtype != (uint8_t)(WifiActionHeader::PEER_LINK_CLOSE))
{
m_rates = fields.rates;
}
if (m_subtype != (uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM))
{
m_meshId = fields.meshId;
}
if (m_subtype != (uint8_t)(WifiActionHeader::PEER_LINK_CLOSE))
{
m_config = fields.config;
}
else
{
//reasonCode not used here
}
}
PeerLinkCloseStart::PlinkCloseStartFields
PeerLinkCloseStart::GetFields () const
{
PlinkCloseStartFields retval;
/// \todo protocol version:
retval.subtype = m_subtype;
retval.capability = m_capability;
retval.aid = m_aid;
retval.rates = m_rates;
retval.meshId = m_meshId;
retval.config = m_config;
return retval;
}
TypeId
PeerLinkCloseStart::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::dot11s::PeerLinkCloseStart")
.SetParent<Header> ()
.SetGroupName ("Mesh")
.AddConstructor<PeerLinkCloseStart> ()
;
return tid;
}
TypeId
PeerLinkCloseStart::GetInstanceTypeId () const
{
return GetTypeId ();
}
void
PeerLinkCloseStart::Print (std::ostream &os) const
{
os << "subtype = " << (uint16_t) m_subtype << std::endl << "capability = " << m_capability << std::endl << "laid = "
<< (uint16_t) m_aid << std::endl << "rates = " << m_rates << std::endl << "meshId = ";
m_meshId.Print (os);
os << std::endl << "configuration = ";
m_config.Print (os);
os << std::endl << "reason code = " << m_reasonCode;
}
uint32_t
PeerLinkCloseStart::GetSerializedSize () const
{
uint32_t size =0; //Peering protocol
NS_ASSERT (m_subtype < 4);
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
size += 2; //capability
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) == m_subtype)
{
size += 2; //AID of remote peer
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
size += m_rates.GetSerializedSize ();
size += m_rates.extended.GetSerializedSize ();
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) != m_subtype)
{
size += m_meshId.GetInformationFieldSize () + 2;
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
size += m_config.GetInformationFieldSize () + 2;
}
else
{
//reasonCode not used here
}
return size;
}
void
PeerLinkCloseStart::Serialize (Buffer::Iterator start) const
{
Buffer::Iterator i = start;
NS_ASSERT (m_subtype < 4);
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
i.WriteHtolsbU16 (m_capability);
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) == m_subtype)
{
i.WriteHtolsbU16 (m_aid);
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
i = m_rates.Serialize (i);
i = m_rates.extended.Serialize (i);
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) != m_subtype)
{
i = m_meshId.Serialize (i);
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
i = m_config.Serialize (i);
}
else
{
//reasonCode not used here
}
}
uint32_t
PeerLinkCloseStart::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
NS_ASSERT (m_subtype < 4);
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
m_capability = i.ReadLsbtohU16 ();
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) == m_subtype)
{
m_aid = i.ReadLsbtohU16 ();
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
i = m_rates.Deserialize (i);
i = m_rates.extended.DeserializeIfPresent (i);
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) != m_subtype)
{
uint8_t id = i.ReadU8 ();
uint8_t length = i.ReadU8 ();
m_meshId.DeserializeInformationField (i, length);
if ((m_meshId.ElementId () != (WifiInformationElementId) id) || (m_meshId.GetInformationFieldSize () != length))
{
NS_FATAL_ERROR ("Broken frame: Element ID does not match IE itself!");
}
i.Next (m_meshId.GetInformationFieldSize ());
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
uint8_t id = i.ReadU8 ();
uint8_t length = i.ReadU8 ();
m_config.DeserializeInformationField (i, length);
if ((m_config.ElementId () != (WifiInformationElementId) id) || (m_config.GetInformationFieldSize () != length))
{
NS_FATAL_ERROR ("Broken frame: Element ID does not match IE itself!");
}
i.Next (m_config.GetInformationFieldSize ());
}
else
{
//reasonCode not used here
}
return i.GetDistanceFrom (start);
}
bool
operator== (const PeerLinkCloseStart & a, const PeerLinkCloseStart & b)
{
return ((a.m_subtype == b.m_subtype) && (a.m_capability == b.m_capability) && (a.m_aid == b.m_aid)
&& (a.m_meshId.IsEqual (b.m_meshId)) && (a.m_config == b.m_config));
}
NS_OBJECT_ENSURE_REGISTERED (PeerLinkConfirmStart);
PeerLinkConfirmStart::PeerLinkConfirmStart () :
m_subtype ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM)), m_capability (0), m_aid (0), m_rates (SupportedRates ()), m_meshId (),
m_config (IeConfiguration ())
{
}
void
PeerLinkConfirmStart::SetPlinkConfirmStart (PeerLinkConfirmStart::PlinkConfirmStartFields fields)
{
m_subtype = fields.subtype;
if (m_subtype != (uint8_t)(WifiActionHeader::PEER_LINK_CLOSE))
{
m_capability = fields.capability;
}
if (m_subtype == (uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM))
{
m_aid = fields.aid;
}
if (m_subtype != (uint8_t)(WifiActionHeader::PEER_LINK_CLOSE))
{
m_rates = fields.rates;
}
if (m_subtype != (uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM))
{
m_meshId = fields.meshId;
}
if (m_subtype != (uint8_t)(WifiActionHeader::PEER_LINK_CLOSE))
{
m_config = fields.config;
}
else
{
//reasonCode not used here
}
}
PeerLinkConfirmStart::PlinkConfirmStartFields
PeerLinkConfirmStart::GetFields () const
{
PlinkConfirmStartFields retval;
/// \todo protocol version:
retval.subtype = m_subtype;
retval.capability = m_capability;
retval.aid = m_aid;
retval.rates = m_rates;
retval.meshId = m_meshId;
retval.config = m_config;
return retval;
}
TypeId
PeerLinkConfirmStart::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::dot11s::PeerLinkConfirmStart")
.SetParent<Header> ()
.SetGroupName ("Mesh")
.AddConstructor<PeerLinkConfirmStart> ()
;
return tid;
}
TypeId
PeerLinkConfirmStart::GetInstanceTypeId () const
{
return GetTypeId ();
}
void
PeerLinkConfirmStart::Print (std::ostream &os) const
{
os << "subtype = " << (uint16_t) m_subtype << std::endl << "capability = " << m_capability << std::endl << "laid = "
<< (uint16_t) m_aid << std::endl << "rates = " << m_rates << std::endl << "meshId = ";
m_meshId.Print (os);
os << std::endl << "configuration = ";
m_config.Print (os);
os << std::endl << "reason code = " << m_reasonCode;
}
uint32_t
PeerLinkConfirmStart::GetSerializedSize () const
{
uint32_t size =0; //Peering protocol
NS_ASSERT (m_subtype < 4);
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
size += 2; //capability
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) == m_subtype)
{
size += 2; //AID of remote peer
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
size += m_rates.GetSerializedSize ();
size += m_rates.extended.GetSerializedSize ();
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) != m_subtype)
{
size += m_meshId.GetInformationFieldSize () + 2;
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
size += m_config.GetInformationFieldSize () + 2;
}
else
{
//reasonCode not used here
}
return size;
}
void
PeerLinkConfirmStart::Serialize (Buffer::Iterator start) const
{
Buffer::Iterator i = start;
NS_ASSERT (m_subtype < 4);
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
i.WriteHtolsbU16 (m_capability);
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) == m_subtype)
{
i.WriteHtolsbU16 (m_aid);
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
i = m_rates.Serialize (i);
i = m_rates.extended.Serialize (i);
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) != m_subtype)
{
i = m_meshId.Serialize (i);
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
i = m_config.Serialize (i);
}
else
{
//reasonCode not used here
}
}
uint32_t
PeerLinkConfirmStart::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
NS_ASSERT (m_subtype < 4);
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
m_capability = i.ReadLsbtohU16 ();
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) == m_subtype)
{
m_aid = i.ReadLsbtohU16 ();
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
i = m_rates.Deserialize (i);
i = m_rates.extended.DeserializeIfPresent (i);
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) != m_subtype)
{
uint8_t id = i.ReadU8 ();
uint8_t length = i.ReadU8 ();
m_meshId.DeserializeInformationField (i, length);
if ((m_meshId.ElementId () != (WifiInformationElementId) id) || (m_meshId.GetInformationFieldSize () != length))
{
NS_FATAL_ERROR ("Broken frame: Element ID does not match IE itself!");
}
i.Next (m_meshId.GetInformationFieldSize ());
}
if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
{
uint8_t id = i.ReadU8 ();
uint8_t length = i.ReadU8 ();
m_config.DeserializeInformationField (i, length);
if ((m_config.ElementId () != (WifiInformationElementId) id) || (m_config.GetInformationFieldSize () != length))
{
NS_FATAL_ERROR ("Broken frame: Element ID does not match IE itself!");
}
i.Next (m_config.GetInformationFieldSize ());
}
else
{
//reasonCode not used here
}
return i.GetDistanceFrom (start);
}
bool
operator== (const PeerLinkConfirmStart & a, const PeerLinkConfirmStart & b)
{
return ((a.m_subtype == b.m_subtype) && (a.m_capability == b.m_capability) && (a.m_aid == b.m_aid)
&& (a.m_meshId.IsEqual (b.m_meshId)) && (a.m_config == b.m_config));
+123 -14
View File
@@ -28,13 +28,12 @@
#include "ie-dot11s-id.h"
namespace ns3
{
class MeshWifiInterfaceMac;
namespace dot11s
{
/**
* \ingroup dot11s
*
* \brief 802.11s Peer link management frame
* \brief 802.11s Peer link open management frame
*
* Peer link management frame included the following (see chapters 7.4.12.1-7.4.12.3 of 802.11s):
* - Subtype field
@@ -42,12 +41,12 @@ namespace dot11s
* - Supported rates
* - Mesh ID of mesh
*/
class PeerLinkFrameStart : public Header
class PeerLinkOpenStart : public Header
{
public:
PeerLinkFrameStart ();
PeerLinkOpenStart ();
///\brief fields:
struct PlinkFrameStartFields
struct PlinkOpenStartFields
{
uint8_t subtype;
IePeeringProtocol protocol; //Peering protocol version - in all subtypes - 3 octets
@@ -58,11 +57,8 @@ public:
IeConfiguration config; //open and confirm
uint16_t reasonCode; //close only
};
///\attention: must be set before deserialize, before only multihop
//action header knows about subtype
void SetPlinkFrameSubtype (uint8_t subtype);
void SetPlinkFrameStart (PlinkFrameStartFields);
PlinkFrameStartFields GetFields () const;
void SetPlinkOpenStart (PlinkOpenStartFields);
PlinkOpenStartFields GetFields () const;
// Inherited from header:
static TypeId GetTypeId ();
@@ -82,13 +78,126 @@ private:
IeConfiguration m_config;
uint16_t m_reasonCode;
friend bool operator== (const PeerLinkFrameStart & a, const PeerLinkFrameStart & b);
friend bool operator== (const PeerLinkOpenStart & a, const PeerLinkOpenStart & b);
PeerLinkFrameStart& operator= (const PeerLinkFrameStart &);
PeerLinkFrameStart (const PeerLinkFrameStart &);
PeerLinkOpenStart& operator= (const PeerLinkOpenStart &);
PeerLinkOpenStart (const PeerLinkOpenStart &);
};
bool operator== (const PeerLinkFrameStart & a, const PeerLinkFrameStart & b);
bool operator== (const PeerLinkOpenStart & a, const PeerLinkOpenStart & b);
/**
* \ingroup dot11s
*
* \brief 802.11s Peer link close management frame
*
* Peer link management frame included the following (see chapters 7.4.12.1-7.4.12.3 of 802.11s):
* - Subtype field
* - Association ID field
* - Supported rates
* - Mesh ID of mesh
*/
class PeerLinkCloseStart : public Header
{
public:
PeerLinkCloseStart ();
///\brief fields:
struct PlinkCloseStartFields
{
uint8_t subtype;
IePeeringProtocol protocol; //Peering protocol version - in all subtypes - 3 octets
uint16_t capability; //open and confirm
uint16_t aid; //confirm only
SupportedRates rates; //open and confirm
IeMeshId meshId; //open and close
IeConfiguration config; //open and confirm
uint16_t reasonCode; //close only
};
void SetPlinkCloseStart (PlinkCloseStartFields);
PlinkCloseStartFields GetFields () const;
// Inherited from header:
static TypeId GetTypeId ();
virtual TypeId GetInstanceTypeId () const;
virtual void Print (std::ostream &os) const;
virtual uint32_t GetSerializedSize () const;
virtual void Serialize (Buffer::Iterator start) const;
virtual uint32_t Deserialize (Buffer::Iterator start);
private:
uint8_t m_subtype;
IePeeringProtocol m_protocol;
uint16_t m_capability;
uint16_t m_aid;
SupportedRates m_rates;
IeMeshId m_meshId;
IeConfiguration m_config;
uint16_t m_reasonCode;
friend bool operator== (const PeerLinkCloseStart & a, const PeerLinkCloseStart & b);
PeerLinkCloseStart& operator= (const PeerLinkCloseStart &);
PeerLinkCloseStart (const PeerLinkCloseStart &);
};
bool operator== (const PeerLinkCloseStart & a, const PeerLinkCloseStart & b);
/**
* \ingroup dot11s
*
* \brief 802.11s Peer link confirm management frame
*
* Peer link management frame included the following (see chapters 7.4.12.1-7.4.12.3 of 802.11s):
* - Subtype field
* - Association ID field
* - Supported rates
* - Mesh ID of mesh
*/
class PeerLinkConfirmStart : public Header
{
public:
PeerLinkConfirmStart ();
///\brief fields:
struct PlinkConfirmStartFields
{
uint8_t subtype;
IePeeringProtocol protocol; //Peering protocol version - in all subtypes - 3 octets
uint16_t capability; //open and confirm
uint16_t aid; //confirm only
SupportedRates rates; //open and confirm
IeMeshId meshId; //open and close
IeConfiguration config; //open and confirm
uint16_t reasonCode; //close only
};
void SetPlinkConfirmStart (PlinkConfirmStartFields);
PlinkConfirmStartFields GetFields () const;
// Inherited from header:
static TypeId GetTypeId ();
virtual TypeId GetInstanceTypeId () const;
virtual void Print (std::ostream &os) const;
virtual uint32_t GetSerializedSize () const;
virtual void Serialize (Buffer::Iterator start) const;
virtual uint32_t Deserialize (Buffer::Iterator start);
private:
uint8_t m_subtype;
IePeeringProtocol m_protocol;
uint16_t m_capability;
uint16_t m_aid;
SupportedRates m_rates;
IeMeshId m_meshId;
IeConfiguration m_config;
uint16_t m_reasonCode;
friend bool operator== (const PeerLinkConfirmStart & a, const PeerLinkConfirmStart & b);
PeerLinkConfirmStart& operator= (const PeerLinkConfirmStart &);
PeerLinkConfirmStart (const PeerLinkConfirmStart &);
};
bool operator== (const PeerLinkConfirmStart & a, const PeerLinkConfirmStart & b);
} // namespace dot11s
} // namespace ns3
#endif
@@ -82,6 +82,8 @@ PeerManagementProtocolMac::Receive (Ptr<Packet> const_packet, const WifiMacHeade
// Beacon shall not be dropped. May be needed to another plugins
return true;
}
uint16_t aid;
IeConfiguration config;
if (header.IsAction ())
{
WifiActionHeader actionHdr;
@@ -96,28 +98,67 @@ PeerManagementProtocolMac::Receive (Ptr<Packet> const_packet, const WifiMacHeade
m_stats.rxMgtBytes += packet->GetSize ();
Mac48Address peerAddress = header.GetAddr2 ();
Mac48Address peerMpAddress = header.GetAddr3 ();
PeerLinkFrameStart::PlinkFrameStartFields fields;
{
PeerLinkFrameStart peerFrame;
peerFrame.SetPlinkFrameSubtype ((uint8_t) actionValue.selfProtectedAction);
packet->RemoveHeader (peerFrame);
fields = peerFrame.GetFields ();
NS_ASSERT (fields.subtype == actionValue.selfProtectedAction);
}
if ((actionValue.selfProtectedAction != WifiActionHeader::PEER_LINK_CLOSE) && !(m_parent->CheckSupportedRates (fields.rates)))
if (actionValue.selfProtectedAction == WifiActionHeader::PEER_LINK_OPEN)
{
m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
// Broken peer link frame - drop it
m_stats.brokenMgt++;
return false;
PeerLinkOpenStart::PlinkOpenStartFields fields;
PeerLinkOpenStart peerFrame;
packet->RemoveHeader (peerFrame);
fields = peerFrame.GetFields ();
NS_ASSERT (fields.subtype == actionValue.selfProtectedAction);
if (!fields.meshId.IsEqual ( *(m_protocol->GetMeshId ())))
{
m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
// Broken peer link frame - drop it
m_stats.brokenMgt++;
return false;
}
if (!(m_parent->CheckSupportedRates (fields.rates)))
{
m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
// Broken peer link frame - drop it
m_stats.brokenMgt++;
return false;
}
aid = fields.aid;
config = fields.config;
}
if ((actionValue.selfProtectedAction != WifiActionHeader::PEER_LINK_CONFIRM) && !fields.meshId.IsEqual (
*(m_protocol->GetMeshId ())))
else if (actionValue.selfProtectedAction == WifiActionHeader::PEER_LINK_CONFIRM)
{
m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
// Broken peer link frame - drop it
m_stats.brokenMgt++;
return false;
PeerLinkConfirmStart::PlinkConfirmStartFields fields;
PeerLinkConfirmStart peerFrame;
packet->RemoveHeader (peerFrame);
fields = peerFrame.GetFields ();
NS_ASSERT (fields.subtype == actionValue.selfProtectedAction);
if (!(m_parent->CheckSupportedRates (fields.rates)))
{
m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
// Broken peer link frame - drop it
m_stats.brokenMgt++;
return false;
}
aid = fields.aid;
config = fields.config;
}
else if (actionValue.selfProtectedAction == WifiActionHeader::PEER_LINK_CLOSE)
{
PeerLinkCloseStart::PlinkCloseStartFields fields;
PeerLinkCloseStart peerFrame;
packet->RemoveHeader (peerFrame);
fields = peerFrame.GetFields ();
NS_ASSERT (fields.subtype == actionValue.selfProtectedAction);
if (!fields.meshId.IsEqual ( *(m_protocol->GetMeshId ())))
{
m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
// Broken peer link frame - drop it
m_stats.brokenMgt++;
return false;
}
aid = fields.aid;
config = fields.config;
}
else
{
NS_FATAL_ERROR ("Unknown subtype" << actionValue.selfProtectedAction);
}
Ptr<IePeerManagement> peerElement;
//Peer Management element is the last element in this frame - so, we can use MeshInformationElementVector
@@ -143,8 +184,7 @@ PeerManagementProtocolMac::Receive (Ptr<Packet> const_packet, const WifiMacHeade
NS_ASSERT (actionValue.selfProtectedAction == WifiActionHeader::PEER_LINK_CLOSE);
}
//Deliver Peer link management frame to protocol:
m_protocol->ReceivePeerLinkFrame (m_ifIndex, peerAddress, peerMpAddress, fields.aid, *peerElement,
fields.config);
m_protocol->ReceivePeerLinkFrame (m_ifIndex, peerAddress, peerMpAddress, aid, *peerElement, config);
// if we can handle a frame - drop it
return false;
}
@@ -202,44 +242,64 @@ PeerManagementProtocolMac::SendPeerLinkManagementFrame (Mac48Address peerAddress
MeshInformationElementVector elements;
elements.AddInformationElement (Ptr<IePeerManagement> (&peerElement));
packet->AddHeader (elements);
PeerLinkFrameStart::PlinkFrameStartFields fields;
fields.rates = m_parent->GetSupportedRates ();
fields.capability = 0;
fields.meshId = *(m_protocol->GetMeshId ());
fields.config = meshConfig;
PeerLinkFrameStart plinkFrame;
//Create an 802.11 frame header:
//Send management frame to MAC:
WifiActionHeader actionHdr;
if (peerElement.SubtypeIsOpen ())
{
PeerLinkOpenStart::PlinkOpenStartFields fields;
fields.rates = m_parent->GetSupportedRates ();
fields.capability = 0;
fields.meshId = *(m_protocol->GetMeshId ());
fields.config = meshConfig;
PeerLinkOpenStart plinkOpen;
WifiActionHeader actionHdr;
m_stats.txOpen++;
WifiActionHeader::ActionValue action;
action.selfProtectedAction = WifiActionHeader::PEER_LINK_OPEN;
fields.subtype = WifiActionHeader::PEER_LINK_OPEN;
actionHdr.SetAction (WifiActionHeader::SELF_PROTECTED, action);
plinkOpen.SetPlinkOpenStart (fields);
packet->AddHeader (plinkOpen);
packet->AddHeader (actionHdr);
}
if (peerElement.SubtypeIsConfirm ())
{
PeerLinkConfirmStart::PlinkConfirmStartFields fields;
fields.rates = m_parent->GetSupportedRates ();
fields.capability = 0;
fields.meshId = *(m_protocol->GetMeshId ());
fields.config = meshConfig;
PeerLinkConfirmStart plinkConfirm;
WifiActionHeader actionHdr;
m_stats.txConfirm++;
WifiActionHeader::ActionValue action;
action.selfProtectedAction = WifiActionHeader::PEER_LINK_CONFIRM;
action.selfProtectedAction = WifiActionHeader::PEER_LINK_CONFIRM;
fields.aid = aid;
fields.subtype = WifiActionHeader::PEER_LINK_CONFIRM;
actionHdr.SetAction (WifiActionHeader::SELF_PROTECTED, action);
plinkConfirm.SetPlinkConfirmStart (fields);
packet->AddHeader (plinkConfirm);
packet->AddHeader (actionHdr);
}
if (peerElement.SubtypeIsClose ())
{
PeerLinkCloseStart::PlinkCloseStartFields fields;
fields.rates = m_parent->GetSupportedRates ();
fields.capability = 0;
fields.meshId = *(m_protocol->GetMeshId ());
fields.config = meshConfig;
PeerLinkCloseStart plinkClose;
WifiActionHeader actionHdr;
m_stats.txClose++;
WifiActionHeader::ActionValue action;
action.selfProtectedAction = WifiActionHeader::PEER_LINK_CLOSE;
fields.subtype = WifiActionHeader::PEER_LINK_CLOSE;
fields.reasonCode = peerElement.GetReasonCode ();
actionHdr.SetAction (WifiActionHeader::SELF_PROTECTED, action);
plinkClose.SetPlinkCloseStart (fields);
packet->AddHeader (plinkClose);
packet->AddHeader (actionHdr);
}
plinkFrame.SetPlinkFrameStart (fields);
packet->AddHeader (plinkFrame);
packet->AddHeader (actionHdr);
m_stats.txMgt++;
m_stats.txMgtBytes += packet->GetSize ();
// Wifi Mac header:
+12 -15
View File
@@ -216,50 +216,47 @@ void
PeerLinkFrameStartTest::DoRun ()
{
{
PeerLinkFrameStart a;
PeerLinkFrameStart::PlinkFrameStartFields fields;
PeerLinkOpenStart a;
PeerLinkOpenStart::PlinkOpenStartFields fields;
fields.subtype = (uint8_t)(WifiActionHeader::PEER_LINK_OPEN);
fields.capability = 0;
fields.aid = 101;
fields.reasonCode = 12;
fields.meshId = IeMeshId ("qwertyuiop");
a.SetPlinkFrameStart (fields);
a.SetPlinkOpenStart (fields);
Ptr<Packet> packet = Create<Packet> ();
packet->AddHeader (a);
PeerLinkFrameStart b;
b.SetPlinkFrameSubtype ((uint8_t)(WifiActionHeader::PEER_LINK_OPEN));
PeerLinkOpenStart b;
packet->RemoveHeader (b);
NS_TEST_EXPECT_MSG_EQ (a, b, "PEER_LINK_OPEN works");
}
{
PeerLinkFrameStart a;
PeerLinkFrameStart::PlinkFrameStartFields fields;
PeerLinkConfirmStart a;
PeerLinkConfirmStart::PlinkConfirmStartFields fields;
fields.subtype = (uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM);
fields.capability = 0;
fields.aid = 1234;
fields.reasonCode = 12;
fields.meshId = IeMeshId ("qwerty");
a.SetPlinkFrameStart (fields);
a.SetPlinkConfirmStart (fields);
Ptr<Packet> packet = Create<Packet> ();
packet->AddHeader (a);
PeerLinkFrameStart b;
b.SetPlinkFrameSubtype ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM));
PeerLinkConfirmStart b;
packet->RemoveHeader (b);
NS_TEST_EXPECT_MSG_EQ (a, b, "PEER_LINK_CONFIRM works");
}
{
PeerLinkFrameStart a;
PeerLinkFrameStart::PlinkFrameStartFields fields;
PeerLinkCloseStart a;
PeerLinkCloseStart::PlinkCloseStartFields fields;
fields.subtype = (uint8_t)(WifiActionHeader::PEER_LINK_CLOSE);
fields.capability = 0;
fields.aid = 10;
fields.meshId = IeMeshId ("qqq");
fields.reasonCode = 12;
a.SetPlinkFrameStart (fields);
a.SetPlinkCloseStart (fields);
Ptr<Packet> packet = Create<Packet> ();
packet->AddHeader (a);
PeerLinkFrameStart b;
b.SetPlinkFrameSubtype ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE));
PeerLinkCloseStart b;
packet->RemoveHeader (b);
NS_TEST_EXPECT_MSG_EQ (a, b, "PEER_LINK_CLOSE works");
}