Bug 881: Bring Wi-Fi IE serdes intelligence into WifiInformationElement object
Introduce WifiInformationElement methods SerializeIE(), DeserializeIE(), and DeserializeOptionalIE() (the latter for use when the IE of interest might not be present), which know how to deal with the IE as a whole. Make use of these in mesh subsystem where WifiInformationElement-derived objects are used. Also add empty implementation of Print() method of WifiInformationElement so that IEs that don't care about being displayed don't need to implement this.
This commit is contained in:
@@ -140,10 +140,7 @@ PeerLinkFrameStart::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
NS_ASSERT (m_subtype < 3);
|
||||
i.WriteU8 (IE11S_MESH_PEERING_PROTOCOL_VERSION);
|
||||
i.WriteU8 (m_protocol.GetInformationSize ());
|
||||
m_protocol.SerializeInformation (i);
|
||||
i.Next (m_protocol.GetInformationSize ());
|
||||
i = m_protocol.SerializeIE (i);
|
||||
if ((uint8_t) (WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
|
||||
{
|
||||
i.WriteHtolsbU16 (m_capability);
|
||||
@@ -158,17 +155,11 @@ PeerLinkFrameStart::Serialize (Buffer::Iterator start) const
|
||||
}
|
||||
if ((uint8_t) (WifiActionHeader::PEER_LINK_CONFIRM) != m_subtype)
|
||||
{
|
||||
i.WriteU8 (IE11S_MESH_ID);
|
||||
i.WriteU8 (m_meshId.GetInformationSize ());
|
||||
m_meshId.SerializeInformation (i);
|
||||
i.Next (m_meshId.GetInformationSize ());
|
||||
i = m_meshId.SerializeIE (i);
|
||||
}
|
||||
if ((uint8_t) (WifiActionHeader::PEER_LINK_CLOSE) != m_subtype)
|
||||
{
|
||||
i.WriteU8 (IE11S_MESH_CONFIGURATION);
|
||||
i.WriteU8 (m_config.GetInformationSize ());
|
||||
m_config.SerializeInformation (i);
|
||||
i.Next (m_config.GetInformationSize ());
|
||||
i = m_config.SerializeIE (i);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -59,10 +59,7 @@ WifiInformationElementVector::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
for(IE_VECTOR::const_iterator i = m_elements.begin (); i != m_elements.end (); i ++)
|
||||
{
|
||||
start.WriteU8((*i)->ElementId ());
|
||||
start.WriteU8 ((*i)->GetInformationSize ());
|
||||
(*i)->SerializeInformation (start);
|
||||
start.Next ((*i)->GetInformationSize ());
|
||||
start = (*i)->SerializeIE (start);
|
||||
}
|
||||
}
|
||||
uint32_t
|
||||
|
||||
@@ -25,6 +25,60 @@ namespace ns3 {
|
||||
WifiInformationElement::~WifiInformationElement ()
|
||||
{}
|
||||
|
||||
void
|
||||
WifiInformationElement::Print (std::ostream &os) const
|
||||
{}
|
||||
|
||||
uint16_t
|
||||
WifiInformationElement::GetSerializedSize () const
|
||||
{
|
||||
return (2 + GetInformationSize ());
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
WifiInformationElement::SerializeIE (Buffer::Iterator i) const
|
||||
{
|
||||
i.WriteU8 (ElementId ());
|
||||
i.WriteU8 (GetInformationSize ());
|
||||
SerializeInformation (i);
|
||||
i.Next (GetInformationSize ());
|
||||
return i;
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
WifiInformationElement::DeserializeIE (Buffer::Iterator i)
|
||||
{
|
||||
Buffer::Iterator start = i;
|
||||
i = DeserializeOptionalIE (i);
|
||||
// This IE was not optional, so confirm that we did actually
|
||||
// deserialise something.
|
||||
NS_ASSERT (i.GetDistanceFrom (start) != 0);
|
||||
return i;
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
WifiInformationElement::DeserializeOptionalIE (Buffer::Iterator i)
|
||||
{
|
||||
Buffer::Iterator start = i;
|
||||
uint8_t elementId = i.ReadU8 ();
|
||||
|
||||
// If the element here isn't the one we're after then we immediately
|
||||
// return the iterator we were passed indicating that we haven't
|
||||
// taken anything from the buffer.
|
||||
if (elementId != ElementId ())
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
uint8_t length = i.ReadU8 ();
|
||||
|
||||
DeserializeInformation (i, length);
|
||||
i.Next (length);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WifiInformationElement::operator< (WifiInformationElement const & a) const
|
||||
{
|
||||
|
||||
@@ -136,25 +136,50 @@ class WifiInformationElement : public SimpleRefCount<WifiInformationElement>
|
||||
{
|
||||
public:
|
||||
virtual ~WifiInformationElement ();
|
||||
/// Serialize entire IE including Element ID and length fields
|
||||
Buffer::Iterator SerializeIE (Buffer::Iterator i) const;
|
||||
/// Deserialize entire IE, which must be present. The iterator
|
||||
/// passed in must be pointing at the Element ID (i.e., the very
|
||||
/// first octet) of the correct type of information element,
|
||||
/// otherwise this method will generate a fatal error.
|
||||
Buffer::Iterator DeserializeIE (Buffer::Iterator i);
|
||||
/// Deserialize entire IE if it is present. The iterator passed in
|
||||
/// must be pointing at the Element ID of an information element. If
|
||||
/// the Element ID is not the one that the given class is interested
|
||||
/// in then it will return the same iterator.
|
||||
Buffer::Iterator DeserializeOptionalIE (Buffer::Iterator i);
|
||||
/// Get the size of the serialized IE including Element ID and
|
||||
/// length fields.
|
||||
uint16_t GetSerializedSize () const;
|
||||
|
||||
///\name Each subclass must implement
|
||||
//\{
|
||||
virtual void Print (std::ostream &os) const = 0;
|
||||
/// Own unique Element ID
|
||||
virtual WifiInformationElementId ElementId () const = 0;
|
||||
/// Length of serialized information
|
||||
/// Length of serialized information (i.e., the length of the body
|
||||
/// of the IE, not including the Element ID and length octets. This
|
||||
/// is the value that will appear in the second octet of the entire
|
||||
/// IE - the length field)
|
||||
virtual uint8_t GetInformationSize () const = 0;
|
||||
/// Serialize information
|
||||
/// Serialize information (i.e., the body of the IE, not including
|
||||
/// the Element ID and length octets)
|
||||
virtual void SerializeInformation (Buffer::Iterator start) const = 0;
|
||||
/// Deserialize information
|
||||
/// Deserialize information (i.e., the body of the IE, not including
|
||||
/// the Element ID and length octets)
|
||||
virtual uint8_t DeserializeInformation (Buffer::Iterator start,
|
||||
uint8_t length) = 0;
|
||||
//\}
|
||||
|
||||
/// In addition, a subclass may optionally override the following...
|
||||
//\{
|
||||
/// Generate human-readable form of IE
|
||||
virtual void Print (std::ostream &os) const;
|
||||
/// Compare information elements using Element ID
|
||||
virtual bool operator< (WifiInformationElement const & a) const;
|
||||
/// Compare two IEs for equality by ID & Length, and then through
|
||||
/// memcmp of serialised version
|
||||
virtual bool operator== (WifiInformationElement const & a) const;
|
||||
//\}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user