--- a/src/devices/mesh/dot11s/peer-management-protocol-mac.cc Wed Jul 29 11:19:59 2009 +0400
+++ b/src/devices/mesh/dot11s/peer-management-protocol-mac.cc Fri Jul 31 14:13:10 2009 +0400
@@ -27,6 +27,8 @@
#include "ns3/mesh-wifi-interface-mac.h"
#include "ns3/simulator.h"
#include "ns3/wifi-mac-header.h"
+#include "ns3/ie-vector.h"
+#include "ns3/log.h"
namespace ns3 {
namespace dot11s {
PeerManagementProtocolMac::PeerManagementProtocolMac (uint32_t interface,
@@ -54,18 +56,22 @@
Ptr<Packet> packet = const_packet->Copy ();
if (header.IsBeacon ())
{
- IeBeaconTiming beaconTiming;
- IeMeshId meshId;
- Ptr<Packet> myBeacon = packet->Copy ();
MgtBeaconHeader beacon_hdr;
- myBeacon->RemoveHeader (beacon_hdr);
- meshId.FindFirst (myBeacon);
+ packet->RemoveHeader (beacon_hdr);
+ //meshId.FindFirst (myBeacon);
bool meshBeacon = false;
- if ((beaconTiming.FindFirst (myBeacon)) && (m_protocol->GetMeshId ()->IsEqual (meshId)))
+ WifiInformationElementVector elements = WifiInformationElementVector::DeserializePacket (packet);
+ Ptr<IeBeaconTiming> beaconTiming = DynamicCast<IeBeaconTiming> (elements.FindFirst (IE11S_BEACON_TIMING));
+ Ptr<IeMeshId> meshId = DynamicCast<IeMeshId> (elements.FindFirst (IE11S_MESH_ID));
+
+ if ((beaconTiming != 0) && (meshId != 0))
{
- meshBeacon = true;
+ if (m_protocol->GetMeshId ()->IsEqual (*meshId))
+ {
+ meshBeacon = true;
+ }
}
- m_protocol->UpdatePeerBeaconTiming (m_ifIndex, meshBeacon, beaconTiming, header.GetAddr2 (),
+ m_protocol->UpdatePeerBeaconTiming (m_ifIndex, meshBeacon, *beaconTiming, header.GetAddr2 (),
Simulator::Now (), MicroSeconds (beacon_hdr.GetBeaconIntervalUs ()));
// Beacon shall not be dropeed. May be needed to another plugins
return true;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/ie-vector.cc Fri Jul 31 14:13:10 2009 +0400
@@ -0,0 +1,212 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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 <boyko@iitp.ru>
+ */
+
+#include "ie-vector.h"
+#include "ns3/test.h"
+#include "ns3/packet.h"
+// All information elements:
+#include "dot11s/ie-dot11s-beacon-timing.h"
+#include "dot11s/ie-dot11s-configuration.h"
+#include "dot11s/ie-dot11s-id.h"
+#include "dot11s/ie-dot11s-metric-report.h"
+#include "dot11s/ie-dot11s-peer-management.h"
+#include "dot11s/ie-dot11s-peering-protocol.h"
+#include "dot11s/ie-dot11s-perr.h"
+#include "dot11s/ie-dot11s-prep.h"
+#include "dot11s/ie-dot11s-preq.h"
+#include "dot11s/ie-dot11s-rann.h"
+
+namespace ns3 {
+WifiInformationElementVector::WifiInformationElementVector () :
+ m_maxSize (1500)
+{
+}
+WifiInformationElementVector::~WifiInformationElementVector ()
+{
+}
+void
+WifiInformationElementVector::SetMaxSize (uint16_t size)
+{
+ m_maxSize = size;
+}
+WifiInformationElementVector::Iterator
+WifiInformationElementVector::Begin ()
+{
+ return m_elements.begin ();
+}
+WifiInformationElementVector::Iterator
+WifiInformationElementVector::End ()
+{
+ return m_elements.end ();
+}
+bool
+WifiInformationElementVector::AddInformationElement (Ptr<WifiInformationElement> element)
+{
+ if (element->GetSerializedSize () + GetSize () > m_maxSize)
+ {
+ return false;
+ }
+ m_elements.push_back (element);
+ return true;
+}
+Ptr<WifiInformationElement>
+WifiInformationElementVector::FindFirst (enum WifiElementId id) const
+{
+ for (IE_VECTOR::const_iterator i = m_elements.begin (); i != m_elements.end (); i++)
+ {
+ if ((*i)->ElementId () == id)
+ {
+ return (*i);
+ }
+ }
+ return 0;
+}
+WifiInformationElementVector
+WifiInformationElementVector::DeserializePacket (Ptr<Packet> packet)
+{
+ WifiInformationElementVector retval;
+ EmptyIe ie;
+ while (packet->PeekHeader (ie))
+ {
+ Ptr<WifiInformationElement> newElement;
+ switch (ie.GetElementId ())
+ {
+ case IE11S_MESH_CONFIGURATION:
+ newElement = Create<dot11s::IeConfiguration> ();
+ break;
+ case IE11S_MESH_ID:
+ newElement = Create<dot11s::IeMeshId> ();
+ break;
+ case IE11S_LINK_METRIC_REPORT:
+ newElement = Create<dot11s::IeLinkMetricReport> ();
+ break;
+ case IE11S_PEERING_MANAGEMENT:
+ newElement = Create<dot11s::IePeerManagement> ();
+ break;
+ case IE11S_BEACON_TIMING:
+ newElement = Create<dot11s::IeBeaconTiming> ();
+ break;
+ case IE11S_RANN:
+ newElement = Create<dot11s::IeRann> ();
+ break;
+ case IE11S_PREQ:
+ newElement = Create<dot11s::IePreq> ();
+ break;
+ case IE11S_PREP:
+ newElement = Create<dot11s::IePrep> ();
+ break;
+ case IE11S_PERR:
+ newElement = Create<dot11s::IePerr> ();
+ break;
+ case IE11S_MESH_PEERING_PROTOCOL_VERSION:
+ newElement = Create<dot11s::IePeeringProtocol> ();
+ break;
+ default:
+ NS_FATAL_ERROR ("Information element " << (uint16_t) ie.GetElementId () << " is not implemented");
+ }
+ packet->RemoveHeader (*newElement);
+ if (!retval.AddInformationElement (newElement))
+ {
+ NS_FATAL_ERROR ("Check max size for information element!");
+ }
+ if (packet->GetSize () == 0)
+ {
+ return retval;
+ }
+ }
+ return retval;
+}
+Ptr<Packet>
+WifiInformationElementVector::MakePacket (bool sortByElementId)
+{
+ if (sortByElementId)
+ {
+ //TODO: sort
+ }
+ Ptr<Packet> packet = Create<Packet> ();
+ for (IE_VECTOR::const_iterator i = m_elements.begin (); i != m_elements.end (); i++)
+ {
+ packet->AddHeader (**i);
+ }
+ return packet;
+}
+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;
+}
+WifiInformationElementVector::EmptyIe::~EmptyIe ()
+{
+}
+WifiInformationElementVector::EmptyIe::EmptyIe () :
+ m_elementId (0), m_length (0)
+{
+}
+TypeId
+WifiInformationElementVector::EmptyIe::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::WifiInformationElementVector::EmptyIe")
+ .SetParent<Header> ();
+ return tid;
+}
+TypeId
+WifiInformationElementVector::EmptyIe::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+uint8_t
+WifiInformationElementVector::EmptyIe::GetLength ()
+{
+ return m_length;
+}
+uint8_t
+WifiInformationElementVector::EmptyIe::GetElementId ()
+{
+ return m_elementId;
+}
+uint32_t
+WifiInformationElementVector::EmptyIe::GetSerializedSize () const
+{
+ return 2;
+}
+void
+WifiInformationElementVector::EmptyIe::Serialize (Buffer::Iterator start) const
+{
+ start.WriteU8 (m_elementId);
+ start.WriteU8 (m_length);
+}
+uint32_t
+WifiInformationElementVector::EmptyIe::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ m_elementId = i.ReadU8 ();
+ m_length = i.ReadU8 ();
+ return i.GetDistanceFrom (start);
+}
+void
+WifiInformationElementVector::EmptyIe::Print (std::ostream &os) const
+{
+}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/ie-vector.h Fri Jul 31 14:13:10 2009 +0400
@@ -0,0 +1,77 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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: Kirill Andreev <andreev@iitp.ru>
+ */
+
+#ifndef IE_VECTOR_H
+#define IE_VECTOR_H
+
+#include "ns3/wifi-information-element.h"
+
+namespace ns3 {
+class Packet;
+/**
+ * \ingroup mesh
+ *
+ * \brief Information element vector
+ *
+ * Implements a vector of WifiInformationElement's
+ */
+class WifiInformationElementVector
+{
+public:
+ WifiInformationElementVector ();
+ ~WifiInformationElementVector ();
+ void SetMaxSize (uint16_t size);
+ typedef std::vector<Ptr<WifiInformationElement> >::iterator Iterator;
+ Iterator Begin ();
+ Iterator End ();
+ bool AddInformationElement (Ptr<WifiInformationElement> element);
+ Ptr<WifiInformationElement> FindFirst (enum WifiElementId id) const;
+ static WifiInformationElementVector DeserializePacket (Ptr<Packet> packet);
+ Ptr<Packet> MakePacket (bool sortByElementId = true);
+private:
+ uint32_t GetSize () const;
+ /**
+ * \brief Implements an empty information element: just elementId and length.
+ * \details Needed to understand, which information element we need to deserialize now
+ */
+ class EmptyIe : public Header
+ {
+ public:
+ EmptyIe ();
+ virtual ~EmptyIe ();
+ static TypeId GetTypeId ();
+ TypeId GetInstanceTypeId () const;
+ uint8_t GetLength ();
+ uint8_t GetElementId ();
+ virtual uint32_t GetSerializedSize () const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ virtual void Print (std::ostream &os) const;
+ private:
+ uint8_t m_elementId;
+ uint8_t m_length;
+ };
+ typedef std::vector<Ptr<WifiInformationElement> > IE_VECTOR;
+ IE_VECTOR m_elements;
+ /// Size in bytes (actually, max packet length)
+ uint16_t m_maxSize;
+};
+}
+#endif
--- a/src/devices/mesh/wifi-information-element.cc Wed Jul 29 11:19:59 2009 +0400
+++ b/src/devices/mesh/wifi-information-element.cc Fri Jul 31 14:13:10 2009 +0400
@@ -70,33 +70,6 @@
PrintInformation (os);
os << "</information_element>\n";
}
-
-bool
-WifiInformationElement::FindFirst (Ptr<Packet> packet)
-{
- const uint8_t * data = packet->PeekData ();
- uint32_t position = 0;
- while (position < packet->GetSize ())
- {
- if (data[position] == ElementId ())
- {
- Ptr<Packet> myIe = packet->CreateFragment (position, data[position + 1] + 2);
- NS_ASSERT (myIe->GetSize () == (uint32_t) (data[position + 1] + 2));
- myIe->RemoveHeader (*this);
- return true;
- }
- else
- {
- if (data[position] > ElementId ())
- {
- return false;
- }
- position += data[position + 1] + 2;
- }
- }
- return false;
-}
-
bool
operator< (WifiInformationElement const & a, WifiInformationElement const & b)
{
--- a/src/devices/mesh/wifi-information-element.h Wed Jul 29 11:19:59 2009 +0400
+++ b/src/devices/mesh/wifi-information-element.h Fri Jul 31 14:13:10 2009 +0400
@@ -1,7 +1,7 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
+/*
* 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;
@@ -14,7 +14,7 @@
* 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 <boyko@iitp.ru>
*/
@@ -30,14 +30,14 @@
class Packet;
/**
* \ingroup mesh
- *
- * \brief Enum of all known information element id (aka tags).
- *
- * For now only 802.11s (mesh) related elements are supported here (so 11S prefix),
+ *
+ * \brief Enum of all known information element id (aka tags).
+ *
+ * For now only 802.11s (mesh) related elements are supported here (so 11S prefix),
* but this can change in future.
- *
- * Note that 802.11s element ids are not yet officially assigned, we use ones
- * compatible with open80211s (http://o11s.org/) implementation.
+ *
+ * Note that 802.11s element ids are not yet officially assigned, we use ones
+ * compatible with open80211s (http://o11s.org/) implementation.
*/
enum WifiElementId {
/* begin of open80211s-compatible IDs */
@@ -63,35 +63,35 @@
/* begin of open80211s-compatible IDs */
IE11S_PREQ = 68,
IE11S_PREP = 69,
- IE11S_PERR = 70,
+ IE11S_PERR = 70,
/* end of open80211s-compatible IDs */
IE11S_PROXY_UPDATE = 37,
IE11S_PROXY_UPDATE_CONFIRMATION,
IE11S_ABBREVIATED_HANDSHAKE,
IE11S_MESH_PEERING_PROTOCOL_VERSION = 74,
-};
-
+};
+
/**
* \ingroup mesh
- *
+ *
* \brief Information element, as defined in 802.11-2007 standard
- *
+ *
* Elements are defined to have a common general format consisting of a 1 octet Element ID field, a 1 octet
* length field, and a variable-length element-specific information field. Each element is assigned a unique
* Element ID as defined in this standard. The Length field specifies the number of octets in the Information
- * field.
+ * field.
*/
-class WifiInformationElement : public Header,
- public RefCountBase // need this to use Ptr<WifiInformationElement>
+class WifiInformationElement : public Header,
+ public RefCountBase // need this to use Ptr<WifiInformationElement>
{
public:
/// Support object system
static TypeId GetTypeId ();
TypeId GetInstanceTypeId () const;
-
+
/// virtual d-tor for subclasses
virtual ~WifiInformationElement () {}
-
+
///\name Inherited from Header
//\{
/**
@@ -120,37 +120,31 @@
* \return the number of bytes read.
*
* This method is used by Packet::RemoveHeader to
- * re-create a header from the byte buffer of a packet.
+ * re-create a header from the byte buffer of a packet.
* The data read is expected to
* match bit-for-bit the representation of this header in real
* networks.
*/
virtual uint32_t Deserialize (Buffer::Iterator start);
/**
- * This method is used by Packet::Print to print the
+ * This method is used by Packet::Print to print the
* content of a trailer as ascii data to a c++ output stream.
* Although the trailer is free to format its output as it
* wishes, it is recommended to follow a few rules to integrate
- * with the packet pretty printer: start with flags, small field
- * values located between a pair of parens. Values should be separated
- * by whitespace. Follow the parens with the important fields,
+ * with the packet pretty printer: start with flags, small field
+ * values located between a pair of parens. Values should be separated
+ * by whitespace. Follow the parens with the important fields,
* separated by whitespace.
* i.e.: (field1 val1 field2 val2 field3 val3) field4 val4 field5 val5
*/
virtual void Print (std::ostream &os) const;
- /**
- * This method takes a packet which must be a list of information
- * elements and looks for an information element of MINE Element ID
- */
- bool FindFirst (Ptr<Packet> packet);
//\}
-
-protected:
- ///\name Each subclass must implement
+ ///\name Each subclass must implement
//\{
/// Own unique Element ID
virtual WifiElementId ElementId () const = 0;
/// Length of serialized information
+protected:
virtual uint8_t GetInformationSize () const = 0;
/// Serialize information
virtual void SerializeInformation (Buffer::Iterator start) const = 0;
@@ -159,7 +153,7 @@
/// Print information
virtual void PrintInformation (std::ostream &os) const = 0;
//\}
-
+
/// Compare information elements using Element ID
friend bool operator< (WifiInformationElement const & a, WifiInformationElement const & b);
};
@@ -173,7 +167,7 @@
{
public:
IeTest (const char * name) : Test (name) {}
- /// Test roundtrip serialization
+ /// Test round-trip serialization
template <typename IE> bool TestRoundtripSerialization (IE a);
};
@@ -181,7 +175,7 @@
IeTest::TestRoundtripSerialization (IE a)
{
bool result (true);
-
+
Ptr<Packet> packet = Create<Packet> ();
packet->AddHeader (a);
IE b;
@@ -189,13 +183,13 @@
NS_TEST_ASSERT_EQUAL (a, b);
packet->AddHeader (a);
IE c;
- bool ok = c.FindFirst (packet);
+ bool ok = packet->RemoveHeader (c);
NS_TEST_ASSERT (ok);
NS_TEST_ASSERT_EQUAL (a, c);
-
+
return result;
}
-#endif
+#endif
} // namespace ns3
#endif /* WIFIINFORMATIONELEMENT_H_ */
--- a/src/devices/mesh/wscript Wed Jul 29 11:19:59 2009 +0400
+++ b/src/devices/mesh/wscript Fri Jul 31 14:13:10 2009 +0400
@@ -5,6 +5,7 @@
obj.source = [
'wifi-information-element.cc',
+ 'ie-vector.cc',
'mesh-point-device.cc',
'mesh-l2-routing-protocol.cc',
'mesh-wifi-beacon.cc',
@@ -14,6 +15,7 @@
headers.module = 'mesh'
headers.source = [
'wifi-information-element.h',
+ 'ie-vector.h',
'mesh-point-device.h',
'mesh-l2-routing-protocol.h',
'mesh-wifi-beacon.h',