merge PacketBB
authorTom Wambold <tom5760@gmail.com>
Sun Sep 13 09:38:01 2009 -0700 (4 months ago)
changeset 4789a37dd7f8de25
parent 4774 066f73df2229
parent 4788 543507c4d939
child 4790 95015b7f0269
merge PacketBB
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/node/packetbb.cc	Sun Sep 13 09:38:01 2009 -0700
     1.3 @@ -0,0 +1,2782 @@
     1.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     1.5 +/* vim: set ts=2 sw=2 sta expandtab ai si cin: */
     1.6 +/* 
     1.7 + * Copyright (c) 2009 Drexel University
     1.8 + * 
     1.9 + * This program is free software; you can redistribute it and/or modify
    1.10 + * it under the terms of the GNU General Public License version 2 as
    1.11 + * published by the Free Software Foundation;
    1.12 + *
    1.13 + * This program is distributed in the hope that it will be useful,
    1.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.16 + * GNU General Public License for more details.
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License
    1.19 + * along with this program; if not, write to the Free Software
    1.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.21 + * 
    1.22 + * Author: Tom Wambold <tom5760@gmail.com>
    1.23 + */
    1.24 +/* These classes implement RFC 5444 - The Generalized Mobile Ad Hoc Network
    1.25 + * (MANET) Packet/PbbMessage Format
    1.26 + * See: http://tools.ietf.org/html/rfc5444 for details */
    1.27 +
    1.28 +#include "ns3/ipv4-address.h"
    1.29 +#include "ns3/ipv6-address.h"
    1.30 +#include "ns3/assert.h"
    1.31 +
    1.32 +#include "packetbb.h"
    1.33 +
    1.34 +static const uint8_t VERSION = 0;
    1.35 +/* Packet flags */
    1.36 +static const uint8_t PHAS_SEQ_NUM = 0x8;
    1.37 +static const uint8_t PHAS_TLV = 0x4;
    1.38 +
    1.39 +/* PbbMessage flags */
    1.40 +static const uint8_t MHAS_ORIG = 0x80;
    1.41 +static const uint8_t MHAS_HOP_LIMIT = 0x40;
    1.42 +static const uint8_t MHAS_HOP_COUNT = 0x20;
    1.43 +static const uint8_t MHAS_SEQ_NUM = 0x10;
    1.44 +
    1.45 +/* Address block flags */
    1.46 +static const uint8_t AHAS_HEAD = 0x80;
    1.47 +static const uint8_t AHAS_FULL_TAIL = 0x40;
    1.48 +static const uint8_t AHAS_ZERO_TAIL = 0x20;
    1.49 +static const uint8_t AHAS_SINGLE_PRE_LEN = 0x10;
    1.50 +static const uint8_t AHAS_MULTI_PRE_LEN = 0x08;
    1.51 +
    1.52 +/* TLV Flags */
    1.53 +static const uint8_t THAS_TYPE_EXT = 0x80;
    1.54 +static const uint8_t THAS_SINGLE_INDEX = 0x40;
    1.55 +static const uint8_t THAS_MULTI_INDEX = 0x20;
    1.56 +static const uint8_t THAS_VALUE = 0x10;
    1.57 +static const uint8_t THAS_EXT_LEN = 0x08;
    1.58 +static const uint8_t TIS_MULTIVALUE = 0x04;
    1.59 +
    1.60 +namespace ns3 {
    1.61 +
    1.62 +NS_OBJECT_ENSURE_REGISTERED (PbbPacket);
    1.63 +
    1.64 +PbbTlvBlock::Iterator
    1.65 +PbbTlvBlock::Begin (void)
    1.66 +{
    1.67 +  return m_tlvList.begin ();
    1.68 +}
    1.69 +
    1.70 +PbbTlvBlock::ConstIterator
    1.71 +PbbTlvBlock::Begin (void) const
    1.72 +{
    1.73 +  return m_tlvList.begin ();
    1.74 +}
    1.75 +
    1.76 +PbbTlvBlock::Iterator
    1.77 +PbbTlvBlock::End (void)
    1.78 +{
    1.79 +  return m_tlvList.end ();
    1.80 +}
    1.81 +
    1.82 +PbbTlvBlock::ConstIterator
    1.83 +PbbTlvBlock::End (void) const
    1.84 +{
    1.85 +  return m_tlvList.end ();
    1.86 +}
    1.87 +
    1.88 +int
    1.89 +PbbTlvBlock::Size (void) const
    1.90 +{
    1.91 +  return m_tlvList.size ();
    1.92 +}
    1.93 +
    1.94 +bool
    1.95 +PbbTlvBlock::Empty (void) const
    1.96 +{
    1.97 +  return m_tlvList.empty ();
    1.98 +}
    1.99 +
   1.100 +Ptr<PbbTlv>
   1.101 +PbbTlvBlock::Front (void) const
   1.102 +{
   1.103 +  return m_tlvList.front ();
   1.104 +}
   1.105 +
   1.106 +Ptr<PbbTlv>
   1.107 +PbbTlvBlock::Back (void) const
   1.108 +{
   1.109 +  return m_tlvList.back ();
   1.110 +}
   1.111 +
   1.112 +void
   1.113 +PbbTlvBlock::PushFront (Ptr<PbbTlv> tlv)
   1.114 +{
   1.115 +  m_tlvList.push_front (tlv);
   1.116 +}
   1.117 +
   1.118 +void
   1.119 +PbbTlvBlock::PopFront (void)
   1.120 +{
   1.121 +  m_tlvList.pop_front ();
   1.122 +}
   1.123 +
   1.124 +void
   1.125 +PbbTlvBlock::PushBack (Ptr<PbbTlv> tlv)
   1.126 +{
   1.127 +  m_tlvList.push_back (tlv);
   1.128 +}
   1.129 +
   1.130 +void
   1.131 +PbbTlvBlock::PopBack (void)
   1.132 +{
   1.133 +  m_tlvList.pop_back ();
   1.134 +}
   1.135 +
   1.136 +PbbTlvBlock::Iterator
   1.137 +PbbTlvBlock::Insert (PbbTlvBlock::Iterator position, const Ptr<PbbTlv> tlv)
   1.138 +{
   1.139 +  return m_tlvList.insert (position, tlv);
   1.140 +}
   1.141 +
   1.142 +PbbTlvBlock::Iterator
   1.143 +PbbTlvBlock::Erase (PbbTlvBlock::Iterator position)
   1.144 +{
   1.145 +  return m_tlvList.erase (position);
   1.146 +}
   1.147 +
   1.148 +PbbTlvBlock::Iterator
   1.149 +PbbTlvBlock::Erase (PbbTlvBlock::Iterator first, PbbTlvBlock::Iterator last)
   1.150 +{
   1.151 +  return m_tlvList.erase (first, last);
   1.152 +}
   1.153 +
   1.154 +void
   1.155 +PbbTlvBlock::Clear (void)
   1.156 +{
   1.157 +  m_tlvList.clear ();
   1.158 +}
   1.159 +
   1.160 +uint32_t
   1.161 +PbbTlvBlock::GetSerializedSize (void) const
   1.162 +{
   1.163 +  /* tlv size */
   1.164 +  uint32_t size = 2;
   1.165 +  for (ConstIterator iter = Begin (); iter != End (); iter++)
   1.166 +    {
   1.167 +      size += (*iter)->GetSerializedSize ();
   1.168 +    }
   1.169 +  return size;
   1.170 +}
   1.171 +
   1.172 +void
   1.173 +PbbTlvBlock::Serialize (Buffer::Iterator &start) const
   1.174 +{
   1.175 +  if (Empty ())
   1.176 +    {
   1.177 +      start.WriteHtonU16 (0);
   1.178 +      return;
   1.179 +    }
   1.180 +
   1.181 +  /* We need to write the size of the TLV block in front, so save its
   1.182 +   * position. */
   1.183 +  Buffer::Iterator tlvsize = start;
   1.184 +  start.Next (2);
   1.185 +  for (ConstIterator iter = Begin (); iter != End (); iter++)
   1.186 +    {
   1.187 +      (*iter)->Serialize (start);
   1.188 +    }
   1.189 +  /* - 2 to not include the size field */
   1.190 +  uint16_t size = start.GetDistanceFrom (tlvsize) - 2;
   1.191 +  tlvsize.WriteHtonU16 (size);
   1.192 +}
   1.193 +
   1.194 +void
   1.195 +PbbTlvBlock::Deserialize (Buffer::Iterator &start)
   1.196 +{
   1.197 +  uint16_t size = start.ReadNtohU16 ();
   1.198 +
   1.199 +  Buffer::Iterator tlvstart = start;
   1.200 +  if (size > 0)
   1.201 +    {
   1.202 +      while (start.GetDistanceFrom (tlvstart) < size)
   1.203 +        {
   1.204 +          Ptr<PbbTlv> newtlv = Create<PbbTlv> ();
   1.205 +          newtlv->Deserialize (start);
   1.206 +          PushBack (newtlv);
   1.207 +        }
   1.208 +    }
   1.209 +}
   1.210 +
   1.211 +void
   1.212 +PbbTlvBlock::Print (std::ostream &os) const
   1.213 +{
   1.214 +  Print (os, 0);
   1.215 +}
   1.216 +
   1.217 +void
   1.218 +PbbTlvBlock::Print (std::ostream &os, int level) const
   1.219 +{
   1.220 +  std::string prefix = "";
   1.221 +  for (int i = 0; i < level; i++)
   1.222 +    {
   1.223 +      prefix.append("\t");
   1.224 +    }
   1.225 +
   1.226 +  os << prefix << "TLV Block {" << std::endl;
   1.227 +  os << prefix << "\tsize = " << Size () << std::endl;
   1.228 +  os << prefix << "\tmembers [" << std::endl;
   1.229 +
   1.230 +  for (ConstIterator iter = Begin (); iter != End (); iter++)
   1.231 +    {
   1.232 +      (*iter)->Print (os, level+2);
   1.233 +    }
   1.234 +
   1.235 +  os << prefix << "\t]" << std::endl;
   1.236 +  os << prefix << "}" << std::endl;
   1.237 +}
   1.238 +
   1.239 +bool
   1.240 +PbbTlvBlock::operator== (const PbbTlvBlock &other) const
   1.241 +{
   1.242 +  if (Size () != other.Size ())
   1.243 +    {
   1.244 +      return false;
   1.245 +    }
   1.246 +
   1.247 +  ConstIterator ti, oi;
   1.248 +  for (ti = Begin (), oi = other.Begin ();
   1.249 +      ti != End () && oi != other.End ();
   1.250 +      ti++, oi++)
   1.251 +    {
   1.252 +      if (**ti != **oi)
   1.253 +        {
   1.254 +          return false;
   1.255 +        }
   1.256 +    }
   1.257 +  return true;
   1.258 +}
   1.259 +
   1.260 +bool
   1.261 +PbbTlvBlock::operator!= (const PbbTlvBlock &other) const
   1.262 +{
   1.263 +  return !(*this == other);
   1.264 +}
   1.265 +
   1.266 +/* End PbbTlvBlock class */
   1.267 +
   1.268 +PbbAddressTlvBlock::Iterator
   1.269 +PbbAddressTlvBlock::Begin (void)
   1.270 +{
   1.271 +  return m_tlvList.begin ();
   1.272 +}
   1.273 +
   1.274 +PbbAddressTlvBlock::ConstIterator
   1.275 +PbbAddressTlvBlock::Begin (void) const
   1.276 +{
   1.277 +  return m_tlvList.begin ();
   1.278 +}
   1.279 +
   1.280 +PbbAddressTlvBlock::Iterator
   1.281 +PbbAddressTlvBlock::End (void)
   1.282 +{
   1.283 +  return m_tlvList.end ();
   1.284 +}
   1.285 +
   1.286 +PbbAddressTlvBlock::ConstIterator
   1.287 +PbbAddressTlvBlock::End (void) const
   1.288 +{
   1.289 +  return m_tlvList.end ();
   1.290 +}
   1.291 +
   1.292 +int
   1.293 +PbbAddressTlvBlock::Size (void) const
   1.294 +{
   1.295 +  return m_tlvList.size ();
   1.296 +}
   1.297 +
   1.298 +bool
   1.299 +PbbAddressTlvBlock::Empty (void) const
   1.300 +{
   1.301 +  return m_tlvList.empty ();
   1.302 +}
   1.303 +
   1.304 +Ptr<PbbAddressTlv>
   1.305 +PbbAddressTlvBlock::Front (void) const
   1.306 +{
   1.307 +  return m_tlvList.front ();
   1.308 +}
   1.309 +
   1.310 +Ptr<PbbAddressTlv>
   1.311 +PbbAddressTlvBlock::Back (void) const
   1.312 +{
   1.313 +  return m_tlvList.back ();
   1.314 +}
   1.315 +
   1.316 +void
   1.317 +PbbAddressTlvBlock::PushFront (Ptr<PbbAddressTlv> tlv)
   1.318 +{
   1.319 +  m_tlvList.push_front (tlv);
   1.320 +}
   1.321 +
   1.322 +void
   1.323 +PbbAddressTlvBlock::PopFront (void)
   1.324 +{
   1.325 +  m_tlvList.pop_front ();
   1.326 +}
   1.327 +
   1.328 +void
   1.329 +PbbAddressTlvBlock::PushBack (Ptr<PbbAddressTlv> tlv)
   1.330 +{
   1.331 +  m_tlvList.push_back (tlv);
   1.332 +}
   1.333 +
   1.334 +void
   1.335 +PbbAddressTlvBlock::PopBack (void)
   1.336 +{
   1.337 +  m_tlvList.pop_back ();
   1.338 +}
   1.339 +
   1.340 +PbbAddressTlvBlock::Iterator
   1.341 +PbbAddressTlvBlock::Insert (PbbAddressTlvBlock::Iterator position, const Ptr<PbbAddressTlv> tlv)
   1.342 +{
   1.343 +  return m_tlvList.insert (position, tlv);
   1.344 +}
   1.345 +
   1.346 +PbbAddressTlvBlock::Iterator
   1.347 +PbbAddressTlvBlock::Erase (PbbAddressTlvBlock::Iterator position)
   1.348 +{
   1.349 +  return m_tlvList.erase (position);
   1.350 +}
   1.351 +
   1.352 +PbbAddressTlvBlock::Iterator
   1.353 +PbbAddressTlvBlock::Erase (PbbAddressTlvBlock::Iterator first, PbbAddressTlvBlock::Iterator last)
   1.354 +{
   1.355 +  return m_tlvList.erase (first, last);
   1.356 +}
   1.357 +
   1.358 +void
   1.359 +PbbAddressTlvBlock::Clear (void)
   1.360 +{
   1.361 +  m_tlvList.clear ();
   1.362 +}
   1.363 +
   1.364 +uint32_t
   1.365 +PbbAddressTlvBlock::GetSerializedSize (void) const
   1.366 +{
   1.367 +  /* tlv size */
   1.368 +  uint32_t size = 2;
   1.369 +  for (ConstIterator iter = Begin (); iter != End (); iter++)
   1.370 +    {
   1.371 +      size += (*iter)->GetSerializedSize ();
   1.372 +    }
   1.373 +  return size;
   1.374 +}
   1.375 +
   1.376 +void
   1.377 +PbbAddressTlvBlock::Serialize (Buffer::Iterator &start) const
   1.378 +{
   1.379 +  if (Empty ())
   1.380 +    {
   1.381 +      start.WriteHtonU16 (0);
   1.382 +      return;
   1.383 +    }
   1.384 +
   1.385 +  /* We need to write the size of the TLV block in front, so save its
   1.386 +   * position. */
   1.387 +  Buffer::Iterator tlvsize = start;
   1.388 +  start.Next (2);
   1.389 +  for (ConstIterator iter = Begin (); iter != End (); iter++)
   1.390 +    {
   1.391 +      (*iter)->Serialize (start);
   1.392 +    }
   1.393 +  /* - 2 to not include the size field */
   1.394 +  uint16_t size = start.GetDistanceFrom (tlvsize) - 2;
   1.395 +  tlvsize.WriteHtonU16 (size);
   1.396 +}
   1.397 +
   1.398 +void
   1.399 +PbbAddressTlvBlock::Deserialize (Buffer::Iterator &start)
   1.400 +{
   1.401 +  uint16_t size = start.ReadNtohU16 ();
   1.402 +
   1.403 +  Buffer::Iterator tlvstart = start;
   1.404 +  if (size > 0)
   1.405 +    {
   1.406 +      while (start.GetDistanceFrom (tlvstart) < size)
   1.407 +      {
   1.408 +        Ptr<PbbAddressTlv> newtlv = Create<PbbAddressTlv> ();
   1.409 +        newtlv->Deserialize (start);
   1.410 +        PushBack (newtlv);
   1.411 +      }
   1.412 +    }
   1.413 +}
   1.414 +
   1.415 +void
   1.416 +PbbAddressTlvBlock::Print (std::ostream &os) const
   1.417 +{
   1.418 +  Print (os, 0);
   1.419 +}
   1.420 +
   1.421 +void
   1.422 +PbbAddressTlvBlock::Print (std::ostream &os, int level) const
   1.423 +{
   1.424 +  std::string prefix = "";
   1.425 +  for (int i = 0; i < level; i++)
   1.426 +    {
   1.427 +      prefix.append("\t");
   1.428 +    }
   1.429 +
   1.430 +  os << prefix << "TLV Block {" << std::endl;
   1.431 +  os << prefix << "\tsize = " << Size () << std::endl;
   1.432 +  os << prefix << "\tmembers [" << std::endl;
   1.433 +
   1.434 +  for (ConstIterator iter = Begin (); iter != End (); iter++)
   1.435 +    {
   1.436 +      (*iter)->Print (os, level+2);
   1.437 +    }
   1.438 +
   1.439 +  os << prefix << "\t]" << std::endl;
   1.440 +  os << prefix << "}" << std::endl;
   1.441 +}
   1.442 +
   1.443 +bool
   1.444 +PbbAddressTlvBlock::operator== (const PbbAddressTlvBlock &other) const
   1.445 +{
   1.446 +  if (Size () != other.Size ())
   1.447 +    {
   1.448 +      return false;
   1.449 +    }
   1.450 +
   1.451 +  ConstIterator it, ot;
   1.452 +  for (it = Begin (), ot = other.Begin ();
   1.453 +      it != End () && ot != other.End ();
   1.454 +      it++, ot++)
   1.455 +    {
   1.456 +      if (**it != **ot)
   1.457 +        {
   1.458 +          return false;
   1.459 +        }
   1.460 +    }
   1.461 +  return true;
   1.462 +}
   1.463 +
   1.464 +bool
   1.465 +PbbAddressTlvBlock::operator!= (const PbbAddressTlvBlock &other) const
   1.466 +{
   1.467 +  return !(*this == other);
   1.468 +}
   1.469 +
   1.470 +
   1.471 +/* End PbbAddressTlvBlock Class */
   1.472 +
   1.473 +PbbPacket::PbbPacket (void)
   1.474 +{
   1.475 +  m_refCount = 1;
   1.476 +  m_version = VERSION;
   1.477 +  m_hasseqnum = false;
   1.478 +}
   1.479 +
   1.480 +uint8_t
   1.481 +PbbPacket::GetVersion (void) const
   1.482 +{
   1.483 +  return m_version;
   1.484 +}
   1.485 +
   1.486 +void
   1.487 +PbbPacket::SetSequenceNumber (uint16_t number)
   1.488 +{
   1.489 +  m_seqnum = number;
   1.490 +  m_hasseqnum = true;
   1.491 +}
   1.492 +
   1.493 +uint16_t
   1.494 +PbbPacket::GetSequenceNumber (void) const
   1.495 +{
   1.496 +  NS_ASSERT (HasSequenceNumber ());
   1.497 +  return m_seqnum;
   1.498 +}
   1.499 +
   1.500 +bool
   1.501 +PbbPacket::HasSequenceNumber (void) const
   1.502 +{
   1.503 +  return m_hasseqnum;
   1.504 +}
   1.505 +
   1.506 +/* Manipulating Packet TLVs */
   1.507 +
   1.508 +PbbPacket::TlvIterator
   1.509 +PbbPacket::TlvBegin (void)
   1.510 +{
   1.511 +  return m_tlvList.Begin ();
   1.512 +}
   1.513 +
   1.514 +PbbPacket::ConstTlvIterator
   1.515 +PbbPacket::TlvBegin (void) const
   1.516 +{
   1.517 +  return m_tlvList.Begin ();
   1.518 +}
   1.519 +
   1.520 +PbbPacket::TlvIterator
   1.521 +PbbPacket::TlvEnd (void)
   1.522 +{
   1.523 +  return m_tlvList.End ();
   1.524 +}
   1.525 +
   1.526 +PbbPacket::ConstTlvIterator
   1.527 +PbbPacket::TlvEnd (void) const
   1.528 +{
   1.529 +  return m_tlvList.End ();
   1.530 +}
   1.531 +
   1.532 +int
   1.533 +PbbPacket::TlvSize (void) const
   1.534 +{
   1.535 +  return m_tlvList.Size ();
   1.536 +}
   1.537 +
   1.538 +bool
   1.539 +PbbPacket::TlvEmpty (void) const
   1.540 +{
   1.541 +  return m_tlvList.Empty ();
   1.542 +}
   1.543 +
   1.544 +Ptr<PbbTlv>
   1.545 +PbbPacket::TlvFront (void)
   1.546 +{
   1.547 +  return m_tlvList.Front ();
   1.548 +}
   1.549 +
   1.550 +const Ptr<PbbTlv>
   1.551 +PbbPacket::TlvFront (void) const
   1.552 +{
   1.553 +  return m_tlvList.Front ();
   1.554 +}
   1.555 +
   1.556 +Ptr<PbbTlv>
   1.557 +PbbPacket::TlvBack (void)
   1.558 +{
   1.559 +  return m_tlvList.Back ();
   1.560 +}
   1.561 +
   1.562 +const Ptr<PbbTlv>
   1.563 +PbbPacket::TlvBack (void) const
   1.564 +{
   1.565 +  return m_tlvList.Back ();
   1.566 +}
   1.567 +
   1.568 +void
   1.569 +PbbPacket::TlvPushFront (Ptr<PbbTlv> tlv)
   1.570 +{
   1.571 +  m_tlvList.PushFront (tlv);
   1.572 +}
   1.573 +
   1.574 +void
   1.575 +PbbPacket::TlvPopFront (void)
   1.576 +{
   1.577 +  m_tlvList.PopFront ();
   1.578 +}
   1.579 +
   1.580 +void
   1.581 +PbbPacket::TlvPushBack (Ptr<PbbTlv> tlv)
   1.582 +{
   1.583 +  m_tlvList.PushBack (tlv);
   1.584 +}
   1.585 +
   1.586 +void
   1.587 +PbbPacket::TlvPopBack (void)
   1.588 +{
   1.589 +  m_tlvList.PopBack ();
   1.590 +}
   1.591 +
   1.592 +PbbPacket::TlvIterator
   1.593 +PbbPacket::Erase (PbbPacket::TlvIterator position)
   1.594 +{
   1.595 +  return m_tlvList.Erase (position);
   1.596 +}
   1.597 +
   1.598 +PbbPacket::TlvIterator
   1.599 +PbbPacket::Erase (PbbPacket::TlvIterator first, PbbPacket::TlvIterator last)
   1.600 +{
   1.601 +  return m_tlvList.Erase (first, last);
   1.602 +}
   1.603 +
   1.604 +void
   1.605 +PbbPacket::TlvClear (void)
   1.606 +{
   1.607 +  m_tlvList.Clear ();
   1.608 +}
   1.609 +
   1.610 +/* Manipulating Packet Messages */
   1.611 +
   1.612 +PbbPacket::MessageIterator
   1.613 +PbbPacket::MessageBegin (void)
   1.614 +{
   1.615 +  return m_messageList.begin ();
   1.616 +}
   1.617 +
   1.618 +PbbPacket::ConstMessageIterator
   1.619 +PbbPacket::MessageBegin (void) const
   1.620 +{
   1.621 +  return m_messageList.begin ();
   1.622 +}
   1.623 +
   1.624 +PbbPacket::MessageIterator
   1.625 +PbbPacket::MessageEnd (void)
   1.626 +{
   1.627 +  return m_messageList.end ();
   1.628 +}
   1.629 +
   1.630 +PbbPacket::ConstMessageIterator
   1.631 +PbbPacket::MessageEnd (void) const
   1.632 +{
   1.633 +  return m_messageList.end ();
   1.634 +}
   1.635 +
   1.636 +int
   1.637 +PbbPacket::MessageSize (void) const
   1.638 +{
   1.639 +  return m_messageList.size ();
   1.640 +}
   1.641 +
   1.642 +bool
   1.643 +PbbPacket::MessageEmpty (void) const
   1.644 +{
   1.645 +  return m_messageList.empty ();
   1.646 +}
   1.647 +
   1.648 +Ptr<PbbMessage>
   1.649 +PbbPacket::MessageFront (void)
   1.650 +{
   1.651 +  return m_messageList.front ();
   1.652 +}
   1.653 +
   1.654 +const Ptr<PbbMessage>
   1.655 +PbbPacket::MessageFront (void) const
   1.656 +{
   1.657 +  return m_messageList.front ();
   1.658 +}
   1.659 +
   1.660 +Ptr<PbbMessage>
   1.661 +PbbPacket::MessageBack (void)
   1.662 +{
   1.663 +  return m_messageList.back ();
   1.664 +}
   1.665 +
   1.666 +const Ptr<PbbMessage>
   1.667 +PbbPacket::MessageBack (void) const
   1.668 +{
   1.669 +  return m_messageList.back ();
   1.670 +}
   1.671 +
   1.672 +void
   1.673 +PbbPacket::MessagePushFront (Ptr<PbbMessage> tlv)
   1.674 +{
   1.675 +  m_messageList.push_front (tlv);
   1.676 +}
   1.677 +
   1.678 +void
   1.679 +PbbPacket::MessagePopFront (void)
   1.680 +{
   1.681 +  m_messageList.pop_front ();
   1.682 +}
   1.683 +
   1.684 +void
   1.685 +PbbPacket::MessagePushBack (Ptr<PbbMessage> tlv)
   1.686 +{
   1.687 +  m_messageList.push_back (tlv);
   1.688 +}
   1.689 +
   1.690 +void
   1.691 +PbbPacket::MessagePopBack (void)
   1.692 +{
   1.693 +  m_messageList.pop_back ();
   1.694 +}
   1.695 +
   1.696 +PbbPacket::MessageIterator
   1.697 +PbbPacket::Erase (PbbPacket::MessageIterator position)
   1.698 +{
   1.699 +  return m_messageList.erase (position);
   1.700 +}
   1.701 +
   1.702 +PbbPacket::MessageIterator
   1.703 +PbbPacket::Erase (PbbPacket::MessageIterator first,
   1.704 +    PbbPacket::MessageIterator last)
   1.705 +{
   1.706 +  return m_messageList.erase (first, last);
   1.707 +}
   1.708 +
   1.709 +void
   1.710 +PbbPacket::MessageClear (void)
   1.711 +{
   1.712 +  m_messageList.clear ();
   1.713 +}
   1.714 +
   1.715 +void
   1.716 +PbbPacket::Ref (void) const
   1.717 +{
   1.718 +  m_refCount++;
   1.719 +}
   1.720 +
   1.721 +void
   1.722 +PbbPacket::Unref (void) const
   1.723 +{
   1.724 +  m_refCount--;
   1.725 +  if (m_refCount == 0)
   1.726 +    {
   1.727 +      delete this;
   1.728 +    }
   1.729 +}
   1.730 +
   1.731 +TypeId
   1.732 +PbbPacket::GetTypeId (void)
   1.733 +{
   1.734 +  static TypeId tid = TypeId ("PbbPacket")
   1.735 +    .SetParent<Header> ()
   1.736 +    .AddConstructor<PbbPacket> ()
   1.737 +  ;
   1.738 +  return tid;
   1.739 +}
   1.740 +
   1.741 +TypeId
   1.742 +PbbPacket::GetInstanceTypeId (void) const
   1.743 +{
   1.744 +  return GetTypeId ();
   1.745 +}
   1.746 +
   1.747 +uint32_t
   1.748 +PbbPacket::GetSerializedSize (void) const
   1.749 +{
   1.750 +  /* Version number + flags */
   1.751 +  uint32_t size = 1;
   1.752 +
   1.753 +  if (HasSequenceNumber())
   1.754 +    {
   1.755 +      size += 2;
   1.756 +    }
   1.757 +
   1.758 +  if (!TlvEmpty ())
   1.759 +    {
   1.760 +      size += m_tlvList.GetSerializedSize ();
   1.761 +    }
   1.762 +
   1.763 +  for (ConstMessageIterator iter = MessageBegin ();
   1.764 +      iter != MessageEnd ();
   1.765 +      iter++)
   1.766 +    {
   1.767 +      size += (*iter)->GetSerializedSize ();
   1.768 +    }
   1.769 +
   1.770 +  return size;
   1.771 +}
   1.772 +
   1.773 +void
   1.774 +PbbPacket::Serialize (Buffer::Iterator start) const
   1.775 +{
   1.776 +  /* We remember the start, so we can write the flags after we check for a
   1.777 +   * sequence number and TLV. */
   1.778 +  Buffer::Iterator bufref = start;
   1.779 +  start.Next ();
   1.780 +
   1.781 +  uint8_t flags = VERSION;
   1.782 +  /* Make room for 4 bit flags */
   1.783 +  flags <<= 4;
   1.784 +
   1.785 +  if (HasSequenceNumber ())
   1.786 +    {
   1.787 +      flags |= PHAS_SEQ_NUM;
   1.788 +      start.WriteHtonU16 (GetSequenceNumber ());
   1.789 +    }
   1.790 +
   1.791 +  if (!TlvEmpty ())
   1.792 +    {
   1.793 +      flags |= PHAS_TLV;
   1.794 +      m_tlvList.Serialize (start);
   1.795 +    }
   1.796 +
   1.797 +  bufref.WriteU8(flags);
   1.798 +
   1.799 +  for (ConstMessageIterator iter = MessageBegin ();
   1.800 +      iter != MessageEnd ();
   1.801 +      iter++)
   1.802 +    {
   1.803 +      (*iter)->Serialize (start);
   1.804 +    }
   1.805 +}
   1.806 +
   1.807 +uint32_t
   1.808 +PbbPacket::Deserialize (Buffer::Iterator start)
   1.809 +{
   1.810 +  Buffer::Iterator begin = start;
   1.811 +
   1.812 +  uint8_t flags = start.ReadU8 ();
   1.813 +
   1.814 +  if (flags & PHAS_SEQ_NUM)
   1.815 +    {
   1.816 +      SetSequenceNumber (start.ReadNtohU16 ());
   1.817 +    }
   1.818 +
   1.819 +  if (flags & PHAS_TLV)
   1.820 +    {
   1.821 +      m_tlvList.Deserialize (start);
   1.822 +    }
   1.823 +
   1.824 +  while (!start.IsEnd())
   1.825 +    {
   1.826 +      Ptr<PbbMessage> newmsg = PbbMessage::DeserializeMessage (start);
   1.827 +      if (newmsg == 0)
   1.828 +        {
   1.829 +          return start.GetDistanceFrom (begin);
   1.830 +        }
   1.831 +      MessagePushBack (newmsg);
   1.832 +    }
   1.833 +
   1.834 +  flags >>= 4;
   1.835 +  m_version = flags;
   1.836 +
   1.837 +  return start.GetDistanceFrom (begin);
   1.838 +}
   1.839 +
   1.840 +void
   1.841 +PbbPacket::Print (std::ostream &os) const
   1.842 +{
   1.843 +  os << "PbbPacket {" << std::endl;
   1.844 +
   1.845 +  if (HasSequenceNumber ())
   1.846 +    {
   1.847 +      os << "\tsequence number = " << GetSequenceNumber ();
   1.848 +    }
   1.849 +
   1.850 +  os << std::endl;
   1.851 +
   1.852 +  m_tlvList.Print (os, 1);
   1.853 +
   1.854 +  for (ConstMessageIterator iter = MessageBegin ();
   1.855 +      iter != MessageEnd ();
   1.856 +      iter++)
   1.857 +    {
   1.858 +      (*iter)->Print (os, 1);
   1.859 +    }
   1.860 +
   1.861 +  os << "}" << std::endl;
   1.862 +}
   1.863 +
   1.864 +bool
   1.865 +PbbPacket::operator== (const PbbPacket &other) const
   1.866 +{
   1.867 +  if (GetVersion () != other.GetVersion ())
   1.868 +    {
   1.869 +      return false;
   1.870 +    }
   1.871 +
   1.872 +  if (HasSequenceNumber () != other.HasSequenceNumber ())
   1.873 +    {
   1.874 +      return false;
   1.875 +    }
   1.876 +
   1.877 +  if (HasSequenceNumber ())
   1.878 +    {
   1.879 +      if (GetSequenceNumber () != other.GetSequenceNumber ())
   1.880 +        return false;
   1.881 +    }
   1.882 +
   1.883 +  if (m_tlvList != other.m_tlvList)
   1.884 +    {
   1.885 +      return false;
   1.886 +    }
   1.887 +
   1.888 +  if (MessageSize () != other.MessageSize ())
   1.889 +    {
   1.890 +        return false;
   1.891 +    }
   1.892 +
   1.893 +  ConstMessageIterator tmi, omi;
   1.894 +  for (tmi = MessageBegin (), omi = other.MessageBegin ();
   1.895 +    tmi != MessageEnd () && omi != other.MessageEnd ();
   1.896 +    tmi++, omi++)
   1.897 +    {
   1.898 +      if (**tmi != **omi)
   1.899 +        {
   1.900 +          return false;
   1.901 +        }
   1.902 +    }
   1.903 +  return true;
   1.904 +}
   1.905 +
   1.906 +bool
   1.907 +PbbPacket::operator!= (const PbbPacket &other) const
   1.908 +{
   1.909 +  return !(*this == other);
   1.910 +}
   1.911 +
   1.912 +/* End PbbPacket class */
   1.913 +
   1.914 +PbbMessage::PbbMessage (void)
   1.915 +{
   1.916 +  m_refCount = 1;
   1.917 +  /* Default to IPv4 */
   1.918 +  m_addrSize = IPV4;
   1.919 +  m_hasOriginatorAddress = false;
   1.920 +  m_hasHopLimit = false;
   1.921 +  m_hasHopCount = false;
   1.922 +  m_hasSequenceNumber = false;
   1.923 +}
   1.924 +
   1.925 +void
   1.926 +PbbMessage::SetType (uint8_t type)
   1.927 +{
   1.928 +  m_type = type;
   1.929 +}
   1.930 +
   1.931 +uint8_t
   1.932 +PbbMessage::GetType (void) const
   1.933 +{
   1.934 +  return m_type;
   1.935 +}
   1.936 +
   1.937 +PbbAddressLength
   1.938 +PbbMessage::GetAddressLength (void) const
   1.939 +{
   1.940 +  return m_addrSize;
   1.941 +}
   1.942 +
   1.943 +void
   1.944 +PbbMessage::SetOriginatorAddress (Address address)
   1.945 +{
   1.946 +  m_originatorAddress = address;
   1.947 +  m_hasOriginatorAddress = true;
   1.948 +}
   1.949 +
   1.950 +Address
   1.951 +PbbMessage::GetOriginatorAddress (void) const
   1.952 +{
   1.953 +  NS_ASSERT (HasOriginatorAddress ());
   1.954 +  return m_originatorAddress;
   1.955 +}
   1.956 +
   1.957 +bool
   1.958 +PbbMessage::HasOriginatorAddress (void) const
   1.959 +{
   1.960 +  return m_hasOriginatorAddress;
   1.961 +}
   1.962 +
   1.963 +void
   1.964 +PbbMessage::SetHopLimit (uint8_t hopLimit)
   1.965 +{
   1.966 +  m_hopLimit = hopLimit;
   1.967 +  m_hasHopLimit = true;
   1.968 +}
   1.969 +
   1.970 +uint8_t
   1.971 +PbbMessage::GetHopLimit (void) const
   1.972 +{
   1.973 +  NS_ASSERT (HasHopLimit ());
   1.974 +  return m_hopLimit;
   1.975 +}
   1.976 +
   1.977 +bool
   1.978 +PbbMessage::HasHopLimit (void) const
   1.979 +{
   1.980 +  return m_hasHopLimit;
   1.981 +}
   1.982 +
   1.983 +void
   1.984 +PbbMessage::SetHopCount (uint8_t hopCount)
   1.985 +{
   1.986 +  m_hopCount = hopCount;
   1.987 +  m_hasHopCount = true;
   1.988 +}
   1.989 +
   1.990 +uint8_t
   1.991 +PbbMessage::GetHopCount (void) const
   1.992 +{
   1.993 +  NS_ASSERT (HasHopCount ());
   1.994 +  return m_hopCount;
   1.995 +}
   1.996 +
   1.997 +bool
   1.998 +PbbMessage::HasHopCount (void) const
   1.999 +{
  1.1000 +  return m_hasHopCount;
  1.1001 +}
  1.1002 +
  1.1003 +void
  1.1004 +PbbMessage::SetSequenceNumber (uint16_t sequenceNumber)
  1.1005 +{
  1.1006 +  m_sequenceNumber = sequenceNumber;
  1.1007 +  m_hasSequenceNumber = true;
  1.1008 +}
  1.1009 +
  1.1010 +uint16_t
  1.1011 +PbbMessage::GetSequenceNumber (void) const
  1.1012 +{
  1.1013 +  NS_ASSERT (HasSequenceNumber ());
  1.1014 +  return m_sequenceNumber;
  1.1015 +}
  1.1016 +
  1.1017 +bool
  1.1018 +PbbMessage::HasSequenceNumber (void) const
  1.1019 +{
  1.1020 +  return m_hasSequenceNumber;
  1.1021 +}
  1.1022 +
  1.1023 +/* Manipulating PbbMessage TLVs */
  1.1024 +
  1.1025 +PbbMessage::TlvIterator
  1.1026 +PbbMessage::TlvBegin (void)
  1.1027 +{
  1.1028 +  return m_tlvList.Begin();
  1.1029 +}
  1.1030 +
  1.1031 +PbbMessage::ConstTlvIterator
  1.1032 +PbbMessage::TlvBegin (void) const
  1.1033 +{
  1.1034 +  return m_tlvList.Begin();
  1.1035 +}
  1.1036 +
  1.1037 +PbbMessage::TlvIterator
  1.1038 +PbbMessage::TlvEnd (void)
  1.1039 +{
  1.1040 +  return m_tlvList.End();
  1.1041 +}
  1.1042 +
  1.1043 +PbbMessage::ConstTlvIterator
  1.1044 +PbbMessage::TlvEnd (void) const
  1.1045 +{
  1.1046 +  return m_tlvList.End();
  1.1047 +}
  1.1048 +
  1.1049 +int
  1.1050 +PbbMessage::TlvSize (void) const
  1.1051 +{
  1.1052 +  return m_tlvList.Size();
  1.1053 +}
  1.1054 +
  1.1055 +bool
  1.1056 +PbbMessage::TlvEmpty (void) const
  1.1057 +{
  1.1058 +  return m_tlvList.Empty();
  1.1059 +}
  1.1060 +
  1.1061 +Ptr<PbbTlv>
  1.1062 +PbbMessage::TlvFront (void)
  1.1063 +{
  1.1064 +  return m_tlvList.Front();
  1.1065 +}
  1.1066 +
  1.1067 +const Ptr<PbbTlv>
  1.1068 +PbbMessage::TlvFront (void) const
  1.1069 +{
  1.1070 +  return m_tlvList.Front();
  1.1071 +}
  1.1072 +
  1.1073 +Ptr<PbbTlv>
  1.1074 +PbbMessage::TlvBack (void)
  1.1075 +{
  1.1076 +  return m_tlvList.Back();
  1.1077 +}
  1.1078 +
  1.1079 +const Ptr<PbbTlv>
  1.1080 +PbbMessage::TlvBack (void) const
  1.1081 +{
  1.1082 +  return m_tlvList.Back();
  1.1083 +}
  1.1084 +
  1.1085 +void
  1.1086 +PbbMessage::TlvPushFront (Ptr<PbbTlv> tlv)
  1.1087 +{
  1.1088 +  m_tlvList.PushFront(tlv);
  1.1089 +}
  1.1090 +
  1.1091 +void
  1.1092 +PbbMessage::TlvPopFront (void)
  1.1093 +{
  1.1094 +  m_tlvList.PopFront();
  1.1095 +}
  1.1096 +
  1.1097 +void
  1.1098 +PbbMessage::TlvPushBack (Ptr<PbbTlv> tlv)
  1.1099 +{
  1.1100 +  m_tlvList.PushBack(tlv);
  1.1101 +}
  1.1102 +
  1.1103 +void
  1.1104 +PbbMessage::TlvPopBack (void)
  1.1105 +{
  1.1106 +  m_tlvList.PopBack();
  1.1107 +}
  1.1108 +
  1.1109 +PbbMessage::TlvIterator
  1.1110 +PbbMessage::TlvErase (PbbMessage::TlvIterator position)
  1.1111 +{
  1.1112 +  return m_tlvList.Erase(position);
  1.1113 +}
  1.1114 +
  1.1115 +PbbMessage::TlvIterator
  1.1116 +PbbMessage::TlvErase (PbbMessage::TlvIterator first, PbbMessage::TlvIterator last)
  1.1117 +{
  1.1118 +  return m_tlvList.Erase(first, last);
  1.1119 +}
  1.1120 +
  1.1121 +void
  1.1122 +PbbMessage::TlvClear (void)
  1.1123 +{
  1.1124 +  return m_tlvList.Clear();
  1.1125 +}
  1.1126 +
  1.1127 +/* Manipulating Address Block and Address TLV pairs */
  1.1128 +
  1.1129 +PbbMessage::AddressBlockIterator
  1.1130 +PbbMessage::AddressBlockBegin (void)
  1.1131 +{
  1.1132 +  return m_addressBlockList.begin();
  1.1133 +}
  1.1134 +
  1.1135 +PbbMessage::ConstAddressBlockIterator
  1.1136 +PbbMessage::AddressBlockBegin (void) const
  1.1137 +{
  1.1138 +  return m_addressBlockList.begin();
  1.1139 +}
  1.1140 +
  1.1141 +PbbMessage::AddressBlockIterator
  1.1142 +PbbMessage::AddressBlockEnd (void)
  1.1143 +{
  1.1144 +  return m_addressBlockList.end();
  1.1145 +}
  1.1146 +
  1.1147 +PbbMessage::ConstAddressBlockIterator
  1.1148 +PbbMessage::AddressBlockEnd (void) const
  1.1149 +{
  1.1150 +  return m_addressBlockList.end();
  1.1151 +}
  1.1152 +
  1.1153 +int
  1.1154 +PbbMessage::AddressBlockSize (void) const
  1.1155 +{
  1.1156 +  return m_addressBlockList.size();
  1.1157 +}
  1.1158 +
  1.1159 +bool
  1.1160 +PbbMessage::AddressBlockEmpty (void) const
  1.1161 +{
  1.1162 +  return m_addressBlockList.empty();
  1.1163 +}
  1.1164 +
  1.1165 +Ptr<PbbAddressBlock>
  1.1166 +PbbMessage::AddressBlockFront (void)
  1.1167 +{
  1.1168 +  return m_addressBlockList.front();
  1.1169 +}
  1.1170 +
  1.1171 +const Ptr<PbbAddressBlock>
  1.1172 +PbbMessage::AddressBlockFront (void) const
  1.1173 +{
  1.1174 +  return m_addressBlockList.front();
  1.1175 +}
  1.1176 +
  1.1177 +Ptr<PbbAddressBlock>
  1.1178 +PbbMessage::AddressBlockBack (void)
  1.1179 +{
  1.1180 +  return m_addressBlockList.back();
  1.1181 +}
  1.1182 +
  1.1183 +const Ptr<PbbAddressBlock>
  1.1184 +PbbMessage::AddressBlockBack (void) const
  1.1185 +{
  1.1186 +  return m_addressBlockList.back();
  1.1187 +}
  1.1188 +
  1.1189 +void
  1.1190 +PbbMessage::AddressBlockPushFront (Ptr<PbbAddressBlock> tlv)
  1.1191 +{
  1.1192 +  m_addressBlockList.push_front(tlv);
  1.1193 +}
  1.1194 +
  1.1195 +void
  1.1196 +PbbMessage::AddressBlockPopFront (void)
  1.1197 +{
  1.1198 +  m_addressBlockList.pop_front();
  1.1199 +}
  1.1200 +
  1.1201 +void
  1.1202 +PbbMessage::AddressBlockPushBack (Ptr<PbbAddressBlock> tlv)
  1.1203 +{
  1.1204 +  m_addressBlockList.push_back(tlv);
  1.1205 +}
  1.1206 +
  1.1207 +void
  1.1208 +PbbMessage::AddressBlockPopBack (void)
  1.1209 +{
  1.1210 +  m_addressBlockList.pop_back();
  1.1211 +}
  1.1212 +
  1.1213 +PbbMessage::AddressBlockIterator
  1.1214 +PbbMessage::AddressBlockErase (PbbMessage::AddressBlockIterator position)
  1.1215 +{
  1.1216 +  return m_addressBlockList.erase(position);
  1.1217 +}
  1.1218 +
  1.1219 +PbbMessage::AddressBlockIterator
  1.1220 +PbbMessage::AddressBlockErase (PbbMessage::AddressBlockIterator first,
  1.1221 +    PbbMessage::AddressBlockIterator last)
  1.1222 +{
  1.1223 +  return m_addressBlockList.erase(first, last);
  1.1224 +}
  1.1225 +
  1.1226 +void
  1.1227 +PbbMessage::AddressBlockClear (void)
  1.1228 +{
  1.1229 +  return m_addressBlockList.clear();
  1.1230 +}
  1.1231 +
  1.1232 +void
  1.1233 +PbbMessage::Ref (void) const
  1.1234 +{
  1.1235 +  m_refCount++;
  1.1236 +}
  1.1237 +
  1.1238 +void
  1.1239 +PbbMessage::Unref (void) const
  1.1240 +{
  1.1241 +  m_refCount--;
  1.1242 +  if (m_refCount == 0)
  1.1243 +    {
  1.1244 +      delete this;
  1.1245 +    }
  1.1246 +}
  1.1247 +
  1.1248 +uint32_t
  1.1249 +PbbMessage::GetSerializedSize (void) const
  1.1250 +{
  1.1251 +  /* msg-type + (msg-flags + msg-addr-length) + 2msg-size */
  1.1252 +  uint32_t size = 4;
  1.1253 +
  1.1254 +  if (HasOriginatorAddress())
  1.1255 +    {
  1.1256 +      size += GetAddressLength() + 1;
  1.1257 +    }
  1.1258 +
  1.1259 +  if (HasHopLimit())
  1.1260 +    {
  1.1261 +      size++;
  1.1262 +    }
  1.1263 +
  1.1264 +  if (HasHopCount())
  1.1265 +    {
  1.1266 +      size++;
  1.1267 +    }
  1.1268 +
  1.1269 +  if (HasSequenceNumber())
  1.1270 +    {
  1.1271 +      size += 2;
  1.1272 +    }
  1.1273 +
  1.1274 +  size += m_tlvList.GetSerializedSize ();
  1.1275 +
  1.1276 +  for (ConstAddressBlockIterator iter = AddressBlockBegin ();
  1.1277 +      iter != AddressBlockEnd ();
  1.1278 +      iter++)
  1.1279 +    {
  1.1280 +      size += (*iter)->GetSerializedSize ();
  1.1281 +    }
  1.1282 +
  1.1283 +  return size;
  1.1284 +}
  1.1285 +
  1.1286 +void
  1.1287 +PbbMessage::Serialize (Buffer::Iterator &start) const
  1.1288 +{
  1.1289 +  Buffer::Iterator front = start;
  1.1290 +
  1.1291 +  start.WriteU8 (GetType());
  1.1292 +
  1.1293 +  /* Save a reference to the spot where we will later write the flags */
  1.1294 +  Buffer::Iterator bufref = start;
  1.1295 +  start.Next (1);
  1.1296 +
  1.1297 +  uint8_t flags = 0;
  1.1298 +
  1.1299 +  flags = GetAddressLength ();
  1.1300 +
  1.1301 +  Buffer::Iterator sizeref = start;
  1.1302 +  start.Next (2);
  1.1303 +
  1.1304 +  if (HasOriginatorAddress ())
  1.1305 +    {
  1.1306 +      flags |= MHAS_ORIG;
  1.1307 +      SerializeOriginatorAddress (start);
  1.1308 +    }
  1.1309 +
  1.1310 +  if (HasHopLimit ())
  1.1311 +    {
  1.1312 +      flags |= MHAS_HOP_LIMIT;
  1.1313 +      start.WriteU8 (GetHopLimit ());
  1.1314 +    }
  1.1315 +
  1.1316 +  if (HasHopCount ())
  1.1317 +    {
  1.1318 +      flags |= MHAS_HOP_COUNT;
  1.1319 +      start.WriteU8 (GetHopCount ());
  1.1320 +    }
  1.1321 +
  1.1322 +  if (HasSequenceNumber ())
  1.1323 +    {
  1.1324 +      flags |= MHAS_SEQ_NUM;
  1.1325 +      start.WriteHtonU16 (GetSequenceNumber ());
  1.1326 +    }
  1.1327 +
  1.1328 +  bufref.WriteU8(flags);
  1.1329 +
  1.1330 +  m_tlvList.Serialize (start);
  1.1331 +
  1.1332 +  for (ConstAddressBlockIterator iter = AddressBlockBegin ();
  1.1333 +      iter != AddressBlockEnd ();
  1.1334 +      iter++)
  1.1335 +    {
  1.1336 +      (*iter)->Serialize (start);
  1.1337 +    }
  1.1338 +
  1.1339 +  sizeref.WriteHtonU16 (front.GetDistanceFrom (start));
  1.1340 +}
  1.1341 +
  1.1342 +Ptr<PbbMessage>
  1.1343 +PbbMessage::DeserializeMessage (Buffer::Iterator &start)
  1.1344 +{
  1.1345 +  /* We need to read the msg-addr-len field to determine what kind of object to
  1.1346 +   * construct. */
  1.1347 +  start.Next ();
  1.1348 +  uint8_t addrlen = start.ReadU8 ();
  1.1349 +  start.Prev (2); /* Go back to the start */
  1.1350 +
  1.1351 +  /* The first four bytes of the flag is the address length.  Set the last four
  1.1352 +   * bytes to 0 to read it. */
  1.1353 +  addrlen = (addrlen & 0xf);
  1.1354 +
  1.1355 +  Ptr<PbbMessage> newmsg;
  1.1356 +
  1.1357 +  switch (addrlen)
  1.1358 +    {
  1.1359 +      case 0:
  1.1360 +      case IPV4:
  1.1361 +        newmsg = Create<PbbMessageIpv4> ();
  1.1362 +        break;
  1.1363 +      case IPV6:
  1.1364 +        newmsg = Create<PbbMessageIpv6> ();
  1.1365 +        break;
  1.1366 +      default:
  1.1367 +        return 0;
  1.1368 +        break;
  1.1369 +    }
  1.1370 +  newmsg->Deserialize (start);
  1.1371 +  return newmsg;
  1.1372 +}
  1.1373 +
  1.1374 +void
  1.1375 +PbbMessage::Deserialize (Buffer::Iterator &start)
  1.1376 +{
  1.1377 +  Buffer::Iterator front = start;
  1.1378 +  SetType (start.ReadU8 ());
  1.1379 +  uint8_t flags = start.ReadU8 ();
  1.1380 +
  1.1381 +  uint16_t size = start.ReadNtohU16 ();
  1.1382 +
  1.1383 +  if (flags & MHAS_ORIG)
  1.1384 +    {
  1.1385 +      SetOriginatorAddress (DeserializeOriginatorAddress (start));
  1.1386 +    }
  1.1387 +
  1.1388 +  if (flags & MHAS_HOP_LIMIT)
  1.1389 +    {
  1.1390 +      SetHopLimit (start.ReadU8 ());
  1.1391 +    }
  1.1392 +
  1.1393 +  if (flags & MHAS_HOP_COUNT)
  1.1394 +    {
  1.1395 +      SetHopCount (start.ReadU8 ());
  1.1396 +    }
  1.1397 +
  1.1398 +  if (flags & MHAS_SEQ_NUM)
  1.1399 +    {
  1.1400 +      SetSequenceNumber (start.ReadNtohU16 ());
  1.1401 +    }
  1.1402 +
  1.1403 +  m_tlvList.Deserialize (start);
  1.1404 +
  1.1405 +  if (size > 0)
  1.1406 +    {
  1.1407 +      while (start.GetDistanceFrom(front) < size)
  1.1408 +        {
  1.1409 +          Ptr<PbbAddressBlock> newab = AddressBlockDeserialize (start);
  1.1410 +          AddressBlockPushBack (newab);
  1.1411 +        }
  1.1412 +    }
  1.1413 +}
  1.1414 +
  1.1415 +void
  1.1416 +PbbMessage::Print (std::ostream &os) const
  1.1417 +{
  1.1418 +  Print (os, 0);
  1.1419 +}
  1.1420 +
  1.1421 +void
  1.1422 +PbbMessage::Print (std::ostream &os, int level) const
  1.1423 +{
  1.1424 +  std::string prefix = "";
  1.1425 +  for (int i = 0; i < level; i++)
  1.1426 +    {
  1.1427 +      prefix.append ("\t");
  1.1428 +    }
  1.1429 +
  1.1430 +  os << prefix << "PbbMessage {" << std::endl;
  1.1431 +
  1.1432 +  os << prefix << "\tmessage type = " << (int)GetType () << std::endl;
  1.1433 +  os << prefix << "\taddress size = " << GetAddressLength () << std::endl;
  1.1434 +
  1.1435 +  if (HasOriginatorAddress ())
  1.1436 +    {
  1.1437 +      os << prefix << "\toriginator address = ";
  1.1438 +      PrintOriginatorAddress (os);
  1.1439 +      os << std::endl;
  1.1440 +    }
  1.1441 +
  1.1442 +  if (HasHopLimit ())
  1.1443 +    {
  1.1444 +      os << prefix << "\thop limit = " << (int)GetHopLimit () << std::endl;
  1.1445 +    }
  1.1446 +
  1.1447 +  if (HasHopCount ())
  1.1448 +    {
  1.1449 +      os << prefix << "\thop count = " << (int)GetHopCount () << std::endl;
  1.1450 +    }
  1.1451 +
  1.1452 +  if (HasSequenceNumber ())
  1.1453 +    {
  1.1454 +      os << prefix << "\tseqnum = " << GetSequenceNumber () << std::endl;
  1.1455 +    }
  1.1456 +
  1.1457 +  m_tlvList.Print (os, level+1);
  1.1458 +
  1.1459 +  for (ConstAddressBlockIterator iter = AddressBlockBegin ();
  1.1460 +      iter != AddressBlockEnd ();
  1.1461 +      iter++)
  1.1462 +    {
  1.1463 +      (*iter)->Print (os, level+1);
  1.1464 +    }
  1.1465 +  os << prefix << "}" << std::endl;
  1.1466 +}
  1.1467 +
  1.1468 +bool
  1.1469 +PbbMessage::operator== (const PbbMessage &other) const
  1.1470 +{
  1.1471 +  if (GetAddressLength () != other.GetAddressLength ())
  1.1472 +    {
  1.1473 +      return false;
  1.1474 +    }
  1.1475 +
  1.1476 +  if (GetType () != other.GetType ())
  1.1477 +    {
  1.1478 +      return false;
  1.1479 +    }
  1.1480 +
  1.1481 +  if (HasOriginatorAddress () != other.HasOriginatorAddress ())
  1.1482 +    {
  1.1483 +      return false;
  1.1484 +    }
  1.1485 +
  1.1486 +  if (HasOriginatorAddress ())
  1.1487 +    {
  1.1488 +      if (GetOriginatorAddress () != other.GetOriginatorAddress ())
  1.1489 +        {
  1.1490 +          return false;
  1.1491 +        }
  1.1492 +    }
  1.1493 +
  1.1494 +  if (HasHopLimit () != other.HasHopLimit ())
  1.1495 +    {
  1.1496 +      return false;
  1.1497 +    }
  1.1498 +
  1.1499 +  if (HasHopLimit ())
  1.1500 +    {
  1.1501 +      if (GetHopLimit () != other.GetHopLimit ())
  1.1502 +        {
  1.1503 +          return false;
  1.1504 +        }
  1.1505 +    }
  1.1506 +
  1.1507 +  if (HasHopCount () != other.HasHopCount ())
  1.1508 +    {
  1.1509 +      return false;
  1.1510 +    }
  1.1511 +
  1.1512 +  if (HasHopCount ())
  1.1513 +    {
  1.1514 +      if (GetHopCount () != other.GetHopCount ())
  1.1515 +        {
  1.1516 +          return false;
  1.1517 +        }
  1.1518 +    }
  1.1519 +
  1.1520 +  if (HasSequenceNumber () != other.HasSequenceNumber ())
  1.1521 +    {
  1.1522 +      return false;
  1.1523 +    }
  1.1524 +
  1.1525 +  if (HasSequenceNumber ())
  1.1526 +    {
  1.1527 +      if (GetSequenceNumber () != other.GetSequenceNumber ())
  1.1528 +        {
  1.1529 +          return false;
  1.1530 +        }
  1.1531 +    }
  1.1532 +
  1.1533 +  if (m_tlvList != other.m_tlvList)
  1.1534 +    {
  1.1535 +      return false;
  1.1536 +    }
  1.1537 +
  1.1538 +  if (AddressBlockSize () != other.AddressBlockSize ())
  1.1539 +    {
  1.1540 +      return false;
  1.1541 +    }
  1.1542 +
  1.1543 +  ConstAddressBlockIterator tai, oai;
  1.1544 +  for (tai = AddressBlockBegin (), oai = other.AddressBlockBegin ();
  1.1545 +      tai != AddressBlockEnd () && oai != other.AddressBlockEnd ();
  1.1546 +      tai++, oai++)
  1.1547 +    {
  1.1548 +      if (**tai != **oai)
  1.1549 +        {
  1.1550 +          return false;
  1.1551 +        }
  1.1552 +    }
  1.1553 +  return true;
  1.1554 +}
  1.1555 +
  1.1556 +bool
  1.1557 +PbbMessage::operator!= (const PbbMessage &other) const
  1.1558 +{
  1.1559 +  return !(*this == other);
  1.1560 +}
  1.1561 +
  1.1562 +/* End PbbMessage Class */
  1.1563 +
  1.1564 +PbbAddressLength
  1.1565 +PbbMessageIpv4::GetAddressLength (void) const
  1.1566 +{
  1.1567 +  return IPV4;
  1.1568 +}
  1.1569 +
  1.1570 +void
  1.1571 +PbbMessageIpv4::SerializeOriginatorAddress (Buffer::Iterator &start) const
  1.1572 +{
  1.1573 +  uint8_t buffer[GetAddressLength () + 1];
  1.1574 +  Ipv4Address::ConvertFrom (GetOriginatorAddress ()).Serialize(buffer);
  1.1575 +  start.Write (buffer, GetAddressLength () + 1);
  1.1576 +}
  1.1577 +
  1.1578 +Address
  1.1579 +PbbMessageIpv4::DeserializeOriginatorAddress (Buffer::Iterator &start) const
  1.1580 +{
  1.1581 +  uint8_t buffer[GetAddressLength () + 1];
  1.1582 +  start.Read(buffer, GetAddressLength () + 1);
  1.1583 +  return Ipv4Address::Deserialize (buffer);
  1.1584 +}
  1.1585 +
  1.1586 +void
  1.1587 +PbbMessageIpv4::PrintOriginatorAddress (std::ostream &os) const
  1.1588 +{
  1.1589 +  Ipv4Address::ConvertFrom (GetOriginatorAddress ()).Print (os);
  1.1590 +}
  1.1591 +
  1.1592 +Ptr<PbbAddressBlock>
  1.1593 +PbbMessageIpv4::AddressBlockDeserialize (Buffer::Iterator &start) const
  1.1594 +{
  1.1595 +  Ptr<PbbAddressBlock> newab = Create<PbbAddressBlockIpv4> ();
  1.1596 +  newab->Deserialize (start);
  1.1597 +  return newab;
  1.1598 +}
  1.1599 +
  1.1600 +/* End PbbMessageIpv4 Class */
  1.1601 +
  1.1602 +PbbAddressLength
  1.1603 +PbbMessageIpv6::GetAddressLength (void) const
  1.1604 +{
  1.1605 +  return IPV6;
  1.1606 +}
  1.1607 +
  1.1608 +void
  1.1609 +PbbMessageIpv6::SerializeOriginatorAddress (Buffer::Iterator &start) const
  1.1610 +{
  1.1611 +  uint8_t buffer[GetAddressLength () + 1];
  1.1612 +  Ipv6Address::ConvertFrom (GetOriginatorAddress ()).Serialize(buffer);
  1.1613 +  start.Write (buffer, GetAddressLength () + 1);
  1.1614 +}
  1.1615 +
  1.1616 +Address
  1.1617 +PbbMessageIpv6::DeserializeOriginatorAddress (Buffer::Iterator &start) const
  1.1618 +{
  1.1619 +  uint8_t buffer[GetAddressLength () + 1];
  1.1620 +  start.Read(buffer, GetAddressLength () + 1);
  1.1621 +  return Ipv6Address::Deserialize (buffer);
  1.1622 +}
  1.1623 +
  1.1624 +void
  1.1625 +PbbMessageIpv6::PrintOriginatorAddress (std::ostream &os) const
  1.1626 +{
  1.1627 +  Ipv6Address::ConvertFrom (GetOriginatorAddress ()).Print (os);
  1.1628 +}
  1.1629 +
  1.1630 +Ptr<PbbAddressBlock>
  1.1631 +PbbMessageIpv6::AddressBlockDeserialize (Buffer::Iterator &start) const
  1.1632 +{
  1.1633 +  Ptr<PbbAddressBlock> newab = Create<PbbAddressBlockIpv6> ();
  1.1634 +  newab->Deserialize (start);
  1.1635 +  return newab;
  1.1636 +}
  1.1637 +
  1.1638 +/* End PbbMessageIpv6 Class */
  1.1639 +
  1.1640 +PbbAddressBlock::PbbAddressBlock ()
  1.1641 +{
  1.1642 +  m_refCount = 1;
  1.1643 +}
  1.1644 +
  1.1645 +/* Manipulating the address block */
  1.1646 +
  1.1647 +PbbAddressBlock::AddressIterator
  1.1648 +PbbAddressBlock::AddressBegin (void)
  1.1649 +{
  1.1650 +  return m_addressList.begin();
  1.1651 +}
  1.1652 +
  1.1653 +PbbAddressBlock::ConstAddressIterator
  1.1654 +PbbAddressBlock::AddressBegin (void) const
  1.1655 +{
  1.1656 +  return m_addressList.begin();
  1.1657 +}
  1.1658 +
  1.1659 +PbbAddressBlock::AddressIterator
  1.1660 +PbbAddressBlock::AddressEnd (void)
  1.1661 +{
  1.1662 +  return m_addressList.end();
  1.1663 +}
  1.1664 +
  1.1665 +PbbAddressBlock::ConstAddressIterator
  1.1666 +PbbAddressBlock::AddressEnd (void) const
  1.1667 +{
  1.1668 +  return m_addressList.end();
  1.1669 +}
  1.1670 +
  1.1671 +int
  1.1672 +PbbAddressBlock::AddressSize (void) const
  1.1673 +{
  1.1674 +  return m_addressList.size();
  1.1675 +}
  1.1676 +
  1.1677 +bool
  1.1678 +PbbAddressBlock::AddressEmpty (void) const
  1.1679 +{
  1.1680 +  return m_addressList.empty();
  1.1681 +}
  1.1682 +
  1.1683 +Address
  1.1684 +PbbAddressBlock::AddressFront (void) const
  1.1685 +{
  1.1686 +  return m_addressList.front();
  1.1687 +}
  1.1688 +
  1.1689 +Address
  1.1690 +PbbAddressBlock::AddressBack (void) const
  1.1691 +{
  1.1692 +  return m_addressList.back();
  1.1693 +}
  1.1694 +
  1.1695 +void
  1.1696 +PbbAddressBlock::AddressPushFront (Address tlv)
  1.1697 +{
  1.1698 +  m_addressList.push_front(tlv);
  1.1699 +}
  1.1700 +
  1.1701 +void
  1.1702 +PbbAddressBlock::AddressPopFront (void)
  1.1703 +{
  1.1704 +  m_addressList.pop_front();
  1.1705 +}
  1.1706 +
  1.1707 +void
  1.1708 +PbbAddressBlock::AddressPushBack (Address tlv)
  1.1709 +{
  1.1710 +  m_addressList.push_back(tlv);
  1.1711 +}
  1.1712 +
  1.1713 +void
  1.1714 +PbbAddressBlock::AddressPopBack (void)
  1.1715 +{
  1.1716 +  m_addressList.pop_back();
  1.1717 +}
  1.1718 +
  1.1719 +PbbAddressBlock::AddressIterator
  1.1720 +PbbAddressBlock::AddressErase (PbbAddressBlock::AddressIterator position)
  1.1721 +{
  1.1722 +  return m_addressList.erase(position);
  1.1723 +}
  1.1724 +
  1.1725 +PbbAddressBlock::AddressIterator
  1.1726 +PbbAddressBlock::AddressErase (PbbAddressBlock::AddressIterator first,
  1.1727 +    PbbAddressBlock::AddressIterator last)
  1.1728 +{
  1.1729 +  return m_addressList.erase(first, last);
  1.1730 +}
  1.1731 +
  1.1732 +  void
  1.1733 +PbbAddressBlock::AddressClear (void)
  1.1734 +{
  1.1735 +  return m_addressList.clear();
  1.1736 +}
  1.1737 +
  1.1738 +/* Manipulating the prefix list */
  1.1739 +
  1.1740 +PbbAddressBlock::PrefixIterator
  1.1741 +PbbAddressBlock::PrefixBegin (void)
  1.1742 +{
  1.1743 +  return m_prefixList.begin ();
  1.1744 +}
  1.1745 +
  1.1746 +PbbAddressBlock::ConstPrefixIterator
  1.1747 +PbbAddressBlock::PrefixBegin (void) const
  1.1748 +{
  1.1749 +  return m_prefixList.begin ();
  1.1750 +}
  1.1751 +
  1.1752 +PbbAddressBlock::PrefixIterator
  1.1753 +PbbAddressBlock::PrefixEnd (void)
  1.1754 +{
  1.1755 +  return m_prefixList.end ();
  1.1756 +}
  1.1757 +
  1.1758 +PbbAddressBlock::ConstPrefixIterator
  1.1759 +PbbAddressBlock::PrefixEnd (void) const
  1.1760 +{
  1.1761 +  return m_prefixList.end ();
  1.1762 +}
  1.1763 +
  1.1764 +int
  1.1765 +PbbAddressBlock::PrefixSize (void) const
  1.1766 +{
  1.1767 +  return m_prefixList.size ();
  1.1768 +}
  1.1769 +
  1.1770 +bool
  1.1771 +PbbAddressBlock::PrefixEmpty (void) const
  1.1772 +{
  1.1773 +  return m_prefixList.empty ();
  1.1774 +}
  1.1775 +
  1.1776 +uint8_t
  1.1777 +PbbAddressBlock::PrefixFront (void) const
  1.1778 +{
  1.1779 +  return m_prefixList.front ();
  1.1780 +}
  1.1781 +
  1.1782 +uint8_t
  1.1783 +PbbAddressBlock::PrefixBack (void) const
  1.1784 +{
  1.1785 +  return m_prefixList.back ();
  1.1786 +}
  1.1787 +
  1.1788 +void
  1.1789 +PbbAddressBlock::PrefixPushFront (uint8_t prefix)
  1.1790 +{
  1.1791 +  m_prefixList.push_front (prefix);
  1.1792 +}
  1.1793 +
  1.1794 +void
  1.1795 +PbbAddressBlock::PrefixPopFront (void)
  1.1796 +{
  1.1797 +  m_prefixList.pop_front ();
  1.1798 +}
  1.1799 +
  1.1800 +void
  1.1801 +PbbAddressBlock::PrefixPushBack (uint8_t prefix)
  1.1802 +{
  1.1803 +  m_prefixList.push_back (prefix);
  1.1804 +}
  1.1805 +
  1.1806 +void
  1.1807 +PbbAddressBlock::PrefixPopBack (void)
  1.1808 +{
  1.1809 +  m_prefixList.pop_back ();
  1.1810 +}
  1.1811 +
  1.1812 +PbbAddressBlock::PrefixIterator
  1.1813 +PbbAddressBlock::PrefixInsert (PbbAddressBlock::PrefixIterator position, const uint8_t value)
  1.1814 +{
  1.1815 +  return m_prefixList.insert (position, value);
  1.1816 +}
  1.1817 +
  1.1818 +PbbAddressBlock::PrefixIterator
  1.1819 +PbbAddressBlock::PrefixErase (PbbAddressBlock::PrefixIterator position)
  1.1820 +{
  1.1821 +  return m_prefixList.erase (position);
  1.1822 +}
  1.1823 +
  1.1824 +PbbAddressBlock::PrefixIterator
  1.1825 +PbbAddressBlock::PrefixErase (PbbAddressBlock::PrefixIterator first, PbbAddressBlock::PrefixIterator last)
  1.1826 +{
  1.1827 +  return m_prefixList.erase (first, last);
  1.1828 +}
  1.1829 +
  1.1830 +void
  1.1831 +PbbAddressBlock::PrefixClear (void)
  1.1832 +{
  1.1833 +  m_prefixList.clear ();
  1.1834 +}
  1.1835 +
  1.1836 +/* Manipulating the TLV block */
  1.1837 +
  1.1838 +PbbAddressBlock::TlvIterator
  1.1839 +PbbAddressBlock::TlvBegin (void)
  1.1840 +{
  1.1841 +  return m_addressTlvList.Begin();
  1.1842 +}
  1.1843 +
  1.1844 +PbbAddressBlock::ConstTlvIterator
  1.1845 +PbbAddressBlock::TlvBegin (void) const
  1.1846 +{
  1.1847 +  return m_addressTlvList.Begin();
  1.1848 +}
  1.1849 +
  1.1850 +PbbAddressBlock::TlvIterator
  1.1851 +PbbAddressBlock::TlvEnd (void)
  1.1852 +{
  1.1853 +  return m_addressTlvList.End();
  1.1854 +}
  1.1855 +
  1.1856 +PbbAddressBlock::ConstTlvIterator
  1.1857 +PbbAddressBlock::TlvEnd (void) const
  1.1858 +{
  1.1859 +  return m_addressTlvList.End();
  1.1860 +}
  1.1861 +
  1.1862 +int
  1.1863 +PbbAddressBlock::TlvSize (void) const
  1.1864 +{
  1.1865 +  return m_addressTlvList.Size();
  1.1866 +}
  1.1867 +
  1.1868 +bool
  1.1869 +PbbAddressBlock::TlvEmpty (void) const
  1.1870 +{
  1.1871 +  return m_addressTlvList.Empty();
  1.1872 +}
  1.1873 +
  1.1874 +Ptr<PbbAddressTlv>
  1.1875 +PbbAddressBlock::TlvFront (void)
  1.1876 +{
  1.1877 +  return m_addressTlvList.Front();
  1.1878 +}
  1.1879 +
  1.1880 +const Ptr<PbbAddressTlv>
  1.1881 +PbbAddressBlock::TlvFront (void) const
  1.1882 +{
  1.1883 +  return m_addressTlvList.Front();
  1.1884 +}
  1.1885 +
  1.1886 +Ptr<PbbAddressTlv>
  1.1887 +PbbAddressBlock::TlvBack (void)
  1.1888 +{
  1.1889 +  return m_addressTlvList.Back();
  1.1890 +}
  1.1891 +
  1.1892 +const Ptr<PbbAddressTlv>
  1.1893 +PbbAddressBlock::TlvBack (void) const
  1.1894 +{
  1.1895 +  return m_addressTlvList.Back();
  1.1896 +}
  1.1897 +
  1.1898 +void
  1.1899 +PbbAddressBlock::TlvPushFront (Ptr<PbbAddressTlv> tlv)
  1.1900 +{
  1.1901 +  m_addressTlvList.PushFront(tlv);
  1.1902 +}
  1.1903 +
  1.1904 +void
  1.1905 +PbbAddressBlock::TlvPopFront (void)
  1.1906 +{
  1.1907 +  m_addressTlvList.PopFront();
  1.1908 +}
  1.1909 +
  1.1910 +void
  1.1911 +PbbAddressBlock::TlvPushBack (Ptr<PbbAddressTlv> tlv)
  1.1912 +{
  1.1913 +  m_addressTlvList.PushBack(tlv);
  1.1914 +}
  1.1915 +
  1.1916 +void
  1.1917 +PbbAddressBlock::TlvPopBack (void)
  1.1918 +{
  1.1919 +  m_addressTlvList.PopBack();
  1.1920 +}
  1.1921 +
  1.1922 +PbbAddressBlock::TlvIterator
  1.1923 +PbbAddressBlock::TlvErase (PbbAddressBlock::TlvIterator position)
  1.1924 +{
  1.1925 +  return m_addressTlvList.Erase(position);
  1.1926 +}
  1.1927 +
  1.1928 +PbbAddressBlock::TlvIterator
  1.1929 +PbbAddressBlock::TlvErase (PbbAddressBlock::TlvIterator first,
  1.1930 +    PbbAddressBlock::TlvIterator last)
  1.1931 +{
  1.1932 +  return m_addressTlvList.Erase(first, last);
  1.1933 +}
  1.1934 +
  1.1935 +void
  1.1936 +PbbAddressBlock::TlvClear (void)
  1.1937 +{
  1.1938 +  return m_addressTlvList.Clear();
  1.1939 +}
  1.1940 +
  1.1941 +void
  1.1942 +PbbAddressBlock::Ref (void) const
  1.1943 +{
  1.1944 +  m_refCount++;
  1.1945 +}
  1.1946 +
  1.1947 +void
  1.1948 +PbbAddressBlock::Unref (void) const
  1.1949 +{
  1.1950 +  m_refCount--;
  1.1951 +  if (m_refCount == 0)
  1.1952 +    {
  1.1953 +      delete this;
  1.1954 +    }
  1.1955 +}
  1.1956 +
  1.1957 +uint32_t
  1.1958 +PbbAddressBlock::GetSerializedSize (void) const
  1.1959 +{
  1.1960 +  /* num-addr + flags */
  1.1961 +  uint32_t size = 2;
  1.1962 +
  1.1963 +  if (AddressSize () == 1)
  1.1964 +    {
  1.1965 +      size += GetAddressLength () + PrefixSize();
  1.1966 +    }
  1.1967 +  else if (AddressSize () > 0)
  1.1968 +    {
  1.1969 +      uint8_t head[GetAddressLength ()];
  1.1970 +      uint8_t headlen = 0;
  1.1971 +      uint8_t tail[GetAddressLength ()];
  1.1972 +      uint8_t taillen = 0;
  1.1973 +
  1.1974 +      GetHeadTail (head, headlen, tail, taillen);
  1.1975 +
  1.1976 +      if (headlen > 0)
  1.1977 +        {
  1.1978 +          size += 1 + headlen;
  1.1979 +        }
  1.1980 +
  1.1981 +      if (taillen > 0)
  1.1982 +        {
  1.1983 +          size++;
  1.1984 +          if (!HasZeroTail (tail, taillen))
  1.1985 +            {
  1.1986 +              size += taillen;
  1.1987 +            }
  1.1988 +        }
  1.1989 +
  1.1990 +      /* mid size */
  1.1991 +      size += (GetAddressLength () - headlen - taillen) * AddressSize ();
  1.1992 +
  1.1993 +      size += PrefixSize ();
  1.1994 +    }
  1.1995 +
  1.1996 +  size += m_addressTlvList.GetSerializedSize ();
  1.1997 +
  1.1998 +  return size;
  1.1999 +}
  1.2000 +
  1.2001 +void
  1.2002 +PbbAddressBlock::Serialize (Buffer::Iterator &start) const
  1.2003 +{
  1.2004 +  start.WriteU8 (AddressSize ());
  1.2005 +
  1.2006 +  if (AddressSize () == 1)
  1.2007 +    {
  1.2008 +      start.WriteU8 (0);
  1.2009 +
  1.2010 +      uint8_t buf[GetAddressLength ()];
  1.2011 +      SerializeAddress (buf, AddressBegin ());
  1.2012 +      start.Write (buf, GetAddressLength ());
  1.2013 +
  1.2014 +      if (PrefixSize () == 1)
  1.2015 +        {
  1.2016 +          start.WriteU8 (PrefixFront ());
  1.2017 +        }
  1.2018 +    }
  1.2019 +  else if (AddressSize () > 0)
  1.2020 +    {
  1.2021 +      Buffer::Iterator bufref = start;
  1.2022 +      uint8_t flags = 0;
  1.2023 +      start.Next ();
  1.2024 +
  1.2025 +      uint8_t head[GetAddressLength ()];
  1.2026 +      uint8_t tail[GetAddressLength ()];
  1.2027 +      uint8_t headlen = 0;
  1.2028 +      uint8_t taillen = 0;
  1.2029 +
  1.2030 +      GetHeadTail (head, headlen, tail, taillen);
  1.2031 +
  1.2032 +      if (headlen > 0)
  1.2033 +        {
  1.2034 +          flags |= AHAS_HEAD;
  1.2035 +          start.WriteU8 (headlen);
  1.2036 +          start.Write (head, headlen);
  1.2037 +        }
  1.2038 +
  1.2039 +      if (taillen > 0)
  1.2040 +        {
  1.2041 +          start.WriteU8 (taillen);
  1.2042 +
  1.2043 +          if (HasZeroTail (tail, taillen))
  1.2044 +            {
  1.2045 +              flags |= AHAS_ZERO_TAIL;
  1.2046 +            }
  1.2047 +          else
  1.2048 +            {
  1.2049 +              flags |= AHAS_FULL_TAIL;
  1.2050 +              start.Write (tail, taillen);
  1.2051 +            }
  1.2052 +        }
  1.2053 +
  1.2054 +      if (headlen + taillen < GetAddressLength ())
  1.2055 +        {
  1.2056 +          uint8_t mid[GetAddressLength ()];
  1.2057 +          for (PbbAddressBlock::ConstAddressIterator iter = AddressBegin ();
  1.2058 +              iter != AddressEnd ();
  1.2059 +              iter++)
  1.2060 +            {
  1.2061 +              SerializeAddress (mid, iter);
  1.2062 +              start.Write (mid + headlen, GetAddressLength () - headlen - taillen);
  1.2063 +            }
  1.2064 +        }
  1.2065 +
  1.2066 +      flags |= GetPrefixFlags ();
  1.2067 +      bufref.WriteU8 (flags);
  1.2068 +
  1.2069 +      for (ConstPrefixIterator iter = PrefixBegin ();
  1.2070 +          iter != PrefixEnd ();
  1.2071 +          iter++)
  1.2072 +        {
  1.2073 +          start.WriteU8 (*iter);
  1.2074 +        }
  1.2075 +    }
  1.2076 +  
  1.2077 +  m_addressTlvList.Serialize (start);
  1.2078 +}
  1.2079 +
  1.2080 +void
  1.2081 +PbbAddressBlock::Deserialize (Buffer::Iterator &start)
  1.2082 +{
  1.2083 +  uint8_t numaddr = start.ReadU8 ();
  1.2084 +  uint8_t flags = start.ReadU8 ();
  1.2085 +
  1.2086 +  if (numaddr > 0)
  1.2087 +    {
  1.2088 +      uint8_t headlen = 0;
  1.2089 +      uint8_t taillen = 0;
  1.2090 +      uint8_t addrtmp[GetAddressLength ()];
  1.2091 +      memset(addrtmp, 0, GetAddressLength ());
  1.2092 +
  1.2093 +      if (flags & AHAS_HEAD)
  1.2094 +        {
  1.2095 +          headlen = start.ReadU8 ();
  1.2096 +          start.Read (addrtmp, headlen);
  1.2097 +        }
  1.2098 +
  1.2099 +      if ((flags & AHAS_FULL_TAIL) ^ (flags & AHAS_ZERO_TAIL))
  1.2100 +        {
  1.2101 +          taillen = start.ReadU8 ();
  1.2102 +          
  1.2103 +          if (flags & AHAS_FULL_TAIL)
  1.2104 +            {
  1.2105 +              start.Read (addrtmp + GetAddressLength () - taillen, taillen);
  1.2106 +            }
  1.2107 +        }
  1.2108 +
  1.2109 +      for (int i = 0; i < numaddr; i++)
  1.2110 +        {
  1.2111 +          start.Read (addrtmp + headlen, GetAddressLength () - headlen - taillen);
  1.2112 +          AddressPushBack (DeserializeAddress (addrtmp));
  1.2113 +        }
  1.2114 +
  1.2115 +      if (flags & AHAS_SINGLE_PRE_LEN)
  1.2116 +        {
  1.2117 +          PrefixPushBack (start.ReadU8 ());
  1.2118 +        }
  1.2119 +      else if (flags & AHAS_MULTI_PRE_LEN)
  1.2120 +        {
  1.2121 +          for (int i = 0; i < numaddr; i++)
  1.2122 +            {
  1.2123 +              PrefixPushBack (start.ReadU8 ());
  1.2124 +            }
  1.2125 +        }
  1.2126 +    }
  1.2127 +
  1.2128 +  m_addressTlvList.Deserialize (start);
  1.2129 +}
  1.2130 +
  1.2131 +void
  1.2132 +PbbAddressBlock::Print (std::ostream &os) const
  1.2133 +{
  1.2134 +  Print (os, 0);
  1.2135 +}
  1.2136 +
  1.2137 +void
  1.2138 +PbbAddressBlock::Print (std::ostream &os, int level) const
  1.2139 +{
  1.2140 +  std::string prefix = "";
  1.2141 +  for (int i = 0; i < level; i++)
  1.2142 +    {
  1.2143 +      prefix.append ("\t");
  1.2144 +    }
  1.2145 +
  1.2146 +  os << prefix << "PbbAddressBlock {" << std::endl;
  1.2147 +  os << prefix << "\taddresses = " << std::endl;
  1.2148 +  for (ConstAddressIterator iter = AddressBegin ();
  1.2149 +      iter != AddressEnd ();
  1.2150 +      iter++)
  1.2151 +    {
  1.2152 +      os << prefix << "\t\t";
  1.2153 +      PrintAddress(os, iter);
  1.2154 +      os << std::endl;
  1.2155 +    }
  1.2156 +
  1.2157 +  os << prefix << "\tprefixes = " << std::endl;
  1.2158 +  for (ConstPrefixIterator iter = PrefixBegin ();
  1.2159 +      iter != PrefixEnd ();
  1.2160 +      iter++)
  1.2161 +    {
  1.2162 +      os << prefix << "\t\t" << (int)(*iter) << std::endl;
  1.2163 +    }
  1.2164 +
  1.2165 +  m_addressTlvList.Print (os, level+1);
  1.2166 +}
  1.2167 +
  1.2168 +bool
  1.2169 +PbbAddressBlock::operator== (const PbbAddressBlock &other) const
  1.2170 +{
  1.2171 +  if (AddressSize () != other.AddressSize ())
  1.2172 +    {
  1.2173 +      return false;
  1.2174 +    }
  1.2175 +
  1.2176 +  ConstAddressIterator tai, oai;
  1.2177 +  for (tai = AddressBegin (), oai = other.AddressBegin ();
  1.2178 +      tai != AddressEnd () && oai != other.AddressEnd ();
  1.2179 +      tai++, oai++)
  1.2180 +    {
  1.2181 +      if (*tai != *oai)
  1.2182 +        {
  1.2183 +          return false;
  1.2184 +        }
  1.2185 +    }
  1.2186 +
  1.2187 +  if (PrefixSize () != other.PrefixSize ())
  1.2188 +    {
  1.2189 +      return false;
  1.2190 +    }
  1.2191 +
  1.2192 +  ConstPrefixIterator tpi, opi;
  1.2193 +  for (tpi = PrefixBegin (), opi = other.PrefixBegin ();
  1.2194 +      tpi != PrefixEnd () && opi != other.PrefixEnd ();
  1.2195 +      tpi++, opi++)
  1.2196 +    {
  1.2197 +      if (*tpi != *opi)
  1.2198 +        {
  1.2199 +          return false;
  1.2200 +        }
  1.2201 +    }
  1.2202 +
  1.2203 +  if (m_addressTlvList != other.m_addressTlvList)
  1.2204 +    {
  1.2205 +      return false;
  1.2206 +    }
  1.2207 +
  1.2208 +  return true;
  1.2209 +}
  1.2210 +
  1.2211 +bool
  1.2212 +PbbAddressBlock::operator!= (const PbbAddressBlock &other) const
  1.2213 +{
  1.2214 +  return !(*this == other);
  1.2215 +}
  1.2216 +
  1.2217 +uint8_t
  1.2218 +PbbAddressBlock::GetPrefixFlags (void) const
  1.2219 +{
  1.2220 +  switch (PrefixSize ())
  1.2221 +    {
  1.2222 +      case 0:
  1.2223 +        return 0;
  1.2224 +        break;
  1.2225 +      case 1:
  1.2226 +        return AHAS_SINGLE_PRE_LEN;
  1.2227 +        break;
  1.2228 +      default:
  1.2229 +        return AHAS_MULTI_PRE_LEN;
  1.2230 +        break;
  1.2231 +    }
  1.2232 +}
  1.2233 +
  1.2234 +void
  1.2235 +PbbAddressBlock::GetHeadTail (uint8_t *head, uint8_t &headlen,
  1.2236 +    uint8_t *tail, uint8_t &taillen) const
  1.2237 +{
  1.2238 +  headlen = GetAddressLength ();
  1.2239 +  taillen = headlen;
  1.2240 +
  1.2241 +  /* Temporary automatic buffers to store serialized addresses */
  1.2242 +  uint8_t * buflast = new uint8_t[GetAddressLength ()];
  1.2243 +  uint8_t * bufcur = new uint8_t[GetAddressLength ()];
  1.2244 +  uint8_t * tmp;
  1.2245 +
  1.2246 +  SerializeAddress (buflast, AddressBegin ());
  1.2247 +
  1.2248 +  /* Skip the first item */
  1.2249 +  for (PbbAddressBlock::ConstAddressIterator iter = AddressBegin ()++;
  1.2250 +      iter != AddressEnd ();
  1.2251 +      iter++)
  1.2252 +    {
  1.2253 +      SerializeAddress (bufcur, iter);
  1.2254 +
  1.2255 +      int i;
  1.2256 +      for (i = 0; i < headlen; i++)
  1.2257 +        {
  1.2258 +          if (buflast[i] != bufcur[i])
  1.2259 +            {
  1.2260 +              headlen = i;
  1.2261 +              break;
  1.2262 +            }
  1.2263 +        }
  1.2264 +
  1.2265 +      /* If headlen == fulllen - 1, then tail is 0 */
  1.2266 +      if (headlen <= GetAddressLength () - 1)
  1.2267 +        {
  1.2268 +          for (i = GetAddressLength () - 1;
  1.2269 +              GetAddressLength () - 1 - i <= taillen && i > headlen;
  1.2270 +              i--)
  1.2271 +            {
  1.2272 +              if (buflast[i] != bufcur[i])
  1.2273 +                {
  1.2274 +                  break;
  1.2275 +                }
  1.2276 +            }
  1.2277 +          taillen = GetAddressLength () - 1 - i;
  1.2278 +        }
  1.2279 +      else if (headlen == 0)
  1.2280 +        {
  1.2281 +          taillen = 0;
  1.2282 +          break;
  1.2283 +        }
  1.2284 +
  1.2285 +      tmp = buflast;
  1.2286 +      buflast = bufcur;
  1.2287 +      bufcur = tmp;
  1.2288 +    }
  1.2289 +
  1.2290 +  memcpy(head, bufcur, headlen);
  1.2291 +  memcpy(tail, bufcur + (GetAddressLength () - taillen), taillen);
  1.2292 +
  1.2293 +  delete[] buflast;
  1.2294 +  delete[] bufcur;
  1.2295 +}
  1.2296 +
  1.2297 +bool
  1.2298 +PbbAddressBlock::HasZeroTail (const uint8_t *tail, uint8_t taillen) const
  1.2299 +{
  1.2300 +  int i;
  1.2301 +  for (i = 0; i < taillen; i++)
  1.2302 +    {
  1.2303 +      if (tail[i] != 0)
  1.2304 +        {
  1.2305 +          break;
  1.2306 +        }
  1.2307 +    }
  1.2308 +  return i == taillen;
  1.2309 +}
  1.2310 +
  1.2311 +/* End PbbAddressBlock Class */
  1.2312 +
  1.2313 +uint8_t
  1.2314 +PbbAddressBlockIpv4::GetAddressLength (void) const
  1.2315 +{
  1.2316 +  return 4;
  1.2317 +}
  1.2318 +
  1.2319 +void
  1.2320 +PbbAddressBlockIpv4::SerializeAddress (uint8_t *buffer, ConstAddressIterator iter) const
  1.2321 +{
  1.2322 +  Ipv4Address::ConvertFrom (*iter).Serialize (buffer);
  1.2323 +}
  1.2324 +
  1.2325 +Address
  1.2326 +PbbAddressBlockIpv4::DeserializeAddress (uint8_t *buffer) const
  1.2327 +{
  1.2328 +  return Ipv4Address::Deserialize (buffer);
  1.2329 +}
  1.2330 +
  1.2331 +void
  1.2332 +PbbAddressBlockIpv4::PrintAddress (std::ostream &os, ConstAddressIterator iter) const
  1.2333 +{
  1.2334 +  Ipv4Address::ConvertFrom (*iter).Print (os);
  1.2335 +}
  1.2336 +
  1.2337 +/* End PbbAddressBlockIpv4 Class */
  1.2338 +
  1.2339 +uint8_t
  1.2340 +PbbAddressBlockIpv6::GetAddressLength (void) const
  1.2341 +{
  1.2342 +  return 16;
  1.2343 +}
  1.2344 +
  1.2345 +void
  1.2346 +PbbAddressBlockIpv6::SerializeAddress (uint8_t *buffer, ConstAddressIterator iter) const
  1.2347 +{
  1.2348 +  Ipv6Address::ConvertFrom (*iter).Serialize (buffer);
  1.2349 +}
  1.2350 +
  1.2351 +Address
  1.2352 +PbbAddressBlockIpv6::DeserializeAddress (uint8_t *buffer) const
  1.2353 +{
  1.2354 +  return Ipv6Address::Deserialize (buffer);
  1.2355 +}
  1.2356 +
  1.2357 +void
  1.2358 +PbbAddressBlockIpv6::PrintAddress (std::ostream &os, ConstAddressIterator iter) const
  1.2359 +{
  1.2360 +  Ipv6Address::ConvertFrom (*iter).Print (os);
  1.2361 +}
  1.2362 +
  1.2363 +/* End PbbAddressBlockIpv6 Class */
  1.2364 +
  1.2365 +PbbTlv::PbbTlv (void)
  1.2366 +{
  1.2367 +  m_refCount = 1;
  1.2368 +  m_hasTypeExt = false;
  1.2369 +  m_hasIndexStart = false;
  1.2370 +  m_hasIndexStop = false;
  1.2371 +  m_isMultivalue = false;
  1.2372 +  m_hasValue = false;
  1.2373 +}
  1.2374 +
  1.2375 +void
  1.2376 +PbbTlv::SetType (uint8_t type)
  1.2377 +{
  1.2378 +  m_type = type;
  1.2379 +}
  1.2380 +
  1.2381 +uint8_t
  1.2382 +PbbTlv::GetType (void) const
  1.2383 +{
  1.2384 +  return m_type;
  1.2385 +}
  1.2386 +
  1.2387 +void
  1.2388 +PbbTlv::SetTypeExt (uint8_t typeExt)
  1.2389 +{
  1.2390 +  m_typeExt = typeExt;
  1.2391 +  m_hasTypeExt = true;
  1.2392 +}
  1.2393 +
  1.2394 +uint8_t
  1.2395 +PbbTlv::GetTypeExt (void) const
  1.2396 +{
  1.2397 +  NS_ASSERT (HasTypeExt ());
  1.2398 +  return m_typeExt;
  1.2399 +}
  1.2400 +
  1.2401 +bool
  1.2402 +PbbTlv::HasTypeExt (void) const
  1.2403 +{
  1.2404 +  return m_hasTypeExt;
  1.2405 +}
  1.2406 +
  1.2407 +void
  1.2408 +PbbTlv::SetIndexStart (uint8_t index)
  1.2409 +{
  1.2410 +  m_indexStart = index;
  1.2411 +  m_hasIndexStart = true;
  1.2412 +}
  1.2413 +
  1.2414 +uint8_t
  1.2415 +PbbTlv::GetIndexStart (void) const
  1.2416 +{
  1.2417 +  NS_ASSERT (HasIndexStart ());
  1.2418 +  return m_indexStart;
  1.2419 +}
  1.2420 +
  1.2421 +bool
  1.2422 +PbbTlv::HasIndexStart (void) const
  1.2423 +{
  1.2424 +  return m_hasIndexStart;
  1.2425 +}
  1.2426 +
  1.2427 +void
  1.2428 +PbbTlv::SetIndexStop (uint8_t index)
  1.2429 +{
  1.2430 +  m_indexStop = index;
  1.2431 +  m_hasIndexStop = true;
  1.2432 +}
  1.2433 +
  1.2434 +uint8_t
  1.2435 +PbbTlv::GetIndexStop (void) const
  1.2436 +{
  1.2437 +  NS_ASSERT (HasIndexStop ());
  1.2438 +  return m_indexStop;
  1.2439 +}
  1.2440 +
  1.2441 +bool
  1.2442 +PbbTlv::HasIndexStop (void) const
  1.2443 +{
  1.2444 +  return m_hasIndexStop;
  1.2445 +}
  1.2446 +
  1.2447 +void
  1.2448 +PbbTlv::SetMultivalue (bool isMultivalue)
  1.2449 +{
  1.2450 +  m_isMultivalue = isMultivalue;
  1.2451 +}
  1.2452 +
  1.2453 +bool
  1.2454 +PbbTlv::IsMultivalue (void) const
  1.2455 +{
  1.2456 +  return m_isMultivalue;
  1.2457 +}
  1.2458 +
  1.2459 +void
  1.2460 +PbbTlv::SetValue (Buffer start)
  1.2461 +{
  1.2462 +  m_hasValue = true;
  1.2463 +  m_value = start;
  1.2464 +}
  1.2465 +
  1.2466 +void
  1.2467 +PbbTlv::SetValue (const uint8_t * buffer, uint32_t size)
  1.2468 +{
  1.2469 +  Buffer value;
  1.2470 +  value.AddAtStart (size);
  1.2471 +  value.Begin ().Write (buffer, size);
  1.2472 +  SetValue (value);
  1.2473 +}
  1.2474 +
  1.2475 +Buffer
  1.2476 +PbbTlv::GetValue (void) const
  1.2477 +{
  1.2478 +  NS_ASSERT (HasValue ());
  1.2479 +  return m_value;
  1.2480 +}
  1.2481 +
  1.2482 +bool
  1.2483 +PbbTlv::HasValue (void) const
  1.2484 +{
  1.2485 +  return m_hasValue;
  1.2486 +}
  1.2487 +
  1.2488 +void
  1.2489 +PbbTlv::Ref (void) const
  1.2490 +{
  1.2491 +  m_refCount++;
  1.2492 +}
  1.2493 +
  1.2494 +void
  1.2495 +PbbTlv::Unref (void) const
  1.2496 +{
  1.2497 +  m_refCount--;
  1.2498 +  if (m_refCount == 0)
  1.2499 +    {
  1.2500 +      delete this;
  1.2501 +    }
  1.2502 +}
  1.2503 +
  1.2504 +uint32_t
  1.2505 +PbbTlv::GetSerializedSize (void) const
  1.2506 +{
  1.2507 +  /* type + flags */
  1.2508 +  uint32_t size = 2;
  1.2509 +
  1.2510 +  if (HasTypeExt ())
  1.2511 +    {
  1.2512 +      size++;
  1.2513 +    }
  1.2514 +
  1.2515 +  if (HasIndexStart ())
  1.2516 +    {
  1.2517 +      size++;
  1.2518 +    }
  1.2519 +
  1.2520 +  if (HasIndexStop ())
  1.2521 +    {
  1.2522 +      size++;
  1.2523 +    }
  1.2524 +
  1.2525 +  if (HasValue ())
  1.2526 +    {
  1.2527 +      if (GetValue ().GetSize () > 255)
  1.2528 +        {
  1.2529 +          size += 2;
  1.2530 +        } 
  1.2531 +      else 
  1.2532 +        {
  1.2533 +          size++;
  1.2534 +        }
  1.2535 +      size += GetValue ().GetSize ();
  1.2536 +    }
  1.2537 +
  1.2538 +  return size;
  1.2539 +}
  1.2540 +
  1.2541 +void
  1.2542 +PbbTlv::Serialize (Buffer::Iterator &start) const
  1.2543 +{
  1.2544 +  start.WriteU8 (GetType ());
  1.2545 +
  1.2546 +  Buffer::Iterator bufref = start;
  1.2547 +  uint8_t flags = 0;
  1.2548 +  start.Next();
  1.2549 +
  1.2550 +  if (HasTypeExt())
  1.2551 +    {
  1.2552 +      flags |= THAS_TYPE_EXT;
  1.2553 +      start.WriteU8 (GetTypeExt ());
  1.2554 +    }
  1.2555 +
  1.2556 +  if (HasIndexStart ())
  1.2557 +    {
  1.2558 +      start.WriteU8 (GetIndexStart ());
  1.2559 +
  1.2560 +      if (HasIndexStop ())
  1.2561 +        {
  1.2562 +          flags |= THAS_MULTI_INDEX;
  1.2563 +          start.WriteU8 (GetIndexStop ());
  1.2564 +        } 
  1.2565 +      else
  1.2566 +        {
  1.2567 +          flags |= THAS_SINGLE_INDEX;
  1.2568 +        }
  1.2569 +    }
  1.2570 +
  1.2571 +  if (HasValue ()) 
  1.2572 +    {
  1.2573 +      flags |= THAS_VALUE;
  1.2574 +
  1.2575 +      uint32_t size = GetValue ().GetSize ();
  1.2576 +      if (size > 255)
  1.2577 +        {
  1.2578 +          flags |= THAS_EXT_LEN;
  1.2579 +          start.WriteHtonU16 (size);
  1.2580 +        }
  1.2581 +      else
  1.2582 +        {
  1.2583 +          start.WriteU8 (size);
  1.2584 +        }
  1.2585 +
  1.2586 +      if (IsMultivalue ())
  1.2587 +        {
  1.2588 +          flags |= TIS_MULTIVALUE;
  1.2589 +        }
  1.2590 +
  1.2591 +      start.Write(GetValue ().Begin (), GetValue ().End ());
  1.2592 +    }
  1.2593 +
  1.2594 +  bufref.WriteU8 (flags);
  1.2595 +}
  1.2596 +
  1.2597 +void
  1.2598 +PbbTlv::Deserialize (Buffer::Iterator &start)
  1.2599 +{
  1.2600 +  SetType (start.ReadU8 ());
  1.2601 +
  1.2602 +  uint8_t flags = start.ReadU8 ();
  1.2603 +
  1.2604 +  if (flags & THAS_TYPE_EXT)
  1.2605 +    {
  1.2606 +      SetTypeExt (start.ReadU8 ());
  1.2607 +    }
  1.2608 +
  1.2609 +  if (flags & THAS_MULTI_INDEX)
  1.2610 +    {
  1.2611 +      SetIndexStart (start.ReadU8 ());
  1.2612 +      SetIndexStop (start.ReadU8 ());
  1.2613 +    }
  1.2614 +  else if (flags & THAS_SINGLE_INDEX)
  1.2615 +    {
  1.2616 +      SetIndexStart (start.ReadU8 ());
  1.2617 +    }
  1.2618 +
  1.2619 +  if (flags & THAS_VALUE)
  1.2620 +    {
  1.2621 +      uint16_t len = 0;
  1.2622 +
  1.2623 +      if (flags & THAS_EXT_LEN)
  1.2624 +        {
  1.2625 +          len = start.ReadNtohU16 ();
  1.2626 +        }
  1.2627 +      else
  1.2628 +        {
  1.2629 +          len = start.ReadU8 ();
  1.2630 +        }
  1.2631 +
  1.2632 +      m_value.AddAtStart (len);
  1.2633 +
  1.2634 +      Buffer::Iterator valueStart = start;
  1.2635 +      start.Next (len);
  1.2636 +      m_value.Begin ().Write (valueStart, start);
  1.2637 +      m_hasValue = true;
  1.2638 +    }
  1.2639 +}
  1.2640 +
  1.2641 +void
  1.2642 +PbbTlv::Print (std::ostream &os) const
  1.2643 +{
  1.2644 +  Print (os, 0);
  1.2645 +}
  1.2646 +
  1.2647 +void
  1.2648 +PbbTlv::Print (std::ostream &os, int level) const
  1.2649 +{
  1.2650 +  std::string prefix = "";
  1.2651 +  for (int i = 0; i < level; i++)
  1.2652 +    {
  1.2653 +      prefix.append ("\t");
  1.2654 +    }
  1.2655 +
  1.2656 +  os << prefix << "PbbTlv {" << std::endl;
  1.2657 +  os << prefix << "\ttype = " << (int)GetType () << std::endl;
  1.2658 +
  1.2659 +  if (HasTypeExt ())
  1.2660 +    {
  1.2661 +      os << prefix << "\ttypeext = " << (int)GetTypeExt () << std::endl;
  1.2662 +    }
  1.2663 +
  1.2664 +  if (HasIndexStart ())
  1.2665 +    {
  1.2666 +      os << prefix << "\tindexStart = " << (int)GetIndexStart () << std::endl;
  1.2667 +    }
  1.2668 +
  1.2669 +  if (HasIndexStop ())
  1.2670 +    {
  1.2671 +      os << prefix << "\tindexStop = " << (int)GetIndexStop () << std::endl;
  1.2672 +    }
  1.2673 +
  1.2674 +  os << prefix << "\tisMultivalue = " << IsMultivalue () << std::endl;
  1.2675 +
  1.2676 +  if (HasValue ())
  1.2677 +    {
  1.2678 +      os << prefix << "\thas value; size = " << GetValue (). GetSize () << std::endl;
  1.2679 +    }
  1.2680 +
  1.2681 +  os << prefix << "}" << std::endl;
  1.2682 +}
  1.2683 +
  1.2684 +bool
  1.2685 +PbbTlv::operator== (const PbbTlv &other) const
  1.2686 +{
  1.2687 +  if (GetType () != other.GetType ())
  1.2688 +    {
  1.2689 +      return false;
  1.2690 +    }
  1.2691 +
  1.2692 +  if (HasTypeExt () != other.HasTypeExt ())
  1.2693 +    {
  1.2694 +      return false;
  1.2695 +    }
  1.2696 +
  1.2697 +  if (HasTypeExt ())
  1.2698 +    {
  1.2699 +      if (GetTypeExt () != other.GetTypeExt ())
  1.2700 +        {
  1.2701 +          return false;
  1.2702 +        }
  1.2703 +    }
  1.2704 +
  1.2705 +  if (HasValue () != other.HasValue ())
  1.2706 +    {
  1.2707 +      return false;
  1.2708 +    }
  1.2709 +
  1.2710 +  if (HasValue ())
  1.2711 +    {
  1.2712 +      Buffer tv = GetValue ();
  1.2713 +      Buffer ov = other.GetValue ();
  1.2714 +      if (tv.GetSize () != ov.GetSize ())
  1.2715 +        {
  1.2716 +          return false;
  1.2717 +        }
  1.2718 +
  1.2719 +      /* The docs say I probably shouldn't use Buffer::PeekData, but I think it
  1.2720 +       * is justified in this case. */
  1.2721 +      if (memcmp (tv.PeekData (), ov.PeekData (), tv.GetSize ()) != 0)
  1.2722 +        {
  1.2723 +          return false;
  1.2724 +        }
  1.2725 +    }
  1.2726 +  return true;
  1.2727 +}
  1.2728 +
  1.2729 +bool
  1.2730 +PbbTlv::operator!= (const PbbTlv &other) const
  1.2731 +{
  1.2732 +  return !(*this == other);
  1.2733 +}
  1.2734 +
  1.2735 +/* End PbbTlv Class */
  1.2736 +
  1.2737 +void 
  1.2738 +PbbAddressTlv::SetIndexStart (uint8_t index)
  1.2739 +{
  1.2740 +  PbbTlv::SetIndexStart (index);
  1.2741 +}
  1.2742 +
  1.2743 +uint8_t
  1.2744 +PbbAddressTlv::GetIndexStart (void) const
  1.2745 +{
  1.2746 +  return PbbTlv::GetIndexStart ();
  1.2747 +}
  1.2748 +
  1.2749 +bool
  1.2750 +PbbAddressTlv::HasIndexStart (void) const
  1.2751 +{
  1.2752 +  return PbbTlv::HasIndexStart ();
  1.2753 +}
  1.2754 +
  1.2755 +void 
  1.2756 +PbbAddressTlv::SetIndexStop (uint8_t index)
  1.2757 +{
  1.2758 +  PbbTlv::SetIndexStop (index);
  1.2759 +}
  1.2760 +
  1.2761 +uint8_t
  1.2762 +PbbAddressTlv::GetIndexStop (void) const
  1.2763 +{
  1.2764 +  return PbbTlv::GetIndexStop ();
  1.2765 +}
  1.2766 +
  1.2767 +bool
  1.2768 +PbbAddressTlv::HasIndexStop (void) const
  1.2769 +{
  1.2770 +  return PbbTlv::HasIndexStop ();
  1.2771 +}
  1.2772 +
  1.2773 +void
  1.2774 +PbbAddressTlv::SetMultivalue (bool isMultivalue)
  1.2775 +{
  1.2776 +  PbbTlv::SetMultivalue (isMultivalue);
  1.2777 +}
  1.2778 +
  1.2779 +bool
  1.2780 +PbbAddressTlv::IsMultivalue (void) const
  1.2781 +{
  1.2782 +  return PbbTlv::IsMultivalue ();
  1.2783 +}
  1.2784 +
  1.2785 +} /* namespace ns3 */
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/node/packetbb.h	Sun Sep 13 09:38:01 2009 -0700
     2.3 @@ -0,0 +1,1727 @@
     2.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2.5 +/* vim: set ts=2 sw=2 sta expandtab ai si cin: */
     2.6 +/* 
     2.7 + * Copyright (c) 2009 Drexel University
     2.8 + * 
     2.9 + * This program is free software; you can redistribute it and/or modify
    2.10 + * it under the terms of the GNU General Public License version 2 as
    2.11 + * published by the Free Software Foundation;
    2.12 + *
    2.13 + * This program is distributed in the hope that it will be useful,
    2.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.16 + * GNU General Public License for more details.
    2.17 + *
    2.18 + * You should have received a copy of the GNU General Public License
    2.19 + * along with this program; if not, write to the Free Software
    2.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2.21 + * 
    2.22 + * Author: Tom Wambold <tom5760@gmail.com>
    2.23 + */
    2.24 +/* These classes implement RFC 5444 - The Generalized Mobile Ad Hoc Network
    2.25 + * (MANET) Packet/PbbMessage Format
    2.26 + * See: http://tools.ietf.org/html/rfc5444 for details */
    2.27 +
    2.28 +#ifndef PACKETBB_H
    2.29 +#define PACKETBB_H
    2.30 +
    2.31 +#include <list>
    2.32 +
    2.33 +#include "ns3/ptr.h"
    2.34 +#include "ns3/address.h"
    2.35 +#include "ns3/header.h"
    2.36 +#include "ns3/buffer.h"
    2.37 +
    2.38 +namespace ns3 {
    2.39 +
    2.40 +/* Forward declare objects */
    2.41 +class PbbMessage;
    2.42 +class PbbAddressBlock;
    2.43 +class PbbTlv;
    2.44 +class PbbAddressTlv;
    2.45 +
    2.46 +/** Used in Messages to determine whether it contains IPv4 or IPv6 addresses */
    2.47 +enum PbbAddressLength {
    2.48 +  IPV4 = 3,
    2.49 +  IPV6 = 15,
    2.50 +};
    2.51 +
    2.52 +/**
    2.53 + * \brief A block of packet or message TLVs (PbbTlv).
    2.54 + *
    2.55 + * Acts similar to a C++ STL container.  Should not be used for Address TLVs.
    2.56 + */
    2.57 +class PbbTlvBlock
    2.58 +{
    2.59 +public:
    2.60 +  typedef std::list< Ptr<PbbTlv> >::iterator Iterator;
    2.61 +  typedef std::list< Ptr<PbbTlv> >::const_iterator ConstIterator;
    2.62 +
    2.63 +  /**
    2.64 +   * \return an iterator to the first TLV in this block.
    2.65 +   */
    2.66 +  Iterator Begin (void);
    2.67 +
    2.68 +  /**
    2.69 +   * \return a const iterator to the first TLV in this block.
    2.70 +   */
    2.71 +  ConstIterator Begin (void) const;
    2.72 +
    2.73 +  /**
    2.74 +   * \return an iterator to the past-the-end element in this block.
    2.75 +   */
    2.76 +  Iterator End (void);
    2.77 +
    2.78 +  /**
    2.79 +   * \return a const iterator to the past-the-end element in this block.
    2.80 +   */
    2.81 +  ConstIterator End (void) const;
    2.82 +
    2.83 +  /**
    2.84 +   * \return the number of TLVs in this block.
    2.85 +   */
    2.86 +  int Size (void) const;
    2.87 +
    2.88 +  /**
    2.89 +   * \return true if there are no TLVs in this block, false otherwise.
    2.90 +   */
    2.91 +  bool Empty (void) const;
    2.92 +
    2.93 +  /**
    2.94 +   * \return a smart pointer to the first TLV in this block.
    2.95 +   */
    2.96 +  Ptr<PbbTlv> Front (void) const;
    2.97 +
    2.98 +  /**
    2.99 +   * \return a smart pointer to the last TLV in this block.
   2.100 +   */
   2.101 +  Ptr<PbbTlv> Back (void) const;
   2.102 +
   2.103 +  /**
   2.104 +   * \brief Prepends a TLV to the front of this block.
   2.105 +   * \param tlv a smart pointer to the TLV to prepend.
   2.106 +   */
   2.107 +  void PushFront (Ptr<PbbTlv> tlv);
   2.108 +
   2.109 +  /**
   2.110 +   * \brief Removes a TLV from the front of this block.
   2.111 +   */
   2.112 +  void PopFront (void);
   2.113 +
   2.114 +  /**
   2.115 +   * \brief Appends a TLV to the back of this block.
   2.116 +   * \param tlv a smart pointer to the TLV to append.
   2.117 +   */
   2.118 +  void PushBack (Ptr<PbbTlv> tlv);
   2.119 +
   2.120 +  /**
   2.121 +   * \brief Removes a TLV from the back of this block.
   2.122 +   */
   2.123 +  void PopBack (void);
   2.124 +
   2.125 +  /**
   2.126 +   * \brief Inserts a TLV at the specified position in this block.
   2.127 +   * \param position an Iterator pointing to the position in this block to
   2.128 +   *        insert the TLV.
   2.129 +   * \param tlv a smart pointer to the TLV to insert.
   2.130 +   * \return An iterator pointing to the newly inserted TLV.
   2.131 +   */
   2.132 +  Iterator Insert (Iterator position, const Ptr<PbbTlv> tlv);
   2.133 +
   2.134 +  /**
   2.135 +   * \brief Removes the TLV at the specified position.
   2.136 +   * \param position an Iterator pointing to the TLV to erase.
   2.137 +   * \return an iterator pointing to the next TLV in the block.
   2.138 +   */
   2.139 +  Iterator Erase (Iterator position);
   2.140 +
   2.141 +  /**
   2.142 +   * \brief Removes all TLVs from [first, last) (includes first, not includes
   2.143 +   *        last).
   2.144 +   * \param first an Iterator pointing to the first TLV to erase (inclusive).
   2.145 +   * \param last an Iterator pointing to the element past the last TLV to erase.
   2.146 +   * \return an iterator pointing to the next TLV in the block.
   2.147 +   */
   2.148 +  Iterator Erase (Iterator first, Iterator last);
   2.149 +
   2.150 +  /**
   2.151 +   * \brief Removes all TLVs from this block.
   2.152 +   */
   2.153 +  void Clear (void);
   2.154 +
   2.155 +  /**
   2.156 +   * \return The size (in bytes) needed to serialize this block.
   2.157 +   */
   2.158 +  uint32_t GetSerializedSize (void) const;
   2.159 +
   2.160 +  /**
   2.161 +   * \brief Serializes this block into the specified buffer.
   2.162 +   * \param start a reference to the point in a buffer to begin serializing.
   2.163 +   *
   2.164 +   * Users should not need to call this.  Blocks will be serialized by their
   2.165 +   * containing packet.
   2.166 +   */
   2.167 +  void Serialize (Buffer::Iterator &start) const;
   2.168 +
   2.169 +  /**
   2.170 +   * \brief Deserializes a block from the specified buffer.
   2.171 +   * \param start a reference to the point in a buffer to begin deserializing.
   2.172 +   *
   2.173 +   * Users should not need to call this.  Blocks will be deserialized by their
   2.174 +   * containing packet.
   2.175 +   */
   2.176 +  void Deserialize (Buffer::Iterator &start);
   2.177 +
   2.178 +  /**
   2.179 +   * \brief Pretty-prints the contents of this block.
   2.180 +   * \param os a stream object to print to.
   2.181 +   */
   2.182 +  void Print (std::ostream &os) const;
   2.183 +
   2.184 +  /**
   2.185 +   * \brief Pretty-prints the contents of this block, with specified indentation.
   2.186 +   * \param os a stream object to print to.
   2.187 +   * \param level level of indentation.
   2.188 +   *
   2.189 +   * This probably never needs to be called by users.  This is used when
   2.190 +   * recursively printing sub-objects.
   2.191 +   */
   2.192 +  void Print (std::ostream &os, int level) const;
   2.193 +
   2.194 +  bool operator== (const PbbTlvBlock &other) const;
   2.195 +  bool operator!= (const PbbTlvBlock &other) const;
   2.196 +
   2.197 +private:
   2.198 +  std::list< Ptr<PbbTlv> > m_tlvList;
   2.199 +};
   2.200 +
   2.201 +/**
   2.202 + * \brief A block of Address TLVs (PbbAddressTlv).
   2.203 + *
   2.204 + * Acts similar to a C++ STL container.
   2.205 + */
   2.206 +class PbbAddressTlvBlock
   2.207 +{
   2.208 +public:
   2.209 +  typedef std::list< Ptr<PbbAddressTlv> >::iterator Iterator;
   2.210 +  typedef std::list< Ptr<PbbAddressTlv> >::const_iterator ConstIterator;
   2.211 +
   2.212 +  /**
   2.213 +   * \return an iterator to the first Address TLV in this block.
   2.214 +   */
   2.215 +  Iterator Begin (void);
   2.216 +
   2.217 +  /**
   2.218 +   * \return a const iterator to the first Address TLV in this block.
   2.219 +   */
   2.220 +  ConstIterator Begin (void) const;
   2.221 +
   2.222 +  /**
   2.223 +   * \return an iterator to the past-the-end element in this block.
   2.224 +   */
   2.225 +  Iterator End (void);
   2.226 +
   2.227 +  /**
   2.228 +   * \return a const iterator to the past-the-end element in this block.
   2.229 +   */
   2.230 +  ConstIterator End (void) const;
   2.231 +
   2.232 +  /**
   2.233 +   * \return the number of Address TLVs in this block.
   2.234 +   */
   2.235 +  int Size (void) const;
   2.236 +
   2.237 +  /**
   2.238 +   * \return true if there are no Address TLVs in this block, false otherwise.
   2.239 +   */
   2.240 +  bool Empty (void) const;
   2.241 +
   2.242 +  /**
   2.243 +   * \return the first Address TLV in this block.
   2.244 +   */
   2.245 +  Ptr<PbbAddressTlv> Front (void) const;
   2.246 +
   2.247 +  /**
   2.248 +   * \return the last AddressTLV in this block.
   2.249 +   */
   2.250 +  Ptr<PbbAddressTlv> Back (void) const;
   2.251 +
   2.252 +  /**
   2.253 +   * \brief Prepends an Address TLV to the front of this block.
   2.254 +   * \param tlv a smart pointer to the Address TLV to prepend.
   2.255 +   */
   2.256 +  void PushFront (Ptr<PbbAddressTlv> tlv);
   2.257 +
   2.258 +  /**
   2.259 +   * \brief Removes an AddressTLV from the front of this block.
   2.260 +   */
   2.261 +  void PopFront (void);
   2.262 +
   2.263 +  /**
   2.264 +   * \brief Appends an Address TLV to the back of this block.
   2.265 +   * \param tlv a smart pointer to the Address TLV to append.
   2.266 +   */
   2.267 +  void PushBack (Ptr<PbbAddressTlv> tlv);
   2.268 +
   2.269 +  /**
   2.270 +   * \brief Removes an Address TLV from the back of this block.
   2.271 +   */
   2.272 +  void PopBack (void);
   2.273 +
   2.274 +  /**
   2.275 +   * \brief Inserts an Address TLV at the specified position in this block.
   2.276 +   * \param position an Iterator pointing to the position in this block to
   2.277 +   *        insert the Address TLV.
   2.278 +   * \param tlv a smart pointer to the Address TLV to insert.
   2.279 +   * \return An iterator pointing to the newly inserted Address TLV.
   2.280 +   */
   2.281 +  Iterator Insert (Iterator position, const Ptr<PbbAddressTlv> tlv);
   2.282 +
   2.283 +  /**
   2.284 +   * \brief Removes the Address TLV at the specified position.
   2.285 +   * \param position an Iterator pointing to the Address TLV to erase.
   2.286 +   * \return an iterator pointing to the next Address TLV in the block.
   2.287 +   */
   2.288 +  Iterator Erase (Iterator position);
   2.289 +
   2.290 +  /**
   2.291 +   * \brief Removes all Address TLVs from [first, last) (includes first, not
   2.292 +   *        includes last).
   2.293 +   * \param first an Iterator pointing to the first Address TLV to erase
   2.294 +   *        (inclusive).
   2.295 +   * \param last an Iterator pointing to the element past the last Address TLV
   2.296 +   *        to erase.
   2.297 +   * \return an iterator pointing to the next Address TLV in the block.
   2.298 +   */
   2.299 +  Iterator Erase (Iterator first, Iterator last);
   2.300 +
   2.301 +  /**
   2.302 +   * \brief Removes all Address TLVs from this block.
   2.303 +   */
   2.304 +  void Clear (void);
   2.305 +
   2.306 +  /**
   2.307 +   * \return The size (in bytes) needed to serialize this block.
   2.308 +   */
   2.309 +  uint32_t GetSerializedSize (void) const;
   2.310 +
   2.311 +  /**
   2.312 +   * \brief Serializes this block into the specified buffer.
   2.313 +   * \param start a reference to the point in a buffer to begin serializing.
   2.314 +   *
   2.315 +   * Users should not need to call this.  Blocks will be serialized by their
   2.316 +   * containing packet.
   2.317 +   */
   2.318 +  void Serialize (Buffer::Iterator &start) const;
   2.319 +
   2.320 +  /**
   2.321 +   * \brief Deserializes a block from the specified buffer.
   2.322 +   * \param start a reference to the point in a buffer to begin deserializing.
   2.323 +   *
   2.324 +   * Users should not need to call this.  Blocks will be deserialized by their
   2.325 +   * containing packet.
   2.326 +   */
   2.327 +  void Deserialize (Buffer::Iterator &start);
   2.328 +
   2.329 +  /**
   2.330 +   * \brief Pretty-prints the contents of this block.
   2.331 +   * \param os a stream object to print to.
   2.332 +   */
   2.333 +  void Print (std::ostream &os) const;
   2.334 +
   2.335 +  /**
   2.336 +   * \brief Pretty-prints the contents of this block, with specified indentation.
   2.337 +   * \param os a stream object to print to.
   2.338 +   * \param level level of indentation.
   2.339 +   *
   2.340 +   * This probably never needs to be called by users.  This is used when
   2.341 +   * recursively printing sub-objects.
   2.342 +   */
   2.343 +  void Print (std::ostream &os, int level) const;
   2.344 +
   2.345 +  bool operator== (const PbbAddressTlvBlock &other) const;
   2.346 +  bool operator!= (const PbbAddressTlvBlock &other) const;
   2.347 +
   2.348 +private:
   2.349 +  std::list< Ptr<PbbAddressTlv> > m_tlvList;
   2.350 +};
   2.351 +
   2.352 +/**
   2.353 + * \brief Main PacketBB Packet object.
   2.354 + *
   2.355 + * A PacketBB packet is made up of zero or more packet TLVs (PbbTlv), and zero
   2.356 + * or more messages (PbbMessage).
   2.357 + *
   2.358 + * See: http://tools.ietf.org/html/rfc5444 for details.
   2.359 + */
   2.360 +class PbbPacket : public Header
   2.361 +{
   2.362 +public:
   2.363 +  typedef std::list< Ptr<PbbTlv> >::iterator TlvIterator;
   2.364 +  typedef std::list< Ptr<PbbTlv> >::const_iterator ConstTlvIterator;
   2.365 +  typedef std::list< Ptr<PbbMessage> >::iterator MessageIterator;
   2.366 +  typedef std::list< Ptr<PbbMessage> >::const_iterator ConstMessageIterator;
   2.367 +
   2.368 +  PbbPacket (void);
   2.369 +
   2.370 +  /**
   2.371 +   * \return the version of PacketBB that constructed this packet.
   2.372 +   *
   2.373 +   * This will always return 0 for packets constructed using this API.
   2.374 +   */
   2.375 +  uint8_t GetVersion (void) const;
   2.376 +
   2.377 +  /**
   2.378 +   * \brief Sets the sequence number of this packet.
   2.379 +   * \param number the sequence number.
   2.380 +   */
   2.381 +  void SetSequenceNumber (uint16_t number);
   2.382 +
   2.383 +  /**
   2.384 +   * \return the sequence number of this packet.
   2.385 +   *
   2.386 +   * Calling this while HasSequenceNumber is False is undefined.  Make sure you
   2.387 +   * check it first.  This will be checked by an assert in debug builds.
   2.388 +   */
   2.389 +  uint16_t GetSequenceNumber (void) const;
   2.390 +
   2.391 +  /**
   2.392 +   * \brief Tests whether or not this packet has a sequence number.
   2.393 +   * \return true if this packet has a sequence number, false otherwise.
   2.394 +   *
   2.395 +   * This should be called before calling GetSequenceNumber to make sure there
   2.396 +   * actually is one.
   2.397 +   */
   2.398 +  bool HasSequenceNumber (void) const;
   2.399 +
   2.400 +  /* Manipulating Packet TLVs */
   2.401 +
   2.402 +  /**
   2.403 +   * \return an iterator to the first Packet TLV in this packet.
   2.404 +   */
   2.405 +  TlvIterator TlvBegin (void);
   2.406 +
   2.407 +  /**
   2.408 +   * \return a const iterator to the first Packet TLV in this packet.
   2.409 +   */
   2.410 +  ConstTlvIterator TlvBegin (void) const;
   2.411 +
   2.412 +  /**
   2.413 +   * \return an iterator to the past-the-end element in this packet TLV block.
   2.414 +   */
   2.415 +  TlvIterator TlvEnd (void);
   2.416 +
   2.417 +  /**
   2.418 +   * \return a const iterator to the past-the-end element in this packet TLV
   2.419 +   *         block.
   2.420 +   */
   2.421 +  ConstTlvIterator TlvEnd (void) const;
   2.422 +
   2.423 +  /**
   2.424 +   * \return the number of packet TLVs in this packet.
   2.425 +   */
   2.426 +  int TlvSize (void) const;
   2.427 +
   2.428 +  /**
   2.429 +   * \return true if there are no packet TLVs in this packet, false otherwise.
   2.430 +   */
   2.431 +  bool TlvEmpty (void) const;
   2.432 +
   2.433 +  /**
   2.434 +   * \return a smart pointer to the first packet TLV in this packet.
   2.435 +   */
   2.436 +  Ptr<PbbTlv> TlvFront (void);
   2.437 +
   2.438 +  /**
   2.439 +   * \return a const smart pointer to the first packet TLV in this packet.
   2.440 +   */
   2.441 +  const Ptr<PbbTlv> TlvFront (void) const;
   2.442 +
   2.443 +  /**
   2.444 +   * \return a smart pointer to the last packet TLV in this packet.
   2.445 +   */
   2.446 +  Ptr<PbbTlv> TlvBack (void);
   2.447 +
   2.448 +  /**
   2.449 +   * \return a const smart pointer to the last packet TLV in this packet.
   2.450 +   */
   2.451 +  const Ptr<PbbTlv> TlvBack (void) const;
   2.452 +
   2.453 +  /**
   2.454 +   * \brief Prepends a packet TLV to the front of this packet.
   2.455 +   * \param tlv a smart pointer to the packet TLV to prepend.
   2.456 +   */
   2.457 +  void TlvPushFront (Ptr<PbbTlv> tlv);
   2.458 +
   2.459 +  /**
   2.460 +   * \brief Removes a packet TLV from the front of this packet.
   2.461 +   */
   2.462 +  void TlvPopFront (void);
   2.463 +
   2.464 +  /**
   2.465 +   * \brief Appends a packet TLV to the back of this packet.
   2.466 +   * \param tlv a smart pointer to the packet TLV to append.
   2.467 +   */
   2.468 +  void TlvPushBack (Ptr<PbbTlv> tlv);
   2.469 +
   2.470 +  /**
   2.471 +   * \brief Removes a packet TLV from the back of this block.
   2.472 +   */
   2.473 +  void TlvPopBack (void);
   2.474 +
   2.475 +  /**
   2.476 +   * \brief Removes the packet TLV at the specified position.
   2.477 +   * \param position an Iterator pointing to the packet TLV to erase.
   2.478 +   * \return an iterator pointing to the next packet TLV in the block.
   2.479 +   */
   2.480 +  TlvIterator Erase (TlvIterator position);
   2.481 +
   2.482 +  /**
   2.483 +   * \brief Removes all packet TLVs from [first, last) (includes first, not
   2.484 +   *        includes last).
   2.485 +   * \param first an Iterator pointing to the first packet TLV to erase
   2.486 +   *        (inclusive).
   2.487 +   * \param last an Iterator pointing to the element past the last packet TLV
   2.488 +   *        to erase.
   2.489 +   * \return an iterator pointing to the next packet TLV in the block.
   2.490 +   */
   2.491 +  TlvIterator Erase (TlvIterator first, TlvIterator last);
   2.492 +
   2.493 +  /**
   2.494 +   * \brief Removes all packet TLVs from this packet.
   2.495 +   */
   2.496 +  void TlvClear (void);
   2.497 +
   2.498 +  /* Manipulating Packet Messages */
   2.499 +
   2.500 +  /**
   2.501 +   * \return an iterator to the first message in this packet.
   2.502 +   */
   2.503 +  MessageIterator MessageBegin (void);
   2.504 +
   2.505 +  /**
   2.506 +   * \return a const iterator to the first message in this packet.
   2.507 +   */
   2.508 +  ConstMessageIterator MessageBegin (void) const;
   2.509 +
   2.510 +  /**
   2.511 +   * \return an iterator to the past-the-end element in this message block.
   2.512 +   */
   2.513 +  MessageIterator MessageEnd (void);
   2.514 +
   2.515 +  /**
   2.516 +   * \return a const iterator to the past-the-end element in this message
   2.517 +   *         block.
   2.518 +   */
   2.519 +  ConstMessageIterator MessageEnd (void) const;
   2.520 +
   2.521 +  /**
   2.522 +   * \return the number of messages in this packet.
   2.523 +   */
   2.524 +  int MessageSize (void) const;
   2.525 +
   2.526 +  /**
   2.527 +   * \return true if there are no messages in this packet, false otherwise.
   2.528 +   */
   2.529 +  bool MessageEmpty (void) const;
   2.530 +
   2.531 +  /**
   2.532 +   * \return a smart pointer to the first message in this packet.
   2.533 +   */
   2.534 +  Ptr<PbbMessage> MessageFront (void);
   2.535 +
   2.536 +  /**
   2.537 +   * \return a cosnt smart pointer to the first message in this packet.
   2.538 +   */
   2.539 +  const Ptr<PbbMessage> MessageFront (void) const;
   2.540 +
   2.541 +  /**
   2.542 +   * \return a smart pointer to the last message in this packet.
   2.543 +   */
   2.544 +  Ptr<PbbMessage> MessageBack (void);
   2.545 +
   2.546 +  /**
   2.547 +   * \return a cosnt smart pointer to the last message in this packet.
   2.548 +   */
   2.549 +  const Ptr<PbbMessage> MessageBack (void) const;
   2.550 +
   2.551 +  /**
   2.552 +   * \brief Prepends a message to the front of this packet.
   2.553 +   * \param message a smart pointer to the message to prepend.
   2.554 +   */
   2.555 +  void MessagePushFront (Ptr<PbbMessage> message);
   2.556 +
   2.557 +  /**
   2.558 +   * \brief Removes a message from the front of this packet.
   2.559 +   */
   2.560 +  void MessagePopFront (void);
   2.561 +
   2.562 +  /**
   2.563 +   * \brief Appends a message to the back of this packet.
   2.564 +   * \param message a smart pointer to the message to append.
   2.565 +   */
   2.566 +  void MessagePushBack (Ptr<PbbMessage> message);
   2.567 +
   2.568 +  /**
   2.569 +   * \brief Removes a message from the back of this packet.
   2.570 +   */
   2.571 +  void MessagePopBack (void);
   2.572 +
   2.573 +  /**
   2.574 +   * \brief Removes the message at the specified position.
   2.575 +   * \param position an Iterator pointing to the message to erase.
   2.576 +   * \return an iterator pointing to the next message in the packet.
   2.577 +   */
   2.578 +  MessageIterator Erase (MessageIterator position);
   2.579 +
   2.580 +  /**
   2.581 +   * \brief Removes all messages from [first, last) (includes first, not
   2.582 +   *        includes last).
   2.583 +   * \param first an Iterator pointing to the first message to erase (inclusive).
   2.584 +   * \param last an Iterator pointing to the element past the last message to erase.
   2.585 +   * \return an iterator pointing to the next message in the block.
   2.586 +   */
   2.587 +  MessageIterator Erase (MessageIterator first, MessageIterator last);
   2.588 +
   2.589 +  /**
   2.590 +   * \brief Removes all messages from this packet.
   2.591 +   */
   2.592 +  void MessageClear (void);
   2.593 +
   2.594 +  /* Smart pointer methods */
   2.595 +  void Ref (void) const;
   2.596 +  void Unref (void) const;
   2.597 +
   2.598 +  /* Methods implemented by all headers */
   2.599 +  static TypeId GetTypeId (void);
   2.600 +  virtual TypeId GetInstanceTypeId (void) const;
   2.601 +
   2.602 +  /**
   2.603 +   * \return The size (in bytes) needed to serialize this packet.
   2.604 +   */
   2.605 +  virtual uint32_t GetSerializedSize (void) const;
   2.606 +
   2.607 +  /**
   2.608 +   * \brief Serializes this packet into the specified buffer.
   2.609 +   * \param start a reference to the point in a buffer to begin serializing.
   2.610 +   */
   2.611 +  virtual void Serialize (Buffer::Iterator start) const;
   2.612 +
   2.613 +  /**
   2.614 +   * \brief Deserializes a packet from the specified buffer.
   2.615 +   * \return the number of bytes deserialized
   2.616 +   *
   2.617 +   * If this returns a number smaller than the total number of bytes in the
   2.618 +   * buffer, there was an error.
   2.619 +   */
   2.620 +  virtual uint32_t Deserialize (Buffer::Iterator start);
   2.621 +
   2.622 +  /**
   2.623 +   * \brief Pretty-prints the contents of this block.
   2.624 +   * \param os a stream object to print to.
   2.625 +   */
   2.626 +  virtual void Print (std::ostream &os) const;
   2.627 +
   2.628 +  bool operator== (const PbbPacket &other) const;
   2.629 +  bool operator!= (const PbbPacket &other) const;
   2.630 +
   2.631 +protected:
   2.632 +  void SerializePacketTlv (Buffer::Iterator &start) const;
   2.633 +
   2.634 +private:
   2.635 +  PbbTlvBlock m_tlvList;
   2.636 +  std::list< Ptr<PbbMessage> > m_messageList;
   2.637 +
   2.638 +  uint8_t m_version;
   2.639 +
   2.640 +  bool m_hasseqnum;
   2.641 +  uint16_t m_seqnum;
   2.642 +
   2.643 +  mutable uint32_t m_refCount;
   2.644 +};
   2.645 +
   2.646 +/**
   2.647 + * \brief A message within a PbbPacket packet.
   2.648 + *
   2.649 + * There may be any number of messages in one packet packet.  This is a pure
   2.650 + * virtual base class, when creating a message, you should instantiate either
   2.651 + * PbbMessageIpv4 or PbbMessageIpv6.
   2.652 + */
   2.653 +class PbbMessage
   2.654 +{
   2.655 +public:
   2.656 +  typedef std::list< Ptr<PbbTlv> >::iterator TlvIterator;
   2.657 +  typedef std::list< Ptr<PbbTlv> >::const_iterator ConstTlvIterator;
   2.658 +  typedef std::list< Ptr<PbbAddressBlock> >::iterator AddressBlockIterator;
   2.659 +  typedef std::list< Ptr<PbbAddressBlock> >::const_iterator ConstAddressBlockIterator;
   2.660 +
   2.661 +  PbbMessage (void);
   2.662 +
   2.663 +  /**
   2.664 +   * \brief Sets the type for this message.
   2.665 +   * \param type the type to set.
   2.666 +   */
   2.667 +  void SetType (uint8_t type);
   2.668 +
   2.669 +  /**
   2.670 +   * \return the type assigned to this packet
   2.671 +   */
   2.672 +  uint8_t GetType (void) const;
   2.673 +
   2.674 +  /**
   2.675 +   * \brief Sets the address for the node that created this packet.
   2.676 +   * \param address the originator address.
   2.677 +   */
   2.678 +  void SetOriginatorAddress (Address address);
   2.679 +
   2.680 +  /**
   2.681 +   * \return the address of the node that created this packet.
   2.682 +   *
   2.683 +   * Calling this while HasOriginatorAddress is False is undefined.  Make sure
   2.684 +   * you check it first.  This will be checked by an assert in debug builds.
   2.685 +   */
   2.686 +  Address GetOriginatorAddress (void) const;
   2.687 +
   2.688 +  /**
   2.689 +   * \brief Tests whether or not this message has an originator address.
   2.690 +   * \return true if this message has an originator address, false otherwise.
   2.691 +   */
   2.692 +  bool HasOriginatorAddress (void) const;
   2.693 +
   2.694 +  /**
   2.695 +   * \brief Sets the maximum number of hops this message should travel
   2.696 +   * \param hoplimit the limit to set
   2.697 +   */
   2.698 +  void SetHopLimit (uint8_t hoplimit);
   2.699 +
   2.700 +  /**
   2.701 +   * \return the maximum number of hops this message should travel.
   2.702 +   *
   2.703 +   * Calling this while HasHopLimit is False is undefined.  Make sure you check
   2.704 +   * it first.  This will be checked by an assert in debug builds.
   2.705 +   */
   2.706 +  uint8_t GetHopLimit (void) const;
   2.707 +
   2.708 +  /**
   2.709 +   * \brief Tests whether or not this message has a hop limit.
   2.710 +   * \return true if this message has a hop limit, false otherwise.
   2.711 +   *
   2.712 +   * If this is set, messages should not hop further than this limit.
   2.713 +   */
   2.714 +  bool HasHopLimit (void) const;
   2.715 +
   2.716 +  /**
   2.717 +   * \brief Sets the current number of hops this message has traveled.
   2.718 +   * \param hopcount the current number of hops
   2.719 +   */
   2.720 +  void SetHopCount (uint8_t hopcount);
   2.721 +
   2.722 +  /**
   2.723 +   * \return the current number of hops this message has traveled.
   2.724 +   *
   2.725 +   * Calling this while HasHopCount is False is undefined.  Make sure you check
   2.726 +   * it first.  This will be checked by an assert in debug builds.
   2.727 +   */
   2.728 +  uint8_t GetHopCount (void) const;
   2.729 +
   2.730 +  /**
   2.731 +   * \brief Tests whether or not this message has a hop count.
   2.732 +   * \return true if this message has a hop limit, false otherwise.
   2.733 +   */
   2.734 +  bool HasHopCount (void) const;
   2.735 +
   2.736 +  /**
   2.737 +   * \brief Sets the sequence number of this message.
   2.738 +   * \param seqnum the sequence number to set.
   2.739 +   */
   2.740 +  void SetSequenceNumber (uint16_t seqnum);
   2.741 +
   2.742 +  /**
   2.743 +   * \return the sequence number of this message.
   2.744 +   *
   2.745 +   * Calling this while HasSequenceNumber is False is undefined.  Make sure you
   2.746 +   * check it first.  This will be checked by an assert in debug builds.
   2.747 +   */
   2.748 +  uint16_t GetSequenceNumber (void) const;
   2.749 +
   2.750 +  /**
   2.751 +   * \brief Tests whether or not this message has a sequence number.
   2.752 +   * \return true if this message has a sequence number, false otherwise.
   2.753 +   */
   2.754 +  bool HasSequenceNumber (void) const;
   2.755 +
   2.756 +  /* Manipulating PbbMessage TLVs */
   2.757 +
   2.758 +  /**
   2.759 +   * \return an iterator to the first message TLV in this message.
   2.760 +   */
   2.761 +  TlvIterator TlvBegin ();
   2.762 +
   2.763 +  /**
   2.764 +   * \return a const iterator to the first message TLV in this message.
   2.765 +   */
   2.766 +  ConstTlvIterator TlvBegin () const;
   2.767 +
   2.768 +  /**
   2.769 +   * \return an iterator to the past-the-end message TLV element in this
   2.770 +   *         message.
   2.771 +   */
   2.772 +  TlvIterator TlvEnd ();
   2.773 +
   2.774 +  /**
   2.775 +   * \return a const iterator to the past-the-end message TLV element in this
   2.776 +   *         message.
   2.777 +   */
   2.778 +  ConstTlvIterator TlvEnd () const;
   2.779 +
   2.780 +  /**
   2.781 +   * \return the number of message TLVs in this message.
   2.782 +   */
   2.783 +  int TlvSize (void) const;
   2.784 +
   2.785 +  /**
   2.786 +   * \return true if there are no message TLVs in this message, false otherwise.
   2.787 +   */
   2.788 +  bool TlvEmpty (void) const;
   2.789 +
   2.790 +  /**
   2.791 +   * \return a smart pointer to the first message TLV in this message.
   2.792 +   */
   2.793 +  Ptr<PbbTlv> TlvFront (void);
   2.794 +
   2.795 +  /**
   2.796 +   * \return a const smart pointer to the first message TLV in this message.
   2.797 +   */
   2.798 +  const Ptr<PbbTlv> TlvFront (void) const;
   2.799 +
   2.800 +  /**
   2.801 +   * \return a smart pointer to the last message TLV in this message.
   2.802 +   */
   2.803 +  Ptr<PbbTlv> TlvBack (void);
   2.804 +
   2.805 +  /**
   2.806 +   * \return a const smart pointer to the last message TLV in this message.
   2.807 +   */
   2.808 +  const Ptr<PbbTlv> TlvBack (void) const;
   2.809 +
   2.810 +  /**
   2.811 +   * \brief Prepends a message TLV to the front of this message.
   2.812 +   * \param tlv a smart pointer to the message TLV to prepend.
   2.813 +   */
   2.814 +  void TlvPushFront (Ptr<PbbTlv> tlv);
   2.815 +
   2.816 +  /**
   2.817 +   * \brief Removes a message TLV from the front of this message.
   2.818 +   */
   2.819 +  void TlvPopFront (void);
   2.820 +
   2.821 +  /**
   2.822 +   * \brief Appends a message TLV to the back of this message.
   2.823 +   * \param tlv a smart pointer to the message TLV to append.
   2.824 +   */
   2.825 +  void TlvPushBack (Ptr<PbbTlv> tlv);
   2.826 +
   2.827 +  /**
   2.828 +   * \brief Removes a message TLV from the back of this message.
   2.829 +   */
   2.830 +  void TlvPopBack (void);
   2.831 +
   2.832 +  /**
   2.833 +   * \brief Removes the message TLV at the specified position.
   2.834 +   * \param position an Iterator pointing to the message TLV to erase.
   2.835 +   * \return an iterator pointing to the next TLV in the block.
   2.836 +   */
   2.837 +  TlvIterator TlvErase (TlvIterator position);
   2.838 +
   2.839 +  /**
   2.840 +   * \brief Removes all message TLVs from [first, last) (includes first, not
   2.841 +   *        includes last).
   2.842 +   * \param first an Iterator pointing to the first message TLV to erase
   2.843 +   *        (inclusive).
   2.844 +   * \param last an Iterator pointing to the element past the last message TLV
   2.845 +   *        to erase.
   2.846 +   * \return an iterator pointing to the next message TLV in the message.
   2.847 +   */
   2.848 +  TlvIterator TlvErase (TlvIterator first, TlvIterator last);
   2.849 +
   2.850 +  /**
   2.851 +   * \brief Removes all message TLVs from this block.
   2.852 +   */
   2.853 +  void TlvClear (void);
   2.854 +
   2.855 +  /* Manipulating Address Block and Address TLV pairs */
   2.856 +
   2.857 +  /**
   2.858 +   * \return an iterator to the first address block in this message.
   2.859 +   */
   2.860 +  AddressBlockIterator AddressBlockBegin ();
   2.861 +
   2.862 +  /**
   2.863 +   * \return a const iterator to the first address block in this message.
   2.864 +   */
   2.865 +  ConstAddressBlockIterator AddressBlockBegin () const;
   2.866 +
   2.867 +  /**
   2.868 +   * \return an iterator to the past-the-end address block element in this
   2.869 +   *         message.
   2.870 +   */
   2.871 +  AddressBlockIterator AddressBlockEnd ();
   2.872 +
   2.873 +  /**
   2.874 +   * \return a const iterator to the past-the-end address block element in this
   2.875 +   *         message.
   2.876 +   */
   2.877 +  ConstAddressBlockIterator AddressBlockEnd () const;
   2.878 +
   2.879 +  /**
   2.880 +   * \return the number of address blocks in this message.
   2.881 +   */
   2.882 +  int AddressBlockSize (void) const;
   2.883 +
   2.884 +  /**
   2.885 +   * \return true if there are no address blocks in this message, false
   2.886 +   *         otherwise.
   2.887 +   */
   2.888 +  bool AddressBlockEmpty (void) const;
   2.889 +
   2.890 +  /**
   2.891 +   * \return a smart pointer to the first address block in this message.
   2.892 +   */
   2.893 +  Ptr<PbbAddressBlock> AddressBlockFront (void);
   2.894 +
   2.895 +  /**
   2.896 +   * \return a const smart pointer to the first address block in this message.
   2.897 +   */
   2.898 +  const Ptr<PbbAddressBlock> AddressBlockFront (void) const;
   2.899 +
   2.900 +  /**
   2.901 +   * \return a smart pointer to the last address block in this message.
   2.902 +   */
   2.903 +  Ptr<PbbAddressBlock> AddressBlockBack (void);
   2.904 +
   2.905 +  /**
   2.906 +   * \return a const smart pointer to the last address block in this message.
   2.907 +   */
   2.908 +  const Ptr<PbbAddressBlock> AddressBlockBack (void) const;
   2.909 +
   2.910 +  /**
   2.911 +   * \brief Prepends an address block to the front of this message.
   2.912 +   * \param block a smart pointer to the address block to prepend.
   2.913 +   */
   2.914 +  void AddressBlockPushFront (Ptr<PbbAddressBlock> block);
   2.915 +
   2.916 +  /**
   2.917 +   * \brief Removes an address block from the front of this message.
   2.918 +   */
   2.919 +  void AddressBlockPopFront (void);
   2.920 +
   2.921 +  /**
   2.922 +   * \brief Appends an address block to the front of this message.
   2.923 +   * \param block a smart pointer to the address block to append.
   2.924 +   */
   2.925 +  void AddressBlockPushBack (Ptr<PbbAddressBlock> block);
   2.926 +
   2.927 +  /**
   2.928 +   * \brief Removes an address block from the back of this message.
   2.929 +   */
   2.930 +  void AddressBlockPopBack (void);
   2.931 +
   2.932 +  /**
   2.933 +   * \brief Removes the address block at the specified position.
   2.934 +   * \param position an Iterator pointing to the address block to erase.
   2.935 +   * \return an iterator pointing to the next address block in the message.
   2.936 +   */
   2.937 +  AddressBlockIterator AddressBlockErase (AddressBlockIterator position);
   2.938 +
   2.939 +  /**
   2.940 +   * \brief Removes all address blocks from [first, last) (includes first, not
   2.941 +   *        includes last).
   2.942 +   * \param first an Iterator pointing to the first address block to erase
   2.943 +   *        (inclusive).
   2.944 +   * \param last an Iterator pointing to the element past the last address
   2.945 +   *        block to erase.
   2.946 +   * \return an iterator pointing to the next address block in the message.
   2.947 +   */
   2.948 +  AddressBlockIterator AddressBlockErase (AddressBlockIterator first,
   2.949 +      AddressBlockIterator last);
   2.950 +
   2.951 +  /**
   2.952 +   * \brief Removes all address blocks from this message.
   2.953 +   */
   2.954 +  void AddressBlockClear (void);
   2.955 +
   2.956 +  /* Smart pointer methods */
   2.957 +  void Ref (void) const;
   2.958 +  void Unref (void) const;
   2.959 +
   2.960 +  /**
   2.961 +   * \brief Deserializes a message, returning the correct object depending on
   2.962 +   *        whether it is an IPv4 message or an IPv6 message.
   2.963 +   * \param start a reference to the point in a buffer to begin deserializing.
   2.964 +   * \return A pointer to the deserialized message, or 0 on error.
   2.965 +   *
   2.966 +   * Users should not need to call this.  Blocks will be deserialized by their
   2.967 +   * containing packet.
   2.968 +   */
   2.969 +  static Ptr<PbbMessage> DeserializeMessage (Buffer::Iterator &start);
   2.970 +
   2.971 +  /**
   2.972 +   * \return The size (in bytes) needed to serialize this message.
   2.973 +   */
   2.974 +  uint32_t GetSerializedSize (void) const;
   2.975 +
   2.976 +  /**
   2.977 +   * \brief Serializes this message into the specified buffer.
   2.978 +   * \param start a reference to the point in a buffer to begin serializing.
   2.979 +   *
   2.980 +   * Users should not need to call this.  Blocks will be deserialized by their
   2.981 +   * containing packet.
   2.982 +   */
   2.983 +  void Serialize (Buffer::Iterator &start) const;
   2.984 +
   2.985 +  /**
   2.986 +   * \brief Deserializes a message from the specified buffer.
   2.987 +   * \param start a reference to the point in a buffer to begin deserializing.
   2.988 +   *
   2.989 +   * Users should not need to call this.  Blocks will be deserialized by their
   2.990 +   * containing packet.
   2.991 +   */
   2.992 +  void Deserialize (Buffer::Iterator &start);
   2.993 +
   2.994 +  /**
   2.995 +   * \brief Pretty-prints the contents of this message.
   2.996 +   * \param os a stream object to print to.
   2.997 +   */
   2.998 +  void Print (std::ostream &os) const;
   2.999 +
  2.1000 +  /**
  2.1001 +   * \brief Pretty-prints the contents of this message, with specified
  2.1002 +   *        indentation.
  2.1003 +   * \param os a stream object to print to.
  2.1004 +   * \param level level of indentation.
  2.1005 +   *
  2.1006 +   * This probably never needs to be called by users.  This is used when
  2.1007 +   * recursively printing sub-objects.
  2.1008 +   */
  2.1009 +  void Print (std::ostream &os, int level) const;
  2.1010 +
  2.1011 +  bool operator== (const PbbMessage &other) const;
  2.1012 +  bool operator!= (const PbbMessage &other) const;
  2.1013 +
  2.1014 +protected:
  2.1015 +  /* PbbMessage size in bytes - 1.
  2.1016 +   *
  2.1017 +   * IPv4 = 4 - 1 = 3, IPv6 = 16 - 1 = 15
  2.1018 +   */
  2.1019 +  virtual PbbAddressLength GetAddressLength (void) const = 0;
  2.1020 +
  2.1021 +  virtual void SerializeOriginatorAddress (Buffer::Iterator &start) const = 0;
  2.1022 +  virtual Address DeserializeOriginatorAddress (Buffer::Iterator &start) const = 0;
  2.1023 +  virtual void PrintOriginatorAddress (std::ostream &os) const = 0;
  2.1024 +
  2.1025 +  virtual Ptr<PbbAddressBlock> AddressBlockDeserialize (Buffer::Iterator &start) const = 0;
  2.1026 +
  2.1027 +private:
  2.1028 +  PbbTlvBlock m_tlvList;
  2.1029 +  std::list< Ptr<PbbAddressBlock> > m_addressBlockList;
  2.1030 +
  2.1031 +  uint8_t m_type;
  2.1032 +  PbbAddressLength m_addrSize;
  2.1033 +
  2.1034 +  bool m_hasOriginatorAddress;
  2.1035 +  Address m_originatorAddress;
  2.1036 +
  2.1037 +  bool m_hasHopLimit;
  2.1038 +  uint8_t m_hopLimit;
  2.1039 +
  2.1040 +  bool m_hasHopCount;
  2.1041 +  uint8_t m_hopCount;
  2.1042 +
  2.1043 +  bool m_hasSequenceNumber;
  2.1044 +  uint16_t m_sequenceNumber;
  2.1045 +
  2.1046 +  mutable uint32_t m_refCount;
  2.1047 +};
  2.1048 +
  2.1049 +/**
  2.1050 + * \brief Concrete IPv4 specific PbbMessage.
  2.1051 + *
  2.1052 + * This message will only contain IPv4 addresses.
  2.1053 + */
  2.1054 +class PbbMessageIpv4 : public PbbMessage {
  2.1055 +protected:
  2.1056 +  virtual PbbAddressLength GetAddressLength (void) const;
  2.1057 +
  2.1058 +  virtual void SerializeOriginatorAddress (Buffer::Iterator &start) const;
  2.1059 +  virtual Address DeserializeOriginatorAddress (Buffer::Iterator &start) const;
  2.1060 +  virtual void PrintOriginatorAddress (std::ostream &os) const;
  2.1061 +
  2.1062 +  virtual Ptr<PbbAddressBlock> AddressBlockDeserialize (Buffer::Iterator &start) const;
  2.1063 +};
  2.1064 +
  2.1065 +/**
  2.1066 + * \brief Concrete IPv6 specific PbbMessage class.
  2.1067 + *
  2.1068 + * This message will only contain IPv6 addresses.
  2.1069 + */
  2.1070 +class PbbMessageIpv6 : public PbbMessage {
  2.1071 +protected:
  2.1072 +  virtual PbbAddressLength GetAddressLength (void) const;
  2.1073 +
  2.1074 +  virtual void SerializeOriginatorAddress (Buffer::Iterator &start) const;
  2.1075 +  virtual Address DeserializeOriginatorAddress (Buffer::Iterator &start) const;
  2.1076 +  virtual void PrintOriginatorAddress (std::ostream &os) const;
  2.1077 +
  2.1078 +  virtual Ptr<PbbAddressBlock> AddressBlockDeserialize (Buffer::Iterator &start) const;
  2.1079 +};
  2.1080 +
  2.1081 +/**
  2.1082 + * \brief An Address Block and its associated Address TLV Blocks.
  2.1083 + *
  2.1084 + * This is a pure virtual base class, when creating address blocks, you should
  2.1085 + * instantiate either PbbAddressBlockIpv4 or PbbAddressBlockIpv6.
  2.1086 + */
  2.1087 +class PbbAddressBlock
  2.1088 +{
  2.1089 +public:
  2.1090 +  typedef std::list< Address >::iterator AddressIterator;
  2.1091 +  typedef std::list< Address >::const_iterator ConstAddressIterator;
  2.1092 +
  2.1093 +  typedef std::list<uint8_t>::iterator PrefixIterator;
  2.1094 +  typedef std::list<uint8_t>::const_iterator ConstPrefixIterator;
  2.1095 +
  2.1096 +  typedef PbbAddressTlvBlock::Iterator TlvIterator;
  2.1097 +  typedef PbbAddressTlvBlock::ConstIterator ConstTlvIterator;
  2.1098 +
  2.1099 +  PbbAddressBlock (void);
  2.1100 +
  2.1101 +  /* Manipulating the address block */
  2.1102 +
  2.1103 +  /**
  2.1104 +   * \return an iterator to the first address in this block.
  2.1105 +   */
  2.1106 +  AddressIterator AddressBegin (void);
  2.1107 +
  2.1108 +  /**
  2.1109 +   * \return a const iterator to the first address in this block.
  2.1110 +   */
  2.1111 +  ConstAddressIterator AddressBegin (void) const;
  2.1112 +
  2.1113 +  /**
  2.1114 +   * \return an iterator to the last address in this block.
  2.1115 +   */
  2.1116 +  AddressIterator AddressEnd (void);
  2.1117 +
  2.1118 +  /**
  2.1119 +   * \return a const iterator to the last address in this block.
  2.1120 +   */
  2.1121 +  ConstAddressIterator AddressEnd (void) const;
  2.1122 +
  2.1123 +  /**
  2.1124 +   * \return the number of addresses in this block.
  2.1125 +   */
  2.1126 +  int AddressSize (void) const;
  2.1127 +
  2.1128 +  /**
  2.1129 +   * \return true if there are no addresses in this block, false otherwise.
  2.1130 +   */
  2.1131 +  bool AddressEmpty (void) const;
  2.1132 +
  2.1133 +  /**
  2.1134 +   * \return the first address in this block.
  2.1135 +   */
  2.1136 +  Address AddressFront (void) const;
  2.1137 +
  2.1138 +  /**
  2.1139 +   * \return the last address in this block.
  2.1140 +   */
  2.1141 +  Address AddressBack (void) const;
  2.1142 +
  2.1143 +  /**
  2.1144 +   * \brief Prepends an address to the front of this block.
  2.1145 +   * \param address the address to prepend.
  2.1146 +   */
  2.1147 +  void AddressPushFront (Address address);
  2.1148 +
  2.1149 +  /**
  2.1150 +   * \brief Removes an address from the front of this block.
  2.1151 +   */
  2.1152 +  void AddressPopFront (void);
  2.1153 +
  2.1154 +  /**
  2.1155 +   * \brief Appends an address to the back of this block.
  2.1156 +   * \param address the address to append.
  2.1157 +   */
  2.1158 +  void AddressPushBack (Address address);
  2.1159 +
  2.1160 +  /**
  2.1161 +   * \brief Removes an address from the back of this block.
  2.1162 +   */
  2.1163 +  void AddressPopBack (void);
  2.1164 +
  2.1165 +  /**
  2.1166 +   * \brief Inserts an address at the specified position in this block.
  2.1167 +   * \param position an Iterator pointing to the position in this block to
  2.1168 +   *        insert the address.
  2.1169 +   * \param value the address to insert.
  2.1170 +   * \return An iterator pointing to the newly inserted address.
  2.1171 +   */
  2.1172 +  AddressIterator AddressInsert (AddressIterator position,
  2.1173 +      const Address value);
  2.1174 +
  2.1175 +  /**
  2.1176 +   * \brief Removes the address at the specified position.
  2.1177 +   * \param position an Iterator pointing to the address to erase.
  2.1178 +   * \return an iterator pointing to the next address in the block.
  2.1179 +   */
  2.1180 +  AddressIterator AddressErase (AddressIterator position);
  2.1181 +
  2.1182 +  /**
  2.1183 +   * \brief Removes all addresses from [first, last) (includes first, not
  2.1184 +   *        includes last).
  2.1185 +   * \param first an Iterator pointing to the first address to erase
  2.1186 +   *        (inclusive).
  2.1187 +   * \param last an Iterator pointing to the element past the last address to
  2.1188 +   *        erase.
  2.1189 +   * \return an iterator pointing to the next address in the block.
  2.1190 +   */
  2.1191 +  AddressIterator AddressErase (AddressIterator first, AddressIterator last);
  2.1192 +
  2.1193 +  /**
  2.1194 +   * \brief Removes all addresses from this block.
  2.1195 +   */
  2.1196 +  void AddressClear (void);
  2.1197 +
  2.1198 +  /* Prefix methods */
  2.1199 +
  2.1200 +  /**
  2.1201 +   * \return an iterator to the first prefix in this block.
  2.1202 +   */
  2.1203 +  PrefixIterator PrefixBegin (void);
  2.1204 +
  2.1205 +  /**
  2.1206 +   * \return a const iterator to the first prefix in this block.
  2.1207 +   */
  2.1208 +  ConstPrefixIterator PrefixBegin (void) const;
  2.1209 +
  2.1210 +  /**
  2.1211 +   * \return an iterator to the last prefix in this block.
  2.1212 +   */
  2.1213 +  PrefixIterator PrefixEnd (void);
  2.1214 +
  2.1215 +  /**
  2.1216 +   * \return a const iterator to the last prefix in this block.
  2.1217 +   */
  2.1218 +  ConstPrefixIterator PrefixEnd (void) const;
  2.1219 +
  2.1220 +  /**
  2.1221 +   * \return the number of prefixes in this block.
  2.1222 +   */
  2.1223 +  int PrefixSize (void) const;
  2.1224 +
  2.1225 +  /**
  2.1226 +   * \return true if there are no prefixes in this block, false otherwise.
  2.1227 +   */
  2.1228 +  bool PrefixEmpty (void) const;
  2.1229 +
  2.1230 +  /**
  2.1231 +   * \return the first prefix in this block.
  2.1232 +   */
  2.1233 +  uint8_t PrefixFront (void) const;
  2.1234 +
  2.1235 +  /**
  2.1236 +   * \return the last prefix in this block.
  2.1237 +   */
  2.1238 +  uint8_t PrefixBack (void) const;
  2.1239 +
  2.1240 +  /**
  2.1241 +   * \brief Prepends a prefix to the front of this block.
  2.1242 +   * \param prefix the prefix to prepend.
  2.1243 +   */
  2.1244 +  void PrefixPushFront (uint8_t prefix);
  2.1245 +
  2.1246 +  /**
  2.1247 +   * \brief Removes a prefix from the front of this block.
  2.1248 +   */
  2.1249 +  void PrefixPopFront (void);
  2.1250 +
  2.1251 +  /**
  2.1252 +   * \brief Appends a prefix to the back of this block.
  2.1253 +   * \param prefix the prefix to append.
  2.1254 +   */
  2.1255 +  void PrefixPushBack (uint8_t prefix);
  2.1256 +
  2.1257 +  /**
  2.1258 +   * \brief Removes a prefix from the back of this block.
  2.1259 +   */
  2.1260 +  void PrefixPopBack (void);
  2.1261 +
  2.1262 +  /**
  2.1263 +   * \brief Inserts a prefix at the specified position in this block.
  2.1264 +   * \param position an Iterator pointing to the position in this block to
  2.1265 +   *        insert the prefix.
  2.1266 +   * \param value the prefix to insert.
  2.1267 +   * \return An iterator pointing to the newly inserted prefix.
  2.1268 +   */
  2.1269 +  PrefixIterator PrefixInsert (PrefixIterator position, const uint8_t value);
  2.1270 +
  2.1271 +  /**
  2.1272 +   * \brief Removes the prefix at the specified position.
  2.1273 +   * \param position an Iterator pointing to the prefix to erase.
  2.1274 +   * \return an iterator pointing to the next prefix in the block.
  2.1275 +   */
  2.1276 +  PrefixIterator PrefixErase (PrefixIterator position);
  2.1277 +
  2.1278 +  /**
  2.1279 +   * \brief Removes all prefixes from [first, last) (includes first, not
  2.1280 +   *        includes last).
  2.1281 +   * \param first an Iterator pointing to the first prefix to erase
  2.1282 +   *        (inclusive).
  2.1283 +   * \param last an Iterator pointing to the element past the last prefix to
  2.1284 +   *        erase.
  2.1285 +   * \return an iterator pointing to the next prefix in the block.
  2.1286 +   */
  2.1287 +  PrefixIterator PrefixErase (PrefixIterator first, PrefixIterator last);
  2.1288 +
  2.1289 +  /**
  2.1290 +   * \brief Removes all prefixes from this block.
  2.1291 +   */
  2.1292 +  void PrefixClear (void);
  2.1293 +
  2.1294 +  /* Manipulating the TLV block */
  2.1295 +
  2.1296 +  /**
  2.1297 +   * \return an iterator to the first address TLV in this block.
  2.1298 +   */
  2.1299 +  TlvIterator TlvBegin (void);
  2.1300 +
  2.1301 +  /**
  2.1302 +   * \return a const iterator to the first address TLV in this block.
  2.1303 +   */
  2.1304 +  ConstTlvIterator TlvBegin (void) const;
  2.1305 +
  2.1306 +  /**
  2.1307 +   * \return an iterator to the last address TLV in this block.
  2.1308 +   */
  2.1309 +  TlvIterator TlvEnd (void);
  2.1310 +
  2.1311 +  /**
  2.1312 +   * \return a const iterator to the last address TLV in this block.
  2.1313 +   */
  2.1314 +  ConstTlvIterator TlvEnd (void) const;
  2.1315 +
  2.1316 +  /**
  2.1317 +   * \return the number of address TLVs in this block.
  2.1318 +   */
  2.1319 +  int TlvSize (void) const;
  2.1320 +
  2.1321 +  /**
  2.1322 +   * \return true if there are no address TLVs in this block, false otherwise.
  2.1323 +   */
  2.1324 +  bool TlvEmpty (void) const;
  2.1325 +
  2.1326 +  /**
  2.1327 +   * \return a smart pointer to the first address TLV in this block.
  2.1328 +   */
  2.1329 +  Ptr<PbbAddressTlv> TlvFront (void);
  2.1330 +
  2.1331 +  /**
  2.1332 +   * \return a const smart pointer to the first address TLV in this message.
  2.1333 +   */
  2.1334 +  const Ptr<PbbAddressTlv> TlvFront (void) const;
  2.1335 +
  2.1336 +  /**
  2.1337 +   * \return a smart pointer to the last address TLV in this message.
  2.1338 +   */
  2.1339 +  Ptr<PbbAddressTlv> TlvBack (void);
  2.1340 +
  2.1341 +  /**
  2.1342 +   * \return a const smart pointer to the last address TLV in this message.
  2.1343 +   */
  2.1344 +  const Ptr<PbbAddressTlv> TlvBack (void) const;
  2.1345 +
  2.1346 +  /**
  2.1347 +   * \brief Prepends an address TLV to the front of this message.
  2.1348 +   * \param address a smart pointer to the address TLV to prepend.
  2.1349 +   */
  2.1350 +  void TlvPushFront (Ptr<PbbAddressTlv> address);
  2.1351 +
  2.1352 +  /**
  2.1353 +   * \brief Removes an address TLV from the front of this message.
  2.1354 +   */
  2.1355 +  void TlvPopFront (void);
  2.1356 +
  2.1357 +  /**
  2.1358 +   * \brief Appends an address TLV to the back of this message.
  2.1359 +   * \param address a smart pointer to the address TLV to append.
  2.1360 +   */
  2.1361 +  void TlvPushBack (Ptr<PbbAddressTlv> address);
  2.1362 +
  2.1363 +  /**
  2.1364 +   * \brief Removes an address TLV from the back of this message.
  2.1365 +   */
  2.1366 +  void TlvPopBack (void);
  2.1367 +
  2.1368 +  /**
  2.1369 +   * \brief Inserts an address TLV at the specified position in this block.
  2.1370 +   * \param position an Iterator pointing to the position in this block to
  2.1371 +   *        insert the address TLV.
  2.1372 +   * \param value the prefix to insert.
  2.1373 +   * \return An iterator pointing to the newly inserted address TLV.
  2.1374 +   */
  2.1375 +  TlvIterator TlvInsert (TlvIterator position, const Ptr<PbbTlv> value);
  2.1376 +
  2.1377 +  /**
  2.1378 +   * \brief Removes the address TLV at the specified position.
  2.1379 +   * \param position an Iterator pointing to the address TLV to erase.
  2.1380 +   * \return an iterator pointing to the next address TLV in the block.
  2.1381 +   */
  2.1382 +  TlvIterator TlvErase (TlvIterator position);
  2.1383 +
  2.1384 +  /**
  2.1385 +   * \brief Removes all address TLVs from [first, last) (includes first, not
  2.1386 +   *        includes last).
  2.1387 +   * \param first an Iterator pointing to the first address TLV to erase
  2.1388 +   *        (inclusive).
  2.1389 +   * \param last an Iterator pointing to the element past the last address TLV
  2.1390 +   *        to erase.
  2.1391 +   * \return an iterator pointing to the next address TLV in the message.
  2.1392 +   */
  2.1393 +  TlvIterator TlvErase (TlvIterator first, TlvIterator last);
  2.1394 +
  2.1395 +  /**
  2.1396 +   * \brief Removes all address TLVs from this block.
  2.1397 +   */
  2.1398 +  void TlvClear (void);
  2.1399 +
  2.1400 +  /* Smart pointer methods */
  2.1401 +  void Ref (void) const;
  2.1402 +  void Unref (void) const;
  2.1403 +
  2.1404 +  /**
  2.1405 +   * \return The size (in bytes) needed to serialize this address block.
  2.1406 +   */
  2.1407 +  uint32_t GetSerializedSize (void) const;
  2.1408 +
  2.1409 +  /**
  2.1410 +   * \brief Serializes this address block into the specified buffer.
  2.1411 +   * \param start a reference to the point in a buffer to begin serializing.
  2.1412 +   *
  2.1413 +   * Users should not need to call this.  Blocks will be deserialized by their
  2.1414 +   * containing packet.
  2.1415 +   */
  2.1416 +  void Serialize (Buffer::Iterator &start) const;
  2.1417 +
  2.1418 +  /**
  2.1419 +   * \brief Deserializes an address block from the specified buffer.
  2.1420 +   * \param start a reference to the point in a buffer to begin deserializing.
  2.1421 +   *
  2.1422 +   * Users should not need to call this.  Blocks will be deserialized by their
  2.1423 +   * containing packet.
  2.1424 +   */
  2.1425 +  void Deserialize (Buffer::Iterator &start);
  2.1426 +
  2.1427 +  /**
  2.1428 +   * \brief Pretty-prints the contents of this address block.
  2.1429 +   * \param os a stream object to print to.
  2.1430 +   */
  2.1431 +  void Print (std::ostream &os) const;
  2.1432 +
  2.1433 +  /**
  2.1434 +   * \brief Pretty-prints the contents of this address block, with specified
  2.1435 +   *        indentation.
  2.1436 +   * \param os a stream object to print to.
  2.1437 +   * \param level level of indentation.
  2.1438 +   *
  2.1439 +   * This probably never needs to be called by users.  This is used when
  2.1440 +   * recursively printing sub-objects.
  2.1441 +   */
  2.1442 +  void Print (std::ostream &os, int level) const;
  2.1443 +
  2.1444 +  bool operator== (const PbbAddressBlock &other) const;
  2.1445 +  bool operator!= (const PbbAddressBlock &other) const;
  2.1446 +
  2.1447 +protected:
  2.1448 +  virtual uint8_t GetAddressLength (void) const = 0;
  2.1449 +
  2.1450 +  virtual void SerializeAddress (uint8_t *buffer, ConstAddressIterator iter) const = 0;
  2.1451 +  virtual Address DeserializeAddress (uint8_t *buffer) const = 0;
  2.1452 +  virtual void PrintAddress (std::ostream &os, ConstAddressIterator iter) const = 0;
  2.1453 +
  2.1454 +private:
  2.1455 +  uint8_t GetPrefixFlags (void) const;
  2.1456 +  void GetHeadTail (uint8_t *head, uint8_t &headlen,
  2.1457 +      uint8_t *tail, uint8_t &taillen) const;
  2.1458 +  bool HasZeroTail (const uint8_t *tail, uint8_t taillen) const;
  2.1459 +
  2.1460 +  std::list<Address> m_addressList;
  2.1461 +  std::list<uint8_t> m_prefixList;
  2.1462 +  PbbAddressTlvBlock m_addressTlvList;
  2.1463 +
  2.1464 +  mutable uint32_t m_refCount;
  2.1465 +};
  2.1466 +
  2.1467 +/**
  2.1468 + * \brief Concrete IPv4 specific PbbAddressBlock.
  2.1469 + *
  2.1470 + * This address block will only contain IPv4 addresses.
  2.1471 + */
  2.1472 +class PbbAddressBlockIpv4 : public PbbAddressBlock
  2.1473 +{
  2.1474 +protected:
  2.1475 +  virtual uint8_t GetAddressLength (void) const;
  2.1476 +
  2.1477 +  virtual void SerializeAddress (uint8_t *buffer, ConstAddressIterator iter) const;
  2.1478 +  virtual Address DeserializeAddress (uint8_t *buffer) const;
  2.1479 +  virtual void PrintAddress (std::ostream &os, ConstAddressIterator iter) const;
  2.1480 +};
  2.1481 +
  2.1482 +/**
  2.1483 + * \brief Concrete IPv6 specific PbbAddressBlock.
  2.1484 + *
  2.1485 + * This address block will only contain IPv6 addresses.
  2.1486 + */
  2.1487 +class PbbAddressBlockIpv6 : public PbbAddressBlock
  2.1488 +{
  2.1489 +protected:
  2.1490 +  virtual uint8_t GetAddressLength (void) const;
  2.1491 +
  2.1492 +  virtual void SerializeAddress (uint8_t *buffer, ConstAddressIterator iter) const;
  2.1493 +  virtual Address DeserializeAddress (uint8_t *buffer) const;
  2.1494 +  virtual void PrintAddress (std::ostream &os, ConstAddressIterator iter) const;
  2.1495 +};
  2.1496 +
  2.1497 +/**
  2.1498 + * \brief A packet or message TLV
  2.1499 + */
  2.1500 +class PbbTlv
  2.1501 +{
  2.1502 +public:
  2.1503 +  PbbTlv (void);
  2.1504 +
  2.1505 +  /**
  2.1506 +   * \brief Sets the type of this TLV.
  2.1507 +   * \param type the type value to set.
  2.1508 +   */
  2.1509 +  void SetType (uint8_t type);
  2.1510 +
  2.1511 +  /**
  2.1512 +   * \return the type of this TLV.
  2.1513 +   */
  2.1514 +  uint8_t GetType (void) const;
  2.1515 +
  2.1516 +  /**
  2.1517 +   * \brief Sets the type extension of this TLV.
  2.1518 +   * \param type the type extension value to set.
  2.1519 +   *
  2.1520 +   * The type extension is like a sub-type used to further distinguish between
  2.1521 +   * TLVs of the same type.
  2.1522 +   */
  2.1523 +  void SetTypeExt (uint8_t type);
  2.1524 +
  2.1525 +  /**
  2.1526 +   * \return the type extension for this TLV.
  2.1527 +   *
  2.1528 +   * Calling this while HasTypeExt is False is undefined.  Make sure you check
  2.1529 +   * it first.  This will be checked by an assert in debug builds.
  2.1530 +   */
  2.1531 +  uint8_t GetTypeExt (void) const;
  2.1532 +
  2.1533 +  /**
  2.1534 +   * \brief Tests whether or not this TLV has a type extension.
  2.1535 +   * \return true if this TLV has a type extension, false otherwise.
  2.1536 +   *
  2.1537 +   * This should be called before calling GetTypeExt to make sure there
  2.1538 +   * actually is one.
  2.1539 +   */
  2.1540 +  bool HasTypeExt (void) const;
  2.1541 +
  2.1542 +  /**
  2.1543 +   * \brief Sets the value of this message to the specified buffer.
  2.1544 +   * \param start a buffer instance.
  2.1545 +   *
  2.1546 +   * The buffer is _not_ copied until this TLV is serialized.  You should not
  2.1547 +   * change the contents of the buffer you pass in to this function.
  2.1548 +   */
  2.1549 +  void SetValue (Buffer start);
  2.1550 +
  2.1551 +  /**
  2.1552 +   * \brief Sets the value of this message to a buffer with the specified data.
  2.1553 +   * \param buffer a pointer to data to put in the TLVs buffer.
  2.1554 +   * \param size the size of the buffer.
  2.1555 +   *
  2.1556 +   * The buffer *is copied* into a *new buffer instance*.  You can free the
  2.1557 +   * data in the buffer provided anytime you wish.
  2.1558 +   */
  2.1559 +  void SetValue (const uint8_t * buffer, uint32_t size);
  2.1560 +
  2.1561 +  /**
  2.1562 +   * \return a Buffer pointing to the value of this TLV.
  2.1563 +   *
  2.1564 +   * Calling this while HasValue is False is undefined.  Make sure you check it
  2.1565 +   * first.  This will be checked by an assert in debug builds.
  2.1566 +   */
  2.1567 +  Buffer GetValue (void) const;
  2.1568 +
  2.1569 +  /**
  2.1570 +   * \brief Tests whether or not this TLV has a value.
  2.1571 +   * \return true if this tlv has a TLV, false otherwise.
  2.1572 +   *
  2.1573 +   * This should be called before calling GetTypeExt to make sure there
  2.1574 +   * actually is one.
  2.1575 +   */
  2.1576 +  bool HasValue (void) const;
  2.1577 +
  2.1578 +  /* Smart pointer methods */
  2.1579 +  void Ref (void) const;
  2.1580 +  void Unref (void) const;
  2.1581 +
  2.1582 +  /**
  2.1583 +   * \return The size (in bytes) needed to serialize this TLV.
  2.1584 +   */
  2.1585 +  uint32_t GetSerializedSize (void) const;
  2.1586 +
  2.1587 +  /**
  2.1588 +   * \brief Serializes this TLV into the specified buffer.
  2.1589 +   * \param start a reference to the point in a buffer to begin serializing.
  2.1590 +   *
  2.1591 +   * Users should not need to call this.  TLVs will be serialized by their
  2.1592 +   * containing blocks.
  2.1593 +   */
  2.1594 +  void Serialize (Buffer::Iterator &start) const;
  2.1595 +
  2.1596 +  /**
  2.1597 +   * \brief Deserializes a TLV from the specified buffer.
  2.1598 +   * \param start a reference to the point in a buffer to begin deserializing.
  2.1599 +   *
  2.1600 +   * Users should not need to call this.  TLVs will be deserialized by their
  2.1601 +   * containing blocks.
  2.1602 +   */
  2.1603 +  void Deserialize (Buffer::Iterator &start);
  2.1604 +
  2.1605 +  /**
  2.1606 +   * \brief Pretty-prints the contents of this TLV.
  2.1607 +   * \param os a stream object to print to.
  2.1608 +   */
  2.1609 +  void Print (std::ostream &os) const;
  2.1610 +
  2.1611 +  /**