Development of RRC headers based on the RRC SAP
authorLluis Parcerisa <parcerisa@gmail.com>
Thu, 29 Nov 2012 17:18:51 +0100
changeset 9443 33e358d8d64d
parent 9440 eb053bae286c
child 9444 c799ca1b8f10
Development of RRC headers based on the RRC SAP
src/lte/model/lte-asn1-header.cc
src/lte/model/lte-asn1-header.h
src/lte/model/lte-rrc-header.cc
src/lte/model/lte-rrc-header.h
src/lte/test/test-asn1-encoding.cc
src/lte/wscript
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-asn1-header.cc	Thu Nov 29 17:18:51 2012 +0100
@@ -0,0 +1,735 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Lluis Parcerisa <lparcerisa@cttc.cat>
+ */
+
+#include "ns3/log.h"
+#include "ns3/lte-asn1-header.h"
+
+#include <stdio.h>
+#include <sstream>
+#include <math.h> // For log()
+
+NS_LOG_COMPONENT_DEFINE ("Asn1Header");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Asn1Header);
+
+TypeId
+Asn1Header::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Asn1Header")
+    .SetParent<Header> ()
+  ;
+  return tid;
+}
+
+TypeId
+Asn1Header::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+// Constructor
+Asn1Header::Asn1Header ()
+{
+  m_serializationPendingBits = 0x00;
+  m_numSerializationPendingBits = 0;
+  m_isDataSerialized = false;
+}
+
+// Destructor
+Asn1Header::~Asn1Header ()
+{
+}
+
+uint32_t
+Asn1Header::GetSerializedSize (void) const
+{
+  if (!m_isDataSerialized)
+    {
+      PreSerialize ();
+    }
+  return m_serializationResult.GetSize ();
+}
+
+void Asn1Header::Serialize (Buffer::Iterator bIterator) const
+{
+  if (!m_isDataSerialized)
+    {
+      PreSerialize ();
+    }
+  bIterator.Write (m_serializationResult.Begin (),m_serializationResult.End ());
+}
+
+void Asn1Header::WriteOctet (uint8_t octet) const
+{
+  m_serializationResult.AddAtEnd (1);
+  Buffer::Iterator bIterator = m_serializationResult.End ();
+  bIterator.Prev ();
+  bIterator.WriteU8 (octet);
+}
+
+template <int N>
+void Asn1Header::SerializeBitset (std::bitset<N> data) const
+{
+
+  size_t dataSize = data.size ();
+  uint8_t pendingBits = dataSize;
+  uint8_t mask = 1;
+  int j;
+
+  // No extension marker (Clause 16.7 ITU-T X.691),
+  // as 3GPP TS 36.331 does not use it in its IE's.
+
+  // Clause 16.8 ITU-T X.691
+  if (dataSize == 0)
+    {
+      return;
+    }
+
+  // Clause 16.9 ITU-T X.691
+  // Clause 16.10 ITU-T X.691
+  if (dataSize <= 65536)
+    {
+      // If there are bits pending to be processed,
+      // append first bits in data to complete an octet.
+      if (m_numSerializationPendingBits > 0)
+        {
+          mask = 0x80 >> m_numSerializationPendingBits;
+          while (pendingBits > 0 && m_numSerializationPendingBits < 8)
+            {
+              m_serializationPendingBits |= (data[pendingBits - 1]) ? mask : 0;
+              pendingBits--;
+              m_numSerializationPendingBits++;
+              mask = (mask >> 1) & (~mask);
+            }
+
+          if (m_numSerializationPendingBits >= 8)
+            {
+              WriteOctet (m_serializationPendingBits);
+              m_numSerializationPendingBits = 0;
+              m_serializationPendingBits = 0;
+            }
+        }
+
+      while (pendingBits > 0)
+        {
+          mask = 1;
+          j = 8;
+
+          // If there are less than 8 remaining bits,
+          // store it to m_serializationPendingBits.
+          if (pendingBits < 8)
+            {
+              mask = 0x80;
+              m_numSerializationPendingBits = pendingBits;
+              while (pendingBits > 0)
+                {
+                  m_serializationPendingBits |= (data[pendingBits - 1]) ? mask : 0;
+                  mask = (mask >> 1) & (~mask);
+                  pendingBits--;
+                }
+            }
+
+          // Write the data to buffer
+          else
+            {
+              uint8_t octetToWrite = 0;
+              for (; j > 0; j--)
+                {
+                  octetToWrite |= (data[pendingBits - j]) ? mask : 0;
+                  mask = (mask << 1) & (~mask);
+                }
+              WriteOctet (octetToWrite);
+              pendingBits -= 8;
+            }
+        }
+    }
+
+  // Clause 16.11 ITU-T X.691
+  else
+    {
+      printf ("FRAGMENTATION NEEDED!\n");
+    }
+}
+
+template <int N>
+void Asn1Header::SerializeBitstring (std::bitset<N> data) const
+{
+  SerializeBitset<N> (data);
+}
+
+
+void Asn1Header::SerializeBitstring (std::bitset<1> data) const
+{
+  SerializeBitstring<1> (data);
+}
+
+void Asn1Header::SerializeBitstring (std::bitset<8> data) const
+{
+  SerializeBitstring<8> (data);
+}
+
+void Asn1Header::SerializeBitstring (std::bitset<10> data) const
+{
+  SerializeBitstring<10> (data);
+}
+
+void Asn1Header::SerializeBitstring (std::bitset<16> data) const
+{
+  SerializeBitstring<16> (data);
+}
+
+void Asn1Header::SerializeBitstring (std::bitset<27> data) const
+{
+  SerializeBitstring<27> (data);
+}
+
+void Asn1Header::SerializeBitstring (std::bitset<28> data) const
+{
+  SerializeBitstring<28> (data);
+}
+
+void Asn1Header::SerializeBitstring (std::bitset<32> data) const
+{
+  SerializeBitstring<32> (data);
+}
+
+void Asn1Header::SerializeBoolean (bool value) const
+{
+  // Clause 12 ITU-T X.691
+  std::bitset<1> val;
+  (value) ? val.set () : val.reset ();
+  SerializeBitset<1> (val);
+}
+
+template <int N>
+void Asn1Header::SerializeSequence (std::bitset<N> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
+{
+  if (isExtensionMarkerPresent)
+    {
+      // Extension marker present, but no extension
+      SerializeBoolean (false);
+    }
+  SerializeBitstring<N> (optionalOrDefaultMask);
+}
+
+void Asn1Header::SerializeSequence (std::bitset<0> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
+{
+  SerializeSequence<0> (optionalOrDefaultMask,isExtensionMarkerPresent);
+}
+
+void Asn1Header::SerializeSequence (std::bitset<1> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
+{
+  SerializeSequence<1> (optionalOrDefaultMask,isExtensionMarkerPresent);
+}
+
+void Asn1Header::SerializeSequence (std::bitset<2> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
+{
+  SerializeSequence<2> (optionalOrDefaultMask,isExtensionMarkerPresent);
+}
+
+void Asn1Header::SerializeSequence (std::bitset<3> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
+{
+  SerializeSequence<3> (optionalOrDefaultMask,isExtensionMarkerPresent);
+}
+
+void Asn1Header::SerializeSequence (std::bitset<4> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
+{
+  SerializeSequence<4> (optionalOrDefaultMask,isExtensionMarkerPresent);
+}
+
+void Asn1Header::SerializeSequence (std::bitset<5> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
+{
+  SerializeSequence<5> (optionalOrDefaultMask,isExtensionMarkerPresent);
+}
+
+void Asn1Header::SerializeSequence (std::bitset<6> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
+{
+  SerializeSequence<6> (optionalOrDefaultMask,isExtensionMarkerPresent);
+}
+
+void Asn1Header::SerializeSequence (std::bitset<9> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
+{
+  SerializeSequence<9> (optionalOrDefaultMask,isExtensionMarkerPresent);
+}
+
+void Asn1Header::SerializeSequence (std::bitset<10> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
+{
+  SerializeSequence<10> (optionalOrDefaultMask,isExtensionMarkerPresent);
+}
+
+void Asn1Header::SerializeSequence (std::bitset<11> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
+{
+  SerializeSequence<11> (optionalOrDefaultMask,isExtensionMarkerPresent);
+}
+
+void Asn1Header::SerializeSequenceOf (int numElems, int nMax, int nMin) const
+{
+  // Clause 20.6 ITU-T X.691
+  SerializeInteger (numElems, nMin, nMax);
+}
+
+void Asn1Header::SerializeEnum (int numElems, int selectedElem) const
+{
+  // Clause 14 ITU-T X.691
+  SerializeInteger (selectedElem, 0, numElems - 1);
+}
+
+void Asn1Header::SerializeChoice (int numOptions, int selectedOption) const
+{
+  // Clause 23.4 ITU-T X.691
+  if (numOptions < 2)
+    {
+      return;
+    }
+
+  SerializeInteger (selectedOption,0,numOptions - 1);
+}
+
+void Asn1Header::SerializeInteger (int n, int nmin, int nmax) const
+{
+  // Misusage check: Ensure nmax>nmin ...
+  if (nmin > nmax)
+    {
+      int aux = nmin;
+      nmin = nmax;
+      nmax = aux;
+    }
+
+  // Clause 11.5.3 ITU-T X.691
+  int range = nmax - nmin + 1;
+  // Substract nmin to n
+  n -= nmin;
+
+  // Clause 11.5.4 ITU-T X.691
+  if (range <= 1)
+    {
+      return;
+    }
+
+  // Clause 11.5.6 ITU-T X.691
+  int requiredBits = ceil (log (range) / log (2.0));
+
+  switch (requiredBits)
+    {
+    case 1:
+      SerializeBitset<1> (std::bitset<1> (n));
+      break;
+    case 2:
+      SerializeBitset<2> (std::bitset<2> (n));
+      break;
+    case 3:
+      SerializeBitset<3> (std::bitset<3> (n));
+      break;
+    case 4:
+      SerializeBitset<4> (std::bitset<4> (n));
+      break;
+    case 5:
+      SerializeBitset<5> (std::bitset<5> (n));
+      break;
+    case 6:
+      SerializeBitset<6> (std::bitset<6> (n));
+      break;
+    case 7:
+      SerializeBitset<7> (std::bitset<7> (n));
+      break;
+    case 8:
+      SerializeBitset<8> (std::bitset<8> (n));
+      break;
+    case 9:
+      SerializeBitset<9> (std::bitset<9> (n));
+      break;
+    case 10:
+      SerializeBitset<10> (std::bitset<10> (n));
+      break;
+    case 11:
+      SerializeBitset<11> (std::bitset<11> (n));
+      break;
+    case 12:
+      SerializeBitset<12> (std::bitset<12> (n));
+      break;
+    case 13:
+      SerializeBitset<13> (std::bitset<13> (n));
+      break;
+    case 14:
+      SerializeBitset<14> (std::bitset<14> (n));
+      break;
+    case 15:
+      SerializeBitset<15> (std::bitset<15> (n));
+      break;
+    case 16:
+      SerializeBitset<16> (std::bitset<16> (n));
+      break;
+    case 17:
+      SerializeBitset<17> (std::bitset<17> (n));
+      break;
+    case 18:
+      SerializeBitset<18> (std::bitset<18> (n));
+      break;
+    case 19:
+      SerializeBitset<19> (std::bitset<19> (n));
+      break;
+    case 20:
+      SerializeBitset<20> (std::bitset<20> (n));
+      break;
+    default:
+      {
+        std::cout << "SerializeInteger " << requiredBits << " Out of range!!" << std::endl;
+        exit (1);
+      }
+    }
+}
+
+void Asn1Header::SerializeNull () const
+{
+  // Clause 18 ITU-T X.691
+  return;
+}
+
+void Asn1Header::FinalizeSerialization () const
+{
+  if (m_numSerializationPendingBits > 0)
+    {
+      m_numSerializationPendingBits = 0;
+      SerializeBitset<8> (std::bitset<8> (m_serializationPendingBits));
+    }
+  m_isDataSerialized = true;
+}
+
+template <int N>
+Buffer::Iterator Asn1Header::DeserializeBitset (std::bitset<N> *data, Buffer::Iterator bIterator)
+{
+
+  int bitsToRead = N;
+  uint8_t mask;
+
+  // Read bits from pending bits
+  if (m_numSerializationPendingBits > 0)
+    {
+      while (bitsToRead > 0 && m_numSerializationPendingBits > 0)
+        {
+          data->set (bitsToRead - 1,(m_serializationPendingBits & 0x80) ? 1 : 0);
+          bitsToRead--;
+          m_numSerializationPendingBits--;
+          m_serializationPendingBits = m_serializationPendingBits << 1;
+        }
+    }
+
+  // Read bits from buffer
+  while (bitsToRead > 0)
+    {
+      uint8_t octet = bIterator.ReadU8 ();
+      // If 8 bits can be allocated to the bitset, set the bits
+      if (bitsToRead >= 8)
+        {
+          mask = 0x80;
+          for (int j = 0; j < 8; j++)
+            {
+              data->set (bitsToRead - 1,(octet & mask) ? 1 : 0);
+              bitsToRead--;
+              mask = mask >> 1;
+            }
+        }
+
+      // Otherwise, we'll have to save the remaining bits
+      else
+        {
+          mask = 0x80;
+          m_numSerializationPendingBits = 8 - bitsToRead;
+          m_serializationPendingBits = octet << bitsToRead;
+          while (bitsToRead > 0)
+            {
+              data->set (bitsToRead - 1,(octet & mask) ? 1 : 0);
+              bitsToRead--;
+              mask = mask >> 1;
+            }
+        }
+    }
+
+  return bIterator;
+}
+
+template <int N>
+Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<N> *data, Buffer::Iterator bIterator)
+{
+  return DeserializeBitset<N> (data,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<1> *data, Buffer::Iterator bIterator)
+{
+  return DeserializeBitstring<1> (data,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<8> *data, Buffer::Iterator bIterator)
+{
+  return DeserializeBitstring<8> (data,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<10> *data, Buffer::Iterator bIterator)
+{
+  return DeserializeBitstring<10> (data,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<16> *data, Buffer::Iterator bIterator)
+{
+  return DeserializeBitstring<16> (data,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<27> *data, Buffer::Iterator bIterator)
+{
+  return DeserializeBitstring<27> (data,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<28> *data, Buffer::Iterator bIterator)
+{
+  return DeserializeBitstring<28> (data,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<32> *data, Buffer::Iterator bIterator)
+{
+  return DeserializeBitstring<32> (data,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeBoolean (bool *value, Buffer::Iterator bIterator)
+{
+  std::bitset<1> readBit;
+  bIterator = DeserializeBitset<1> (&readBit,bIterator);
+  *value = (readBit[0] == 1) ? true : false;
+  return bIterator;
+}
+
+Buffer::Iterator Asn1Header::DeserializeInteger (int *n, int nmin, int nmax, Buffer::Iterator bIterator)
+{
+  // Misusage check: Ensure nmax>nmin ...
+  if (nmin > nmax)
+    {
+      int aux = nmin;
+      nmin = nmax;
+      nmax = aux;
+    }
+
+  int range = nmax - nmin + 1;
+
+  if (range == 1)
+    {
+      return bIterator;
+    }
+
+  int requiredBits = ceil (log (range) / log (2.0));
+
+  std::bitset<1> bitsRead1;
+  std::bitset<2> bitsRead2;
+  std::bitset<3> bitsRead3;
+  std::bitset<4> bitsRead4;
+  std::bitset<5> bitsRead5;
+  std::bitset<6> bitsRead6;
+  std::bitset<7> bitsRead7;
+  std::bitset<8> bitsRead8;
+  std::bitset<9> bitsRead9;
+  std::bitset<10> bitsRead10;
+  std::bitset<11> bitsRead11;
+  std::bitset<12> bitsRead12;
+  std::bitset<13> bitsRead13;
+  std::bitset<14> bitsRead14;
+  std::bitset<15> bitsRead15;
+  std::bitset<16> bitsRead16;
+  std::bitset<17> bitsRead17;
+  std::bitset<18> bitsRead18;
+  std::bitset<19> bitsRead19;
+  std::bitset<20> bitsRead20;
+
+  switch (requiredBits)
+    {
+    case 1:
+      bIterator = DeserializeBitset<1> (&bitsRead1,bIterator);
+      *n = (int)bitsRead1.to_ulong ();
+      break;
+    case 2: 
+      bIterator = DeserializeBitset<2> (&bitsRead2,bIterator);
+      *n = (int)bitsRead2.to_ulong ();
+      break;
+    case 3: 
+      bIterator = DeserializeBitset<3> (&bitsRead3,bIterator);
+      *n = (int)bitsRead3.to_ulong ();
+      break;
+    case 4: 
+      bIterator = DeserializeBitset<4> (&bitsRead4,bIterator);
+      *n = (int)bitsRead4.to_ulong ();
+      break;
+    case 5:
+      bIterator = DeserializeBitset<5> (&bitsRead5,bIterator);
+      *n = (int)bitsRead5.to_ulong ();
+      break;
+    case 6:
+      bIterator = DeserializeBitset<6> (&bitsRead6,bIterator);
+      *n = (int)bitsRead6.to_ulong ();
+      break;
+    case 7:
+      bIterator = DeserializeBitset<7> (&bitsRead7,bIterator);
+      *n = (int)bitsRead7.to_ulong ();
+      break;
+    case 8:
+      bIterator = DeserializeBitset<8> (&bitsRead8,bIterator);
+      *n = (int)bitsRead8.to_ulong ();
+      break;
+    case 9:
+      bIterator = DeserializeBitset<9> (&bitsRead9,bIterator);
+      *n = (int)bitsRead9.to_ulong ();
+      break;
+    case 10:
+      bIterator = DeserializeBitset<10> (&bitsRead10,bIterator);
+      *n = (int)bitsRead10.to_ulong ();
+      break;
+    case 11:
+      bIterator = DeserializeBitset<11> (&bitsRead11,bIterator);
+      *n = (int)bitsRead11.to_ulong ();
+      break;
+    case 12:
+      bIterator = DeserializeBitset<12> (&bitsRead12,bIterator);
+      *n = (int)bitsRead12.to_ulong ();
+      break;
+    case 13:
+      bIterator = DeserializeBitset<13> (&bitsRead13,bIterator);
+      *n = (int)bitsRead13.to_ulong ();
+      break;
+    case 14:
+      bIterator = DeserializeBitset<14> (&bitsRead14,bIterator);
+      *n = (int)bitsRead14.to_ulong ();
+      break;
+    case 15:
+      bIterator = DeserializeBitset<15> (&bitsRead15,bIterator);
+      *n = (int)bitsRead15.to_ulong ();
+      break;
+    case 16:
+      bIterator = DeserializeBitset<16> (&bitsRead16,bIterator);
+      *n = (int)bitsRead16.to_ulong ();
+      break;
+    case 17:
+      bIterator = DeserializeBitset<17> (&bitsRead17,bIterator);
+      *n = (int)bitsRead17.to_ulong ();
+      break;
+    case 18:
+      bIterator = DeserializeBitset<18> (&bitsRead18,bIterator);
+      *n = (int)bitsRead18.to_ulong ();
+      break;
+    case 19:
+      bIterator = DeserializeBitset<19> (&bitsRead19,bIterator);
+      *n = (int)bitsRead19.to_ulong ();
+      break;
+    case 20:
+      bIterator = DeserializeBitset<20> (&bitsRead20,bIterator);
+      *n = (int)bitsRead20.to_ulong ();
+      break;
+    default:
+      {
+        std::cout << "SerializeInteger Out of range!!" << std::endl;
+        exit (1);
+      }
+    }
+
+  *n += nmin;
+
+  return bIterator;
+}
+
+Buffer::Iterator Asn1Header::DeserializeChoice (int numOptions, int *selectedOption, Buffer::Iterator bIterator)
+{
+  return DeserializeInteger (selectedOption,0,numOptions - 1,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeEnum (int numElems, int *selectedElem, Buffer::Iterator bIterator)
+{
+  return DeserializeInteger (selectedElem,0,numElems - 1,bIterator);
+}
+
+template <int N>
+Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<N> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
+{
+  if (isExtensionMarkerPresent)
+    {
+      bool dummy;
+      bIterator = DeserializeBoolean (&dummy,bIterator);
+    }
+  bIterator = DeserializeBitset<N> (optionalOrDefaultMask,bIterator);
+  return bIterator;
+}
+
+Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<0> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
+{
+  return DeserializeSequence<0> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<1> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
+{
+  return DeserializeSequence<1> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<2> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
+{
+  return DeserializeSequence<2> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<3> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
+{
+  return DeserializeSequence<3> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<4> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
+{
+  return DeserializeSequence<4> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<5> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
+{
+  return DeserializeSequence<5> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<6> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
+{
+  return DeserializeSequence<6> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<9> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
+{
+  return DeserializeSequence<9> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<10> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
+{
+  return DeserializeSequence<10> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<11> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
+{
+  return DeserializeSequence<11> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
+}
+
+Buffer::Iterator Asn1Header::DeserializeNull (Buffer::Iterator bIterator)
+{
+  return bIterator;
+}
+
+Buffer::Iterator Asn1Header::DeserializeSequenceOf (int *numElems, int nMax, int nMin, Buffer::Iterator bIterator)
+{
+  return DeserializeInteger (numElems,nMin,nMax,bIterator);
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-asn1-header.h	Thu Nov 29 17:18:51 2012 +0100
@@ -0,0 +1,139 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Lluis Parcerisa <lparcerisa@cttc.cat>
+ */
+
+#ifndef ASN1_HEADER_H
+#define ASN1_HEADER_H
+
+#include "ns3/header.h"
+
+#include <bitset>
+#include <string>
+
+#include "ns3/lte-rrc-sap.h"
+
+namespace ns3 {
+
+/**
+ * This class has the purpose to encode Information Elements according
+ * to ASN.1 syntax, as defined in ITU-T  X-691.
+ * IMPORTANT: The encoding is done following the UNALIGNED variant.
+ */
+class Asn1Header : public Header
+{
+public:
+  Asn1Header ();
+  virtual ~Asn1Header ();
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  uint32_t GetSerializedSize (void) const;
+  void Serialize (Buffer::Iterator bIterator) const;
+
+  // Pure virtual methods, implemented in child classes
+  virtual void PreSerialize (void) const = 0;
+  virtual uint32_t Deserialize (Buffer::Iterator bIterator) = 0;
+  virtual void Print (std::ostream &os) const = 0;
+
+protected:
+  mutable uint8_t m_serializationPendingBits;
+  mutable uint8_t m_numSerializationPendingBits;
+  mutable bool m_isDataSerialized;
+  mutable Buffer m_serializationResult;
+
+  // Function to write in m_serializationResult, after resizing its size
+  void WriteOctet (uint8_t octet) const;
+
+  // Serialization functions
+  void SerializeBoolean (bool value) const;
+  void SerializeInteger (int n, int nmin, int nmax) const;
+  void SerializeOctetstring (std::string s) const;
+  void SerializeSequenceOf (int numElems, int nMax, int nMin) const;
+  void SerializeChoice (int numOptions, int selectedOption) const;
+  void SerializeEnum (int numElems, int selectedElem) const;
+  void SerializeNull () const;
+  void FinalizeSerialization () const;
+
+  template <int N>
+  void SerializeBitset (std::bitset<N> data) const;
+
+  template <int N>
+  void SerializeSequence (std::bitset<N> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
+  void SerializeSequence (std::bitset<0> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
+  void SerializeSequence (std::bitset<1> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
+  void SerializeSequence (std::bitset<2> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
+  void SerializeSequence (std::bitset<3> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
+  void SerializeSequence (std::bitset<4> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
+  void SerializeSequence (std::bitset<5> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
+  void SerializeSequence (std::bitset<6> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
+  void SerializeSequence (std::bitset<9> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
+  void SerializeSequence (std::bitset<10> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
+  void SerializeSequence (std::bitset<11> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
+
+  template <int N>
+  void SerializeBitstring (std::bitset<N> bitstring) const;
+  void SerializeBitstring (std::bitset<1> bitstring) const;
+  void SerializeBitstring (std::bitset<8> bitstring) const;
+  void SerializeBitstring (std::bitset<10> bitstring) const;
+  void SerializeBitstring (std::bitset<16> bitstring) const;
+  void SerializeBitstring (std::bitset<27> bitstring) const;
+  void SerializeBitstring (std::bitset<28> bitstring) const;
+  void SerializeBitstring (std::bitset<32> bitstring) const;
+
+  // Deserialization functions
+  template <int N>
+  Buffer::Iterator DeserializeBitset (std::bitset<N> *data, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeBitset (std::bitset<8> *data, Buffer::Iterator bIterator);
+
+  Buffer::Iterator DeserializeBoolean (bool *value, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeInteger (int *n, int nmin, int nmax, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeChoice (int numOptions, int *selectedOption, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeEnum (int numElems, int *selectedElem, Buffer::Iterator bIterator);
+
+  template <int N>
+  Buffer::Iterator DeserializeSequence (std::bitset<N> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeSequence (std::bitset<0> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeSequence (std::bitset<1> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeSequence (std::bitset<2> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeSequence (std::bitset<3> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeSequence (std::bitset<4> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeSequence (std::bitset<5> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeSequence (std::bitset<6> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeSequence (std::bitset<9> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeSequence (std::bitset<10> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeSequence (std::bitset<11> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
+
+  template <int N>
+  Buffer::Iterator DeserializeBitstring (std::bitset<N> *bitstring, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeBitstring (std::bitset<1> *bitstring, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeBitstring (std::bitset<8> *bitstring, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeBitstring (std::bitset<10> *bitstring, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeBitstring (std::bitset<16> *bitstring, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeBitstring (std::bitset<27> *bitstring, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeBitstring (std::bitset<28> *bitstring, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeBitstring (std::bitset<32> *bitstring, Buffer::Iterator bIterator);
+
+  Buffer::Iterator DeserializeNull (Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeSequenceOf (int *numElems, int nMax, int nMin, Buffer::Iterator bIterator);
+};
+
+} // namespace ns3
+
+#endif // EPC_ASN1_HEADER_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-rrc-header.cc	Thu Nov 29 17:18:51 2012 +0100
@@ -0,0 +1,2586 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Lluis Parcerisa <lparcerisa@cttc.cat>
+ */
+
+#include "ns3/log.h"
+#include "ns3/lte-rrc-header.h"
+
+#include <stdio.h>
+#include <sstream>
+#include <math.h> // For log()
+
+#define MAX_DRB 11 // According to section 6.4 3GPP TS 36.331
+#define MAX_EARFCN 65535
+#define MAX_RAT_CAPABILITIES 8
+#define MAX_SI_MESSAGE 32
+#define MAX_SIB 32
+
+NS_LOG_COMPONENT_DEFINE ("RrcHeader");
+
+namespace ns3 {
+
+//////////////////// RrcAsn1Header class ///////////////////////////////
+RrcAsn1Header::RrcAsn1Header ()
+{
+}
+
+void
+RrcAsn1Header::SerializeDrbToAddModList (std::list<LteRrcSap::DrbToAddMod> drbToAddModList) const
+{
+  // Serialize DRB-ToAddModList sequence-of
+  SerializeSequenceOf (drbToAddModList.size (),MAX_DRB,1);
+
+  // Serialize the elements in the sequence-of list
+  std::list<LteRrcSap::DrbToAddMod>::iterator it = drbToAddModList.begin ();
+  for (; it != drbToAddModList.end (); it++)
+    {
+      // Serialize DRB-ToAddMod sequence
+      // 5 otional fields. Extension marker is present.
+      std::bitset<5> drbToAddModListOptionalFieldsPresent = std::bitset<5> ();
+      drbToAddModListOptionalFieldsPresent.set (4,1); // eps-BearerIdentity present
+      drbToAddModListOptionalFieldsPresent.set (3,0); // pdcp-Config not present
+      drbToAddModListOptionalFieldsPresent.set (2,1); // rlc-Config present
+      drbToAddModListOptionalFieldsPresent.set (1,1); // logicalChannelIdentity present
+      drbToAddModListOptionalFieldsPresent.set (0,1); // logicalChannelConfig present
+      SerializeSequence<5> (drbToAddModListOptionalFieldsPresent,true);
+
+      // Serialize eps-BearerIdentity::=INTEGER (0..15)
+      SerializeInteger (it->epsBearerIdentity,0,15);
+
+      // Serialize drb-Identity ::= INTEGER (1..32)
+      SerializeInteger (it->drbIdentity,1,32);
+
+      switch (it->rlcConfig.choice)
+        {
+        case LteRrcSap::RlcConfig::AM:
+          // Serialize rlc-Config choice
+          SerializeChoice (4,0);
+
+          // Serialize UL-AM-RLC
+          SerializeSequence<0> (std::bitset<0> (),false);
+          SerializeEnum (64,0);  // t-PollRetransmit
+          SerializeEnum (8,0);   // pollPDU
+          SerializeEnum (16,0);  // pollByte
+          SerializeEnum (8,0);   // maxRetxThreshold
+
+          // Serialize DL-AM-RLC
+          SerializeSequence<0> (std::bitset<0> (),false);
+          SerializeEnum (32,0);  // t-Reordering
+          SerializeEnum (64,0);  // t-StatusProhibit
+          break;
+
+        case LteRrcSap::RlcConfig::UM_BI_DIRECTIONAL:
+          // Serialize rlc-Config choice
+          SerializeChoice (4,1);
+
+          // Serialize UL-UM-RLC
+          SerializeSequence<0> (std::bitset<0> (),false);
+          SerializeEnum (2,0);  // sn-FieldLength
+
+          // Serialize DL-UM-RLC
+          SerializeSequence<0> (std::bitset<0> (),false);
+          SerializeEnum (2,0);  // sn-FieldLength
+          SerializeEnum (32,0);  // t-Reordering
+          break;
+
+        case LteRrcSap::RlcConfig::UM_UNI_DIRECTIONAL_UL:
+          // Serialize rlc-Config choice
+          SerializeChoice (4,2);
+
+          // Serialize UL-UM-RLC
+          SerializeSequence<0> (std::bitset<0> (),false);
+          SerializeEnum (2,0);  // sn-FieldLength
+          break;
+
+        case LteRrcSap::RlcConfig::UM_UNI_DIRECTIONAL_DL:
+          // Serialize rlc-Config choice
+          SerializeChoice (4,3);
+
+          // Serialize DL-UM-RLC
+          SerializeSequence<0> (std::bitset<0> (),false);
+          SerializeEnum (2,0);  // sn-FieldLength
+          SerializeEnum (32,0);  // t-Reordering
+          break;
+        }
+
+      // Serialize logicalChannelIdentity ::=INTEGER (3..10)
+      SerializeInteger (it->logicalChannelIdentity,3,10);
+
+      // Serialize logicalChannelConfig
+      SerializeLogicalChannelConfig (it->logicalChannelConfig);
+    }
+}
+
+void
+RrcAsn1Header::SerializeSrbToAddModList (std::list<LteRrcSap::SrbToAddMod> srbToAddModList) const
+{
+  // Serialize SRB-ToAddModList ::= SEQUENCE (SIZE (1..2)) OF SRB-ToAddMod
+  SerializeSequenceOf (srbToAddModList.size (),2,1);
+
+  // Serialize the elements in the sequence-of list
+  std::list<LteRrcSap::SrbToAddMod>::iterator it = srbToAddModList.begin ();
+  for (; it != srbToAddModList.end (); it++)
+    {
+      // Serialize SRB-ToAddMod sequence
+      // 2 otional fields. Extension marker is present.
+      std::bitset<2> srbToAddModListOptionalFieldsPresent = std::bitset<2> ();
+      srbToAddModListOptionalFieldsPresent.set (1,0); // rlc-Config not present
+      srbToAddModListOptionalFieldsPresent.set (0,1); // logicalChannelConfig present
+      SerializeSequence<2> (srbToAddModListOptionalFieldsPresent,true);
+
+      // Serialize srb-Identity ::= INTEGER (1..2)
+      SerializeInteger (it->srbIdentity,1,2);
+
+      // Serialize logicalChannelConfig choice
+      // 2 options, selected option 0 (var "explicitValue", of type LogicalChannelConfig)
+      SerializeChoice (2,0);
+
+      // Serialize LogicalChannelConfig 
+      SerializeLogicalChannelConfig (it->logicalChannelConfig);
+    }
+}
+
+void
+RrcAsn1Header::SerializeLogicalChannelConfig (LteRrcSap::LogicalChannelConfig logicalChannelConfig) const
+{
+  // Serialize LogicalChannelConfig sequence
+  // 1 optional field, which is present. No extension marker.
+  SerializeSequence<1> (std::bitset<1> (1),false);
+
+  // Serialize ul-SpecificParameters sequence
+  // no optional/default fields. No extension marker.
+  SerializeSequence<0> (std::bitset<0> (),false);
+
+  // Serialize priority ::= INTEGER (1..16)
+  SerializeInteger (logicalChannelConfig.priority,1,16);
+
+  // Serialize prioritisedBitRate
+  int prioritizedBitRate;
+  switch (logicalChannelConfig.prioritizedBitRateKbps)
+    {
+    case 0:
+      prioritizedBitRate = 0;
+      break;
+    case 8:
+      prioritizedBitRate = 1;
+      break;
+    case 16:
+      prioritizedBitRate = 2;
+      break;
+    case 32:
+      prioritizedBitRate = 3;
+      break;
+    case 64:
+      prioritizedBitRate = 4;
+      break;
+    case 128:
+      prioritizedBitRate = 5;
+      break;
+    case 256:
+      prioritizedBitRate = 6;
+      break;
+    default:
+      prioritizedBitRate = 7;          // Infinity
+    }
+  SerializeEnum (16,prioritizedBitRate);
+
+  // Serialize bucketSizeDuration
+  int bucketSizeDuration;
+  switch (logicalChannelConfig.bucketSizeDurationMs)
+    {
+    case 50:
+      bucketSizeDuration = 0;
+      break;
+    case 100:
+      bucketSizeDuration = 1;
+      break;
+    case 150:
+      bucketSizeDuration = 2;
+      break;
+    case 300:
+      bucketSizeDuration = 3;
+      break;
+    case 500:
+      bucketSizeDuration = 4;
+      break;
+    case 1000:
+      bucketSizeDuration = 5;
+      break;
+    default:
+      bucketSizeDuration = 5;
+    }
+  SerializeEnum (8,bucketSizeDuration);
+
+  // Serialize logicalChannelGroup ::= INTEGER (0..3)
+  SerializeInteger (logicalChannelConfig.logicalChannelGroup,0,3);
+}
+
+void
+RrcAsn1Header::SerializePhysicalConfigDedicated (LteRrcSap::PhysicalConfigDedicated physicalConfigDedicated) const
+{
+  // Serialize PhysicalConfigDedicated Sequence
+  std::bitset<10> optionalFieldsPhysicalConfigDedicated;
+  optionalFieldsPhysicalConfigDedicated.set (9,0);  // pdsch-ConfigDedicated not present
+  optionalFieldsPhysicalConfigDedicated.set (8,0);  // pucch-ConfigDedicated not present
+  optionalFieldsPhysicalConfigDedicated.set (7,0);  // pusch-ConfigDedicated not present
+  optionalFieldsPhysicalConfigDedicated.set (6,0);  // uplinkPowerControlDedicated not present
+  optionalFieldsPhysicalConfigDedicated.set (5,0);  // tpc-PDCCH-ConfigPUCCH not present
+  optionalFieldsPhysicalConfigDedicated.set (4,0);  // tpc-PDCCH-ConfigPUSCH not present
+  optionalFieldsPhysicalConfigDedicated.set (3,0);  // cqi-ReportConfig not present
+  optionalFieldsPhysicalConfigDedicated.set (2,physicalConfigDedicated.haveSoundingRsUlConfigDedicated);  // soundingRS-UL-ConfigDedicated
+  optionalFieldsPhysicalConfigDedicated.set (1,physicalConfigDedicated.haveAntennaInfoDedicated);  // antennaInfo
+  optionalFieldsPhysicalConfigDedicated.set (0,0);  // schedulingRequestConfig not present
+  SerializeSequence<10> (optionalFieldsPhysicalConfigDedicated,true);
+
+  if (physicalConfigDedicated.haveSoundingRsUlConfigDedicated)
+    {
+      // Serialize SoundingRS-UL-ConfigDedicated choice:
+      switch (physicalConfigDedicated.soundingRsUlConfigDedicated.type)
+        {
+        case LteRrcSap::SoundingRsUlConfigDedicated::RESET:
+          SerializeChoice (2,0);
+          SerializeNull ();
+          break;
+        case LteRrcSap::SoundingRsUlConfigDedicated::SETUP:
+          // 2 options, selected: 1 (setup)
+          SerializeChoice (2,1);
+
+          // Serialize setup sequence
+          // 0 optional / default fields, no extension marker.
+          SerializeSequence<0> (std::bitset<0> (),false);
+
+          // Serialize srs-Bandwidth
+          SerializeEnum (4,physicalConfigDedicated.soundingRsUlConfigDedicated.srsBandwidth);
+
+          // Serialize  srs-HoppingBandwidth
+          SerializeEnum (4,0);
+
+          // Serialize freqDomainPosition
+          SerializeInteger (0,0,23);
+
+          // Serialize duration
+          SerializeBoolean (false);
+
+          // Serialize srs-ConfigIndex
+          SerializeInteger (physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex,0,1023);
+
+          // Serialize transmissionComb
+          SerializeInteger (0,0,1);
+
+          // Serialize cyclicShift
+          SerializeEnum (8,0);
+
+          break;
+        }
+    }
+
+  if (physicalConfigDedicated.haveAntennaInfoDedicated)
+    {
+      // Serialize antennaInfo choice
+      // 2 options. Selected: 0 ("explicitValue" of type "AntennaInfoDedicated")
+      SerializeChoice (2,0);
+
+      // Serialize AntennaInfoDedicated sequence
+      // 1 optional parameter, not present. No extension marker.
+      SerializeSequence<1> (std::bitset<1> (0),false);
+
+      // Serialize transmissionMode
+      SerializeEnum (8,physicalConfigDedicated.antennaInfo.transmissionMode);
+
+      // Serialize ue-TransmitAntennaSelection choice
+      SerializeChoice (2,0);
+
+      // Serialize release
+      SerializeNull ();
+    }
+}
+
+void
+RrcAsn1Header::SerializeRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated radioResourceConfigDedicated) const
+{
+  // 6 optional fields. Extension marker is present.
+  std::bitset<6> optionalFieldsPresent = std::bitset<6> ();
+  optionalFieldsPresent.set (5,1);  // srb-ToAddModList present
+  optionalFieldsPresent.set (4,1);  // drb-ToAddModList present
+  optionalFieldsPresent.set (3,1);  // drb-ToReleaseList present
+  optionalFieldsPresent.set (2,0);  // mac-MainConfig not present
+  optionalFieldsPresent.set (1,0);  // sps-Config not present
+  optionalFieldsPresent.set (0,(radioResourceConfigDedicated.havePhysicalConfigDedicated) ? 1 : 0);
+  SerializeSequence<6> (optionalFieldsPresent,true);
+
+  // Serialize srbToAddModList
+  SerializeSrbToAddModList (radioResourceConfigDedicated.srbToAddModList);
+
+  // Serialize drbToAddModList
+  SerializeDrbToAddModList (radioResourceConfigDedicated.drbToAddModList);
+
+  // Serialize drbToReleaseList
+  SerializeSequenceOf (radioResourceConfigDedicated.drbToReleaseList.size (),MAX_DRB,1);
+  std::list<uint8_t>::iterator it = radioResourceConfigDedicated.drbToReleaseList.begin ();
+  for (; it != radioResourceConfigDedicated.drbToReleaseList.end (); it++)
+    {
+      // DRB-Identity ::= INTEGER (1..32)
+      SerializeInteger (*it,1,32);
+    }
+
+  if (radioResourceConfigDedicated.havePhysicalConfigDedicated)
+    {
+      SerializePhysicalConfigDedicated (radioResourceConfigDedicated.physicalConfigDedicated);
+    }
+}
+
+void
+RrcAsn1Header::SerializeSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 systemInformationBlockType1) const
+{
+  // 3 optional fields, no extension marker.
+  std::bitset<3> sysInfoBlk1Opts;
+  sysInfoBlk1Opts.set (2,0); // p-Max absent
+  sysInfoBlk1Opts.set (1,0); // tdd-Config absent
+  sysInfoBlk1Opts.set (0,0); // nonCriticalExtension absent
+  SerializeSequence (sysInfoBlk1Opts,false);
+
+  // Serialize cellAccessRelatedInfo
+  // 1 optional field (csgIdentity) which is present, no extension marker.
+  SerializeSequence (std::bitset<1> (1),false);
+
+  // Serialize plmn-IdentityList
+  SerializeSequenceOf (1,6,1);
+  // PLMN-IdentityInfo 
+  SerializeSequence (std::bitset<0> (),false);
+  // plmn-Identity sequence, mcc is optional, no extension marker
+  SerializeSequence (std::bitset<1> (0), false);
+  // Serialize mnc
+  int x = systemInformationBlockType1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity;
+  int nDig = (x > 99) ? 3 : 2;
+
+  SerializeSequenceOf (nDig,3,2);
+  for (int i = nDig - 1; i >= 0; i--)
+    {
+      int n = floor (x / pow (10,i));
+      SerializeInteger (n,0,9);
+      x -= n * pow (10,i);
+    }
+  // cellReservedForOperatorUse 
+  SerializeEnum (2,0);
+
+  // Serialize trackingAreaCode
+  SerializeBitstring (std::bitset<16> (0));
+  // Serialize cellIdentity
+  SerializeBitstring (std::bitset<28> (systemInformationBlockType1.cellAccessRelatedInfo.cellIdentity));
+  // Serialize cellBarred
+  SerializeEnum (2,0);
+  // Serialize intraFreqReselection
+  SerializeEnum (2,0);
+  // Serialize csg-Indication
+  SerializeBoolean (systemInformationBlockType1.cellAccessRelatedInfo.csgIndication);
+  // Serialize csg-Identity
+  SerializeBitstring (std::bitset<27> (systemInformationBlockType1.cellAccessRelatedInfo.csgIdentity));
+
+  // Serialize cellSelectionInfo
+  SerializeSequence (std::bitset<1> (0),false);
+  // Serialize q-RxLevMin
+  SerializeInteger (-50,-70,-22);
+
+  // Serialize freqBandIndicator
+  SerializeInteger (1,1,64);
+
+  // Serialize schedulingInfoList
+  SerializeSequenceOf (1,MAX_SI_MESSAGE,1);
+  // SchedulingInfo
+  SerializeSequence (std::bitset<0> (),false);
+  // si-Periodicity
+  SerializeEnum (7,0);
+  // sib-MappingInfo
+  SerializeSequenceOf (0,MAX_SIB - 1,0);
+
+  // Serialize si-WindowLength
+  SerializeEnum (7,0);
+
+  // Serialize systemInfoValueTag
+  SerializeInteger (0,0,31);
+}
+
+void
+RrcAsn1Header::SerializeRadioResourceConfigCommonSIB () const
+{
+  SerializeSequence (std::bitset<0> (0),true);
+  // rach-ConfigCommon
+  SerializeSequence (std::bitset<0> (0),true);
+  SerializeSequence (std::bitset<1> (0),false); // preambleInfo
+  SerializeEnum (16,0); // numberOfRA-Preambles
+  SerializeSequence (std::bitset<0> (0),false); // powerRampingParameters
+  SerializeEnum (4,0); // powerRampingStep
+  SerializeEnum (16,0); // preambleInitialReceivedTargetPower
+  SerializeSequence (std::bitset<0> (0),false); // ra-SupervisionInfo
+  SerializeEnum (11,0); // preambleTransMax
+  SerializeEnum (8,0); // ra-ResponseWindowSize
+  SerializeEnum (8,0); // mac-ContentionResolutionTimer
+  SerializeInteger (1,1,8); // maxHARQ-Msg3Tx
+  // bcch-Config 
+  SerializeSequence (std::bitset<0> (0),false);
+  SerializeEnum (4,0); // modificationPeriodCoeff
+  // pcch-Config 
+  SerializeSequence (std::bitset<0> (0),false);
+  SerializeEnum (4,0); // defaultPagingCycle
+  SerializeEnum (8,0); // nB
+  // prach-Config 
+  SerializeSequence (std::bitset<1> (0),false);
+  SerializeInteger (0,0,1023); // rootSequenceIndex
+  // pdsch-ConfigCommon 
+  SerializeSequence (std::bitset<0> (0),false);
+  SerializeInteger (0,-60,50); // referenceSignalPower
+  SerializeInteger (0,0,3); // p-b
+  // pusch-ConfigCommon 
+  SerializeSequence (std::bitset<0> (0),false);
+  SerializeSequence (std::bitset<0> (0),false); // pusch-ConfigBasic
+  SerializeInteger (1,1,4); // n-SB
+  SerializeEnum (2,0); // hoppingMode
+  SerializeInteger (0,0,98); // pusch-HoppingOffset
+  SerializeBoolean (false); // enable64QAM
+  SerializeSequence (std::bitset<0> (0),false); // UL-ReferenceSignalsPUSCH
+  SerializeBoolean (false); // groupHoppingEnabled
+  SerializeInteger (0,0,29); // groupAssignmentPUSCH
+  SerializeBoolean (false); // sequenceHoppingEnabled
+  SerializeInteger (0,0,7); // cyclicShift
+  // pucch-ConfigCommon 
+  SerializeSequence (std::bitset<0> (0),false);
+  SerializeEnum (3,0); // deltaPUCCH-Shift
+  SerializeInteger (0,0,98); // nRB-CQI
+  SerializeInteger (0,0,7); // nCS-AN
+  SerializeInteger (0,0,2047); // n1PUCCH-AN
+  // soundingRS-UL-ConfigCommon 
+  SerializeChoice (2,0);
+  SerializeNull (); // release
+  // uplinkPowerControlCommon 
+  SerializeSequence (std::bitset<0> (0),false);
+  SerializeInteger (0,-126,24); // p0-NominalPUSCH
+  SerializeEnum (8,0); // alpha
+  SerializeInteger (-50,-127,-96); // p0-NominalPUCCH
+  SerializeSequence (std::bitset<0> (0),false); // deltaFList-PUCCH
+  SerializeEnum (3,0); // deltaF-PUCCH-Format1
+  SerializeEnum (3,0); // deltaF-PUCCH-Format1b
+  SerializeEnum (4,0); // deltaF-PUCCH-Format2
+  SerializeEnum (3,0); // deltaF-PUCCH-Format2a
+  SerializeEnum (3,0); // deltaF-PUCCH-Format2b
+  SerializeInteger (0,-1,6);
+  // ul-CyclicPrefixLength 
+  SerializeEnum (2,0);
+}
+
+void
+RrcAsn1Header::SerializeSystemInformationBlockType2 () const
+{
+  SerializeSequence (std::bitset<2> (0),true);
+
+  // RadioResourceConfigCommonSIB
+  SerializeRadioResourceConfigCommonSIB ();
+
+  // ue-TimersAndConstants
+  SerializeSequence (std::bitset<0> (0),true);
+  SerializeEnum (8,0); // t300
+  SerializeEnum (8,0); // t301
+  SerializeEnum (7,0); // t310
+  SerializeEnum (8,0); // n310
+  SerializeEnum (7,0); // t311
+  SerializeEnum (8,0); // n311
+  // freqInfo
+  SerializeSequence (std::bitset<2> (0),false);
+  SerializeInteger (29,1,32); // additionalSpectrumEmission
+  // timeAlignmentTimerCommon
+  SerializeEnum (8,0);
+}
+
+Buffer::Iterator
+RrcAsn1Header::DeserializeRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated *radioResourceConfigDedicated, Buffer::Iterator bIterator)
+{
+  // Deserialize RadioResourceConfigDedicated sequence
+  std::bitset<6> optionalFieldsPresent = std::bitset<6> ();
+  bIterator = DeserializeSequence (&optionalFieldsPresent,true,bIterator);
+
+  if (optionalFieldsPresent[5])
+    {
+      // Deserialize srb-ToAddModList
+      bIterator = DeserializeSrbToAddModList (&(radioResourceConfigDedicated->srbToAddModList),bIterator);
+    }
+
+  if (optionalFieldsPresent[4])
+    {
+      // Deserialize drb-ToAddModList
+      bIterator = DeserializeDrbToAddModList (&(radioResourceConfigDedicated->drbToAddModList),bIterator);
+    }
+
+  if (optionalFieldsPresent[3])
+    {
+      // Deserialize drb-ToReleaseList
+      int n;
+      int val;
+      bIterator = DeserializeSequenceOf (&n,MAX_DRB,1,bIterator);
+      for (int i = 0; i < n; i++)
+        {
+          bIterator = DeserializeInteger (&val,1,32,bIterator);
+          radioResourceConfigDedicated->drbToReleaseList.push_back (val);
+        }
+    }
+
+  if (optionalFieldsPresent[2])
+    {
+      // Deserialize mac-MainConfig
+      // ...
+    }
+
+  if (optionalFieldsPresent[1])
+    {
+      // Deserialize sps-Config
+      // ...
+    }
+
+  radioResourceConfigDedicated->havePhysicalConfigDedicated = optionalFieldsPresent[0];
+  if (optionalFieldsPresent[0])
+    {
+      // Deserialize physicalConfigDedicated
+      bIterator = DeserializePhysicalConfigDedicated (&radioResourceConfigDedicated->physicalConfigDedicated,bIterator);
+    }
+
+  return bIterator;
+}
+
+Buffer::Iterator
+RrcAsn1Header::DeserializeSrbToAddModList (std::list<LteRrcSap::SrbToAddMod> *srbToAddModList, Buffer::Iterator bIterator)
+{
+  int numElems;
+  bIterator = DeserializeSequenceOf (&numElems,2,1,bIterator);
+
+  srbToAddModList->clear ();
+
+  // Deserialize SRB-ToAddMod elements
+  for (int i = 0; i < numElems; i++)
+    {
+      LteRrcSap::SrbToAddMod srbToAddMod;
+      // Deserialize SRB-ToAddMod sequence
+      // 2 optional fields, extension marker present
+      std::bitset<2> optionalFields;
+      bIterator = DeserializeSequence (&optionalFields,true,bIterator);
+
+      // Deserialize srbIdentity
+      int n;
+      bIterator = DeserializeInteger (&n,1,2,bIterator);
+      srbToAddMod.srbIdentity = n;
+
+      if (optionalFields[1])
+        {
+          // Deserialize rlcConfig choice
+          // ...
+        }
+
+      if (optionalFields[0])
+        {
+          // Deserialize logicalChannelConfig choice
+          int sel;
+          bIterator = DeserializeChoice (2,&sel,bIterator);
+
+          // Deserialize logicalChannelConfig defaultValue
+          if (sel == 1)
+            {
+              bIterator = DeserializeNull (bIterator);
+            }
+
+          // Deserialize logicalChannelConfig explicitValue
+          else if (sel == 0)
+            {
+              bIterator = DeserializeLogicalChannelConfig (&srbToAddMod.logicalChannelConfig,bIterator);
+            }
+        }
+      srbToAddModList->insert (srbToAddModList->end (),srbToAddMod);
+    }
+
+  return bIterator;
+}
+
+Buffer::Iterator
+RrcAsn1Header::DeserializeDrbToAddModList (std::list<LteRrcSap::DrbToAddMod> *drbToAddModList, Buffer::Iterator bIterator)
+{
+  int n;
+  int val;
+  bIterator = DeserializeSequenceOf (&n,MAX_DRB,1,bIterator);
+
+  drbToAddModList->clear ();
+
+  for (int i = 0; i < n; i++)
+    {
+      LteRrcSap::DrbToAddMod drbToAddMod;
+
+      std::bitset<5> optionalFields;
+      bIterator = DeserializeSequence (&optionalFields,true,bIterator);
+
+      if (optionalFields[4])
+        {
+          // Deserialize epsBearerIdentity
+          bIterator = DeserializeInteger (&val,0,15,bIterator);
+          drbToAddMod.epsBearerIdentity = val;
+        }
+
+      bIterator = DeserializeInteger (&val,1,32,bIterator);
+      drbToAddMod.drbIdentity = val;
+
+      if (optionalFields[3])
+        {
+          // Deserialize pdcp-Config
+          // ...
+        }
+
+      if (optionalFields[2])
+        {
+          // Deserialize RLC-Config
+          int chosen;
+          bIterator = DeserializeChoice (4,&chosen,bIterator);
+
+          int sel;
+          std::bitset<0> bitset0;
+          switch (chosen)
+            {
+            case 0:
+              drbToAddMod.rlcConfig.choice = LteRrcSap::RlcConfig::AM;
+
+              // Deserialize UL-AM-RLC
+              bIterator = DeserializeSequence<0> (&bitset0,false, bIterator);
+              bIterator = DeserializeEnum (64,&sel, bIterator); // t-PollRetransmit
+              bIterator = DeserializeEnum (8,&sel, bIterator); // pollPDU
+              bIterator = DeserializeEnum (16,&sel, bIterator); // pollByte
+              bIterator = DeserializeEnum (8,&sel, bIterator); // maxRetxThreshold
+
+              // Deserialize DL-AM-RLC
+              bIterator = DeserializeSequence<0> (&bitset0,false, bIterator);
+              bIterator = DeserializeEnum (32,&sel, bIterator); // t-Reordering
+              bIterator = DeserializeEnum (64,&sel, bIterator); // t-StatusProhibit
+              break;
+
+            case 1:
+              drbToAddMod.rlcConfig.choice = LteRrcSap::RlcConfig::UM_BI_DIRECTIONAL;
+
+              // Deserialize UL-UM-RLC
+              bIterator = DeserializeSequence<0> (&bitset0,false, bIterator);
+              bIterator = DeserializeEnum (2,&sel, bIterator); // sn-FieldLength
+
+              // Deserialize DL-UM-RLC
+              bIterator = DeserializeSequence<0> (&bitset0,false, bIterator);
+              bIterator = DeserializeEnum (2,&sel, bIterator); // sn-FieldLength
+              bIterator = DeserializeEnum (32,&sel, bIterator); // t-Reordering
+              break;
+
+            case 2:
+              drbToAddMod.rlcConfig.choice = LteRrcSap::RlcConfig::UM_UNI_DIRECTIONAL_UL;
+
+              // Deserialize UL-UM-RLC
+              bIterator = DeserializeSequence<0> (&bitset0,false, bIterator);
+              bIterator = DeserializeEnum (2,&sel, bIterator); // sn-FieldLength
+              break;
+
+            case 3:
+              drbToAddMod.rlcConfig.choice = LteRrcSap::RlcConfig::UM_UNI_DIRECTIONAL_DL;
+
+              // Deserialize DL-UM-RLC
+              bIterator = DeserializeSequence<0> (&bitset0,false, bIterator);
+              bIterator = DeserializeEnum (2,&sel, bIterator); // sn-FieldLength
+              bIterator = DeserializeEnum (32,&sel, bIterator); // t-Reordering
+              break;
+            }
+
+        }
+
+      if (optionalFields[1])
+        {
+          bIterator = DeserializeInteger (&val,3,10,bIterator);
+          drbToAddMod.logicalChannelIdentity = val;
+        }
+
+      if (optionalFields[0])
+        {
+          bIterator = DeserializeLogicalChannelConfig (&drbToAddMod.logicalChannelConfig,bIterator);
+        }
+
+      drbToAddModList->insert (drbToAddModList->end (),drbToAddMod);
+    }
+  return bIterator;
+}
+
+Buffer::Iterator
+RrcAsn1Header::DeserializeLogicalChannelConfig (LteRrcSap::LogicalChannelConfig *logicalChannelConfig, Buffer::Iterator bIterator)
+{
+  int n;
+
+  // Deserialize LogicalChannelConfig sequence
+  // 1 optional field, no extension marker.
+  std::bitset<1> bitset1;
+  bIterator = DeserializeSequence (&bitset1,false,bIterator);
+
+  if (bitset1[0])
+    {
+      // Deserialize ul-SpecificParameters sequence
+      std::bitset<0> bitset0;
+      bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+      // Deserialize priority
+      bIterator = DeserializeInteger (&n,1,16,bIterator);
+      logicalChannelConfig->priority = n;
+
+      // Deserialize prioritisedBitRate
+      bIterator = DeserializeEnum (16,&n,bIterator);
+      uint16_t prioritizedBitRateKbps;
+
+      switch (n)
+        {
+        case 0:
+          prioritizedBitRateKbps = 0;
+          break;
+        case 1:
+          prioritizedBitRateKbps = 8;
+          break;
+        case 2:
+          prioritizedBitRateKbps = 16;
+          break;
+        case 3:
+          prioritizedBitRateKbps = 32;
+          break;
+        case 4:
+          prioritizedBitRateKbps = 64;
+          break;
+        case 5:
+          prioritizedBitRateKbps = 128;
+          break;
+        case 6:
+          prioritizedBitRateKbps = 256;
+          break;
+        case 7:
+          prioritizedBitRateKbps = 10000;
+          break;
+        }
+      logicalChannelConfig->prioritizedBitRateKbps = prioritizedBitRateKbps;
+
+      // Deserialize bucketSizeDuration
+      bIterator = DeserializeEnum (8,&n,bIterator);
+      uint16_t bucketSizeDurationMs;
+      switch (n)
+        {
+        case 0:
+          bucketSizeDurationMs = 50;
+          break;
+        case 1:
+          bucketSizeDurationMs = 100;
+          break;
+        case 2:
+          bucketSizeDurationMs = 150;
+          break;
+        case 3:
+          bucketSizeDurationMs = 300;
+          break;
+        case 4:
+          bucketSizeDurationMs = 500;
+          break;
+        case 5:
+          bucketSizeDurationMs = 1000;
+          break;
+        }
+      logicalChannelConfig->bucketSizeDurationMs = bucketSizeDurationMs;
+
+      // Deserialize logicalChannelGroup
+      bIterator = DeserializeInteger (&n,0,3,bIterator);
+      logicalChannelConfig->logicalChannelGroup = n;
+    }
+  return bIterator;
+}
+
+Buffer::Iterator
+RrcAsn1Header::DeserializePhysicalConfigDedicated (LteRrcSap::PhysicalConfigDedicated *physicalConfigDedicated, Buffer::Iterator bIterator)
+{
+  std::bitset<10> optionalFieldPresent;
+  bIterator = DeserializeSequence (&optionalFieldPresent,true,bIterator);
+
+  if (optionalFieldPresent[9])
+    {
+      // Deserialize pdsch-ConfigDedicated
+      // ...
+    }
+  if (optionalFieldPresent[8])
+    {
+      // Deserialize pucch-ConfigDedicated
+      // ...
+    }
+  if (optionalFieldPresent[7])
+    {
+      // Deserialize pusch-ConfigDedicated
+      // ...
+    }
+  if (optionalFieldPresent[6])
+    {
+      // Deserialize uplinkPowerControlDedicated
+      // ...
+    }
+  if (optionalFieldPresent[5])
+    {
+      // Deserialize tpc-PDCCH-ConfigPUCCH
+      // ...
+    }
+  if (optionalFieldPresent[4])
+    {
+      // Deserialize tpc-PDCCH-ConfigPUSCH
+      // ...
+    }
+  if (optionalFieldPresent[3])
+    {
+      // Deserialize cqi-ReportConfig
+      // ...
+    }
+  physicalConfigDedicated->haveSoundingRsUlConfigDedicated = optionalFieldPresent[2];
+  if (optionalFieldPresent[2])
+    {
+      // Deserialize soundingRS-UL-ConfigDedicated
+      int sel;
+      bIterator = DeserializeChoice (2,&sel,bIterator);
+
+      if (sel == 0)
+        {
+          physicalConfigDedicated->soundingRsUlConfigDedicated.type = LteRrcSap::SoundingRsUlConfigDedicated::RESET;
+
+          bIterator = DeserializeNull (bIterator);
+        }
+
+      else if (sel == 1)
+        {
+          physicalConfigDedicated->soundingRsUlConfigDedicated.type = LteRrcSap::SoundingRsUlConfigDedicated::SETUP;
+
+          std::bitset<0> bitset0;
+          bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+          int slct;
+
+          // Deserialize srs-Bandwidth
+          bIterator = DeserializeEnum (4,&slct,bIterator);
+          physicalConfigDedicated->soundingRsUlConfigDedicated.srsBandwidth = slct;
+
+          // Deserialize srs-HoppingBandwidth
+          bIterator = DeserializeEnum (4,&slct,bIterator);
+
+          // Deserialize freqDomainPosition
+          bIterator = DeserializeInteger (&slct,0,23,bIterator);
+
+          // Deserialize duration
+          bool duration;
+          bIterator = DeserializeBoolean (&duration,bIterator);
+
+          // Deserialize srs-ConfigIndex
+          bIterator = DeserializeInteger (&slct,0,1023,bIterator);
+          physicalConfigDedicated->soundingRsUlConfigDedicated.srsConfigIndex = slct;
+
+          // Deserialize transmissionComb
+          bIterator = DeserializeInteger (&slct,0,1,bIterator);
+
+          // Deserialize cyclicShift
+          bIterator = DeserializeEnum (8,&slct,bIterator);
+        }
+    }
+  physicalConfigDedicated->haveAntennaInfoDedicated = optionalFieldPresent[1];
+  if (optionalFieldPresent[1])
+    {
+      // Deserialize antennaInfo
+      int sel;
+      bIterator = DeserializeChoice (2,&sel,bIterator);
+      if (sel == 1)
+        {
+          bIterator = DeserializeNull (bIterator);
+        }
+      else if (sel == 0)
+        {
+          std::bitset<1> codebookSubsetRestrictionPresent;
+          bIterator = DeserializeSequence (&codebookSubsetRestrictionPresent,false,bIterator);
+
+          int txmode;
+          bIterator = DeserializeEnum (8,&txmode,bIterator);
+          physicalConfigDedicated->antennaInfo.transmissionMode = txmode;
+
+          if (codebookSubsetRestrictionPresent[0])
+            {
+              // Deserialize codebookSubsetRestriction
+              // ...
+            }
+
+          int txantennaselchosen;
+          bIterator = DeserializeChoice (2,&txantennaselchosen,bIterator);
+          if (txantennaselchosen == 0)
+            {
+              // Deserialize ue-TransmitAntennaSelection release
+              bIterator = DeserializeNull (bIterator);
+            }
+          else if (txantennaselchosen == 1)
+            {
+              // Deserialize ue-TransmitAntennaSelection setup
+              // ...
+            }
+        }
+    }
+  if (optionalFieldPresent[0])
+    {
+      // Deserialize schedulingRequestConfig
+      // ...
+    }
+  return bIterator;
+}
+
+void
+RrcAsn1Header::Print (std::ostream &os, LteRrcSap::RadioResourceConfigDedicated radioResourceConfigDedicated) const
+{
+  os << "   srbToAddModList: " << std::endl;
+  std::list<LteRrcSap::SrbToAddMod>::iterator it = radioResourceConfigDedicated.srbToAddModList.begin ();
+  for (; it != radioResourceConfigDedicated.srbToAddModList.end (); it++)
+    {
+      os << "      srbIdentity: " << (int)it->srbIdentity << std::endl;
+      os << "      logicalChannelConfig: " << std::endl;
+      os << "         priority: " <<  (int)it->logicalChannelConfig.priority << std::endl;
+      os << "         prioritizedBitRateKbps: " <<  (int)it->logicalChannelConfig.prioritizedBitRateKbps << std::endl;
+      os << "         bucketSizeDurationMs: " <<  (int)it->logicalChannelConfig.bucketSizeDurationMs << std::endl;
+      os << "         logicalChannelGroup: " <<  (int)it->logicalChannelConfig.logicalChannelGroup << std::endl;
+    }
+  os << std::endl;
+
+  os << "   drbToAddModList: " << std::endl;
+  std::list<LteRrcSap::DrbToAddMod>::iterator it2 = radioResourceConfigDedicated.drbToAddModList.begin ();
+  for (; it2 != radioResourceConfigDedicated.drbToAddModList.end (); it2++)
+    {
+      os << "      epsBearerIdentity: " << (int)it2->epsBearerIdentity << std::endl;
+      os << "      drbIdentity: " << (int)it2->drbIdentity << std::endl;
+      os << "      rlcConfig: " << it2->rlcConfig.choice << std::endl;
+      os << "      logicalChannelIdentity: " << (int)it2->logicalChannelIdentity << std::endl;
+      os << "      logicalChannelConfig: " << std::endl;
+      os << "         priority: " <<  (int)it2->logicalChannelConfig.priority << std::endl;
+      os << "         prioritizedBitRateKbps: " <<  (int)it2->logicalChannelConfig.prioritizedBitRateKbps << std::endl;
+      os << "         bucketSizeDurationMs: " <<  (int)it2->logicalChannelConfig.bucketSizeDurationMs << std::endl;
+      os << "         logicalChannelGroup: " <<  (int)it2->logicalChannelConfig.logicalChannelGroup << std::endl;
+    }
+  os << std::endl;
+
+  os << "   drbToReleaseList: ";
+  std::list<uint8_t>::iterator it3 = radioResourceConfigDedicated.drbToReleaseList.begin ();
+  for (; it3 != radioResourceConfigDedicated.drbToReleaseList.end (); it3++)
+    {
+      os << (int)*it3 << ", ";
+    }
+  os << std::endl;
+
+  os << "   havePhysicalConfigDedicated: " << radioResourceConfigDedicated.havePhysicalConfigDedicated << std::endl;
+
+  if (radioResourceConfigDedicated.havePhysicalConfigDedicated)
+    {
+      os << "   physicalConfigDedicated: " << std::endl;
+
+      os << "      haveSoundingRsUlConfigDedicated: " << radioResourceConfigDedicated.physicalConfigDedicated.haveSoundingRsUlConfigDedicated << std::endl;
+      if (radioResourceConfigDedicated.physicalConfigDedicated.haveSoundingRsUlConfigDedicated)
+        {
+          os << "      soundingRsUlConfigDedicated: " << std::endl;
+          os << "         type: " << radioResourceConfigDedicated.physicalConfigDedicated.soundingRsUlConfigDedicated.type << std::endl;
+          os << "         srsBandwidth: " << (int)radioResourceConfigDedicated.physicalConfigDedicated.soundingRsUlConfigDedicated.srsBandwidth << std::endl;
+          os << "         srsConfigIndex: " << (int)radioResourceConfigDedicated.physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex << std::endl;
+        }
+
+      os << "      haveAntennaInfoDedicated: " << radioResourceConfigDedicated.physicalConfigDedicated.haveAntennaInfoDedicated << std::endl;
+      if (radioResourceConfigDedicated.physicalConfigDedicated.haveAntennaInfoDedicated)
+        {
+          os << "      antennaInfo Tx mode: " << (int)radioResourceConfigDedicated.physicalConfigDedicated.antennaInfo.transmissionMode << std::endl;
+        }
+    }
+}
+
+Buffer::Iterator
+RrcAsn1Header::DeserializeSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 *systemInformationBlockType1, Buffer::Iterator bIterator)
+{
+  std::bitset<0> bitset0;
+  int n;
+
+  std::bitset<3> sysInfoBlkT1Opts;
+  bIterator = DeserializeSequence (&sysInfoBlkT1Opts,false,bIterator);
+
+  // Deserialize cellAccessRelatedInfo
+  std::bitset<1> cellAccessRelatedInfoOpts;
+  bIterator = DeserializeSequence (&cellAccessRelatedInfoOpts,false,bIterator);
+
+  // Deserialize plmn-IdentityList
+  int numPlmnIdentityInfoElements;
+  bIterator = DeserializeSequenceOf (&numPlmnIdentityInfoElements,6,1,bIterator);
+  for (int i = 0; i < numPlmnIdentityInfoElements; i++)
+    {
+      bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+      // plmn-Identity
+      std::bitset<1> isMccPresent;
+      bIterator = DeserializeSequence (&isMccPresent,false,bIterator);
+      if (isMccPresent[0])
+        {
+          // Deserialize mcc
+          // ...
+        }
+      // Deserialize mnc
+      int mncDigits;
+      int mnc = 0;
+      bIterator = DeserializeSequenceOf (&mncDigits,3,2,bIterator);
+
+      for (int j = mncDigits - 1; j >= 0; j--)
+        {
+          bIterator = DeserializeInteger (&n,0,9,bIterator);
+          mnc += n * pow (10,j);
+        }
+      systemInformationBlockType1->cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity = mnc;
+
+      // cellReservedForOperatorUse
+      bIterator = DeserializeEnum (2,&n,bIterator);
+    }
+
+  // Deserialize trackingAreaCode
+  std::bitset<16> trackingAreaCode;
+  bIterator = DeserializeBitstring (&trackingAreaCode,bIterator);
+
+  // Deserialize cellIdentity
+  std::bitset<28> cellIdentity;
+  bIterator = DeserializeBitstring (&cellIdentity,bIterator);
+  systemInformationBlockType1->cellAccessRelatedInfo.cellIdentity = cellIdentity.to_ulong ();
+
+  // Deserialize cellBarred
+  bIterator = DeserializeEnum (2,&n,bIterator);
+
+  // Deserialize intraFreqReselection
+  bIterator = DeserializeEnum (2,&n,bIterator);
+
+  // Deserialize csg-Indication
+  bIterator = DeserializeBoolean (&systemInformationBlockType1->cellAccessRelatedInfo.csgIndication,bIterator);
+
+  if (cellAccessRelatedInfoOpts[0])
+    {
+      // Deserialize csg-Identity
+      std::bitset<27> csgIdentity;
+      bIterator = DeserializeBitstring (&csgIdentity,bIterator);
+      systemInformationBlockType1->cellAccessRelatedInfo.csgIdentity = csgIdentity.to_ulong ();
+    }
+
+  // Deserialize cellSelectionInfo
+  std::bitset<1> qRxLevMinOffsetPresent;
+  bIterator = DeserializeSequence (&qRxLevMinOffsetPresent,false,bIterator);
+  bIterator = DeserializeInteger (&n,-70,-22,bIterator); //q-RxLevMin
+  if (qRxLevMinOffsetPresent[0])
+    {
+      // Deserialize qRxLevMinOffset
+      // ...
+    }
+
+  if (sysInfoBlkT1Opts[2])
+    {
+      // Deserialize p-Max
+      // ...
+    }
+
+  // freqBandIndicator
+  bIterator = DeserializeInteger (&n,1,64,bIterator);
+
+  // schedulingInfoList
+  int numSchedulingInfo;
+  bIterator = DeserializeSequenceOf (&numSchedulingInfo,MAX_SI_MESSAGE,1,bIterator);
+  for (int i = 0; i < numSchedulingInfo; i++)
+    {
+      bIterator = DeserializeSequence (&bitset0,false,bIterator);
+      bIterator = DeserializeEnum (7,&n,bIterator); // si-Periodicity
+      int numSibType;
+      bIterator = DeserializeSequenceOf (&numSibType,MAX_SIB - 1,0, bIterator); // sib-MappingInfo
+      for (int j = 0; j < numSibType; j++)
+        {
+          bIterator = DeserializeEnum (16,&n,bIterator); // SIB-Type
+        }
+    }
+
+  if (sysInfoBlkT1Opts[1])
+    {
+      // tdd-Config
+      // ...
+    }
+
+  // si-WindowLength
+  bIterator = DeserializeEnum (7,&n,bIterator);
+
+  // systemInfoValueTag
+  bIterator = DeserializeInteger (&n,0,31,bIterator);
+
+  if (sysInfoBlkT1Opts[0])
+    {
+      // Deserialize nonCriticalExtension
+      // ...
+    }
+  return bIterator;
+}
+
+Buffer::Iterator
+RrcAsn1Header::DeserializeSystemInformationBlockType2 (Buffer::Iterator bIterator)
+{
+  std::bitset<0> bitset0;
+  int n;
+
+  std::bitset<2> sysInfoBlkT2Opts;
+  bIterator = DeserializeSequence (&sysInfoBlkT2Opts,true,bIterator);
+  if (sysInfoBlkT2Opts[1])
+    {
+      // Deserialize ac-BarringInfo
+      // ...
+    }
+
+  // Deserialize radioResourceConfigCommon
+  bIterator = DeserializeRadioResourceConfigCommonSib (bIterator);
+
+  // Deserialize ue-TimersAndConstants
+  bIterator = DeserializeSequence (&bitset0,true,bIterator);
+  bIterator = DeserializeEnum (8,&n,bIterator); // t300
+  bIterator = DeserializeEnum (8,&n,bIterator); // t301
+  bIterator = DeserializeEnum (7,&n,bIterator); // t310
+  bIterator = DeserializeEnum (8,&n,bIterator); // n310
+  bIterator = DeserializeEnum (7,&n,bIterator); // t311
+  bIterator = DeserializeEnum (8,&n,bIterator); // n311
+
+  // Deserialize freqInfo
+  std::bitset<2> freqInfoOpts;
+  bIterator = DeserializeSequence (&freqInfoOpts,false,bIterator);
+  if (freqInfoOpts[1])
+    {
+      // Deserialize ul-CarrierFreq
+      // ...
+    }
+  if (freqInfoOpts[0])
+    {
+      // Deserialize ul-Bandwidth
+      // ...
+    }
+  bIterator = DeserializeInteger (&n,1,32,bIterator); // additionalSpectrumEmission
+
+  if (sysInfoBlkT2Opts[0])
+    {
+      // Deserialize mbsfn-SubframeConfigList
+      // ...
+    }
+
+  // Deserialize timeAlignmentTimerCommon
+  bIterator = DeserializeEnum (8,&n,bIterator);
+
+  return bIterator;
+}
+
+
+Buffer::Iterator
+RrcAsn1Header::DeserializeRadioResourceConfigCommon (Buffer::Iterator bIterator)
+{
+  std::bitset<0> bitset0;
+  int n;
+
+  std::bitset<9> rrCfgCommOptions;
+  bIterator = DeserializeSequence (&rrCfgCommOptions,true,bIterator);
+
+  // rach-ConfigCommon
+  if (rrCfgCommOptions[8])
+    {
+      // ...
+    }
+
+  // prach-Config
+  std::bitset<1> prachConfigInfoPresent;
+  bIterator = DeserializeSequence (&prachConfigInfoPresent,false,bIterator);
+
+  // prach-Config -> rootSequenceIndex
+  bIterator = DeserializeInteger (&n,0,1023,bIterator);
+
+  // prach-Config -> prach-ConfigInfo
+  if (prachConfigInfoPresent[0])
+    {
+      // ...
+    }
+
+  // pdsch-ConfigCommon
+  if (rrCfgCommOptions[7])
+    {
+      // ...
+    }
+
+  // pusch-ConfigCommon
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+  // pusch-ConfigCommon -> pusch-ConfigBasic
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+  // pusch-ConfigCommon -> pusch-ConfigBasic -> n-SB
+  bIterator = DeserializeInteger (&n,1,4,bIterator);
+
+  // pusch-ConfigCommon -> pusch-ConfigBasic -> hoppingMode
+  bIterator = DeserializeEnum (2,&n,bIterator);
+
+  // pusch-ConfigCommon -> pusch-ConfigBasic -> pusch-HoppingOffset
+  bIterator = DeserializeInteger (&n,0,98,bIterator);
+
+  // pusch-ConfigCommon -> pusch-ConfigBasic -> enable64QAM
+  bool enable64QAM;
+  bIterator = DeserializeBoolean (&enable64QAM,bIterator);
+
+  // ul-ReferenceSignalsPUSCH
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+  // groupHoppingEnabled
+  bool dummyBool;
+  bIterator = DeserializeBoolean (&dummyBool,bIterator);
+
+  // groupAssignmentPUSCH
+  bIterator = DeserializeInteger (&n,0,29,bIterator);
+
+  // sequenceHoppingEnabled
+  bIterator = DeserializeBoolean (&dummyBool,bIterator);
+
+  // cyclicShift
+  bIterator = DeserializeInteger (&n,0,7,bIterator);
+
+  // phich-Config
+  if (rrCfgCommOptions[6])
+    {
+      // ...
+    }
+
+  // pucch-ConfigCommon
+  if (rrCfgCommOptions[5])
+    {
+      // ...
+    }
+
+  // soundingRS-UL-ConfigCommon
+  if (rrCfgCommOptions[4])
+    {
+      // ...
+    }
+
+  // uplinkPowerControlCommon
+  if (rrCfgCommOptions[3])
+    {
+      // ...
+    }
+
+  // antennaInfoCommon
+  if (rrCfgCommOptions[2])
+    {
+      // ...
+    }
+
+  // p-Max
+  if (rrCfgCommOptions[1])
+    {
+      // ...
+    }
+
+  // tdd-Config
+  if (rrCfgCommOptions[0])
+    {
+      // ...
+    }
+
+  // ul-CyclicPrefixLength
+  bIterator = DeserializeEnum (2,&n,bIterator);
+
+  return bIterator;
+}
+
+Buffer::Iterator
+RrcAsn1Header::DeserializeRadioResourceConfigCommonSib (Buffer::Iterator bIterator)
+{
+  std::bitset<0> bitset0;
+  int n;
+
+  bIterator = DeserializeSequence (&bitset0,true,bIterator);
+  // rach-ConfigCommon
+  bIterator = DeserializeSequence (&bitset0,true,bIterator);
+  // preambleInfo
+  std::bitset<1> preamblesGroupAConfigPresent;
+  bIterator = DeserializeSequence (&preamblesGroupAConfigPresent,false,bIterator);
+  bIterator = DeserializeEnum (16,&n,bIterator); // numberOfRA-Preambles
+
+  if (preamblesGroupAConfigPresent[0])
+    {
+      // Deserialize preamblesGroupAConfig
+      // ...
+    }
+  // powerRampingParameters
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+  bIterator = DeserializeEnum (4,&n,bIterator); // powerRampingStep
+  bIterator = DeserializeEnum (16,&n,bIterator); // preambleInitialReceivedTargetPower
+  // ra-SupervisionInfo
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+  bIterator = DeserializeEnum (11,&n,bIterator); // preambleTransMax
+  bIterator = DeserializeEnum (8,&n,bIterator); // ra-ResponseWindowSize
+  bIterator = DeserializeEnum (8,&n,bIterator); // mac-ContentionResolutionTimer
+
+  bIterator = DeserializeInteger (&n,1,8,bIterator); //maxHARQ-Msg3Tx
+
+  // bcch-Config 
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+  bIterator = DeserializeEnum (4,&n,bIterator); // modificationPeriodCoeff
+
+  // pcch-Config 
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+  bIterator = DeserializeEnum (4,&n,bIterator); // defaultPagingCycle
+  bIterator = DeserializeEnum (8,&n,bIterator); // nB
+
+  // prach-Config 
+  std::bitset<1> prachConfigInfoPresent;
+  bIterator = DeserializeSequence (&prachConfigInfoPresent,false,bIterator);
+  // prach-Config -> rootSequenceIndex
+  bIterator = DeserializeInteger (&n,0,1023,bIterator);
+  // prach-Config -> prach-ConfigInfo
+  if (prachConfigInfoPresent[0])
+    {
+      // ...
+    }
+
+  // pdsch-ConfigCommon 
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+  bIterator = DeserializeInteger (&n,-60,50,bIterator); // referenceSignalPower
+  bIterator = DeserializeInteger (&n,0,3,bIterator); // p-b
+
+  // pusch-ConfigCommon
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+  // pusch-ConfigCommon -> pusch-ConfigBasic
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+  // pusch-ConfigCommon -> pusch-ConfigBasic -> n-SB
+  bIterator = DeserializeInteger (&n,1,4,bIterator);
+
+  // pusch-ConfigCommon -> pusch-ConfigBasic -> hoppingMode
+  bIterator = DeserializeEnum (2,&n,bIterator);
+
+  // pusch-ConfigCommon -> pusch-ConfigBasic -> pusch-HoppingOffset
+  bIterator = DeserializeInteger (&n,0,98,bIterator);
+
+  // pusch-ConfigCommon -> pusch-ConfigBasic -> enable64QAM
+  bool dummyBoolean;
+  bIterator = DeserializeBoolean (&dummyBoolean,bIterator);
+
+  // ul-ReferenceSignalsPUSCH 
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+  // groupHoppingEnabled 
+  bIterator = DeserializeBoolean (&dummyBoolean,bIterator);
+
+  // groupAssignmentPUSCH 
+  bIterator = DeserializeInteger (&n,0,29,bIterator);
+
+  // sequenceHoppingEnabled 
+  bIterator = DeserializeBoolean (&dummyBoolean,bIterator);
+
+  // cyclicShift 
+  bIterator = DeserializeInteger (&n,0,7,bIterator);
+
+  // pucch-ConfigCommon 
+  bIterator = DeserializeEnum (3,&n,bIterator); // deltaPUCCH-Shift 
+  bIterator = DeserializeInteger (&n,0,98,bIterator); // nRB-CQI 
+  bIterator = DeserializeInteger (&n,0,7,bIterator); // nCS-AN 
+  bIterator = DeserializeInteger (&n,0,2047,bIterator); // n1PUCCH-AN 
+
+  // soundingRS-UL-ConfigCommon
+  int choice;
+  bIterator = DeserializeChoice (2,&choice,bIterator);
+  if (choice == 0)
+    {
+      bIterator = DeserializeNull (bIterator); // release
+    }
+  if (choice == 1)
+    {
+      // setup
+      // ...
+    }
+
+  // uplinkPowerControlCommon 
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+  bIterator = DeserializeInteger (&n,-126,24,bIterator); // p0-NominalPUSCH
+  bIterator = DeserializeEnum (8,&n,bIterator); // alpha 
+  bIterator = DeserializeInteger (&n,-127,-96,bIterator); // p0-NominalPUCCH 
+  //deltaFList-PUCCH 
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+  bIterator = DeserializeEnum (3,&n,bIterator); // deltaF-PUCCH-Format1 
+  bIterator = DeserializeEnum (3,&n,bIterator); // deltaF-PUCCH-Format1b 
+  bIterator = DeserializeEnum (4,&n,bIterator); // deltaF-PUCCH-Format2 
+  bIterator = DeserializeEnum (3,&n,bIterator); // deltaF-PUCCH-Format2a 
+  bIterator = DeserializeEnum (3,&n,bIterator); // deltaF-PUCCH-Format2b
+  bIterator = DeserializeInteger (&n,-1,6,bIterator); // deltaPreambleMsg3 
+ 
+  // ul-CyclicPrefixLength
+  bIterator = DeserializeEnum (2,&n,bIterator);
+
+  return bIterator;
+}
+//////////////////// RrcConnectionRequest class ////////////////////////
+
+// Constructor
+RrcConnectionRequestHeader::RrcConnectionRequestHeader ()
+{
+  m_mmec = std::bitset<8> (0ul);
+  m_mTmsi = std::bitset<32> (0ul);
+  m_establishmentCause = MO_SIGNALLING;
+  m_spare = std::bitset<1> (0ul);
+}
+
+void
+RrcConnectionRequestHeader::Print (std::ostream &os) const
+{
+  os << "MMEC:" << m_mmec << std::endl;
+  os << "MTMSI:" << m_mTmsi << std::endl;
+  os << "EstablishmentCause:" << m_establishmentCause << std::endl;
+  os << "Spare: " << m_spare << std::endl;
+}
+
+void
+RrcConnectionRequestHeader::PreSerialize () const
+{
+  m_serializationResult = Buffer ();
+
+  // Serialize RRCConnectionRequest sequence:
+  // no default or optional fields. Extension marker not present.
+  SerializeSequence<0> (std::bitset<0> (),false);
+
+  // Serialize criticalExtensions choice:
+  // 2 options, selected: 0 (option: rrcConnectionRequest-r8)
+  SerializeChoice (2,0);
+
+  // Serialize RRCConnectionRequest-r8-IEs sequence:
+  // no default or optional fields. Extension marker not present.
+  SerializeSequence<0> (std::bitset<0> (),false);
+
+  // Serialize InitialUE-Identity choice:
+  // 2 options, selected: 0 (option: s-TMSI)
+  SerializeChoice (2,0);
+
+  // Serialize S-TMSI sequence:
+  // no default or optional fields. Extension marker not present.
+  SerializeSequence<0> (std::bitset<0> (),false);
+
+  // Serialize mmec : MMEC ::= BIT STRING (SIZE (8))
+  SerializeBitstring<8> (m_mmec);
+
+  // Serialize m-TMSI ::= BIT STRING (SIZE (32))
+  SerializeBitstring<32> (m_mTmsi);
+
+  // Serialize establishmentCause : EstablishmentCause ::= ENUMERATED
+  SerializeEnum (8,m_establishmentCause);
+
+  // Serialize spare : BIT STRING (SIZE (1))
+  SerializeBitstring<1> (std::bitset<1> ());
+
+  // Finish serialization
+  FinalizeSerialization ();
+}
+
+uint32_t
+RrcConnectionRequestHeader::Deserialize (Buffer::Iterator bIterator)
+{
+  std::bitset<1> dummy;
+  std::bitset<0> optionalOrDefaultMask;
+  int selectedOption;
+
+  // Deserialize RCConnectionRequest sequence
+  bIterator = DeserializeSequence (&optionalOrDefaultMask,false,bIterator);
+
+  // Deserialize criticalExtensions choice:
+  bIterator = DeserializeChoice (2,&selectedOption,bIterator);
+
+  // Deserialize RRCConnectionRequest-r8-IEs sequence
+  bIterator = DeserializeSequence (&optionalOrDefaultMask,false,bIterator);
+
+  // Deserialize InitialUE-Identity choice
+  bIterator = DeserializeChoice (2,&selectedOption,bIterator);
+
+  // Deserialize S-TMSI sequence
+  bIterator = DeserializeSequence (&optionalOrDefaultMask,false,bIterator);
+
+  // Deserialize mmec
+  bIterator = DeserializeBitstring (&m_mmec,bIterator);
+
+  // Deserialize m-TMSI
+  bIterator = DeserializeBitstring (&m_mTmsi,bIterator);
+
+  // Deserialize establishmentCause
+  bIterator = DeserializeEnum (8,&selectedOption,bIterator);
+
+  // Deserialize spare
+  bIterator = DeserializeBitstring (&dummy,bIterator);
+
+  return GetSerializedSize ();
+}
+
+void
+RrcConnectionRequestHeader::SetMessage (RrcConnectionRequest msg)
+{
+  m_mTmsi = std::bitset<32> ((uint32_t)msg.ueIdentity);
+  m_mmec = std::bitset<8> ((uint32_t)(msg.ueIdentity >> 32));
+  m_isDataSerialized = false;
+}
+
+std::bitset<8>
+RrcConnectionRequestHeader::getMmec () const
+{
+  return m_mmec;
+}
+
+std::bitset<32>
+RrcConnectionRequestHeader::getMtmsi () const
+{
+  return m_mTmsi;
+}
+
+
+//////////////////// RrcConnectionSetup class ////////////////////////
+RrcConnectionSetupHeader::RrcConnectionSetupHeader ()
+{
+}
+ 
+void
+RrcConnectionSetupHeader::Print (std::ostream &os) const
+{
+  os << "rrcTransactionIdentifier: " << (int)rrcTransactionIdentifier << std::endl;
+  os << "radioResourceConfigDedicated:" << std::endl;
+  RrcAsn1Header::Print (os,radioResourceConfigDedicated);
+}
+
+void
+RrcConnectionSetupHeader::PreSerialize () const
+{
+  m_serializationResult = Buffer ();
+
+  // Serialize RRCConnectionSetup sequence:
+  // no default or optional fields. Extension marker not present.
+  SerializeSequence (std::bitset<0> (),false);
+
+  // Serialize rrc-TransactionIdentifier ::=INTEGER (0..3)
+  SerializeInteger (rrcTransactionIdentifier,0,3);
+
+  // Serialize criticalExtensions choice:
+  // 2 options, selected: 0 (option: c1)
+  SerializeChoice (2,0);
+
+  // Serialize c1 choice:
+  // 8 options, selected: 0 (option: rrcConnectionSetup-r8)
+  SerializeChoice (8,0);
+
+  // Serialize rrcConnectionSetup-r8 sequence
+  // 1 optional fields (not present). Extension marker not present.
+  SerializeSequence (std::bitset<1> (0),false);
+
+  // Serialize RadioResourceConfigDedicated sequence
+  SerializeRadioResourceConfigDedicated (radioResourceConfigDedicated);
+
+  // Serialize nonCriticalExtension sequence
+  // 2 optional fields, none present. No extension marker.
+  SerializeSequence (std::bitset<2> (0),false);
+
+  // Finish serialization
+  FinalizeSerialization ();
+}
+
+
+uint32_t
+RrcConnectionSetupHeader::Deserialize (Buffer::Iterator bIterator)
+{
+  // Deserialize RRCConnectionSetup sequence
+  std::bitset<0> bitset0;
+  std::bitset<1> bitset1;
+  std::bitset<2> bitset2;
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+  // Deserialize rrc-TransactionIdentifier ::=INTEGER (0..3)
+  int n;
+  bIterator = DeserializeInteger (&n,0,3,bIterator);
+  rrcTransactionIdentifier = n;
+
+  // Deserialize criticalExtensions choice
+  int criticalExtensionChoice;
+  bIterator = DeserializeChoice (2,&criticalExtensionChoice,bIterator);
+  if (criticalExtensionChoice == 1)
+    {
+      // Deserialize criticalExtensionsFuture
+      bIterator = DeserializeSequence (&bitset0,false,bIterator);
+    }
+  else if (criticalExtensionChoice == 0)
+    {
+      // Deserialize c1
+      int c1;
+      bIterator = DeserializeChoice (8,&c1,bIterator);
+
+      if (c1 > 0)
+        {
+          // Deserialize spareX , X:=7..1
+          bIterator = DeserializeNull (bIterator);
+        }
+      else if (c1 == 0)
+        {
+          // Deserialize rrcConnectionSetup-r8
+          // 1 optional fields, no extension marker.
+          bIterator = DeserializeSequence (&bitset1,false,bIterator);
+
+          // Deserialize radioResourceConfigDedicated
+          bIterator = DeserializeRadioResourceConfigDedicated (&radioResourceConfigDedicated,bIterator);
+
+          if (bitset1[0])
+            {
+              // Deserialize nonCriticalExtension
+              // 2 optional fields, no extension marker.
+              bIterator = DeserializeSequence (&bitset2,false,bIterator);
+
+              // Deserialization of lateR8NonCriticalExtension and nonCriticalExtension
+              // ...
+            }
+        }
+    }
+  return GetSerializedSize ();
+}
+
+void
+RrcConnectionSetupHeader::SetMessage (RrcConnectionSetup msg)
+{
+  rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
+  radioResourceConfigDedicated = msg.radioResourceConfigDedicated;
+  m_isDataSerialized = false;
+}
+
+uint8_t
+RrcConnectionSetupHeader::GetRrcTransactionIdentifier () const
+{
+  return rrcTransactionIdentifier;
+}
+
+bool
+RrcConnectionSetupHeader::HavePhysicalConfigDedicated () const
+{
+  return radioResourceConfigDedicated.havePhysicalConfigDedicated;
+}
+
+std::list<LteRrcSap::SrbToAddMod>
+RrcConnectionSetupHeader::GetSrbToAddModList () const
+{
+  return radioResourceConfigDedicated.srbToAddModList;
+}
+
+std::list<LteRrcSap::DrbToAddMod>
+RrcConnectionSetupHeader::GetDrbToAddModList () const
+{
+  return radioResourceConfigDedicated.drbToAddModList;
+} 
+
+std::list<uint8_t>
+RrcConnectionSetupHeader::GetDrbToReleaseList () const
+{
+  return radioResourceConfigDedicated.drbToReleaseList;
+}
+
+LteRrcSap::PhysicalConfigDedicated
+RrcConnectionSetupHeader::GetPhysicalConfigDedicated () const
+{
+  return radioResourceConfigDedicated.physicalConfigDedicated;
+}
+
+LteRrcSap::RadioResourceConfigDedicated
+RrcConnectionSetupHeader::GetRadioResourceConfigDedicated () const
+{
+  return radioResourceConfigDedicated;
+}
+
+//////////////////// RrcConnectionSetupCompleteHeader class ////////////////////////
+
+RrcConnectionSetupCompleteHeader::RrcConnectionSetupCompleteHeader ()
+{
+}
+
+void
+RrcConnectionSetupCompleteHeader::PreSerialize () const
+{
+  m_serializationResult = Buffer ();
+
+  // Serialize RRCConnectionSetupComplete sequence:
+  // no default or optional fields. Extension marker not present.
+  SerializeSequence<0> (std::bitset<0> (),false);
+
+  // Serialize rrc-TransactionIdentifier
+  SerializeInteger (m_rrcTransactionIdentifier,0,3);
+
+  // Serialize criticalExtensions choice
+  // 2 options, selected 0 (c1)
+  SerializeChoice (2,0);
+
+  // Choose spare3 NULL
+  SerializeChoice (4,1);
+
+  // Serialize spare3 NULL
+  SerializeNull ();
+
+  // Finish serialization
+  FinalizeSerialization ();
+}
+
+uint32_t
+RrcConnectionSetupCompleteHeader::Deserialize (Buffer::Iterator bIterator)
+{
+  std::bitset<0> bitset0;
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+  int n;
+  bIterator = DeserializeInteger (&n,0,3,bIterator);
+  m_rrcTransactionIdentifier = n;
+
+  bIterator = DeserializeChoice (2,&n,bIterator);
+
+  if (n == 1)
+    {
+      // Deserialize criticalExtensionsFuture
+      bIterator = DeserializeSequence (&bitset0,false,bIterator);
+    }
+  else if (n == 0)
+    {
+      // Deserialize c1
+      int c1Chosen;
+      bIterator = DeserializeChoice (4,&c1Chosen,bIterator);
+
+      if (c1Chosen == 0)
+        {
+          // Deserialize rrcConnectionSetupComplete-r8
+          // ...
+        }
+      else
+        {
+          bIterator = DeserializeNull (bIterator);
+        }
+    }
+
+  return GetSerializedSize ();
+}
+
+void
+RrcConnectionSetupCompleteHeader::Print (std::ostream &os) const
+{
+  os << "rrcTransactionIdentifier: " << (int) m_rrcTransactionIdentifier << std::endl;
+}
+
+void
+RrcConnectionSetupCompleteHeader::SetMessage (RrcConnectionSetupCompleted msg)
+{
+  m_rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
+  m_isDataSerialized = false;
+}
+
+uint8_t
+RrcConnectionSetupCompleteHeader::GetRrcTransactionIdentifier () const
+{
+  return m_rrcTransactionIdentifier;
+}
+
+//////////////////// RrcConnectionReconfigurationCompleteHeader class ////////////////////////
+
+RrcConnectionReconfigurationCompleteHeader::RrcConnectionReconfigurationCompleteHeader ()
+{
+}
+
+void
+RrcConnectionReconfigurationCompleteHeader::PreSerialize () const
+{
+  m_serializationResult = Buffer ();
+
+  // Serialize RRCConnectionSetupComplete sequence:
+  // no default or optional fields. Extension marker not present.
+  SerializeSequence<0> (std::bitset<0> (),false);
+
+  // Serialize rrc-TransactionIdentifier
+  SerializeInteger (m_rrcTransactionIdentifier,0,3);
+
+  // Serialize criticalExtensions choice
+  // 2 options, selected 1 (criticalExtensionsFuture)
+  SerializeChoice (2,1);
+
+  // Choose criticalExtensionsFuture
+  SerializeSequence<0> (std::bitset<0> (),false);
+
+  // Finish serialization
+  FinalizeSerialization ();
+}
+
+uint32_t
+RrcConnectionReconfigurationCompleteHeader::Deserialize (Buffer::Iterator bIterator)
+{
+  std::bitset<0> bitset0;
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+  int n;
+  bIterator = DeserializeInteger (&n,0,3,bIterator);
+  m_rrcTransactionIdentifier = n;
+
+  bIterator = DeserializeChoice (2,&n,bIterator);
+
+  if (n == 1)
+    {
+      // Deserialize criticalExtensionsFuture
+      bIterator = DeserializeSequence (&bitset0,false,bIterator);
+    }
+  else if (n == 0)
+    {
+      // Deserialize rrcConnectionReconfigurationComplete-r8
+      // ...
+    }
+
+  return GetSerializedSize ();
+}
+
+void
+RrcConnectionReconfigurationCompleteHeader::Print (std::ostream &os) const
+{
+  os << "rrcTransactionIdentifier: " << (int) m_rrcTransactionIdentifier << std::endl;
+}
+
+void
+RrcConnectionReconfigurationCompleteHeader::SetMessage (RrcConnectionReconfigurationCompleted msg)
+{
+  m_rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
+  m_isDataSerialized = false;
+}
+
+uint8_t
+RrcConnectionReconfigurationCompleteHeader::GetRrcTransactionIdentifier () const
+{
+  return m_rrcTransactionIdentifier;
+}
+
+//////////////////// RrcConnectionReconfigurationHeader class ////////////////////////
+
+RrcConnectionReconfigurationHeader::RrcConnectionReconfigurationHeader ()
+{
+}
+
+void
+RrcConnectionReconfigurationHeader::PreSerialize () const
+{
+  m_serializationResult = Buffer ();
+
+  // Serialize RRCConnectionSetupComplete sequence:
+  // no default or optional fields. Extension marker not present.
+  SerializeSequence<0> (std::bitset<0> (),false);
+
+  // Serialize rrc-TransactionIdentifier
+  SerializeInteger (m_rrcTransactionIdentifier,0,3);
+
+  // Serialize criticalExtensions choice
+  // 2 options, selected 0 (c1)
+  SerializeChoice (2,0);
+
+  // Serialize c1 choice
+  // 8 options, selected 0 (rrcConnectionReconfiguration-r8)
+  SerializeChoice (8,0);
+
+  // Serialize RRCConnectionReconfiguration-r8-IEs sequence:
+  // 6 optional fields. Extension marker not present.
+  std::bitset<6> options;
+  options.set (5,m_haveMeasConfig);
+  options.set (4,m_haveMobilityControlInfo);
+  options.set (3,0); // No dedicatedInfoNASList
+  options.set (2,m_haveRadioResourceConfigDedicated);
+  options.set (1,0); // No securityConfigHO
+  options.set (0,0); // No nonCriticalExtension
+  SerializeSequence<6> (options,false);
+
+
+  if (m_haveMeasConfig)
+    {
+      // Serialize MeasConfig sequence
+      // 11 optional fields, extension marker present
+      std::bitset<11> measConfigOptional (0);
+      SerializeSequence (measConfigOptional,true);
+    }
+
+  if (m_haveMobilityControlInfo)
+    {
+      // Serialize MobilityControlInfo
+
+      // 4 optional fields, extension marker present.
+      std::bitset<4> mobCtrlIntoOptional;
+      mobCtrlIntoOptional.set (3,m_mobilityControlInfo.haveCarrierFreq);
+      mobCtrlIntoOptional.set (2,m_mobilityControlInfo.haveCarrierBandwidth);
+      mobCtrlIntoOptional.set (1,0); // No additionalSpectrumEmission
+      mobCtrlIntoOptional.set (0,m_mobilityControlInfo.haveRachConfigDedicated);
+      SerializeSequence (mobCtrlIntoOptional,true);
+
+      // Serialize targetPhysCellId
+      SerializeInteger (m_mobilityControlInfo.targetPhysCellId,0,503);
+
+      if (m_mobilityControlInfo.haveCarrierFreq)
+        {
+          SerializeSequence (std::bitset<1> (1),false);
+          SerializeInteger (m_mobilityControlInfo.carrierFreq.dlCarrierFreq,0,MAX_EARFCN);
+          SerializeInteger (m_mobilityControlInfo.carrierFreq.ulCarrierFreq,0,MAX_EARFCN);
+        }
+
+      if (m_mobilityControlInfo.haveCarrierBandwidth)
+        {
+          SerializeSequence (std::bitset<1> (1),false);
+          SerializeEnum (16,m_mobilityControlInfo.carrierBandwidth.dlBandwidth);
+          SerializeEnum (16,m_mobilityControlInfo.carrierBandwidth.ulBandwidth);
+        }
+
+      // Serialize t304
+      SerializeEnum (8,0);
+
+      // Serialize newUE-Identitiy
+      SerializeBitstring (std::bitset<16> (m_mobilityControlInfo.newUeIdentity));
+
+      // Serialize radioResourceConfigCommon
+      // 9 optional fields, none present. Extension marker yes.
+      SerializeSequence (std::bitset<9> (0),true);
+
+      // Serialize PRACH-Config
+      // 1 optional, 0 extension marker.
+      SerializeSequence (std::bitset<1> (0),false);
+
+      // Serialize PRACH-Config rootSequenceIndex
+      SerializeInteger (0,0,1023);
+
+      // Serialize PUSCH-ConfigCommon
+      SerializeSequence (std::bitset<0> (),false);
+
+      // Serialize pusch-ConfigBasic
+      SerializeSequence (std::bitset<0> (),false);
+      SerializeInteger (1,1,4);
+      SerializeEnum (2,0);
+      SerializeInteger (0,0,98);
+      SerializeBoolean (false);
+
+      // Serialize UL-ReferenceSignalsPUSCH
+      SerializeSequence (std::bitset<0> (),false);
+      SerializeBoolean (false);
+      SerializeInteger (0,0,29);
+      SerializeBoolean (false);
+      SerializeInteger (4,0,7); // **************
+
+      // Serialize UL-CyclicPrefixLength
+      SerializeEnum (2,0);
+
+      if (m_mobilityControlInfo.haveRachConfigDedicated)
+        {
+          SerializeSequence (std::bitset<0> (),false);
+          SerializeInteger (m_mobilityControlInfo.rachConfigDedicated.raPreambleIndex,0,63);
+          SerializeInteger (m_mobilityControlInfo.rachConfigDedicated.raPrachMaskIndex,0,15);
+        }
+    }
+
+  if (m_haveRadioResourceConfigDedicated)
+    {
+      // Serialize RadioResourceConfigDedicated
+      SerializeRadioResourceConfigDedicated (m_radioResourceConfigDedicated);
+    }
+
+  // Finish serialization
+  FinalizeSerialization ();
+}
+
+uint32_t
+RrcConnectionReconfigurationHeader::Deserialize (Buffer::Iterator bIterator)
+{
+  // pag 106
+  std::bitset<0> bitset0;
+
+  // RRCConnectionReconfiguration sequence
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+  // rrc-TransactionIdentifier
+  int n;
+  bIterator = DeserializeInteger (&n,0,3,bIterator);
+  m_rrcTransactionIdentifier = n;
+
+  // criticalExtensions
+  int sel;
+  bIterator = DeserializeChoice (2,&sel,bIterator);
+  if (sel == 1)
+    {
+      // criticalExtensionsFuture
+      bIterator = DeserializeSequence (&bitset0,false,bIterator);
+    }
+  else if (sel == 0)
+    {
+      // c1
+      int c1Chosen;
+      bIterator = DeserializeChoice (8,&c1Chosen,bIterator);
+      if (c1Chosen > 0)
+        {
+          bIterator = DeserializeNull (bIterator);
+        }
+      else if (c1Chosen == 0)
+        {
+          // rrcConnectionReconfiguration-r8
+          std::bitset<6> rrcConnRecOpts;
+          bIterator = DeserializeSequence (&rrcConnRecOpts,false,bIterator);
+
+          m_haveMeasConfig = rrcConnRecOpts[5];
+          if (m_haveMeasConfig)
+            {
+              std::bitset<11> bitset11;
+
+              // measConfig
+              bIterator = DeserializeSequence (&bitset11,true,bIterator);
+
+              if (bitset11[10])
+                {
+                  // measObjectToRemoveList
+                }
+              if (bitset11[9])
+                {
+                  // measObjectToAddModList
+                }
+              if (bitset11[8])
+                {
+                  // reportConfigToRemoveList
+                }
+              if (bitset11[7])
+                {
+                  // reportConfigToAddModList
+                }
+              if (bitset11[6])
+                {
+                  // measIdToRemoveList
+                }
+              if (bitset11[5])
+                {
+                  // measIdToAddModList
+                }
+              if (bitset11[4])
+                {
+                  // quantityConfig
+                }
+              if (bitset11[3])
+                {
+                  // measGapConfig
+                }
+              if (bitset11[2])
+                {
+                  // s-Measure
+                }
+              if (bitset11[1])
+                {
+                  // preRegistrationInfoHRPD
+                }
+              if (bitset11[0])
+                {
+                  // speedStatePars
+                }
+            }
+
+          m_haveMobilityControlInfo = rrcConnRecOpts[4];
+          if (m_haveMobilityControlInfo)
+            {
+              // mobilityControlInfo
+              std::bitset<4> mobCtrlOpts;
+              bIterator = DeserializeSequence (&mobCtrlOpts,true,bIterator);
+
+              // PhysCellId
+              bIterator = DeserializeInteger (&n,0,503,bIterator);
+              m_mobilityControlInfo.targetPhysCellId = n;
+
+              // carrierFreq
+              m_mobilityControlInfo.haveCarrierFreq = mobCtrlOpts[3];
+              if (m_mobilityControlInfo.haveCarrierFreq)
+                {
+                  std::bitset<1> ulCarrierFreqPresent;
+                  bIterator = DeserializeSequence (&ulCarrierFreqPresent,false,bIterator);
+
+                  bIterator = DeserializeInteger (&n,0,MAX_EARFCN,bIterator);
+                  m_mobilityControlInfo.carrierFreq.dlCarrierFreq = n;
+
+                  if (ulCarrierFreqPresent[0])
+                    {
+                      bIterator = DeserializeInteger (&n,0,MAX_EARFCN,bIterator);
+                      m_mobilityControlInfo.carrierFreq.ulCarrierFreq = n;
+                    }
+                }
+
+              // carrierBandwidth
+              m_mobilityControlInfo.haveCarrierBandwidth = mobCtrlOpts[2];
+              if (m_mobilityControlInfo.haveCarrierBandwidth)
+                {
+                  std::bitset<1> ulBandwidthPresent;
+                  bIterator = DeserializeSequence (&ulBandwidthPresent,false,bIterator);
+
+                  bIterator = DeserializeEnum (16,&n,bIterator);
+                  m_mobilityControlInfo.carrierBandwidth.dlBandwidth = n;
+
+                  if (ulBandwidthPresent[0])
+                    {
+                      bIterator = DeserializeEnum (16,&n,bIterator);
+                      m_mobilityControlInfo.carrierBandwidth.ulBandwidth = n;
+                    }
+                }
+
+              // additionalSpectrumEmission
+              if (mobCtrlOpts[1])
+                {
+                  // ...
+                }
+
+              // t304
+              bIterator = DeserializeEnum (8,&n,bIterator);
+
+              // newUE-Identity
+              std::bitset<16> cRnti;
+              bIterator = DeserializeBitstring (&cRnti, bIterator);
+              m_mobilityControlInfo.newUeIdentity = cRnti.to_ulong ();
+
+              // radioResourceConfigCommon
+              bIterator = DeserializeRadioResourceConfigCommon (bIterator);
+
+              m_mobilityControlInfo.haveRachConfigDedicated = mobCtrlOpts[0];
+              if (m_mobilityControlInfo.haveRachConfigDedicated)
+                {
+                  bIterator = DeserializeSequence (&bitset0, false, bIterator);
+                  bIterator = DeserializeInteger (&n,0,63, bIterator);
+                  m_mobilityControlInfo.rachConfigDedicated.raPreambleIndex = n;
+                  bIterator = DeserializeInteger (&n,0,15, bIterator);
+                  m_mobilityControlInfo.rachConfigDedicated.raPrachMaskIndex = n;
+                }
+            }
+
+          // dedicatedInfoNASList
+          if (rrcConnRecOpts[3])
+            {
+              // ...
+            }
+
+          // radioResourceConfigDedicated
+          m_haveRadioResourceConfigDedicated = rrcConnRecOpts[2];
+          if (m_haveRadioResourceConfigDedicated)
+            {
+              bIterator = DeserializeRadioResourceConfigDedicated (&m_radioResourceConfigDedicated,bIterator);
+            }
+
+          // securityConfigHO
+          if (rrcConnRecOpts[1])
+            {
+              // ...
+            }
+
+          // nonCriticalExtension
+          if (rrcConnRecOpts[0])
+            {
+              // ...
+            }
+        }
+    }
+
+  return GetSerializedSize ();
+}
+
+void
+RrcConnectionReconfigurationHeader::Print (std::ostream &os) const
+{
+  os << "rrcTransactionIdentifier: " << (int) m_rrcTransactionIdentifier << std::endl;
+  os << "haveMeasConfig: " << m_haveMeasConfig << std::endl;
+  os << "haveMobilityControlInfo: " << m_haveMobilityControlInfo << std::endl;
+  if (m_haveMobilityControlInfo)
+    {
+      os << "targetPhysCellId: " << (int)m_mobilityControlInfo.targetPhysCellId << std::endl;
+      os << "haveCarrierFreq: " << m_mobilityControlInfo.haveCarrierFreq << std::endl;
+      if (m_mobilityControlInfo.haveCarrierFreq)
+        {
+          os << "  carrierFreq.dlCarrierFreq: " << (int) m_mobilityControlInfo.carrierFreq.dlCarrierFreq << std::endl;
+          os << "  carrierFreq.dlCarrierFreq: " << (int) m_mobilityControlInfo.carrierFreq.ulCarrierFreq << std::endl;
+        }
+      os << "haveCarrierBandwidth: " << m_mobilityControlInfo.haveCarrierBandwidth << std::endl;
+      if (m_mobilityControlInfo.haveCarrierBandwidth)
+        {
+          os << "  carrierBandwidth.dlBandwidth: " << (int) m_mobilityControlInfo.carrierBandwidth.dlBandwidth << std::endl;
+          os << "  carrierBandwidth.ulBandwidth: " << (int) m_mobilityControlInfo.carrierBandwidth.ulBandwidth << std::endl;
+        }
+      os << "newUeIdentity: " << (int) m_mobilityControlInfo.newUeIdentity << std::endl;
+      os << "haveRachConfigDedicated: " << m_mobilityControlInfo.haveRachConfigDedicated << std::endl;
+      if (m_mobilityControlInfo.haveRachConfigDedicated)
+        {
+          os << "raPreambleIndex: " << (int) m_mobilityControlInfo.rachConfigDedicated.raPreambleIndex << std::endl;
+          os << "raPrachMaskIndex: "  << (int) m_mobilityControlInfo.rachConfigDedicated.raPrachMaskIndex << std::endl;
+        }
+    }
+  os << "haveRadioResourceConfigDedicated: " << m_haveRadioResourceConfigDedicated << std::endl;
+  if (m_haveRadioResourceConfigDedicated)
+    {
+      RrcAsn1Header::Print (os,m_radioResourceConfigDedicated);
+    }
+}
+
+void
+RrcConnectionReconfigurationHeader::SetMessage (RrcConnectionReconfiguration msg)
+{
+  m_rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
+  m_haveMeasConfig = msg.haveMeasConfig;
+  m_measConfig = msg.measConfig;
+  m_haveMobilityControlInfo = msg.haveMobilityControlInfo;
+  m_mobilityControlInfo = msg.mobilityControlInfo;
+  m_haveRadioResourceConfigDedicated = msg.haveRadioResourceConfigDedicated;
+  m_radioResourceConfigDedicated = msg.radioResourceConfigDedicated;
+
+  m_isDataSerialized = false;
+}
+
+uint8_t
+RrcConnectionReconfigurationHeader::GetRrcTransactionIdentifier () const
+{
+  return m_rrcTransactionIdentifier;
+}
+
+bool
+RrcConnectionReconfigurationHeader::GetHaveMeasConfig ()
+{
+  return m_haveMeasConfig;
+}
+
+LteRrcSap::MeasConfig
+RrcConnectionReconfigurationHeader::GetMeasConfig ()
+{
+  return m_measConfig;
+}
+
+bool
+RrcConnectionReconfigurationHeader::GetHaveMobilityControlInfo ()
+{
+  return m_haveMobilityControlInfo;
+}
+
+LteRrcSap::MobilityControlInfo
+RrcConnectionReconfigurationHeader::GetMobilityControlInfo ()
+{
+  return m_mobilityControlInfo;
+}
+
+bool
+RrcConnectionReconfigurationHeader::GetHaveRadioResourceConfigDedicated ()
+{
+  return m_haveRadioResourceConfigDedicated;
+}
+
+LteRrcSap::RadioResourceConfigDedicated
+RrcConnectionReconfigurationHeader::GetRadioResourceConfigDedicated ()
+{
+  return m_radioResourceConfigDedicated;
+}
+
+bool
+RrcConnectionReconfigurationHeader::HavePhysicalConfigDedicated () const
+{
+  return m_radioResourceConfigDedicated.havePhysicalConfigDedicated;
+}
+
+std::list<LteRrcSap::SrbToAddMod> 
+RrcConnectionReconfigurationHeader::GetSrbToAddModList () const
+{
+  return m_radioResourceConfigDedicated.srbToAddModList;
+}
+
+std::list<LteRrcSap::DrbToAddMod> 
+RrcConnectionReconfigurationHeader::GetDrbToAddModList () const
+{
+  return m_radioResourceConfigDedicated.drbToAddModList;
+}
+
+std::list<uint8_t> 
+RrcConnectionReconfigurationHeader::GetDrbToReleaseList () const
+{
+  return m_radioResourceConfigDedicated.drbToReleaseList;
+}
+
+LteRrcSap::PhysicalConfigDedicated 
+RrcConnectionReconfigurationHeader::GetPhysicalConfigDedicated () const
+{
+  return m_radioResourceConfigDedicated.physicalConfigDedicated;
+}
+
+
+//////////////////// HandoverPreparationInfoHeader class ////////////////////////
+
+HandoverPreparationInfoHeader::HandoverPreparationInfoHeader ()
+{
+}
+
+void
+HandoverPreparationInfoHeader::PreSerialize () const
+{
+  m_serializationResult = Buffer ();
+
+  // Serialize HandoverPreparationInformation sequence:
+  // no default or optional fields. Extension marker not present.
+  SerializeSequence<0> (std::bitset<0> (),false);
+
+  // Serialize criticalExtensions choice
+  // 2 options, selected 0 (c1)
+  SerializeChoice (2,0);
+
+  // Serialize c1 choice
+  // 8 options, selected 0 (handoverPreparationInformation-r8)
+  SerializeChoice (8,0);
+
+  // Serialize HandoverPreparationInformation-r8-IEs sequence
+  // 4 optional fields, no extension marker.
+  std::bitset<4> handoverPrepInfoOpts;
+  handoverPrepInfoOpts.set (3,1); // as-Config present
+  handoverPrepInfoOpts.set (2,0); // rrm-Config not present
+  handoverPrepInfoOpts.set (1,0); // as-Context not present
+  handoverPrepInfoOpts.set (0,0); // nonCriticalExtension not present
+  SerializeSequence (handoverPrepInfoOpts,false);
+
+  // Serialize ue-RadioAccessCapabilityInfo
+  SerializeSequenceOf (0,MAX_RAT_CAPABILITIES,0);
+
+  // Serialize as-Config
+  SerializeSequence (std::bitset<0> (),true);
+
+  // Serialize sourceMeasConfig
+  // 11 optional fields, extension marker present
+  std::bitset<11> measConfigOptional (0);
+  SerializeSequence (measConfigOptional,true);
+
+  // Serialize sourceRadioResourceConfig
+  SerializeRadioResourceConfigDedicated (m_asConfig.sourceRadioResourceConfig);
+
+  // Serialize sourceSecurityAlgorithmConfig
+  SerializeSequence (std::bitset<0> (),false);
+  // cipheringAlgorithm
+  SerializeEnum (8,0);
+  // integrityProtAlgorithm
+  SerializeEnum (8,0);
+
+  // Serialize sourceUE-Identity
+  SerializeBitstring (std::bitset<16> (m_asConfig.sourceUeIdentity));
+
+  // Serialize sourceMasterInformationBlock
+  SerializeSequence (std::bitset<0> (),false);
+  SerializeEnum (6,m_asConfig.sourceMasterInformationBlock.dlBandwidth); // dl-Bandwidth
+  SerializeSequence (std::bitset<0> (),false); // phich-Config sequence
+  SerializeEnum (2,0); // phich-Duration
+  SerializeEnum (4,0); // phich-Resource
+  SerializeBitstring (std::bitset<8> (m_asConfig.sourceMasterInformationBlock.systemFrameNumber)); // systemFrameNumber
+  SerializeBitstring (std::bitset<10> (321)); // spare
+
+  // Serialize sourceSystemInformationBlockType1 sequence
+  SerializeSystemInformationBlockType1 (m_asConfig.sourceSystemInformationBlockType1);
+
+  // Serialize sourceSystemInformationBlockType2
+  SerializeSystemInformationBlockType2 ();
+
+  // Serialize AntennaInfoCommon 
+  SerializeSequence (std::bitset<0> (0),false);
+  SerializeEnum (4,0); // antennaPortsCount 
+
+  // Serialize sourceDlCarrierFreq
+  SerializeInteger (m_asConfig.sourceDlCarrierFreq,0,MAX_EARFCN);
+
+  // Finish serialization
+  FinalizeSerialization ();
+}
+
+uint32_t
+HandoverPreparationInfoHeader::Deserialize (Buffer::Iterator bIterator)
+{
+  std::bitset<0> bitset0;
+  int n;
+
+  // Deserialize HandoverPreparationInformation sequence
+  // 0 optional fields, no extension marker
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+  // Deserialize criticalExtensions choice
+  int criticalExtensionsChosen;
+  bIterator = DeserializeChoice (2,&criticalExtensionsChosen,bIterator);
+
+  if (criticalExtensionsChosen == 1)
+    {
+      // Deserialize criticalExtensionsFuture
+      bIterator = DeserializeSequence (&bitset0,false,bIterator);
+    }
+  else if (criticalExtensionsChosen == 0)
+    {
+      // Deserialize c1 choice
+      int c1Chosen;
+      bIterator = DeserializeChoice (8,&c1Chosen,bIterator);
+      if (c1Chosen > 0)
+        {
+          bIterator = DeserializeNull (bIterator);
+        }
+      else if (c1Chosen == 0)
+        {
+          // Deserialize handoverPreparationInformation-r8
+          std::bitset<4> handoverPrepInfoOpts;
+          bIterator = DeserializeSequence (&handoverPrepInfoOpts,false,bIterator);
+
+          // Deserialize ue-RadioAccessCapabilityInfo
+          bIterator = DeserializeSequenceOf (&n,MAX_RAT_CAPABILITIES,0,bIterator);
+          for (int i = 0; i < n; i++)
+            {
+              // Deserialize UE-CapabilityRAT-Container
+              // ...
+            }
+
+          if (handoverPrepInfoOpts[3])
+            {
+              // Deserialize as-Config sequence
+              bIterator = DeserializeSequence (&bitset0,true,bIterator);
+
+              // Deserialize sourceMeasConfig
+              std::bitset<11> bitset11;
+              bIterator = DeserializeSequence (&bitset11,true,bIterator);
+
+              if (bitset11[10]) //measObjectToRemoveList
+                {
+                  // ...
+                }
+              if (bitset11[9]) //measObjectToAddModList
+                {
+                  // ...
+                }
+              if (bitset11[8]) //reportConfigToRemoveList
+                {
+                  // ...
+                }
+              if (bitset11[7]) //reportConfigToAddModList
+                {
+                  // ...
+                }
+              if (bitset11[6]) //measIdToRemoveList
+                {
+                  // ...
+                }
+              if (bitset11[5]) //measIdToAddModList
+                {
+                  // ...
+                }
+              if (bitset11[4]) //quantityConfig
+                {
+                  // ...
+                }
+              if (bitset11[3]) //measGapConfig
+                {
+                  // ...
+                }
+              if (bitset11[2]) //s-Measure
+                {
+                  // ...
+                }
+              if (bitset11[1]) //preRegistrationInfoHRPD
+                {
+                  // ...
+                }
+              if (bitset11[0]) //speedStatePars
+                {
+                  // ...
+                }
+
+              // Deserialize sourceRadioResourceConfig
+              bIterator = DeserializeRadioResourceConfigDedicated (&m_asConfig.sourceRadioResourceConfig,bIterator);
+
+              // Deserialize sourceSecurityAlgorithmConfig
+              bIterator = DeserializeSequence (&bitset0,false,bIterator);
+              bIterator = DeserializeEnum (8,&n,bIterator); // cipheringAlgorithm
+              bIterator = DeserializeEnum (8,&n,bIterator); // integrityProtAlgorithm
+
+              // Deserialize sourceUE-Identity
+              std::bitset<16> cRnti;
+              bIterator = DeserializeBitstring (&cRnti,bIterator);
+              m_asConfig.sourceUeIdentity = cRnti.to_ulong ();
+
+              // Deserialize sourceMasterInformationBlock
+              bIterator = DeserializeSequence (&bitset0,false,bIterator);
+              bIterator = DeserializeEnum (6,&n,bIterator); // dl-Bandwidth
+              m_asConfig.sourceMasterInformationBlock.dlBandwidth = n;
+
+              // phich-Config
+              bIterator = DeserializeSequence (&bitset0,false,bIterator);
+              bIterator = DeserializeEnum (2,&n,bIterator); // phich-Duration
+              bIterator = DeserializeEnum (4,&n,bIterator); // phich-Resource
+
+              // systemFrameNumber
+              std::bitset<8> systemFrameNumber;
+              bIterator = DeserializeBitstring (&systemFrameNumber,bIterator);
+              m_asConfig.sourceMasterInformationBlock.systemFrameNumber = systemFrameNumber.to_ulong ();
+              // spare
+              std::bitset<10> spare;
+              bIterator = DeserializeBitstring (&spare,bIterator);
+
+              // Deserialize sourceSystemInformationBlockType1
+              bIterator = DeserializeSystemInformationBlockType1 (&m_asConfig.sourceSystemInformationBlockType1,bIterator);
+
+              // Deserialize sourceSystemInformationBlockType2
+              bIterator = DeserializeSystemInformationBlockType2 (bIterator);
+
+              // Deserialize antennaInfoCommon
+              bIterator = DeserializeSequence (&bitset0,false,bIterator);
+              bIterator = DeserializeEnum (4,&n,bIterator); // antennaPortsCount
+
+              // Deserialize sourceDl-CarrierFreq
+              bIterator = DeserializeInteger (&n,0,MAX_EARFCN,bIterator);
+              m_asConfig.sourceDlCarrierFreq = n;
+            }
+          if (handoverPrepInfoOpts[2])
+            {
+              // Deserialize rrm-Config
+              // ...
+            }
+          if (handoverPrepInfoOpts[1])
+            {
+              // Deserialize as-Context
+              // ...
+            }
+          if (handoverPrepInfoOpts[0])
+            {
+              // Deserialize nonCriticalExtension
+              // ...
+            }
+        }
+    }
+
+  return GetSerializedSize ();
+}
+
+void
+HandoverPreparationInfoHeader::Print (std::ostream &os) const
+{
+  RrcAsn1Header::Print (os,m_asConfig.sourceRadioResourceConfig);
+  os << "sourceUeIdentity: " << m_asConfig.sourceUeIdentity << std::endl;
+  os << "dlBandwidth: " << (int)m_asConfig.sourceMasterInformationBlock.dlBandwidth << std::endl;
+  os << "systemFrameNumber: " << (int)m_asConfig.sourceMasterInformationBlock.systemFrameNumber << std::endl;
+  os << "plmnIdentityInfo.plmnIdentity: " << (int) m_asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity << std::endl;
+  os << "cellAccessRelatedInfo.cellIdentity " << (int)m_asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.cellIdentity << std::endl;
+  os << "cellAccessRelatedInfo.csgIndication: " << m_asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIndication << std::endl;
+  os << "cellAccessRelatedInfo.csgIdentity: " << (int)m_asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIdentity << std::endl;
+  os << "sourceDlCarrierFreq: " << m_asConfig.sourceDlCarrierFreq << std::endl;
+}
+
+void
+HandoverPreparationInfoHeader::SetMessage (HandoverPreparationInfo msg)
+{
+  m_asConfig = msg.asConfig;
+  m_isDataSerialized = false;
+}
+
+LteRrcSap::AsConfig
+HandoverPreparationInfoHeader::GetAsConfig () const
+{
+  return m_asConfig;
+}
+
+
+} // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-rrc-header.h	Thu Nov 29 17:18:51 2012 +0100
@@ -0,0 +1,221 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Lluis Parcerisa <lparcerisa@cttc.cat>
+ */
+
+#ifndef RRC_HEADER_H
+#define RRC_HEADER_H
+
+#include "ns3/header.h"
+
+#include <bitset>
+#include <string>
+
+#include "ns3/lte-rrc-sap.h"
+#include "ns3/lte-asn1-header.h"
+
+namespace ns3 {
+
+/**
+ * This class extends Asn1Header functions, adding serialization/deserialization
+ * of some Information elements defined in 3GPP TS 36.331
+ */
+class RrcAsn1Header : public Asn1Header
+{
+public:
+  RrcAsn1Header ();
+
+protected:
+  // Serialization functions
+  void SerializeSrbToAddModList (std::list<LteRrcSap::SrbToAddMod> srbToAddModList) const;
+  void SerializeDrbToAddModList (std::list<LteRrcSap::DrbToAddMod> drbToAddModList) const;
+  void SerializeLogicalChannelConfig (LteRrcSap::LogicalChannelConfig logicalChannelConfig) const;
+  void SerializeRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated radioResourceConfigDedicated) const;
+  void SerializePhysicalConfigDedicated (LteRrcSap::PhysicalConfigDedicated physicalConfigDedicated) const;
+  void SerializeSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 systemInformationBlockType1) const;
+  void SerializeSystemInformationBlockType2 () const;
+  void SerializeRadioResourceConfigCommonSIB () const;
+
+  // Deserialization functions
+  Buffer::Iterator DeserializeDrbToAddModList (std::list<LteRrcSap::DrbToAddMod> *drbToAddModLis, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeSrbToAddModList (std::list<LteRrcSap::SrbToAddMod> *srbToAddModList, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeLogicalChannelConfig (LteRrcSap::LogicalChannelConfig *logicalChannelConfig, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated *radioResourceConfigDedicated, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializePhysicalConfigDedicated (LteRrcSap::PhysicalConfigDedicated *physicalConfigDedicated, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 *systemInformationBlockType1, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeSystemInformationBlockType2 (Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeRadioResourceConfigCommon (Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeRadioResourceConfigCommonSib (Buffer::Iterator bIterator);
+
+  void Print (std::ostream &os, LteRrcSap::RadioResourceConfigDedicated radioResourceConfigDedicated) const;
+};
+
+/**
+* This class manages the serialization/deserialization of RrcConnectionRequest IE
+*/
+class RrcConnectionRequestHeader : public RrcAsn1Header,
+                                   LteRrcSap
+{
+public:
+  RrcConnectionRequestHeader ();
+  void PreSerialize () const;
+  uint32_t Deserialize (Buffer::Iterator bIterator);
+  void Print (std::ostream &os) const;
+  void SetMessage (RrcConnectionRequest msg);
+
+  std::bitset<8> getMmec () const;
+  std::bitset<32> getMtmsi () const;
+
+private:
+  std::bitset<8> m_mmec;
+  std::bitset<32> m_mTmsi;
+  enum
+  {
+    EMERGENCY = 0, HIGHPRIORITYACCESS, MT_ACCESS,
+    MO_SIGNALLING, MO_DATA, SPARE3, SPARE2, SPARE1
+  } m_establishmentCause;
+  std::bitset<1> m_spare;
+};
+
+/**
+* This class manages the serialization/deserialization of RrcConnectionSetup IE
+*/
+class RrcConnectionSetupHeader : public RrcAsn1Header,
+                                 LteRrcSap
+{
+public:
+  RrcConnectionSetupHeader ();
+  void PreSerialize () const;
+  uint32_t Deserialize (Buffer::Iterator bIterator);
+  void Print (std::ostream &os) const;
+  void SetMessage (RrcConnectionSetup msg);
+
+  uint8_t GetRrcTransactionIdentifier () const;
+  bool HavePhysicalConfigDedicated () const;
+  std::list<LteRrcSap::SrbToAddMod> GetSrbToAddModList () const;
+  std::list<LteRrcSap::DrbToAddMod> GetDrbToAddModList () const;
+  std::list<uint8_t> GetDrbToReleaseList () const;
+  LteRrcSap::PhysicalConfigDedicated GetPhysicalConfigDedicated () const;
+  LteRrcSap::RadioResourceConfigDedicated GetRadioResourceConfigDedicated () const;
+
+private:
+  uint8_t rrcTransactionIdentifier;
+  mutable RadioResourceConfigDedicated radioResourceConfigDedicated;
+};
+
+/**
+* This class manages the serialization/deserialization of RrcConnectionSetupComplete IE
+*/
+class RrcConnectionSetupCompleteHeader : public RrcAsn1Header,
+                                         LteRrcSap
+{
+public:
+  RrcConnectionSetupCompleteHeader ();
+  void PreSerialize () const;
+  uint32_t Deserialize (Buffer::Iterator bIterator);
+  void Print (std::ostream &os) const;
+  void SetMessage (RrcConnectionSetupCompleted msg);
+
+  uint8_t GetRrcTransactionIdentifier () const;
+
+private:
+  uint8_t m_rrcTransactionIdentifier;
+
+};
+
+/**
+* This class manages the serialization/deserialization of RrcConnectionSetupComplete IE
+*/
+class RrcConnectionReconfigurationCompleteHeader : public RrcAsn1Header,
+                                                   LteRrcSap
+{
+public:
+  RrcConnectionReconfigurationCompleteHeader ();
+  void PreSerialize () const;
+  uint32_t Deserialize (Buffer::Iterator bIterator);
+  void Print (std::ostream &os) const;
+  void SetMessage (RrcConnectionReconfigurationCompleted msg);
+
+  uint8_t GetRrcTransactionIdentifier () const;
+
+private:
+  uint8_t m_rrcTransactionIdentifier;
+
+};
+
+/**
+* This class manages the serialization/deserialization of RrcConnectionReconfiguration IE
+*/
+class RrcConnectionReconfigurationHeader : public RrcAsn1Header,
+                                           LteRrcSap
+{
+public:
+  RrcConnectionReconfigurationHeader ();
+  void PreSerialize () const;
+  uint32_t Deserialize (Buffer::Iterator bIterator);
+  void Print (std::ostream &os) const;
+  void SetMessage (RrcConnectionReconfiguration msg);
+
+  uint8_t GetRrcTransactionIdentifier () const;
+  bool GetHaveMeasConfig ();
+  MeasConfig GetMeasConfig ();
+  bool GetHaveMobilityControlInfo ();
+  MobilityControlInfo GetMobilityControlInfo ();
+  bool GetHaveRadioResourceConfigDedicated ();
+  RadioResourceConfigDedicated GetRadioResourceConfigDedicated ();
+
+  // RadioResourceConfigDedicated functions
+  bool HavePhysicalConfigDedicated () const;
+  std::list<LteRrcSap::SrbToAddMod> GetSrbToAddModList () const;
+  std::list<LteRrcSap::DrbToAddMod> GetDrbToAddModList () const;
+  std::list<uint8_t> GetDrbToReleaseList () const;
+  LteRrcSap::PhysicalConfigDedicated GetPhysicalConfigDedicated () const;
+
+private:
+  uint8_t m_rrcTransactionIdentifier;
+  bool m_haveMeasConfig;
+  MeasConfig m_measConfig;
+  bool m_haveMobilityControlInfo;
+  MobilityControlInfo m_mobilityControlInfo;
+  bool m_haveRadioResourceConfigDedicated;
+  RadioResourceConfigDedicated m_radioResourceConfigDedicated;
+};
+
+/**
+* This class manages the serialization/deserialization of HandoverPreparationInfo IE
+*/
+class HandoverPreparationInfoHeader : public RrcAsn1Header,
+                                      LteRrcSap
+{
+public:
+  HandoverPreparationInfoHeader ();
+  void PreSerialize () const;
+  uint32_t Deserialize (Buffer::Iterator bIterator);
+  void Print (std::ostream &os) const;
+  void SetMessage (HandoverPreparationInfo msg);
+
+  AsConfig GetAsConfig () const;
+
+private:
+  AsConfig m_asConfig;
+};
+
+} // namespace ns3
+
+#endif // EPC_ASN1_HEADER_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/test-asn1-encoding.cc	Thu Nov 29 17:18:51 2012 +0100
@@ -0,0 +1,624 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011, 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Lluis Parcerisa <lparcerisa@cttc.cat>
+ */
+
+#include "ns3/log.h"
+#include "ns3/string.h"
+#include "ns3/double.h"
+#include "ns3/enum.h"
+#include "ns3/boolean.h"
+#include "ns3/test.h"
+#include "ns3/ptr.h"
+#include "ns3/packet.h"
+
+#include "ns3/lte-rrc-header.h"
+#include "ns3/lte-rrc-sap.h"
+
+NS_LOG_COMPONENT_DEFINE ("Asn1EncodingTest");
+
+namespace ns3 {
+
+class TestUtils
+{
+public:
+  // Function to output packet contents in hex format
+  static void printPacketContentsHex (Packet *pkt)
+  {
+    uint32_t psize = pkt->GetSize ();
+    uint8_t buffer[psize];
+    pkt->CopyData (buffer, psize); 
+    for (uint32_t i = 0; i < psize; i++)
+      {
+        printf ("%02x ",buffer[i]);
+      }
+    printf ("\n\n");
+  }
+  // Function to output packet contents in binary format
+  static void printPacketContentsBin (Packet *pkt)
+  {
+    uint32_t psize = pkt->GetSize ();
+    uint8_t buffer[psize];
+    pkt->CopyData (buffer, psize); 
+    for (uint32_t i = 0; i < psize; i++)
+      {
+        std::cout << std::bitset<8> (buffer[i]) << " ";
+      }
+    std::cout << std::endl << std::endl;
+  }
+};
+
+// --------------------------- CLASS RrcHeaderTestCase -----------------------------
+/**
+ * This class provides common functions to be inherited
+ * by the children TestCases
+ */
+class RrcHeaderTestCase : public TestCase
+{
+public:
+  RrcHeaderTestCase (std::string s);
+  virtual void DoRun (void) = 0;
+  LteRrcSap::RadioResourceConfigDedicated CreateRadioResourceConfigDedicated ();
+  void AssertEqualRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated rrcd1, LteRrcSap::RadioResourceConfigDedicated rrcd2);
+};
+
+RrcHeaderTestCase :: RrcHeaderTestCase (std::string s) : TestCase (s)
+{
+}
+
+LteRrcSap::RadioResourceConfigDedicated
+RrcHeaderTestCase :: CreateRadioResourceConfigDedicated ()
+{
+  LteRrcSap::RadioResourceConfigDedicated rrd;
+
+  rrd.drbToReleaseList = std::list<uint8_t> (4,2);
+
+  LteRrcSap::SrbToAddMod srbToAddMod;
+  srbToAddMod.srbIdentity = 2;
+
+  LteRrcSap::LogicalChannelConfig logicalChannelConfig;
+  logicalChannelConfig.priority = 9;
+  logicalChannelConfig.prioritizedBitRateKbps = 128;
+  logicalChannelConfig.bucketSizeDurationMs = 100;
+  logicalChannelConfig.logicalChannelGroup = 3;
+  srbToAddMod.logicalChannelConfig = logicalChannelConfig;
+
+  rrd.srbToAddModList.insert (rrd.srbToAddModList.begin (),srbToAddMod);
+
+  LteRrcSap::DrbToAddMod drbToAddMod;
+  drbToAddMod.epsBearerIdentity = 1;
+  drbToAddMod.drbIdentity = 1;
+  drbToAddMod.logicalChannelIdentity = 5;
+  LteRrcSap::RlcConfig rlcConfig;
+  rlcConfig.choice = LteRrcSap::RlcConfig::UM_BI_DIRECTIONAL;
+  drbToAddMod.rlcConfig = rlcConfig;
+
+  LteRrcSap::LogicalChannelConfig logicalChannelConfig2;
+  logicalChannelConfig2.priority = 7;
+  logicalChannelConfig2.prioritizedBitRateKbps = 256;
+  logicalChannelConfig2.bucketSizeDurationMs = 50;
+  logicalChannelConfig2.logicalChannelGroup = 2;
+  drbToAddMod.logicalChannelConfig = logicalChannelConfig2;
+
+  rrd.drbToAddModList.insert (rrd.drbToAddModList.begin (),drbToAddMod);
+
+  rrd.havePhysicalConfigDedicated = true;
+  LteRrcSap::PhysicalConfigDedicated physicalConfigDedicated;
+  physicalConfigDedicated.haveSoundingRsUlConfigDedicated = true;
+  physicalConfigDedicated.soundingRsUlConfigDedicated.type = LteRrcSap::SoundingRsUlConfigDedicated::SETUP;
+  physicalConfigDedicated.soundingRsUlConfigDedicated.srsBandwidth = 2;
+  physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex = 12;
+
+  physicalConfigDedicated.haveAntennaInfoDedicated = true;
+  physicalConfigDedicated.antennaInfo.transmissionMode = 3;
+
+  rrd.physicalConfigDedicated = physicalConfigDedicated;
+
+  return rrd;
+}
+
+void
+RrcHeaderTestCase :: AssertEqualRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated rrcd1, LteRrcSap::RadioResourceConfigDedicated rrcd2)
+{
+  NS_TEST_ASSERT_MSG_EQ (rrcd1.srbToAddModList.size (), rrcd2.srbToAddModList.size (),"SrbToAddModList different sizes");
+ 
+  std::list<LteRrcSap::SrbToAddMod> srcSrbToAddModList = rrcd1.srbToAddModList;
+  std::list<LteRrcSap::SrbToAddMod>::iterator it1 = srcSrbToAddModList.begin ();
+  std::list<LteRrcSap::SrbToAddMod> dstSrbToAddModList = rrcd2.srbToAddModList;
+  std::list<LteRrcSap::SrbToAddMod>::iterator it2 = dstSrbToAddModList.begin ();
+
+  for (; it1 != srcSrbToAddModList.end (); it1++, it2++)
+    {
+      NS_TEST_ASSERT_MSG_EQ (it1->srbIdentity,it2->srbIdentity, "srbIdentity");
+      NS_TEST_ASSERT_MSG_EQ (it1->logicalChannelConfig.priority,it2->logicalChannelConfig.priority, "logicalChannelConfig.priority");
+      NS_TEST_ASSERT_MSG_EQ (it1->logicalChannelConfig.prioritizedBitRateKbps,it2->logicalChannelConfig.prioritizedBitRateKbps, "logicalChannelConfig.prioritizedBitRateKbps");
+      NS_TEST_ASSERT_MSG_EQ (it1->logicalChannelConfig.bucketSizeDurationMs,it2->logicalChannelConfig.bucketSizeDurationMs, "logicalChannelConfig.bucketSizeDurationMs");
+      NS_TEST_ASSERT_MSG_EQ (it1->logicalChannelConfig.logicalChannelGroup,it2->logicalChannelConfig.logicalChannelGroup, "logicalChannelConfig.logicalChannelGroup");
+    }
+
+  NS_TEST_ASSERT_MSG_EQ (rrcd1.drbToAddModList.size (), rrcd2.drbToAddModList.size (),"DrbToAddModList different sizes");
+
+  std::list<LteRrcSap::DrbToAddMod> srcDrbToAddModList = rrcd1.drbToAddModList;
+  std::list<LteRrcSap::DrbToAddMod>::iterator it3 = srcDrbToAddModList.begin ();
+  std::list<LteRrcSap::DrbToAddMod> dstDrbToAddModList = rrcd2.drbToAddModList;
+  std::list<LteRrcSap::DrbToAddMod>::iterator it4 = dstDrbToAddModList.begin ();
+
+  for (; it3 != srcDrbToAddModList.end (); it3++, it4++)
+    {
+      NS_TEST_ASSERT_MSG_EQ (it3->epsBearerIdentity,it4->epsBearerIdentity, "epsBearerIdentity");
+      NS_TEST_ASSERT_MSG_EQ (it3->drbIdentity,it4->drbIdentity, "drbIdentity");
+      NS_TEST_ASSERT_MSG_EQ (it3->rlcConfig.choice,it4->rlcConfig.choice, "rlcConfig.choice");
+      NS_TEST_ASSERT_MSG_EQ (it3->logicalChannelIdentity,it4->logicalChannelIdentity, "logicalChannelIdentity");
+      NS_TEST_ASSERT_MSG_EQ (it3->epsBearerIdentity,it4->epsBearerIdentity, "epsBearerIdentity");
+
+      NS_TEST_ASSERT_MSG_EQ (it3->logicalChannelConfig.priority,it4->logicalChannelConfig.priority, "logicalChannelConfig.priority");
+      NS_TEST_ASSERT_MSG_EQ (it3->logicalChannelConfig.prioritizedBitRateKbps,it4->logicalChannelConfig.prioritizedBitRateKbps, "logicalChannelConfig.prioritizedBitRateKbps");
+      NS_TEST_ASSERT_MSG_EQ (it3->logicalChannelConfig.bucketSizeDurationMs,it4->logicalChannelConfig.bucketSizeDurationMs, "logicalChannelConfig.bucketSizeDurationMs");
+      NS_TEST_ASSERT_MSG_EQ (it3->logicalChannelConfig.logicalChannelGroup,it4->logicalChannelConfig.logicalChannelGroup, "logicalChannelConfig.logicalChannelGroup");
+    }
+
+  NS_TEST_ASSERT_MSG_EQ (rrcd1.drbToReleaseList.size (), rrcd2.drbToReleaseList.size (),"DrbToReleaseList different sizes");
+
+  std::list<uint8_t> srcDrbToReleaseList = rrcd1.drbToReleaseList;
+  std::list<uint8_t> dstDrbToReleaseList = rrcd2.drbToReleaseList;
+  std::list<uint8_t>::iterator it5 = srcDrbToReleaseList.begin ();
+  std::list<uint8_t>::iterator it6 = dstDrbToReleaseList.begin ();
+
+  for (; it5 != srcDrbToReleaseList.end (); it5++, it6++)
+    {
+      NS_TEST_ASSERT_MSG_EQ (*it5, *it6,"element != in DrbToReleaseList");
+    }
+
+  NS_TEST_ASSERT_MSG_EQ (rrcd1.havePhysicalConfigDedicated,rrcd2.havePhysicalConfigDedicated, "HavePhysicalConfigDedicated");
+
+  if (rrcd1.havePhysicalConfigDedicated)
+    {
+      NS_TEST_ASSERT_MSG_EQ (rrcd1.physicalConfigDedicated.haveSoundingRsUlConfigDedicated,
+                             rrcd2.physicalConfigDedicated.haveSoundingRsUlConfigDedicated,
+                             "haveSoundingRsUlConfigDedicated");
+
+      NS_TEST_ASSERT_MSG_EQ (rrcd1.physicalConfigDedicated.soundingRsUlConfigDedicated.type,
+                             rrcd2.physicalConfigDedicated.soundingRsUlConfigDedicated.type,
+                             "soundingRsUlConfigDedicated.type");
+      NS_TEST_ASSERT_MSG_EQ (rrcd1.physicalConfigDedicated.soundingRsUlConfigDedicated.srsBandwidth,
+                             rrcd2.physicalConfigDedicated.soundingRsUlConfigDedicated.srsBandwidth,
+                             "soundingRsUlConfigDedicated.srsBandwidth");
+
+      NS_TEST_ASSERT_MSG_EQ (rrcd1.physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex,
+                             rrcd2.physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex,
+                             "soundingRsUlConfigDedicated.srsConfigIndex");
+
+      NS_TEST_ASSERT_MSG_EQ (rrcd1.physicalConfigDedicated.haveAntennaInfoDedicated,
+                             rrcd2.physicalConfigDedicated.haveAntennaInfoDedicated,
+                             "haveAntennaInfoDedicated");
+
+      if (rrcd1.physicalConfigDedicated.haveAntennaInfoDedicated)
+        {
+          NS_TEST_ASSERT_MSG_EQ (rrcd1.physicalConfigDedicated.antennaInfo.transmissionMode,
+                                 rrcd2.physicalConfigDedicated.antennaInfo.transmissionMode,
+                                 "antennaInfo.transmissionMode");
+        }
+    }
+}
+
+// --------------------------- CLASS RrcConnectionRequestTestCase -----------------------------
+class RrcConnectionRequestTestCase : public RrcHeaderTestCase
+{
+public:
+  RrcConnectionRequestTestCase ();
+  virtual void DoRun (void);
+};
+
+RrcConnectionRequestTestCase::RrcConnectionRequestTestCase () : RrcHeaderTestCase ("Testing RrcConnectionRequest")
+{
+}
+
+void
+RrcConnectionRequestTestCase::DoRun (void)
+{
+  std::cout << "============= RrcConnectionRequestTestCase ===========" << std::endl;
+  // add header
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->Print (std::cout);
+  std::cout << std::endl;
+
+  LteRrcSap::RrcConnectionRequest msg;
+  msg.ueIdentity = 0x83fecafeca;
+
+  RrcConnectionRequestHeader source;
+  source.SetMessage (msg);
+
+  std::cout << "--------- SOURCE INFO: -------" << std::endl;
+  source.Print (std::cout);
+  packet->AddHeader (source);
+  std::cout << std::endl;
+
+  // print serialized packet contents
+  std::cout << "---- SERIALIZED PACKET CONTENTS (HEX): -------" << std::endl;
+  std::cout << "Hex: ";
+  TestUtils::printPacketContentsHex (GetPointer (packet));
+  std::cout << "Bin: ";
+  TestUtils::printPacketContentsBin (GetPointer (packet));
+
+  // remove header
+  RrcConnectionRequestHeader destination;
+  packet->RemoveHeader (destination);
+  std::cout << "--------- DESTINATION INFO: -------" << std::endl;
+  destination.Print (std::cout);
+
+  // Check that the destination and source headers contain the same values
+  NS_TEST_ASSERT_MSG_EQ (source.getMmec (),destination.getMmec (), "Different m_mmec!");
+  NS_TEST_ASSERT_MSG_EQ (source.getMtmsi (),destination.getMtmsi (), "Different m_mTmsi!");
+}
+
+// --------------------------- CLASS RrcConnectionSetupTestCase -----------------------------
+class RrcConnectionSetupTestCase : public RrcHeaderTestCase
+{
+public:
+  RrcConnectionSetupTestCase ();
+  virtual void DoRun (void);
+};
+
+RrcConnectionSetupTestCase::RrcConnectionSetupTestCase () : RrcHeaderTestCase ("Testing RrcConnectionSetupTestCase")
+{
+}
+
+void
+RrcConnectionSetupTestCase::DoRun (void)
+{
+  std::cout << "============= RrcConnectionSetupTestCase ===========" << std::endl;
+  // add header
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->Print (std::cout);
+  std::cout << std::endl;
+
+  LteRrcSap::RrcConnectionSetup msg;
+  msg.rrcTransactionIdentifier = 3;
+  msg.radioResourceConfigDedicated = CreateRadioResourceConfigDedicated ();
+
+  RrcConnectionSetupHeader source;
+  source.SetMessage (msg);
+
+  std::cout << "--------- SOURCE INFO: -------" << std::endl;
+  source.Print (std::cout);
+  packet->AddHeader (source);
+  std::cout << std::endl;
+
+  // print serialized packet contents
+  std::cout << "---- SERIALIZED PACKET CONTENTS: -------" << std::endl;
+  std::cout << "Hex: ";
+  TestUtils::printPacketContentsHex (GetPointer (packet));
+  std::cout << "Bin: ";
+  TestUtils::printPacketContentsBin (GetPointer (packet));
+
+  // remove header
+  RrcConnectionSetupHeader destination;
+  packet->RemoveHeader (destination);
+  std::cout << "--------- DESTINATION INFO: -------" << std::endl;
+  destination.Print (std::cout);
+
+  // Check that the destination and source headers contain the same values
+  NS_TEST_ASSERT_MSG_EQ (source.GetRrcTransactionIdentifier (),destination.GetRrcTransactionIdentifier (), "RrcTransactionIdentifier");
+
+  AssertEqualRadioResourceConfigDedicated (source.GetRadioResourceConfigDedicated (),destination.GetRadioResourceConfigDedicated ());
+}
+
+// --------------------------- CLASS RrcConnectionSetupCompleteTestCase -----------------------------
+class RrcConnectionSetupCompleteTestCase : public RrcHeaderTestCase
+{
+public:
+  RrcConnectionSetupCompleteTestCase ();
+  virtual void DoRun (void);
+};
+
+RrcConnectionSetupCompleteTestCase::RrcConnectionSetupCompleteTestCase () : RrcHeaderTestCase ("Testing RrcConnectionSetupCompleteTestCase")
+{
+}
+
+void
+RrcConnectionSetupCompleteTestCase::DoRun (void)
+{
+  std::cout << "============= RrcConnectionSetupCompleteTestCase ===========" << std::endl;
+  // add header
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->Print (std::cout);
+  std::cout << std::endl;
+
+  LteRrcSap::RrcConnectionSetupCompleted msg;
+  msg.rrcTransactionIdentifier = 3;
+
+  RrcConnectionSetupCompleteHeader source;
+  source.SetMessage (msg);
+
+  std::cout << "--------- SOURCE INFO: -------" << std::endl;
+  source.Print (std::cout);
+  packet->AddHeader (source);
+  std::cout << std::endl;
+
+  // print serialized packet contents
+  std::cout << "---- SERIALIZED PACKET CONTENTS: -------" << std::endl;
+  std::cout << "Hex: ";
+  TestUtils::printPacketContentsHex (GetPointer (packet));
+  std::cout << "Bin: ";
+  TestUtils::printPacketContentsBin (GetPointer (packet));
+
+  // remove header
+  RrcConnectionSetupCompleteHeader destination;
+  packet->RemoveHeader (destination);
+  std::cout << "--------- DESTINATION INFO: -------" << std::endl;
+  destination.Print (std::cout);
+
+  // Check that the destination and source headers contain the same values
+  NS_TEST_ASSERT_MSG_EQ (source.GetRrcTransactionIdentifier (),destination.GetRrcTransactionIdentifier (), "RrcTransactionIdentifier");
+}
+
+// --------------------------- CLASS RrcConnectionReconfigurationCompleteTestCase -----------------------------
+class RrcConnectionReconfigurationCompleteTestCase : public RrcHeaderTestCase
+{
+public:
+  RrcConnectionReconfigurationCompleteTestCase ();
+  virtual void DoRun (void);
+};
+
+RrcConnectionReconfigurationCompleteTestCase::RrcConnectionReconfigurationCompleteTestCase ()
+  : RrcHeaderTestCase ("Testing RrcConnectionReconfigurationCompleteTestCase")
+{
+}
+
+void
+RrcConnectionReconfigurationCompleteTestCase::DoRun (void)
+{
+  std::cout << "============= RrcConnectionReconfigurationCompleteTestCase ===========" << std::endl;
+  // add header
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->Print (std::cout);
+  std::cout << std::endl;
+
+  LteRrcSap::RrcConnectionReconfigurationCompleted msg;
+  msg.rrcTransactionIdentifier = 2;
+
+  RrcConnectionReconfigurationCompleteHeader source;
+  source.SetMessage (msg);
+
+  std::cout << "--------- SOURCE INFO: -------" << std::endl;
+  source.Print (std::cout);
+  packet->AddHeader (source);
+  std::cout << std::endl;
+
+  // print serialized packet contents
+  std::cout << "---- SERIALIZED PACKET CONTENTS: -------" << std::endl;
+  std::cout << "Hex: ";
+  TestUtils::printPacketContentsHex (GetPointer (packet));
+  std::cout << "Bin: ";
+  TestUtils::printPacketContentsBin (GetPointer (packet));
+
+  // remove header
+  RrcConnectionReconfigurationCompleteHeader destination;
+  packet->RemoveHeader (destination);
+  std::cout << "--------- DESTINATION INFO: -------" << std::endl;
+  destination.Print (std::cout);
+
+  // Check that the destination and source headers contain the same values
+  NS_TEST_ASSERT_MSG_EQ (source.GetRrcTransactionIdentifier (),destination.GetRrcTransactionIdentifier (), "RrcTransactionIdentifier");
+}
+
+// --------------------------- CLASS RrcConnectionReconfigurationTestCase -----------------------------
+class RrcConnectionReconfigurationTestCase : public RrcHeaderTestCase
+{
+public:
+  RrcConnectionReconfigurationTestCase ();
+  virtual void DoRun (void);
+};
+
+RrcConnectionReconfigurationTestCase::RrcConnectionReconfigurationTestCase ()
+  : RrcHeaderTestCase ("Testing RrcConnectionReconfigurationTestCase")
+{
+}
+
+void
+RrcConnectionReconfigurationTestCase::DoRun (void)
+{
+  std::cout << "============= RrcConnectionReconfigurationTestCase ===========" << std::endl;
+  // add header
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->Print (std::cout);
+  std::cout << std::endl;
+
+  LteRrcSap::RrcConnectionReconfiguration msg;
+  msg.rrcTransactionIdentifier = 2;
+
+  msg.haveMeasConfig = false;
+  msg.haveMobilityControlInfo = true;
+  msg.mobilityControlInfo.targetPhysCellId = 4;
+  msg.mobilityControlInfo.haveCarrierFreq = true;
+  msg.mobilityControlInfo.carrierFreq.dlCarrierFreq = 3;
+  msg.mobilityControlInfo.carrierFreq.ulCarrierFreq = 5;
+  msg.mobilityControlInfo.haveCarrierBandwidth = true;
+  msg.mobilityControlInfo.carrierBandwidth.dlBandwidth = 5;
+  msg.mobilityControlInfo.carrierBandwidth.ulBandwidth = 3;
+  msg.mobilityControlInfo.newUeIdentity = 11;
+  msg.mobilityControlInfo.haveRachConfigDedicated = true;
+  msg.mobilityControlInfo.rachConfigDedicated.raPreambleIndex = 2; 
+  msg.mobilityControlInfo.rachConfigDedicated.raPrachMaskIndex = 2;
+
+  msg.haveRadioResourceConfigDedicated = true;
+
+  msg.radioResourceConfigDedicated = CreateRadioResourceConfigDedicated ();
+
+  RrcConnectionReconfigurationHeader source;
+  source.SetMessage (msg);
+
+  std::cout << "--------- SOURCE INFO: -------" << std::endl;
+  source.Print (std::cout);
+  packet->AddHeader (source);
+  std::cout << std::endl;
+
+  // print serialized packet contents
+  std::cout << "---- SERIALIZED PACKET CONTENTS: -------" << std::endl;
+  std::cout << "Hex: ";
+  TestUtils::printPacketContentsHex (GetPointer (packet));
+  std::cout << "Bin: ";
+  TestUtils::printPacketContentsBin (GetPointer (packet));
+
+  // remove header
+  RrcConnectionReconfigurationHeader destination;
+  packet->RemoveHeader (destination);
+  std::cout << "--------- DESTINATION INFO: -------" << std::endl;
+  destination.Print (std::cout);
+
+  // Check that the destination and source headers contain the same values
+  NS_TEST_ASSERT_MSG_EQ (source.GetRrcTransactionIdentifier (),destination.GetRrcTransactionIdentifier (), "RrcTransactionIdentifier");
+  NS_TEST_ASSERT_MSG_EQ (source.GetHaveMeasConfig (),destination.GetHaveMeasConfig (), "GetHaveMeasConfig");
+  NS_TEST_ASSERT_MSG_EQ (source.GetHaveMobilityControlInfo (),destination.GetHaveMobilityControlInfo (), "GetHaveMobilityControlInfo");
+  NS_TEST_ASSERT_MSG_EQ (source.GetHaveRadioResourceConfigDedicated (),destination.GetHaveRadioResourceConfigDedicated (), "GetHaveRadioResourceConfigDedicated");
+
+  if ( source.GetHaveMobilityControlInfo () )
+    {
+      NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().targetPhysCellId,destination.GetMobilityControlInfo ().targetPhysCellId, "GetMobilityControlInfo().targetPhysCellId");
+      NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().haveCarrierFreq,destination.GetMobilityControlInfo ().haveCarrierFreq, "GetMobilityControlInfo().haveCarrierFreq");
+      NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().haveCarrierBandwidth,destination.GetMobilityControlInfo ().haveCarrierBandwidth, "GetMobilityControlInfo().haveCarrierBandwidth");
+      NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().newUeIdentity,destination.GetMobilityControlInfo ().newUeIdentity, "GetMobilityControlInfo().newUeIdentity");
+      NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().haveRachConfigDedicated,destination.GetMobilityControlInfo ().haveRachConfigDedicated, "GetMobilityControlInfo().haveRachConfigDedicated");
+
+      if (source.GetMobilityControlInfo ().haveCarrierFreq)
+        {
+          NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().carrierFreq.dlCarrierFreq,
+                                 destination.GetMobilityControlInfo ().carrierFreq.dlCarrierFreq,
+                                 "GetMobilityControlInfo().carrierFreq.dlCarrierFreq");
+          NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().carrierFreq.ulCarrierFreq,
+                                 destination.GetMobilityControlInfo ().carrierFreq.ulCarrierFreq,
+                                 "GetMobilityControlInfo().carrierFreq.ulCarrierFreq");
+        }
+
+      if (source.GetMobilityControlInfo ().haveCarrierBandwidth)
+        {
+          NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().carrierBandwidth.dlBandwidth,
+                                 destination.GetMobilityControlInfo ().carrierBandwidth.dlBandwidth,
+                                 "GetMobilityControlInfo().carrierBandwidth.dlBandwidth");
+          NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().carrierBandwidth.ulBandwidth,
+                                 destination.GetMobilityControlInfo ().carrierBandwidth.ulBandwidth,
+                                 "GetMobilityControlInfo().carrierBandwidth.ulBandwidth");
+        }
+
+      if (source.GetMobilityControlInfo ().haveRachConfigDedicated)
+        {
+          NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().rachConfigDedicated.raPreambleIndex,
+                                 destination.GetMobilityControlInfo ().rachConfigDedicated.raPreambleIndex,
+                                 "GetMobilityControlInfo().rachConfigDedicated.raPreambleIndex");
+          NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().rachConfigDedicated.raPrachMaskIndex,
+                                 destination.GetMobilityControlInfo ().rachConfigDedicated.raPrachMaskIndex,
+                                 "GetMobilityControlInfo().rachConfigDedicated.raPrachMaskIndex");
+        }
+    }
+
+  if (source.GetHaveRadioResourceConfigDedicated ())
+    {
+      AssertEqualRadioResourceConfigDedicated (source.GetRadioResourceConfigDedicated (), destination.GetRadioResourceConfigDedicated ());
+    }
+}
+
+// --------------------------- CLASS HandoverPreparationInfoTestCase -----------------------------
+class HandoverPreparationInfoTestCase : public RrcHeaderTestCase
+{
+public:
+  HandoverPreparationInfoTestCase ();
+  virtual void DoRun (void);
+};
+
+HandoverPreparationInfoTestCase::HandoverPreparationInfoTestCase () : RrcHeaderTestCase ("Testing HandoverPreparationInfoTestCase")
+{
+}
+
+void
+HandoverPreparationInfoTestCase::DoRun (void)
+{
+  std::cout << "============= HandoverPreparationInfoTestCase ===========" << std::endl;
+  // add header
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->Print (std::cout);
+  std::cout << std::endl;
+
+  LteRrcSap::HandoverPreparationInfo msg;
+  msg.asConfig.sourceDlCarrierFreq = 3;
+  msg.asConfig.sourceUeIdentity = 11;
+  msg.asConfig.sourceRadioResourceConfig = CreateRadioResourceConfigDedicated ();
+  msg.asConfig.sourceMasterInformationBlock.dlBandwidth = 3;
+  msg.asConfig.sourceMasterInformationBlock.systemFrameNumber = 1;
+
+  msg.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIndication = true;
+  msg.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.cellIdentity = 5;
+  msg.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIdentity = 4;
+  msg.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity = 123;
+
+  HandoverPreparationInfoHeader source;
+  source.SetMessage (msg);
+
+  std::cout << "--------- SOURCE INFO: -------" << std::endl;
+  source.Print (std::cout);
+  packet->AddHeader (source);
+  std::cout << std::endl;
+
+  // print serialized packet contents
+  std::cout << "---- SERIALIZED PACKET CONTENTS: -------" << std::endl;
+  std::cout << "Hex: ";
+  TestUtils::printPacketContentsHex (GetPointer (packet));
+  std::cout << "Bin: ";
+  TestUtils::printPacketContentsBin (GetPointer (packet));
+
+  // remove header
+  HandoverPreparationInfoHeader destination;
+  packet->RemoveHeader (destination);
+  std::cout << "--------- DESTINATION INFO: -------" << std::endl;
+  destination.Print (std::cout);
+
+  // Check that the destination and source headers contain the same values
+  AssertEqualRadioResourceConfigDedicated (source.GetAsConfig ().sourceRadioResourceConfig, destination.GetAsConfig ().sourceRadioResourceConfig);
+  NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceUeIdentity, destination.GetAsConfig ().sourceUeIdentity, "sourceUeIdentity");
+  NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceMasterInformationBlock.dlBandwidth,destination.GetAsConfig ().sourceMasterInformationBlock.dlBandwidth, "dlBandwidth");
+  NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceMasterInformationBlock.systemFrameNumber, destination.GetAsConfig ().sourceMasterInformationBlock.systemFrameNumber, "systemFrameNumber");
+  NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity, destination.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity, "plmnIdentity");
+  NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIndication, destination.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIndication, "csgIndication");
+  NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.cellIdentity, destination.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.cellIdentity, "cellIdentity");
+  NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIdentity, destination.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIdentity, "csgIdentity");
+  NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceDlCarrierFreq, destination.GetAsConfig ().sourceDlCarrierFreq, "sourceDlCarrierFreq");
+}
+
+// --------------------------- CLASS Asn1EncodingSuite -----------------------------
+class Asn1EncodingSuite : public TestSuite
+{
+public:
+  Asn1EncodingSuite ();
+};
+
+Asn1EncodingSuite::Asn1EncodingSuite ()
+  : TestSuite ("test-asn1-encoding", UNIT)
+{
+  Packet::EnablePrinting ();
+  NS_LOG_FUNCTION (this);
+  AddTestCase (new RrcConnectionRequestTestCase);
+  AddTestCase (new RrcConnectionSetupTestCase);
+  AddTestCase (new RrcConnectionSetupCompleteTestCase);
+  AddTestCase (new RrcConnectionReconfigurationCompleteTestCase);
+  AddTestCase (new RrcConnectionReconfigurationTestCase);
+  AddTestCase (new HandoverPreparationInfoTestCase);
+}
+
+Asn1EncodingSuite asn1EncodingSuite;
+
+} // namespace ns3
+
--- a/src/lte/wscript	Thu Nov 29 12:44:23 2012 +0100
+++ b/src/lte/wscript	Thu Nov 29 17:18:51 2012 +0100
@@ -82,6 +82,8 @@
         'model/epc-ue-nas.cc',
         'model/lte-harq-phy.cc',
         'model/epc-mme.cc',
+        'model/lte-asn1-header.cc',
+	'model/lte-rrc-header.cc',
         ]
 
     module_test = bld.create_ns3_module_test_library('lte')
@@ -115,6 +117,7 @@
         'test/lte-test-harq.cc',
         'test/test-lte-rrc.cc',
         'test/test-lte-x2-handover.cc',
+        'test/test-asn1-encoding.cc',
         ]
 
     headers = bld.new_task_gen(features=['ns3header'])
@@ -200,6 +203,8 @@
         'model/epc-ue-nas.h',
         'model/lte-harq-phy.h',
         'model/epc-mme.h',
+        'model/lte-asn1-header.h',
+	'model/lte-rrc-header.h',
         ]
 
     if (bld.env['ENABLE_EXAMPLES']):