OLD | NEW |
(Empty) | |
| 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| 2 /* |
| 3 * Copyright (c) 2009 IITP RAS |
| 4 * |
| 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; |
| 8 * |
| 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. |
| 13 * |
| 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 |
| 17 * |
| 18 * Author: Pavel Boyko <boyko@iitp.ru> |
| 19 */ |
| 20 |
| 21 #include "wifi-information-element-vector.h" |
| 22 #include "ns3/packet.h" |
| 23 #include <algorithm> |
| 24 #include "ns3/test.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" |
| 37 |
| 38 namespace ns3 { |
| 39 bool |
| 40 operator< (WifiInformationElement const & a, WifiInformationElement const & b) |
| 41 { |
| 42 return (a.ElementId () < b.ElementId ()); |
| 43 } |
| 44 |
| 45 WifiInformationElementVector::WifiInformationElementVector () : |
| 46 m_maxSize (1500) |
| 47 { |
| 48 } |
| 49 WifiInformationElementVector::~WifiInformationElementVector () |
| 50 { |
| 51 } |
| 52 TypeId |
| 53 WifiInformationElementVector::GetTypeId () |
| 54 { |
| 55 static TypeId tid = TypeId ("ns3::WifiInformationElementVector") |
| 56 .SetParent<Header> (); |
| 57 return tid; |
| 58 } |
| 59 TypeId |
| 60 WifiInformationElementVector::GetInstanceTypeId () const |
| 61 { |
| 62 return GetTypeId (); |
| 63 } |
| 64 uint32_t |
| 65 WifiInformationElementVector::GetSerializedSize () const |
| 66 { |
| 67 return GetSize (); |
| 68 } |
| 69 void |
| 70 WifiInformationElementVector::Serialize (Buffer::Iterator start) const |
| 71 { |
| 72 for(std::vector<Ptr<WifiInformationElement> >::const_iterator i = m_elements.b
egin (); i != m_elements.end (); i ++) |
| 73 { |
| 74 start.WriteU8((*i)->ElementId ()); |
| 75 start.WriteU8 ((*i)->GetInformationSize ()); |
| 76 (*i)->SerializeInformation (start); |
| 77 start.Next ((*i)->GetInformationSize ()); |
| 78 } |
| 79 } |
| 80 uint32_t |
| 81 WifiInformationElementVector::Deserialize (Buffer::Iterator start) |
| 82 { |
| 83 Buffer::Iterator i = start; |
| 84 uint32_t size = start.GetSize(); |
| 85 while (size > 0) |
| 86 { |
| 87 uint32_t deserialized = DeserializeSingleIe(i); |
| 88 i.Next (deserialized); |
| 89 size -= deserialized; |
| 90 } |
| 91 return i.GetDistanceFrom(start); |
| 92 } |
| 93 uint32_t |
| 94 WifiInformationElementVector::DeserializeSingleIe(Buffer::Iterator start) |
| 95 { |
| 96 Buffer::Iterator i = start; |
| 97 uint8_t id = i.ReadU8 (); |
| 98 uint8_t length = i.ReadU8 (); |
| 99 Ptr<WifiInformationElement> newElement; |
| 100 switch (id) |
| 101 { |
| 102 case IE11S_MESH_CONFIGURATION: |
| 103 newElement = Create<dot11s::IeConfiguration> (); |
| 104 break; |
| 105 case IE11S_MESH_ID: |
| 106 newElement = Create<dot11s::IeMeshId> (); |
| 107 break; |
| 108 case IE11S_LINK_METRIC_REPORT: |
| 109 newElement = Create<dot11s::IeLinkMetricReport> (); |
| 110 break; |
| 111 case IE11S_PEERING_MANAGEMENT: |
| 112 newElement = Create<dot11s::IePeerManagement> (); |
| 113 break; |
| 114 case IE11S_BEACON_TIMING: |
| 115 newElement = Create<dot11s::IeBeaconTiming> (); |
| 116 break; |
| 117 case IE11S_RANN: |
| 118 newElement = Create<dot11s::IeRann> (); |
| 119 break; |
| 120 case IE11S_PREQ: |
| 121 newElement = Create<dot11s::IePreq> (); |
| 122 break; |
| 123 case IE11S_PREP: |
| 124 newElement = Create<dot11s::IePrep> (); |
| 125 break; |
| 126 case IE11S_PERR: |
| 127 newElement = Create<dot11s::IePerr> (); |
| 128 break; |
| 129 case IE11S_MESH_PEERING_PROTOCOL_VERSION: |
| 130 newElement = Create<dot11s::IePeeringProtocol> (); |
| 131 break; |
| 132 default: |
| 133 NS_FATAL_ERROR ("Information element " << (uint16_t) id << " is not implemen
ted"); |
| 134 return 0; |
| 135 } |
| 136 if (GetSize () + length > m_maxSize) |
| 137 { |
| 138 NS_FATAL_ERROR ("Check max size for information element!"); |
| 139 } |
| 140 newElement->DeserializeInformation (i, length); |
| 141 i.Next (length); |
| 142 m_elements.push_back (newElement); |
| 143 return i.GetDistanceFrom(start); |
| 144 } |
| 145 void |
| 146 WifiInformationElementVector::Print(std::ostream & os) const |
| 147 { |
| 148 //TODO |
| 149 } |
| 150 void |
| 151 WifiInformationElementVector::SetMaxSize (uint16_t size) |
| 152 { |
| 153 m_maxSize = size; |
| 154 } |
| 155 WifiInformationElementVector::Iterator |
| 156 WifiInformationElementVector::Begin () |
| 157 { |
| 158 return m_elements.begin (); |
| 159 } |
| 160 WifiInformationElementVector::Iterator |
| 161 WifiInformationElementVector::End () |
| 162 { |
| 163 return m_elements.end (); |
| 164 } |
| 165 bool |
| 166 WifiInformationElementVector::AddInformationElement (Ptr<WifiInformationElement>
element) |
| 167 { |
| 168 if (element->GetInformationSize () + 2 + GetSize () > m_maxSize) |
| 169 { |
| 170 return false; |
| 171 } |
| 172 m_elements.push_back (element); |
| 173 return true; |
| 174 } |
| 175 Ptr<WifiInformationElement> |
| 176 WifiInformationElementVector::FindFirst (enum WifiElementId id) const |
| 177 { |
| 178 for (IE_VECTOR::const_iterator i = m_elements.begin (); i != m_elements.end ()
; i++) |
| 179 { |
| 180 if ((*i)->ElementId () == id) |
| 181 { |
| 182 return (*i); |
| 183 } |
| 184 } |
| 185 return 0; |
| 186 } |
| 187 namespace { |
| 188 struct PIEComparator |
| 189 { |
| 190 bool |
| 191 operator () (Ptr<WifiInformationElement> a, Ptr<WifiInformationElement> b) con
st |
| 192 { |
| 193 return ((*PeekPointer (a)) < (*PeekPointer (b))); |
| 194 } |
| 195 }; |
| 196 } |
| 197 uint32_t |
| 198 WifiInformationElementVector::GetSize () const |
| 199 { |
| 200 uint32_t size = 0; |
| 201 for (IE_VECTOR::const_iterator i = m_elements.begin (); i != m_elements.end ()
; i++) |
| 202 { |
| 203 size += ((*i)->GetInformationSize () + 2); |
| 204 } |
| 205 return size; |
| 206 } |
| 207 bool |
| 208 operator== (const WifiInformationElementVector & a, const WifiInformationElement
Vector & b) |
| 209 { |
| 210 if (a.m_elements.size () != b.m_elements.size ()) |
| 211 { |
| 212 NS_ASSERT(false); |
| 213 return false; |
| 214 } |
| 215 WifiInformationElementVector::IE_VECTOR::const_iterator j = b.m_elements.begin
(); |
| 216 for (WifiInformationElementVector::IE_VECTOR::const_iterator i = a.m_elements.
begin (); i |
| 217 != a.m_elements.end (); i++, j++) |
| 218 { |
| 219 if ((*i)->ElementId () != (*j)->ElementId ()) |
| 220 { |
| 221 return false; |
| 222 } |
| 223 if ((*i)->GetInformationSize () != (*j)->GetInformationSize ()) |
| 224 { |
| 225 return false; |
| 226 } |
| 227 uint8_t id = (*i)->ElementId (); |
| 228 switch (id) |
| 229 { |
| 230 case IE11S_MESH_CONFIGURATION: |
| 231 if (DynamicCast<dot11s::IeConfiguration> ((*i)) == 0) |
| 232 { |
| 233 return false; |
| 234 } |
| 235 if (DynamicCast<dot11s::IeConfiguration> ((*j)) == 0) |
| 236 { |
| 237 return false; |
| 238 } |
| 239 if (!(*DynamicCast<dot11s::IeConfiguration> ((*i)) == *DynamicCast<dot11
s::IeConfiguration> ((*j)))) |
| 240 { |
| 241 return false; |
| 242 } |
| 243 break; |
| 244 case IE11S_MESH_ID: |
| 245 if (DynamicCast<dot11s::IeMeshId> ((*i)) == 0) |
| 246 { |
| 247 return false; |
| 248 } |
| 249 if (DynamicCast<dot11s::IeMeshId> ((*j)) == 0) |
| 250 { |
| 251 return false; |
| 252 } |
| 253 if (!(*DynamicCast<dot11s::IeMeshId> ((*i)) == *DynamicCast<dot11s::IeMe
shId> ((*j)))) |
| 254 { |
| 255 return false; |
| 256 } |
| 257 break; |
| 258 case IE11S_LINK_METRIC_REPORT: |
| 259 if (DynamicCast<dot11s::IeLinkMetricReport> ((*i)) == 0) |
| 260 { |
| 261 return false; |
| 262 } |
| 263 if (DynamicCast<dot11s::IeLinkMetricReport> ((*j)) == 0) |
| 264 { |
| 265 return false; |
| 266 } |
| 267 if (!(*DynamicCast<dot11s::IeLinkMetricReport> ((*i)) == *DynamicCast<do
t11s::IeLinkMetricReport> ( |
| 268 (*j)))) |
| 269 { |
| 270 return false; |
| 271 } |
| 272 break; |
| 273 case IE11S_PEERING_MANAGEMENT: |
| 274 if (DynamicCast<dot11s::IePeerManagement> ((*i)) == 0) |
| 275 { |
| 276 return false; |
| 277 } |
| 278 if (DynamicCast<dot11s::IePeerManagement> ((*j)) == 0) |
| 279 { |
| 280 return false; |
| 281 } |
| 282 if (!(*DynamicCast<dot11s::IePeerManagement> ((*i)) == *DynamicCast<dot1
1s::IePeerManagement> ((*j)))) |
| 283 { |
| 284 return false; |
| 285 } |
| 286 break; |
| 287 case IE11S_BEACON_TIMING: |
| 288 if (DynamicCast<dot11s::IeBeaconTiming> ((*i)) == 0) |
| 289 { |
| 290 return false; |
| 291 } |
| 292 if (DynamicCast<dot11s::IeBeaconTiming> ((*j)) == 0) |
| 293 { |
| 294 return false; |
| 295 } |
| 296 if (!(*DynamicCast<dot11s::IeBeaconTiming> ((*i)) == *DynamicCast<dot11s
::IeBeaconTiming> ((*j)))) |
| 297 { |
| 298 return false; |
| 299 } |
| 300 break; |
| 301 case IE11S_RANN: |
| 302 if (DynamicCast<dot11s::IeRann> ((*i)) == 0) |
| 303 { |
| 304 return false; |
| 305 } |
| 306 if (DynamicCast<dot11s::IeRann> ((*j)) == 0) |
| 307 { |
| 308 return false; |
| 309 } |
| 310 if (!(*DynamicCast<dot11s::IeRann> ((*i)) == *DynamicCast<dot11s::IeRann
> ((*j)))) |
| 311 { |
| 312 return false; |
| 313 } |
| 314 break; |
| 315 case IE11S_PREQ: |
| 316 if (DynamicCast<dot11s::IePreq> ((*i)) == 0) |
| 317 { |
| 318 return false; |
| 319 } |
| 320 if (DynamicCast<dot11s::IePreq> ((*j)) == 0) |
| 321 { |
| 322 return false; |
| 323 } |
| 324 if (!(*DynamicCast<dot11s::IePreq> ((*i)) == *DynamicCast<dot11s::IePreq
> ((*j)))) |
| 325 { |
| 326 return false; |
| 327 } |
| 328 break; |
| 329 case IE11S_PREP: |
| 330 if (DynamicCast<dot11s::IePrep> ((*i)) == 0) |
| 331 { |
| 332 return false; |
| 333 } |
| 334 if (DynamicCast<dot11s::IePrep> ((*j)) == 0) |
| 335 { |
| 336 return false; |
| 337 } |
| 338 if (!(*DynamicCast<dot11s::IePrep> ((*i)) == *DynamicCast<dot11s::IePrep
> ((*j)))) |
| 339 { |
| 340 return false; |
| 341 } |
| 342 |
| 343 break; |
| 344 case IE11S_PERR: |
| 345 if (DynamicCast<dot11s::IePerr> ((*i)) == 0) |
| 346 { |
| 347 return false; |
| 348 } |
| 349 if (DynamicCast<dot11s::IePerr> ((*j)) == 0) |
| 350 { |
| 351 return false; |
| 352 } |
| 353 if (!(*DynamicCast<dot11s::IePerr> ((*i)) == *DynamicCast<dot11s::IePerr
> ((*j)))) |
| 354 { |
| 355 return false; |
| 356 } |
| 357 break; |
| 358 case IE11S_MESH_PEERING_PROTOCOL_VERSION: |
| 359 break; |
| 360 default: |
| 361 NS_FATAL_ERROR ("Information element " << (uint16_t) id << " is not impl
emented"); |
| 362 return false; |
| 363 } |
| 364 } |
| 365 return true; |
| 366 } |
| 367 #ifdef RUN_SELF_TESTS |
| 368 |
| 369 /// Built-in self test for WifiInformationElementVector |
| 370 struct WifiInformationElementVectorBist : public Test |
| 371 { |
| 372 WifiInformationElementVectorBist () : |
| 373 Test ("Mesh/WifiInformationElementVector") |
| 374 { |
| 375 }; |
| 376 virtual bool |
| 377 RunTests (); |
| 378 }; |
| 379 |
| 380 /// Test instance |
| 381 static WifiInformationElementVectorBist g_IePrepBist; |
| 382 |
| 383 bool |
| 384 WifiInformationElementVectorBist::RunTests () |
| 385 { |
| 386 bool result = true; |
| 387 WifiInformationElementVector vector; |
| 388 { |
| 389 //Mesh ID test |
| 390 Ptr<dot11s::IeMeshId> meshId = Create<dot11s::IeMeshId> ("qwerty"); |
| 391 vector.AddInformationElement (meshId); |
| 392 } |
| 393 { |
| 394 Ptr<dot11s::IeConfiguration> config = Create<dot11s::IeConfiguration> (); |
| 395 vector.AddInformationElement (config); |
| 396 } |
| 397 { |
| 398 Ptr<dot11s::IeLinkMetricReport> report = Create<dot11s::IeLinkMetricReport>
(123456); |
| 399 vector.AddInformationElement (report); |
| 400 } |
| 401 { |
| 402 Ptr<dot11s::IePeerManagement> peerMan1 = Create<dot11s::IePeerManagement> ()
; |
| 403 peerMan1->SetPeerOpen (1); |
| 404 Ptr<dot11s::IePeerManagement> peerMan2 = Create<dot11s::IePeerManagement> ()
; |
| 405 peerMan2->SetPeerConfirm (1, 2); |
| 406 Ptr<dot11s::IePeerManagement> peerMan3 = Create<dot11s::IePeerManagement> ()
; |
| 407 peerMan3->SetPeerClose (1, 2, dot11s::REASON11S_MESH_CAPABILITY_POLICY_VIOLA
TION); |
| 408 vector.AddInformationElement (peerMan1); |
| 409 vector.AddInformationElement (peerMan2); |
| 410 vector.AddInformationElement (peerMan3); |
| 411 } |
| 412 { |
| 413 Ptr<dot11s::IeBeaconTiming> beaconTiming = Create<dot11s::IeBeaconTiming> (
); |
| 414 beaconTiming->AddNeighboursTimingElementUnit (1, Seconds (1.0), Seconds (4.0
)); |
| 415 beaconTiming->AddNeighboursTimingElementUnit (2, Seconds (2.0), Seconds (3.0
)); |
| 416 beaconTiming->AddNeighboursTimingElementUnit (3, Seconds (3.0), Seconds (2.0
)); |
| 417 beaconTiming->AddNeighboursTimingElementUnit (4, Seconds (4.0), Seconds (1.0
)); |
| 418 vector.AddInformationElement (beaconTiming); |
| 419 } |
| 420 { |
| 421 Ptr<dot11s::IeRann> rann = Create<dot11s::IeRann> (); |
| 422 rann->SetFlags (1); |
| 423 rann->SetHopcount (2); |
| 424 rann->SetTTL (4); |
| 425 rann->DecrementTtl (); |
| 426 NS_TEST_ASSERT_EQUAL (rann->GetTtl (), 3); |
| 427 rann->SetOriginatorAddress (Mac48Address ("11:22:33:44:55:66")); |
| 428 rann->SetDestSeqNumber (5); |
| 429 rann->SetMetric (6); |
| 430 rann->IncrementMetric (2); |
| 431 NS_TEST_ASSERT_EQUAL (rann->GetMetric (), 8); |
| 432 vector.AddInformationElement (rann); |
| 433 } |
| 434 { |
| 435 Ptr<dot11s::IePreq> preq = Create<dot11s::IePreq> (); |
| 436 preq->SetHopcount (0); |
| 437 preq->SetTTL (1); |
| 438 preq->SetPreqID (2); |
| 439 preq->SetOriginatorAddress (Mac48Address ("11:22:33:44:55:66")); |
| 440 preq->SetOriginatorSeqNumber (3); |
| 441 preq->SetLifetime (4); |
| 442 preq->AddDestinationAddressElement (false, false, Mac48Address ("11:11:11:11
:11:11"), 5); |
| 443 preq->AddDestinationAddressElement (false, false, Mac48Address ("22:22:22:22
:22:22"), 6); |
| 444 vector.AddInformationElement (preq); |
| 445 } |
| 446 { |
| 447 Ptr<dot11s::IePrep> prep = Create<dot11s::IePrep> (); |
| 448 prep->SetFlags (12); |
| 449 prep->SetHopcount (11); |
| 450 prep->SetTtl (10); |
| 451 prep->SetDestinationAddress (Mac48Address ("11:22:33:44:55:66")); |
| 452 prep->SetDestinationSeqNumber (123); |
| 453 prep->SetLifetime (5000); |
| 454 prep->SetMetric (4321); |
| 455 prep->SetOriginatorAddress (Mac48Address ("33:00:22:00:11:00")); |
| 456 prep->SetOriginatorSeqNumber (666); |
| 457 vector.AddInformationElement (prep); |
| 458 } |
| 459 { |
| 460 Ptr<dot11s::IePerr> perr = Create<dot11s::IePerr> (); |
| 461 dot11s::HwmpProtocol::FailedDestination dest; |
| 462 dest.destination = Mac48Address ("11:22:33:44:55:66"); |
| 463 dest.seqnum = 1; |
| 464 perr->AddAddressUnit (dest); |
| 465 dest.destination = Mac48Address ("10:20:30:40:50:60"); |
| 466 dest.seqnum = 2; |
| 467 perr->AddAddressUnit (dest); |
| 468 dest.destination = Mac48Address ("01:02:03:04:05:06"); |
| 469 dest.seqnum = 3; |
| 470 perr->AddAddressUnit (dest); |
| 471 vector.AddInformationElement (perr); |
| 472 } |
| 473 Ptr<Packet> packet = Create<Packet> (); |
| 474 packet->AddHeader (vector); |
| 475 WifiInformationElementVector resultVector; |
| 476 packet->RemoveHeader (resultVector); |
| 477 NS_TEST_ASSERT (vector == resultVector); |
| 478 ·· |
| 479 return result; |
| 480 } |
| 481 |
| 482 #endif // RUN_SELF_TESTS |
| 483 } //namespace ns3 |
OLD | NEW |