diff --git a/src/mesh/model/mesh-information-element-vector.cc b/src/mesh/model/mesh-information-element-vector.cc index d6ed0e882..26a05e654 100644 --- a/src/mesh/model/mesh-information-element-vector.cc +++ b/src/mesh/model/mesh-information-element-vector.cc @@ -41,18 +41,24 @@ namespace ns3 NS_OBJECT_ENSURE_REGISTERED(MeshInformationElementVector); MeshInformationElementVector::MeshInformationElementVector() + : m_maxSize(1500) { } MeshInformationElementVector::~MeshInformationElementVector() { + for (IE_VECTOR::iterator i = m_elements.begin(); i != m_elements.end(); i++) + { + *i = nullptr; + } + m_elements.clear(); } TypeId MeshInformationElementVector::GetTypeId() { static TypeId tid = TypeId("ns3::MeshInformationElementVector") - .SetParent() + .SetParent
() .SetGroupName("Mesh") .AddConstructor(); return tid; @@ -64,6 +70,44 @@ MeshInformationElementVector::GetInstanceTypeId() const return GetTypeId(); } +uint32_t +MeshInformationElementVector::GetSerializedSize() const +{ + return GetSize(); +} + +void +MeshInformationElementVector::Serialize(Buffer::Iterator start) const +{ + for (IE_VECTOR::const_iterator i = m_elements.begin(); i != m_elements.end(); i++) + { + start = (*i)->Serialize(start); + } +} + +uint32_t +MeshInformationElementVector::Deserialize(Buffer::Iterator start) +{ + NS_FATAL_ERROR("This variant should not be called on a variable-sized header"); + return 0; +} + +uint32_t +MeshInformationElementVector::Deserialize(Buffer::Iterator start, Buffer::Iterator end) +{ + uint32_t size = start.GetDistanceFrom(end); + uint32_t remaining = size; + while (remaining > 0) + { + uint32_t deserialized = DeserializeSingleIe(start); + start.Next(deserialized); + NS_ASSERT(deserialized <= remaining); + remaining -= deserialized; + } + NS_ASSERT_MSG(remaining == 0, "Error in deserialization"); + return size; +} + uint32_t MeshInformationElementVector::DeserializeSingleIe(Buffer::Iterator start) { @@ -105,7 +149,8 @@ MeshInformationElementVector::DeserializeSingleIe(Buffer::Iterator start) newElement = Create(); break; default: - return WifiInformationElementVector::DeserializeSingleIe(i); + NS_FATAL_ERROR("Information element " << +id << " is not implemented"); + return 0; } if (GetSize() + length > m_maxSize) { @@ -116,4 +161,91 @@ MeshInformationElementVector::DeserializeSingleIe(Buffer::Iterator start) return i.GetDistanceFrom(start); } +void +MeshInformationElementVector::Print(std::ostream& os) const +{ + for (IE_VECTOR::const_iterator i = m_elements.begin(); i != m_elements.end(); i++) + { + os << "("; + (*i)->Print(os); + os << ")"; + } +} + +MeshInformationElementVector::Iterator +MeshInformationElementVector::Begin() +{ + return m_elements.begin(); +} + +MeshInformationElementVector::Iterator +MeshInformationElementVector::End() +{ + return m_elements.end(); +} + +bool +MeshInformationElementVector::AddInformationElement(Ptr element) +{ + if (element->GetSerializedSize() + GetSize() > m_maxSize) + { + return false; + } + m_elements.push_back(element); + return true; +} + +Ptr +MeshInformationElementVector::FindFirst(WifiInformationElementId id) const +{ + for (IE_VECTOR::const_iterator i = m_elements.begin(); i != m_elements.end(); i++) + { + if ((*i)->ElementId() == id) + { + return (*i); + } + } + return nullptr; +} + +uint32_t +MeshInformationElementVector::GetSize() const +{ + uint32_t size = 0; + for (IE_VECTOR::const_iterator i = m_elements.begin(); i != m_elements.end(); i++) + { + size += (*i)->GetSerializedSize(); + } + return size; +} + +bool +MeshInformationElementVector::operator==(const MeshInformationElementVector& a) const +{ + if (m_elements.size() != a.m_elements.size()) + { + NS_ASSERT(false); + return false; + } + // In principle we could bypass some of the faffing about (and speed + // the comparison) by simply serialising each IE vector into a + // buffer and memcmp'ing the two. + // + // I'm leaving it like this, however, so that there is the option of + // having individual Information Elements implement slightly more + // flexible equality operators. + MeshInformationElementVector::IE_VECTOR::const_iterator j = a.m_elements.begin(); + for (MeshInformationElementVector::IE_VECTOR::const_iterator i = m_elements.begin(); + i != m_elements.end(); + i++, j++) + { + if (!(*(*i) == *(*j))) + { + return false; + } + } + + return true; +} + } // namespace ns3 diff --git a/src/mesh/model/mesh-information-element-vector.h b/src/mesh/model/mesh-information-element-vector.h index 6abb7fbd6..2f9f63073 100644 --- a/src/mesh/model/mesh-information-element-vector.h +++ b/src/mesh/model/mesh-information-element-vector.h @@ -21,7 +21,7 @@ #ifndef MESH_INFORMATION_ELEMENT_VECTOR_H #define MESH_INFORMATION_ELEMENT_VECTOR_H -#include "ns3/wifi-information-element-vector.h" +#include "ns3/wifi-information-element.h" namespace ns3 { @@ -30,7 +30,17 @@ namespace ns3 ((WifiInformationElementId)74) // to be removed (Protocol ID should be part of the Mesh Peering // Management IE) -class MeshInformationElementVector : public WifiInformationElementVector +/** + * \brief Information element vector + * \ingroup wifi + * + * Implements a vector of WifiInformationElements. + * Information elements typically come in groups, and the + * WifiInformationElementVector class provides a representation of a + * series of IEs, and the facility for serialisation to and + * deserialisation from the over-the-air format. + */ +class MeshInformationElementVector : public Header { public: MeshInformationElementVector(); @@ -41,8 +51,88 @@ class MeshInformationElementVector : public WifiInformationElementVector * \return the object TypeId */ static TypeId GetTypeId(); + TypeId GetInstanceTypeId() const override; - uint32_t DeserializeSingleIe(Buffer::Iterator start) override; + uint32_t GetSerializedSize() const override; + void Serialize(Buffer::Iterator start) const override; + /** + * \attention This variant should not be used but is implemented due to + * backward compatibility reasons + * + * \param start buffer location to start deserializing from + * \return number of bytes deserialized + */ + uint32_t Deserialize(Buffer::Iterator start) override; + /** + * Deserialize a number of WifiInformationElements + * + * The size of this Header should equal start.GetDistanceFrom (end). + * + * \param start starting buffer location + * \param end ending buffer location + * \return number of bytes deserialized + */ + uint32_t Deserialize(Buffer::Iterator start, Buffer::Iterator end) override; + void Print(std::ostream& os) const override; + + /** + * \brief Needed when you try to deserialize a lonely IE inside other header + * + * \param start is the start of the buffer + * + * \return deserialized bytes + */ + uint32_t DeserializeSingleIe(Buffer::Iterator start); + + /// As soon as this is a vector, we define an Iterator + typedef std::vector>::iterator Iterator; + /** + * Returns Begin of the vector + * \returns the begin of the vector + */ + Iterator Begin(); + /** + * Returns End of the vector + * \returns the end of the vector + */ + Iterator End(); + /** + * add an IE, if maxSize has exceeded, returns false + * + * \param element wifi information element to add + * \returns true is added + */ + bool AddInformationElement(Ptr element); + /** + * vector of pointers to information elements is the body of IeVector + * + * \param id the element id to find + * \returns the information element + */ + Ptr FindFirst(WifiInformationElementId id) const; + + /** + * Check if the given WifiInformationElementVectors are equivalent. + * + * \param a another WifiInformationElementVector + * + * \return true if the given WifiInformationElementVectors are equivalent, + * false otherwise + */ + virtual bool operator==(const MeshInformationElementVector& a) const; + + protected: + /** + * typedef for a vector of WifiInformationElements. + */ + typedef std::vector> IE_VECTOR; + /** + * Current number of bytes + * \returns the number of bytes + */ + uint32_t GetSize() const; + IE_VECTOR m_elements; //!< Information element vector + uint16_t m_maxSize; //!< Size in bytes (actually, max packet length) }; } // namespace ns3 diff --git a/src/wifi/CMakeLists.txt b/src/wifi/CMakeLists.txt index 0aa984c73..6d77d71a7 100644 --- a/src/wifi/CMakeLists.txt +++ b/src/wifi/CMakeLists.txt @@ -118,7 +118,6 @@ set(source_files model/wifi-default-ack-manager.cc model/wifi-default-assoc-manager.cc model/wifi-default-protection-manager.cc - model/wifi-information-element-vector.cc model/wifi-information-element.cc model/wifi-mac-header.cc model/wifi-mac-queue-container.cc @@ -267,7 +266,6 @@ set(header_files model/wifi-default-ack-manager.h model/wifi-default-assoc-manager.h model/wifi-default-protection-manager.h - model/wifi-information-element-vector.h model/wifi-information-element.h model/wifi-mac-header.h model/wifi-mac-queue-container.h diff --git a/src/wifi/model/wifi-information-element-vector.cc b/src/wifi/model/wifi-information-element-vector.cc deleted file mode 100644 index ac532f59d..000000000 --- a/src/wifi/model/wifi-information-element-vector.cc +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2009 IITP RAS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Pavel Boyko - */ - -#include "wifi-information-element-vector.h" - -namespace ns3 -{ - -NS_OBJECT_ENSURE_REGISTERED(WifiInformationElementVector); - -WifiInformationElementVector::WifiInformationElementVector() - : m_maxSize(1500) -{ -} - -WifiInformationElementVector::~WifiInformationElementVector() -{ - for (IE_VECTOR::iterator i = m_elements.begin(); i != m_elements.end(); i++) - { - *i = nullptr; - } - m_elements.clear(); -} - -TypeId -WifiInformationElementVector::GetTypeId() -{ - static TypeId tid = TypeId("ns3::WifiInformationElementVector") - .SetParent
() - .SetGroupName("Wifi") - .AddConstructor(); - return tid; -} - -TypeId -WifiInformationElementVector::GetInstanceTypeId() const -{ - return GetTypeId(); -} - -uint32_t -WifiInformationElementVector::GetSerializedSize() const -{ - return GetSize(); -} - -void -WifiInformationElementVector::Serialize(Buffer::Iterator start) const -{ - for (IE_VECTOR::const_iterator i = m_elements.begin(); i != m_elements.end(); i++) - { - start = (*i)->Serialize(start); - } -} - -uint32_t -WifiInformationElementVector::Deserialize(Buffer::Iterator start) -{ - NS_FATAL_ERROR("This variant should not be called on a variable-sized header"); - return 0; -} - -uint32_t -WifiInformationElementVector::Deserialize(Buffer::Iterator start, Buffer::Iterator end) -{ - uint32_t size = start.GetDistanceFrom(end); - uint32_t remaining = size; - while (remaining > 0) - { - uint32_t deserialized = DeserializeSingleIe(start); - start.Next(deserialized); - NS_ASSERT(deserialized <= remaining); - remaining -= deserialized; - } - NS_ASSERT_MSG(remaining == 0, "Error in deserialization"); - return size; -} - -uint32_t -WifiInformationElementVector::DeserializeSingleIe(Buffer::Iterator start) -{ - Buffer::Iterator i = start; - uint8_t id = i.ReadU8(); - // unused: uint8_t length = i.ReadU8 (); - // but need side effects of read: - i.ReadU8(); - Ptr newElement; - switch (id) - { - case 0: // eliminate compiler warning - default: - NS_FATAL_ERROR("Information element " << +id << " is not implemented"); - return 0; - } - /* unreachable: b/c switch is guaranteed to return from this function - if (GetSize () + length > m_maxSize) - { - NS_FATAL_ERROR ("Check max size for information element!"); - } - newElement->DeserializeInformationField (i, length); - i.Next (length); - m_elements.push_back (newElement); - return i.GetDistanceFrom (start); - */ -} - -void -WifiInformationElementVector::Print(std::ostream& os) const -{ - for (IE_VECTOR::const_iterator i = m_elements.begin(); i != m_elements.end(); i++) - { - os << "("; - (*i)->Print(os); - os << ")"; - } -} - -WifiInformationElementVector::Iterator -WifiInformationElementVector::Begin() -{ - return m_elements.begin(); -} - -WifiInformationElementVector::Iterator -WifiInformationElementVector::End() -{ - return m_elements.end(); -} - -bool -WifiInformationElementVector::AddInformationElement(Ptr element) -{ - if (element->GetSerializedSize() + GetSize() > m_maxSize) - { - return false; - } - m_elements.push_back(element); - return true; -} - -Ptr -WifiInformationElementVector::FindFirst(WifiInformationElementId id) const -{ - for (IE_VECTOR::const_iterator i = m_elements.begin(); i != m_elements.end(); i++) - { - if ((*i)->ElementId() == id) - { - return (*i); - } - } - return nullptr; -} - -uint32_t -WifiInformationElementVector::GetSize() const -{ - uint32_t size = 0; - for (IE_VECTOR::const_iterator i = m_elements.begin(); i != m_elements.end(); i++) - { - size += (*i)->GetSerializedSize(); - } - return size; -} - -bool -WifiInformationElementVector::operator==(const WifiInformationElementVector& a) const -{ - if (m_elements.size() != a.m_elements.size()) - { - NS_ASSERT(false); - return false; - } - // In principle we could bypass some of the faffing about (and speed - // the comparison) by simply serialising each IE vector into a - // buffer and memcmp'ing the two. - // - // I'm leaving it like this, however, so that there is the option of - // having individual Information Elements implement slightly more - // flexible equality operators. - WifiInformationElementVector::IE_VECTOR::const_iterator j = a.m_elements.begin(); - for (WifiInformationElementVector::IE_VECTOR::const_iterator i = m_elements.begin(); - i != m_elements.end(); - i++, j++) - { - if (!(*(*i) == *(*j))) - { - return false; - } - } - - return true; -} - -} // namespace ns3 diff --git a/src/wifi/model/wifi-information-element-vector.h b/src/wifi/model/wifi-information-element-vector.h deleted file mode 100644 index 23b45a794..000000000 --- a/src/wifi/model/wifi-information-element-vector.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2009 IITP RAS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Authors: Kirill Andreev - * Pavel Boyko - */ - -#ifndef WIFI_INFORMATION_ELEMENT_VECTOR_H -#define WIFI_INFORMATION_ELEMENT_VECTOR_H - -#include "wifi-information-element.h" - -namespace ns3 -{ - -/** - * \brief Information element vector - * \ingroup wifi - * - * Implements a vector of WifiInformationElements. - * Information elements typically come in groups, and the - * WifiInformationElementVector class provides a representation of a - * series of IEs, and the facility for serialisation to and - * deserialisation from the over-the-air format. - */ -class WifiInformationElementVector : public Header -{ - public: - WifiInformationElementVector(); - ~WifiInformationElementVector() override; - - /** - * \brief Get the type ID. - * \return the object TypeId - */ - static TypeId GetTypeId(); - - TypeId GetInstanceTypeId() const override; - uint32_t GetSerializedSize() const override; - void Serialize(Buffer::Iterator start) const override; - /** - * \attention This variant should not be used but is implemented due to - * backward compatibility reasons - * - * \param start buffer location to start deserializing from - * \return number of bytes deserialized - */ - uint32_t Deserialize(Buffer::Iterator start) override; - /** - * Deserialize a number of WifiInformationElements - * - * The size of this Header should equal start.GetDistanceFrom (end). - * - * \param start starting buffer location - * \param end ending buffer location - * \return number of bytes deserialized - */ - uint32_t Deserialize(Buffer::Iterator start, Buffer::Iterator end) override; - void Print(std::ostream& os) const override; - - /** - * \brief Needed when you try to deserialize a lonely IE inside other header - * - * \param start is the start of the buffer - * - * \return deserialized bytes - */ - virtual uint32_t DeserializeSingleIe(Buffer::Iterator start); - /// As soon as this is a vector, we define an Iterator - typedef std::vector>::iterator Iterator; - /** - * Returns Begin of the vector - * \returns the begin of the vector - */ - Iterator Begin(); - /** - * Returns End of the vector - * \returns the end of the vector - */ - Iterator End(); - /** - * add an IE, if maxSize has exceeded, returns false - * - * \param element wifi information element to add - * \returns true is added - */ - bool AddInformationElement(Ptr element); - /** - * vector of pointers to information elements is the body of IeVector - * - * \param id the element id to find - * \returns the information element - */ - Ptr FindFirst(WifiInformationElementId id) const; - - /** - * Check if the given WifiInformationElementVectors are equivalent. - * - * \param a another WifiInformationElementVector - * - * \return true if the given WifiInformationElementVectors are equivalent, - * false otherwise - */ - virtual bool operator==(const WifiInformationElementVector& a) const; - - protected: - /** - * typedef for a vector of WifiInformationElements. - */ - typedef std::vector> IE_VECTOR; - /** - * Current number of bytes - * \returns the number of bytes - */ - uint32_t GetSize() const; - IE_VECTOR m_elements; //!< Information element vector - uint16_t m_maxSize; //!< Size in bytes (actually, max packet length) -}; - -} // namespace ns3 - -#endif /* WIFI_INFORMATION_ELEMENT_VECTOR_H */