diff --git a/src/devices/mesh/dot11s/peer-link-frame.cc b/src/devices/mesh/dot11s/peer-link-frame.cc index e47f618de..b0769ddee 100644 --- a/src/devices/mesh/dot11s/peer-link-frame.cc +++ b/src/devices/mesh/dot11s/peer-link-frame.cc @@ -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 { diff --git a/src/devices/wifi/wifi-information-element-vector.cc b/src/devices/wifi/wifi-information-element-vector.cc index 9bc7e7114..6483765b5 100644 --- a/src/devices/wifi/wifi-information-element-vector.cc +++ b/src/devices/wifi/wifi-information-element-vector.cc @@ -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 diff --git a/src/devices/wifi/wifi-information-element.cc b/src/devices/wifi/wifi-information-element.cc index 753e782ea..e382e4ec7 100644 --- a/src/devices/wifi/wifi-information-element.cc +++ b/src/devices/wifi/wifi-information-element.cc @@ -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 { diff --git a/src/devices/wifi/wifi-information-element.h b/src/devices/wifi/wifi-information-element.h index ef0c4a93c..19d39149d 100644 --- a/src/devices/wifi/wifi-information-element.h +++ b/src/devices/wifi/wifi-information-element.h @@ -136,25 +136,50 @@ class WifiInformationElement : public SimpleRefCount { 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; + //\} }; }