replace RefCountBase with SimpleRefCount<> to avoid duplicate refcounting implementations.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
3 * Copyright (c) 2009 IITP RAS
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Author: Pavel Boyko <boyko@iitp.ru>
21 #include "wifi-information-element-vector.h"
22 #include "ns3/packet.h"
25 #include "ns3/hwmp-protocol.h"
26 // All information elements:
27 #include "dot11s/ie-dot11s-beacon-timing.h"
28 #include "dot11s/ie-dot11s-configuration.h"
29 #include "dot11s/ie-dot11s-id.h"
30 #include "dot11s/ie-dot11s-metric-report.h"
31 #include "dot11s/ie-dot11s-peer-management.h"
32 #include "dot11s/ie-dot11s-peering-protocol.h"
33 #include "dot11s/ie-dot11s-perr.h"
34 #include "dot11s/ie-dot11s-prep.h"
35 #include "dot11s/ie-dot11s-preq.h"
36 #include "dot11s/ie-dot11s-rann.h"
40 WifiInformationElement::~WifiInformationElement ()
44 operator< (WifiInformationElement const & a, WifiInformationElement const & b)
46 return (a.ElementId () < b.ElementId ());
49 WifiInformationElementVector::WifiInformationElementVector () :
53 WifiInformationElementVector::~WifiInformationElementVector ()
55 for (IE_VECTOR::iterator i = m_elements.begin (); i != m_elements.end (); i++)
62 WifiInformationElementVector::GetTypeId ()
64 static TypeId tid = TypeId ("ns3::WifiInformationElementVector")
66 .AddConstructor<WifiInformationElementVector> ();
70 WifiInformationElementVector::GetInstanceTypeId () const
75 WifiInformationElementVector::GetSerializedSize () const
80 WifiInformationElementVector::Serialize (Buffer::Iterator start) const
82 for(IE_VECTOR::const_iterator i = m_elements.begin (); i != m_elements.end (); i ++)
84 start.WriteU8((*i)->ElementId ());
85 start.WriteU8 ((*i)->GetInformationSize ());
86 (*i)->SerializeInformation (start);
87 start.Next ((*i)->GetInformationSize ());
91 WifiInformationElementVector::Deserialize (Buffer::Iterator start)
93 Buffer::Iterator i = start;
94 uint32_t size = start.GetSize();
97 uint32_t deserialized = DeserializeSingleIe(i);
98 i.Next (deserialized);
101 return i.GetDistanceFrom(start);
104 WifiInformationElementVector::DeserializeSingleIe(Buffer::Iterator start)
106 Buffer::Iterator i = start;
107 uint8_t id = i.ReadU8 ();
108 uint8_t length = i.ReadU8 ();
109 Ptr<WifiInformationElement> newElement;
112 case IE11S_MESH_CONFIGURATION:
113 newElement = Create<dot11s::IeConfiguration> ();
116 newElement = Create<dot11s::IeMeshId> ();
118 case IE11S_LINK_METRIC_REPORT:
119 newElement = Create<dot11s::IeLinkMetricReport> ();
121 case IE11S_PEERING_MANAGEMENT:
122 newElement = Create<dot11s::IePeerManagement> ();
124 case IE11S_BEACON_TIMING:
125 newElement = Create<dot11s::IeBeaconTiming> ();
128 newElement = Create<dot11s::IeRann> ();
131 newElement = Create<dot11s::IePreq> ();
134 newElement = Create<dot11s::IePrep> ();
137 newElement = Create<dot11s::IePerr> ();
139 case IE11S_MESH_PEERING_PROTOCOL_VERSION:
140 newElement = Create<dot11s::IePeeringProtocol> ();
143 NS_FATAL_ERROR ("Information element " << (uint16_t) id << " is not implemented");
146 if (GetSize () + length > m_maxSize)
148 NS_FATAL_ERROR ("Check max size for information element!");
150 newElement->DeserializeInformation (i, length);
152 m_elements.push_back (newElement);
153 return i.GetDistanceFrom(start);
156 WifiInformationElementVector::Print(std::ostream & os) const
161 WifiInformationElementVector::SetMaxSize (uint16_t size)
165 WifiInformationElementVector::Iterator
166 WifiInformationElementVector::Begin ()
168 return m_elements.begin ();
170 WifiInformationElementVector::Iterator
171 WifiInformationElementVector::End ()
173 return m_elements.end ();
176 WifiInformationElementVector::AddInformationElement (Ptr<WifiInformationElement> element)
178 if (element->GetInformationSize () + 2 + GetSize () > m_maxSize)
182 m_elements.push_back (element);
185 Ptr<WifiInformationElement>
186 WifiInformationElementVector::FindFirst (enum WifiElementId id) const
188 for (IE_VECTOR::const_iterator i = m_elements.begin (); i != m_elements.end (); i++)
190 if ((*i)->ElementId () == id)
201 operator () (Ptr<WifiInformationElement> a, Ptr<WifiInformationElement> b) const
203 return ((*PeekPointer (a)) < (*PeekPointer (b)));
208 WifiInformationElementVector::GetSize () const
211 for (IE_VECTOR::const_iterator i = m_elements.begin (); i != m_elements.end (); i++)
213 size += ((*i)->GetInformationSize () + 2);
219 operator== (const WifiInformationElementVector & a, const WifiInformationElementVector & b)
221 if (a.m_elements.size () != b.m_elements.size ())
226 WifiInformationElementVector::IE_VECTOR::const_iterator j = b.m_elements.begin ();
227 for (WifiInformationElementVector::IE_VECTOR::const_iterator i = a.m_elements.begin (); i
228 != a.m_elements.end (); i++, j++)
230 if ((*i)->ElementId () != (*j)->ElementId ())
234 if ((*i)->GetInformationSize () != (*j)->GetInformationSize ())
238 uint8_t id = (*i)->ElementId ();
241 case IE11S_MESH_CONFIGURATION:
242 if (DynamicCast<dot11s::IeConfiguration> ((*i)) == 0)
246 if (DynamicCast<dot11s::IeConfiguration> ((*j)) == 0)
250 if (!(*DynamicCast<dot11s::IeConfiguration> ((*i)) == *DynamicCast<dot11s::IeConfiguration> ((*j))))
256 if (DynamicCast<dot11s::IeMeshId> ((*i)) == 0)
260 if (DynamicCast<dot11s::IeMeshId> ((*j)) == 0)
264 if (!(*DynamicCast<dot11s::IeMeshId> ((*i)) == *DynamicCast<dot11s::IeMeshId> ((*j))))
269 case IE11S_LINK_METRIC_REPORT:
270 if (DynamicCast<dot11s::IeLinkMetricReport> ((*i)) == 0)
274 if (DynamicCast<dot11s::IeLinkMetricReport> ((*j)) == 0)
278 if (!(*DynamicCast<dot11s::IeLinkMetricReport> ((*i)) == *DynamicCast<dot11s::IeLinkMetricReport> (
284 case IE11S_PEERING_MANAGEMENT:
285 if (DynamicCast<dot11s::IePeerManagement> ((*i)) == 0)
289 if (DynamicCast<dot11s::IePeerManagement> ((*j)) == 0)
293 if (!(*DynamicCast<dot11s::IePeerManagement> ((*i)) == *DynamicCast<dot11s::IePeerManagement> ((*j))))
298 case IE11S_BEACON_TIMING:
299 if (DynamicCast<dot11s::IeBeaconTiming> ((*i)) == 0)
303 if (DynamicCast<dot11s::IeBeaconTiming> ((*j)) == 0)
307 if (!(*DynamicCast<dot11s::IeBeaconTiming> ((*i)) == *DynamicCast<dot11s::IeBeaconTiming> ((*j))))
313 if (DynamicCast<dot11s::IeRann> ((*i)) == 0)
317 if (DynamicCast<dot11s::IeRann> ((*j)) == 0)
321 if (!(*DynamicCast<dot11s::IeRann> ((*i)) == *DynamicCast<dot11s::IeRann> ((*j))))
327 if (DynamicCast<dot11s::IePreq> ((*i)) == 0)
331 if (DynamicCast<dot11s::IePreq> ((*j)) == 0)
335 if (!(*DynamicCast<dot11s::IePreq> ((*i)) == *DynamicCast<dot11s::IePreq> ((*j))))
341 if (DynamicCast<dot11s::IePrep> ((*i)) == 0)
345 if (DynamicCast<dot11s::IePrep> ((*j)) == 0)
349 if (!(*DynamicCast<dot11s::IePrep> ((*i)) == *DynamicCast<dot11s::IePrep> ((*j))))
356 if (DynamicCast<dot11s::IePerr> ((*i)) == 0)
360 if (DynamicCast<dot11s::IePerr> ((*j)) == 0)
364 if (!(*DynamicCast<dot11s::IePerr> ((*i)) == *DynamicCast<dot11s::IePerr> ((*j))))
369 case IE11S_MESH_PEERING_PROTOCOL_VERSION:
372 NS_FATAL_ERROR ("Information element " << (uint16_t) id << " is not implemented");
379 //-----------------------------------------------------------------------------
381 //-----------------------------------------------------------------------------
382 /// Built-in self test for WifiInformationElementVector and all IE
383 struct WifiInformationElementVectorBist : public TestCase
385 WifiInformationElementVectorBist () :
386 TestCase ("Serializarion test for all mesh information elements")
393 WifiInformationElementVectorBist::DoRun ()
395 WifiInformationElementVector vector;
398 Ptr<dot11s::IeMeshId> meshId = Create<dot11s::IeMeshId> ("qwerty");
399 vector.AddInformationElement (meshId);
402 Ptr<dot11s::IeConfiguration> config = Create<dot11s::IeConfiguration> ();
403 vector.AddInformationElement (config);
406 Ptr<dot11s::IeLinkMetricReport> report = Create<dot11s::IeLinkMetricReport> (123456);
407 vector.AddInformationElement (report);
410 Ptr<dot11s::IePeerManagement> peerMan1 = Create<dot11s::IePeerManagement> ();
411 peerMan1->SetPeerOpen (1);
412 Ptr<dot11s::IePeerManagement> peerMan2 = Create<dot11s::IePeerManagement> ();
413 peerMan2->SetPeerConfirm (1, 2);
414 Ptr<dot11s::IePeerManagement> peerMan3 = Create<dot11s::IePeerManagement> ();
415 peerMan3->SetPeerClose (1, 2, dot11s::REASON11S_MESH_CAPABILITY_POLICY_VIOLATION);
416 vector.AddInformationElement (peerMan1);
417 vector.AddInformationElement (peerMan2);
418 vector.AddInformationElement (peerMan3);
421 Ptr<dot11s::IeBeaconTiming> beaconTiming = Create<dot11s::IeBeaconTiming> ();
422 beaconTiming->AddNeighboursTimingElementUnit (1, Seconds (1.0), Seconds (4.0));
423 beaconTiming->AddNeighboursTimingElementUnit (2, Seconds (2.0), Seconds (3.0));
424 beaconTiming->AddNeighboursTimingElementUnit (3, Seconds (3.0), Seconds (2.0));
425 beaconTiming->AddNeighboursTimingElementUnit (4, Seconds (4.0), Seconds (1.0));
426 vector.AddInformationElement (beaconTiming);
429 Ptr<dot11s::IeRann> rann = Create<dot11s::IeRann> ();
431 rann->SetHopcount (2);
433 rann->DecrementTtl ();
434 NS_TEST_ASSERT_MSG_EQ (rann->GetTtl (), 3, "SetTtl works");
435 rann->SetOriginatorAddress (Mac48Address ("11:22:33:44:55:66"));
436 rann->SetDestSeqNumber (5);
438 rann->IncrementMetric (2);
439 NS_TEST_ASSERT_MSG_EQ (rann->GetMetric (), 8, "SetMetric works");
440 vector.AddInformationElement (rann);
443 Ptr<dot11s::IePreq> preq = Create<dot11s::IePreq> ();
444 preq->SetHopcount (0);
447 preq->SetOriginatorAddress (Mac48Address ("11:22:33:44:55:66"));
448 preq->SetOriginatorSeqNumber (3);
449 preq->SetLifetime (4);
450 preq->AddDestinationAddressElement (false, false, Mac48Address ("11:11:11:11:11:11"), 5);
451 preq->AddDestinationAddressElement (false, false, Mac48Address ("22:22:22:22:22:22"), 6);
452 vector.AddInformationElement (preq);
455 Ptr<dot11s::IePrep> prep = Create<dot11s::IePrep> ();
457 prep->SetHopcount (11);
459 prep->SetDestinationAddress (Mac48Address ("11:22:33:44:55:66"));
460 prep->SetDestinationSeqNumber (123);
461 prep->SetLifetime (5000);
462 prep->SetMetric (4321);
463 prep->SetOriginatorAddress (Mac48Address ("33:00:22:00:11:00"));
464 prep->SetOriginatorSeqNumber (666);
465 vector.AddInformationElement (prep);
468 Ptr<dot11s::IePerr> perr = Create<dot11s::IePerr> ();
469 dot11s::HwmpProtocol::FailedDestination dest;
470 dest.destination = Mac48Address ("11:22:33:44:55:66");
472 perr->AddAddressUnit (dest);
473 dest.destination = Mac48Address ("10:20:30:40:50:60");
475 perr->AddAddressUnit (dest);
476 dest.destination = Mac48Address ("01:02:03:04:05:06");
478 perr->AddAddressUnit (dest);
479 vector.AddInformationElement (perr);
481 Ptr<Packet> packet = Create<Packet> ();
482 packet->AddHeader (vector);
483 WifiInformationElementVector resultVector;
484 packet->RemoveHeader (resultVector);
485 NS_TEST_ASSERT_MSG_EQ (vector, resultVector, "Roundtrip serialization of all known information elements works");
490 class MeshTestSuite : public TestSuite
496 MeshTestSuite::MeshTestSuite ()
497 : TestSuite ("devices-mesh", UNIT)
499 AddTestCase (new WifiInformationElementVectorBist);
502 MeshTestSuite g_meshTestSuite;