/* -*-  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>
 * Modified by:
 *          Danilo Abrignani <danilo.abrignani@unibo.it> (Carrier Aggregation - GSoC 2015)
 *          Biljana Bojovic <biljana.bojovic@cttc.es> (Carrier Aggregation)
 */

#include "ns3/log.h"
#include "ns3/lte-rrc-header.h"

#include <stdio.h>
#include <sstream>

#define MAX_DRB 11 // According to section 6.4 3GPP TS 36.331
#define MAX_EARFCN 262143
#define MAX_RAT_CAPABILITIES 8
#define MAX_SI_MESSAGE 32
#define MAX_SIB 32

#define MAX_REPORT_CONFIG_ID 32
#define MAX_OBJECT_ID 32
#define MAX_MEAS_ID 32
#define MAX_CELL_MEAS 32
#define MAX_CELL_REPORT 8

#define MAX_SCELL_REPORT 5
#define MAX_SCELL_CONF 5
namespace ns3 {

NS_LOG_COMPONENT_DEFINE ("RrcHeader");


//////////////////// RrcAsn1Header class ///////////////////////////////
RrcAsn1Header::RrcAsn1Header ()
{
}

TypeId
RrcAsn1Header::GetTypeId (void)
{
  static TypeId tid = TypeId ("ns3::RrcAsn1Header")
    .SetParent<Header> ()
    .SetGroupName("Lte")
  ;
  return tid;
}

TypeId
RrcAsn1Header::GetInstanceTypeId (void) const
{
  return GetTypeId ();
}

int
RrcAsn1Header::GetMessageType ()
{
  return m_messageType;
}

int
RrcAsn1Header::BandwidthToEnum (uint16_t bandwidth) const
{
  int n;
  switch (bandwidth)
    {
      case 6: n = 0; break;
      case 15: n = 1; break;
      case 25: n = 2; break;
      case 50: n = 3; break;
      case 75: n = 4; break;
      case 100: n = 5; break;
      default:
        NS_FATAL_ERROR ("Wrong bandwidth: " << bandwidth);
    }
  return n;
}

uint16_t
RrcAsn1Header::EnumToBandwidth (int n) const
{
  uint16_t bw;
  switch (n)
    {
      case 0: bw = 6; break;
      case 1: bw = 15; break;
      case 2: bw = 25; break;
      case 3: bw = 50; break;
      case 4: bw = 75; break;
      case 5: bw = 100; break;
      default:
        NS_FATAL_ERROR ("Wrong enum value for bandwidth: " << n);
    }
  return bw;
}

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 (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::UM_BI_DIRECTIONAL:
          // Serialize rlc-Config choice
          SerializeChoice (4,1,true);

          // Serialize UL-UM-RLC
          SerializeSequence (std::bitset<0> (),false);
          SerializeEnum (2,0);  // sn-FieldLength

          // Serialize DL-UM-RLC
          SerializeSequence (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,true);

          // Serialize UL-UM-RLC
          SerializeSequence (std::bitset<0> (),false);
          SerializeEnum (2,0);  // sn-FieldLength
          break;

        case LteRrcSap::RlcConfig::UM_UNI_DIRECTIONAL_DL:
          // Serialize rlc-Config choice
          SerializeChoice (4,3,true);

          // Serialize DL-UM-RLC
          SerializeSequence (std::bitset<0> (),false);
          SerializeEnum (2,0);  // sn-FieldLength
          SerializeEnum (32,0);  // t-Reordering
          break;

        case LteRrcSap::RlcConfig::AM:
        default:
          // Serialize rlc-Config choice
          SerializeChoice (4,0,true);

          // Serialize UL-AM-RLC
          SerializeSequence (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 (std::bitset<0> (),false);
          SerializeEnum (32,0);  // t-Reordering
          SerializeEnum (64,0);  // t-StatusProhibit
          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 (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,false);

      // Serialize LogicalChannelConfig 
      SerializeLogicalChannelConfig (it->logicalChannelConfig);
    }
}

void
RrcAsn1Header::SerializeLogicalChannelConfig (LteRrcSap::LogicalChannelConfig logicalChannelConfig) const
{
  // Serialize LogicalChannelConfig sequence
  // 1 optional field (ul-SpecificParameters), which is present. Extension marker present.
  SerializeSequence (std::bitset<1> (1),true);

  // Serialize ul-SpecificParameters sequence
  // 1 optional field (logicalChannelGroup), which is present. No extension marker.
  SerializeSequence (std::bitset<1> (1),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,physicalConfigDedicated.havePdschConfigDedicated);  // pdsch-ConfigDedicated
  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 (optionalFieldsPhysicalConfigDedicated,true);

  if (physicalConfigDedicated.havePdschConfigDedicated)
    {
      // Serialize Pdsch-ConfigDedicated Sequence:
      // 0 optional / default fields, no extension marker.
      SerializeSequence (std::bitset<0> (),false);

      // Serialize  p-a
      // Assuming the value in the struct is the enum index
      SerializeEnum (8,physicalConfigDedicated.pdschConfigDedicated.pa);

      // Serialize release
      SerializeNull ();
    }

  if (physicalConfigDedicated.haveSoundingRsUlConfigDedicated)
    {
      // Serialize SoundingRS-UL-ConfigDedicated choice:
      switch (physicalConfigDedicated.soundingRsUlConfigDedicated.type)
        {
        case LteRrcSap::SoundingRsUlConfigDedicated::RESET:
          SerializeChoice (2,0,false);
          SerializeNull ();
          break;

        case LteRrcSap::SoundingRsUlConfigDedicated::SETUP:
        default:
          // 2 options, selected: 1 (setup)
          SerializeChoice (2,1,false);

          // Serialize setup sequence
          // 0 optional / default fields, no extension marker.
          SerializeSequence (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,false);

      // Serialize AntennaInfoDedicated sequence
      // 1 optional parameter, not present. No extension marker.
      SerializeSequence (std::bitset<1> (0),false);

      // Serialize transmissionMode
      // Assuming the value in the struct is the enum index
      SerializeEnum (8,physicalConfigDedicated.antennaInfo.transmissionMode);

      // Serialize ue-TransmitAntennaSelection choice
      SerializeChoice (2,0,false);

      // Serialize release
      SerializeNull ();
    }
}

void
RrcAsn1Header::SerializeRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated radioResourceConfigDedicated) const
{
  bool isSrbToAddModListPresent = !radioResourceConfigDedicated.srbToAddModList.empty ();
  bool isDrbToAddModListPresent = !radioResourceConfigDedicated.drbToAddModList.empty ();
  bool isDrbToReleaseListPresent = !radioResourceConfigDedicated.drbToReleaseList.empty ();

  // 6 optional fields. Extension marker is present.
  std::bitset<6> optionalFieldsPresent = std::bitset<6> ();
  optionalFieldsPresent.set (5,isSrbToAddModListPresent);  // srb-ToAddModList present
  optionalFieldsPresent.set (4,isDrbToAddModListPresent);  // drb-ToAddModList present
  optionalFieldsPresent.set (3,isDrbToReleaseListPresent);  // 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 (optionalFieldsPresent,true);

  // Serialize srbToAddModList
  if (isSrbToAddModListPresent)
    {
      SerializeSrbToAddModList (radioResourceConfigDedicated.srbToAddModList);
    }

  // Serialize drbToAddModList
  if (isDrbToAddModListPresent)
    {
      SerializeDrbToAddModList (radioResourceConfigDedicated.drbToAddModList);
    }

  // Serialize drbToReleaseList
  if (isDrbToReleaseListPresent)
    {
      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);

  SerializePlmnIdentity (systemInformationBlockType1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity);

  // 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::SerializeRadioResourceConfigCommon (LteRrcSap::RadioResourceConfigCommon radioResourceConfigCommon) const
{
  // 9 optional fields. Extension marker yes.
  std::bitset<9> rrCfgCmmOpts;
  rrCfgCmmOpts.set (8,1); // rach-ConfigCommon is present
  rrCfgCmmOpts.set (7,0); // pdsch-ConfigCommon not present
  rrCfgCmmOpts.set (6,0); // phich-Config not present
  rrCfgCmmOpts.set (5,0); // pucch-ConfigCommon  not present
  rrCfgCmmOpts.set (4,0); // soundingRS-UL-ConfigCommon not present
  rrCfgCmmOpts.set (3,0); // uplinkPowerControlCommon not present
  rrCfgCmmOpts.set (2,0); // antennaInfoCommon not present
  rrCfgCmmOpts.set (1,0); // p-Max not present
  rrCfgCmmOpts.set (0,0); // tdd-Config not present

  SerializeSequence (rrCfgCmmOpts,true);

  if (rrCfgCmmOpts[8])
    {
      // Serialize RACH-ConfigCommon
      SerializeRachConfigCommon (radioResourceConfigCommon.rachConfigCommon);
    }

  // 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);
}

void
RrcAsn1Header::SerializeRadioResourceConfigCommonSib (LteRrcSap::RadioResourceConfigCommonSib radioResourceConfigCommonSib) const
{
  SerializeSequence (std::bitset<0> (0),true);

  // rach-ConfigCommon
  SerializeRachConfigCommon (radioResourceConfigCommonSib.rachConfigCommon);

  // 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,false);
  SerializeNull (); // release
  // uplinkPowerControlCommon 
  SerializeSequence (std::bitset<0> (0),false);
  SerializeInteger (0,-126,24); // p0-NominalPUSCH
  SerializeEnum (8,0); // alpha
  SerializeInteger (-110,-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 (LteRrcSap::SystemInformationBlockType2 systemInformationBlockType2) const
{
  SerializeSequence (std::bitset<2> (0),true);

  // RadioResourceConfigCommonSib
  SerializeRadioResourceConfigCommonSib (systemInformationBlockType2.radioResourceConfigCommon);

  // 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> (3),false);
  SerializeInteger ((int) systemInformationBlockType2.freqInfo.ulCarrierFreq, 0, MAX_EARFCN);
  SerializeEnum (6, BandwidthToEnum (systemInformationBlockType2.freqInfo.ulBandwidth));

  SerializeInteger (29,1,32); // additionalSpectrumEmission
  // timeAlignmentTimerCommon
  SerializeEnum (8,0);
}

void
RrcAsn1Header::SerializeMeasResults (LteRrcSap::MeasResults measResults) const
{
  // Watchdog: if list has 0 elements, set boolean to false
  if (measResults.measResultListEutra.empty ())
    {
      measResults.haveMeasResultNeighCells = false;
    }

    std::bitset<4> measResultOptional;
    measResultOptional.set (3,  measResults.haveScellsMeas);
    measResultOptional.set (2, false); //LocationInfo-r10
    measResultOptional.set (1, false); // MeasResultForECID-r9
    measResultOptional.set (0, measResults.haveMeasResultNeighCells);
    SerializeSequence(measResultOptional,true);

  // Serialize measId
  SerializeInteger (measResults.measId,1,MAX_MEAS_ID);

  // Serialize measResultServCell sequence
  SerializeSequence (std::bitset<0> (0),false);

  // Serialize rsrpResult
  SerializeInteger (measResults.rsrpResult,0,97);

  // Serialize rsrqResult
  SerializeInteger (measResults.rsrqResult,0,34);

  if (measResults.haveMeasResultNeighCells)
    {
      // Serialize Choice = 0 (MeasResultListEUTRA)
      SerializeChoice (4,0,false);

      // Serialize measResultNeighCells
      SerializeSequenceOf (measResults.measResultListEutra.size (),MAX_CELL_REPORT,1);

      // serialize MeasResultEutra elements in the list
      std::list<LteRrcSap::MeasResultEutra>::iterator it;
      for (it = measResults.measResultListEutra.begin (); it != measResults.measResultListEutra.end (); it++)
        {
          SerializeSequence (std::bitset<1> (it->haveCgiInfo),false);

          // Serialize PhysCellId
          SerializeInteger (it->physCellId, 0, 503);

          // Serialize CgiInfo
          if (it->haveCgiInfo)
            {
              SerializeSequence (std::bitset<1> (it->cgiInfo.plmnIdentityList.size ()),false);

              // Serialize cellGlobalId
              SerializeSequence (std::bitset<0> (0),false);
              SerializePlmnIdentity (it->cgiInfo.plmnIdentity);
              SerializeBitstring (std::bitset<28> (it->cgiInfo.cellIdentity));

              // Serialize trackingAreaCode
              SerializeBitstring (std::bitset<16> (it->cgiInfo.trackingAreaCode));

              // Serialize plmn-IdentityList
              if (!it->cgiInfo.plmnIdentityList.empty ())
                {
                  SerializeSequenceOf (it->cgiInfo.plmnIdentityList.size (),5,1);
                  std::list<uint32_t>::iterator it2;
                  for (it2 = it->cgiInfo.plmnIdentityList.begin (); it2 != it->cgiInfo.plmnIdentityList.end (); it2++)
                    {
                      SerializePlmnIdentity (*it2);
                    }
                }
            }

          // Serialize measResult
          std::bitset<2> measResultFieldsPresent;
          measResultFieldsPresent[1] = it->haveRsrpResult;
          measResultFieldsPresent[0] = it->haveRsrqResult;
          SerializeSequence (measResultFieldsPresent,true);

          if (it->haveRsrpResult)
            {
              SerializeInteger (it->rsrpResult,0,97);
            }

          if (it->haveRsrqResult)
            {
              SerializeInteger (it->rsrqResult,0,34);
            }
        }
    }
    if (measResults.haveScellsMeas)
      {
        // Serialize measResultNeighCells
        SerializeSequenceOf (measResults.measScellResultList.measResultScell.size (),MAX_SCELL_REPORT,1);
        // serialize MeasResultServFreqList-r10 elements in the list
        std::list<LteRrcSap::MeasResultScell>::iterator it;
        for (it = measResults.measScellResultList.measResultScell.begin (); it != measResults.measScellResultList.measResultScell.end (); it++)
          {
            // Serialize measId
            SerializeInteger (it->servFreqId,0,MAX_MEAS_ID); // ToDo: change with FreqId, currently is the componentCarrierId
             // Serialize MeasResultServFreqList
            std::bitset<2> measResultScellPresent;
            measResultScellPresent[0] = measResults.measScellResultList.haveMeasurementResultsServingSCells;
            measResultScellPresent[1] = measResults.measScellResultList.haveMeasurementResultsNeighCell; // Not implemented
            SerializeSequence (measResultScellPresent,true);

            // Serialize measResult
            std::bitset<2> measResultScellFieldsPresent;
            measResultScellFieldsPresent[1] = it->haveRsrpResult;
            measResultScellFieldsPresent[0] = it->haveRsrqResult;
            SerializeSequence (measResultScellFieldsPresent,true);

            if (it->haveRsrpResult)
              {
                SerializeInteger (it->rsrpResult,0,97);
              }

            if (it->haveRsrqResult)
              {
                SerializeInteger (it->rsrqResult,0,34);
              }
            
          }
      }
}

void
RrcAsn1Header::SerializePlmnIdentity (uint32_t plmnId) const
{
  // plmn-Identity sequence, mcc is optional, no extension marker
  SerializeSequence (std::bitset<1> (0), false);

  // Serialize mnc
  int nDig = (plmnId > 99) ? 3 : 2;

  SerializeSequenceOf (nDig,3,2);
  for (int i = nDig - 1; i >= 0; i--)
    {
      int n = floor (plmnId / pow (10,i));
      SerializeInteger (n,0,9);
      plmnId -= n * pow (10,i);
    }

  // cellReservedForOperatorUse 
  SerializeEnum (2,0);
}

void 
RrcAsn1Header::SerializeRachConfigCommon (LteRrcSap::RachConfigCommon rachConfigCommon) const
{
  // rach-ConfigCommon
  SerializeSequence (std::bitset<0> (0),true);

  // preambleInfo
  SerializeSequence (std::bitset<1> (0),false);

  // numberOfRA-Preambles
  switch (rachConfigCommon.preambleInfo.numberOfRaPreambles)
    {
    case 4:
      SerializeEnum (16,0);
      break;
    case 8:
      SerializeEnum (16,1);
      break;
    case 12:
      SerializeEnum (16,2);
      break;
    case 16:
      SerializeEnum (16,3);
      break;
    case 20:
      SerializeEnum (16,4);
      break;
    case 24:
      SerializeEnum (16,5);
      break;
    case 28:
      SerializeEnum (16,6);
      break;
    case 32:
      SerializeEnum (16,7);
      break;
    case 36:
      SerializeEnum (16,8);
      break;
    case 40:
      SerializeEnum (16,9);
      break;
    case 44:
      SerializeEnum (16,10);
      break;
    case 48:
      SerializeEnum (16,11);
      break;
    case 52:
      SerializeEnum (16,12);
      break;
    case 56:
      SerializeEnum (16,13);
      break;
    case 60:
      SerializeEnum (16,14);
      break;
    case 64:
      SerializeEnum (16,15);
      break;
    default:
      NS_FATAL_ERROR ("Wrong numberOfRA-Preambles value");
    }

  SerializeSequence (std::bitset<0> (0),false); // powerRampingParameters
  SerializeEnum (4,0); // powerRampingStep
  SerializeEnum (16,0); // preambleInitialReceivedTargetPower
  SerializeSequence (std::bitset<0> (0),false); // ra-SupervisionInfo

  // preambleTransMax
  switch (rachConfigCommon.raSupervisionInfo.preambleTransMax)
    {
    case 3:
      SerializeEnum (11,0);
      break;
    case 4:
      SerializeEnum (11,1);
      break;
    case 5:
      SerializeEnum (11,2);
      break;
    case 6:
      SerializeEnum (11,3);
      break;
    case 7:
      SerializeEnum (11,4);
      break;
    case 8:
      SerializeEnum (11,5);
      break;
    case 10:
      SerializeEnum (11,6);
      break;
    case 20:
      SerializeEnum (11,7);
      break;
    case 50:
      SerializeEnum (11,8);
      break;
    case 100:
      SerializeEnum (11,9);
      break;
    case 200:
      SerializeEnum (11,10);
      break;
    default:
      SerializeEnum (11,0);
    }

  // ra-ResponseWindowSize
  switch (rachConfigCommon.raSupervisionInfo.raResponseWindowSize)
    {
    case 2:
      SerializeEnum (8,0);
      break;
    case 3:
      SerializeEnum (8,1);
      break;
    case 4:
      SerializeEnum (8,2);
      break;
    case 5:
      SerializeEnum (8,3);
      break;
    case 6:
      SerializeEnum (8,4);
      break;
    case 7:
      SerializeEnum (8,5);
      break;
    case 8:
      SerializeEnum (8,6);
      break;
    case 10:
      SerializeEnum (8,7);
      break;
    default:
      SerializeEnum (8,0);
    }

  SerializeEnum (8,0); // mac-ContentionResolutionTimer
  SerializeInteger (1,1,8); // maxHARQ-Msg3Tx

  // connEstFailCount
  switch (rachConfigCommon.txFailParam.connEstFailCount)
    {
    case 1:
      SerializeEnum (8,1);
      break;
    case 2:
      SerializeEnum (8,2);
      break;
    case 3:
      SerializeEnum (8,3);
      break;
    case 4:
      SerializeEnum (8,4);
      break;
    default:
      SerializeEnum (8,1);
    }
}

void
RrcAsn1Header::SerializeQoffsetRange (int8_t qOffsetRange) const
{
  switch (qOffsetRange)
    {
    case -24:
      SerializeEnum (31,0);
      break;
    case -22:
      SerializeEnum (31,1);
      break;
    case -20:
      SerializeEnum (31,2);
      break;
    case -18:
      SerializeEnum (31,3);
      break;
    case -16:
      SerializeEnum (31,4);
      break;
    case -14:
      SerializeEnum (31,5);
      break;
    case -12:
      SerializeEnum (31,6);
      break;
    case -10:
      SerializeEnum (31,7);
      break;
    case -8:
      SerializeEnum (31,8);
      break;
    case -6:
      SerializeEnum (31,9);
      break;
    case -5:
      SerializeEnum (31,10);
      break;
    case -4:
      SerializeEnum (31,11);
      break;
    case -3:
      SerializeEnum (31,12);
      break;
    case -2:
      SerializeEnum (31,13);
      break;
    case -1:
      SerializeEnum (31,14);
      break;
    case 0:
      SerializeEnum (31,15);
      break;
    case 1:
      SerializeEnum (31,16);
      break;
    case 2:
      SerializeEnum (31,17);
      break;
    case 3:
      SerializeEnum (31,18);
      break;
    case 4:
      SerializeEnum (31,19);
      break;
    case 5:
      SerializeEnum (31,20);
      break;
    case 6:
      SerializeEnum (31,21);
      break;
    case 8:
      SerializeEnum (31,22);
      break;
    case 10:
      SerializeEnum (31,23);
      break;
    case 12:
      SerializeEnum (31,24);
      break;
    case 14:
      SerializeEnum (31,25);
      break;
    case 16:
      SerializeEnum (31,26);
      break;
    case 18:
      SerializeEnum (31,27);
      break;
    case 20:
      SerializeEnum (31,28);
      break;
    case 22:
      SerializeEnum (31,29);
      break;
    case 24:
      SerializeEnum (31,30);
      break;
    default:
      SerializeEnum (31,15);
    }
}

void
RrcAsn1Header::SerializeThresholdEutra (LteRrcSap::ThresholdEutra thresholdEutra) const
{
  switch (thresholdEutra.choice)
    {
    case LteRrcSap::ThresholdEutra::THRESHOLD_RSRP:
      SerializeChoice (2,0,false);
      SerializeInteger (thresholdEutra.range, 0, 97);
      break;
    case LteRrcSap::ThresholdEutra::THRESHOLD_RSRQ:
    default:
      SerializeChoice (2,1,false);
      SerializeInteger (thresholdEutra.range, 0, 34);
    }
}

void
RrcAsn1Header::SerializeMeasConfig (LteRrcSap::MeasConfig measConfig) const
{
  // Serialize MeasConfig sequence
  // 11 optional fields, extension marker present
  std::bitset<11> measConfigOptional;
  measConfigOptional.set (10, !measConfig.measObjectToRemoveList.empty () );
  measConfigOptional.set (9, !measConfig.measObjectToAddModList.empty () );
  measConfigOptional.set (8, !measConfig.reportConfigToRemoveList.empty () );
  measConfigOptional.set (7, !measConfig.reportConfigToAddModList.empty () );
  measConfigOptional.set (6, !measConfig.measIdToRemoveList.empty () );
  measConfigOptional.set (5, !measConfig.measIdToAddModList.empty () );
  measConfigOptional.set (4, measConfig.haveQuantityConfig ); 
  measConfigOptional.set (3, measConfig.haveMeasGapConfig ); 
  measConfigOptional.set (2, measConfig.haveSmeasure ); 
  measConfigOptional.set (1, false ); // preRegistrationInfoHRPD
  measConfigOptional.set (0, measConfig.haveSpeedStatePars ); 
  SerializeSequence (measConfigOptional,true);

  if (!measConfig.measObjectToRemoveList.empty ())
    {
      SerializeSequenceOf (measConfig.measObjectToRemoveList.size (),MAX_OBJECT_ID,1);
      for (std::list<uint8_t>::iterator it = measConfig.measObjectToRemoveList.begin (); it != measConfig.measObjectToRemoveList.end (); it++)
        {
          SerializeInteger (*it, 1, MAX_OBJECT_ID);
        }
    }

  if (!measConfig.measObjectToAddModList.empty ())
    {
      SerializeSequenceOf (measConfig.measObjectToAddModList.size (),MAX_OBJECT_ID,1);
      for (std::list<LteRrcSap::MeasObjectToAddMod>::iterator it = measConfig.measObjectToAddModList.begin (); it != measConfig.measObjectToAddModList.end (); it++)
        {
          SerializeSequence (std::bitset<0> (), false);
          SerializeInteger (it->measObjectId, 1, MAX_OBJECT_ID);
          SerializeChoice (4, 0, true); // Select MeasObjectEUTRA

          // Serialize measObjectEutra
          std::bitset<5> measObjOpts;
          measObjOpts.set (4,!it->measObjectEutra.cellsToRemoveList.empty () );
          measObjOpts.set (3,!it->measObjectEutra.cellsToAddModList.empty () );
          measObjOpts.set (2,!it->measObjectEutra.blackCellsToRemoveList.empty () );
          measObjOpts.set (1,!it->measObjectEutra.blackCellsToAddModList.empty () );
          measObjOpts.set (0,it->measObjectEutra.haveCellForWhichToReportCGI);
          SerializeSequence (measObjOpts, true);

          // Serialize carrierFreq
          SerializeInteger (it->measObjectEutra.carrierFreq, 0, MAX_EARFCN);

          // Serialize  allowedMeasBandwidth
          SerializeEnum (6, BandwidthToEnum (it->measObjectEutra.allowedMeasBandwidth));

          SerializeBoolean (it->measObjectEutra.presenceAntennaPort1);
          SerializeBitstring (std::bitset<2> (it->measObjectEutra.neighCellConfig));
          SerializeQoffsetRange (it->measObjectEutra.offsetFreq);

          if (!it->measObjectEutra.cellsToRemoveList.empty ())
            {
              SerializeSequenceOf (it->measObjectEutra.cellsToRemoveList.size (),MAX_CELL_MEAS,1);
              for (std::list<uint8_t>::iterator it2 = it->measObjectEutra.cellsToRemoveList.begin (); it2 != it->measObjectEutra.cellsToRemoveList.end (); it2++)
                {
                  SerializeInteger (*it2, 1, MAX_CELL_MEAS);
                }
            }

          if (!it->measObjectEutra.cellsToAddModList.empty ())
            {
              SerializeSequenceOf (it->measObjectEutra.cellsToAddModList.size (), MAX_CELL_MEAS, 1);
              for (std::list<LteRrcSap::CellsToAddMod>::iterator it2 = it->measObjectEutra.cellsToAddModList.begin (); it2 != it->measObjectEutra.cellsToAddModList.end (); it2++)
                {
                  SerializeSequence (std::bitset<0> (), false);

                  // Serialize cellIndex
                  SerializeInteger (it2->cellIndex, 1, MAX_CELL_MEAS);

                  // Serialize PhysCellId
                  SerializeInteger (it2->physCellId,0,503);

                  // Serialize cellIndividualOffset
                  SerializeQoffsetRange (it2->cellIndividualOffset);
                }
            }

          if (!it->measObjectEutra.blackCellsToRemoveList.empty () )
            {
              SerializeSequenceOf (it->measObjectEutra.blackCellsToRemoveList.size (),MAX_CELL_MEAS,1);
              for (std::list<uint8_t>::iterator it2 = it->measObjectEutra.blackCellsToRemoveList.begin (); it2 != it->measObjectEutra.blackCellsToRemoveList.end (); it2++)
                {
                  SerializeInteger (*it2, 1, MAX_CELL_MEAS);
                }
            }

          if (!it->measObjectEutra.blackCellsToAddModList.empty () )
            {
              SerializeSequenceOf (it->measObjectEutra.blackCellsToAddModList.size (), MAX_CELL_MEAS, 1);
              for (std::list<LteRrcSap::BlackCellsToAddMod>::iterator it2 = it->measObjectEutra.blackCellsToAddModList.begin (); it2 != it->measObjectEutra.blackCellsToAddModList.end (); it2++)
                {
                  SerializeSequence (std::bitset<0> (),false);
                  SerializeInteger (it2->cellIndex, 1, MAX_CELL_MEAS);

                  // Serialize PhysCellIdRange
                  // range optional
                  std::bitset<1> rangePresent = std::bitset<1> (it2->physCellIdRange.haveRange);
                  SerializeSequence (rangePresent,false);
                  SerializeInteger (it2->physCellIdRange.start,0,503);
                  if (it2->physCellIdRange.haveRange)
                    {
                      switch (it2->physCellIdRange.range)
                        {
                        case 4:
                          SerializeEnum (16, 0);
                          break;
                        case 8:
                          SerializeEnum (16, 1);
                          break;
                        case 12:
                          SerializeEnum (16, 2);
                          break;
                        case 16:
                          SerializeEnum (16, 3);
                          break;
                        case 24:
                          SerializeEnum (16, 4);
                          break;
                        case 32:
                          SerializeEnum (16, 5);
                          break;
                        case 48:
                          SerializeEnum (16, 6);
                          break;
                        case 64:
                          SerializeEnum (16, 7);
                          break;
                        case 84:
                          SerializeEnum (16, 8);
                          break;
                        case 96:
                          SerializeEnum (16, 9);
                          break;
                        case 128:
                          SerializeEnum (16, 10);
                          break;
                        case 168:
                          SerializeEnum (16, 11);
                          break;
                        case 252:
                          SerializeEnum (16, 12);
                          break;
                        case 504:
                          SerializeEnum (16, 13);
                          break;
                        default:
                          SerializeEnum (16, 0);
                        }
                    }
                }

            }

          if (it->measObjectEutra.haveCellForWhichToReportCGI)
            {
              SerializeInteger (it->measObjectEutra.cellForWhichToReportCGI,0,503);
            }
        }
    }


  if (!measConfig.reportConfigToRemoveList.empty () )
    {
      SerializeSequenceOf (measConfig.reportConfigToRemoveList.size (),MAX_REPORT_CONFIG_ID,1);
      for (std::list<uint8_t>::iterator it = measConfig.reportConfigToRemoveList.begin (); it != measConfig.reportConfigToRemoveList.end (); it++)
        {
          SerializeInteger (*it, 1,MAX_REPORT_CONFIG_ID);
        }
    }

  if (!measConfig.reportConfigToAddModList.empty () )
    {
      SerializeSequenceOf (measConfig.reportConfigToAddModList.size (),MAX_REPORT_CONFIG_ID,1);
      for (std::list<LteRrcSap::ReportConfigToAddMod>::iterator it = measConfig.reportConfigToAddModList.begin (); it != measConfig.reportConfigToAddModList.end (); it++)
        {
          SerializeSequence (std::bitset<0> (), false);
          SerializeInteger (it->reportConfigId,1,MAX_REPORT_CONFIG_ID);
          SerializeChoice (2,0,false); // reportConfigEUTRA

          // Serialize ReportConfigEUTRA
          SerializeSequence (std::bitset<0> (), true);
          switch (it->reportConfigEutra.triggerType)
            {
            case LteRrcSap::ReportConfigEutra::PERIODICAL:
              SerializeChoice (2, 1, false); 
              SerializeSequence (std::bitset<0> (),false);
              switch (it->reportConfigEutra.purpose)
                {
                case LteRrcSap::ReportConfigEutra::REPORT_CGI:
                  SerializeEnum (2,1);
                  break;
                case LteRrcSap::ReportConfigEutra::REPORT_STRONGEST_CELLS:
                default:
                  SerializeEnum (2,0);
                }
              break;
            case LteRrcSap::ReportConfigEutra::EVENT:
            default: 
              SerializeChoice (2, 0, false);
              SerializeSequence (std::bitset<0> (),false);
              switch (it->reportConfigEutra.eventId)
                {
                case LteRrcSap::ReportConfigEutra::EVENT_A1:
                  SerializeChoice (5, 0, true);
                  SerializeSequence (std::bitset<0> (),false);
                  SerializeThresholdEutra (it->reportConfigEutra.threshold1);
                  break;
                case LteRrcSap::ReportConfigEutra::EVENT_A2:
                  SerializeChoice (5, 1, true);
                  SerializeSequence (std::bitset<0> (),false);
                  SerializeThresholdEutra (it->reportConfigEutra.threshold1);
                  break;
                case LteRrcSap::ReportConfigEutra::EVENT_A3:
                  SerializeChoice (5, 2, true);
                  SerializeSequence (std::bitset<0> (),false);
                  SerializeInteger (it->reportConfigEutra.a3Offset,-30,30);
                  SerializeBoolean (it->reportConfigEutra.reportOnLeave);
                  break;
                case LteRrcSap::ReportConfigEutra::EVENT_A4:
                  SerializeChoice (5, 3, true);
                  SerializeSequence (std::bitset<0> (),false);
                  SerializeThresholdEutra (it->reportConfigEutra.threshold1);
                  break;
                case LteRrcSap::ReportConfigEutra::EVENT_A5:
                default:
                  SerializeChoice (5, 4, true);
                  SerializeSequence (std::bitset<0> (),false);
                  SerializeThresholdEutra (it->reportConfigEutra.threshold1);
                  SerializeThresholdEutra (it->reportConfigEutra.threshold2);
                }

              SerializeInteger (it->reportConfigEutra.hysteresis, 0, 30);

              switch (it->reportConfigEutra.timeToTrigger)
                {
                case 0:
                  SerializeEnum (16, 0);
                  break;
                case 40:
                  SerializeEnum (16, 1);
                  break;
                case 64:
                  SerializeEnum (16, 2);
                  break;
                case 80:
                  SerializeEnum (16, 3);
                  break;
                case 100:
                  SerializeEnum (16, 4);
                  break;
                case 128:
                  SerializeEnum (16, 5);
                  break;
                case 160:
                  SerializeEnum (16, 6);
                  break;
                case 256:
                  SerializeEnum (16, 7);
                  break;
                case 320:
                  SerializeEnum (16, 8);
                  break;
                case 480:
                  SerializeEnum (16, 9);
                  break;
                case 512:
                  SerializeEnum (16, 10);
                  break;
                case 640:
                  SerializeEnum (16, 11);
                  break;
                case 1024:
                  SerializeEnum (16, 12);
                  break;
                case 1280:
                  SerializeEnum (16, 13);
                  break;
                case 2560:
                  SerializeEnum (16, 14);
                  break;
                case 5120:
                default:
                  SerializeEnum (16, 15);
                }
            } // end trigger type

          // Serialize triggerQuantity
          if (it->reportConfigEutra.triggerQuantity == LteRrcSap::ReportConfigEutra::RSRP)
            {
              SerializeEnum (2, 0);
            }
          else
            {
              SerializeEnum (2, 1);
            }

          // Serialize reportQuantity
          if (it->reportConfigEutra.reportQuantity == LteRrcSap::ReportConfigEutra::SAME_AS_TRIGGER_QUANTITY)
            {
              SerializeEnum (2, 0);
            }
          else
            {
              SerializeEnum (2, 1);
            }

          // Serialize maxReportCells
          SerializeInteger (it->reportConfigEutra.maxReportCells, 1, MAX_CELL_REPORT);

          // Serialize reportInterval
          switch (it->reportConfigEutra.reportInterval)
            {
            case LteRrcSap::ReportConfigEutra::MS120:
              SerializeEnum (16, 0);
              break;
            case LteRrcSap::ReportConfigEutra::MS240:
              SerializeEnum (16, 1);
              break;
            case LteRrcSap::ReportConfigEutra::MS480:
              SerializeEnum (16, 2);
              break;
            case LteRrcSap::ReportConfigEutra::MS640:
              SerializeEnum (16, 3);
              break;
            case LteRrcSap::ReportConfigEutra::MS1024:
              SerializeEnum (16, 4);
              break;
            case LteRrcSap::ReportConfigEutra::MS2048:
              SerializeEnum (16, 5);
              break;
            case LteRrcSap::ReportConfigEutra::MS5120:
              SerializeEnum (16, 6);
              break;
            case LteRrcSap::ReportConfigEutra::MS10240:
              SerializeEnum (16, 7);
              break;
            case LteRrcSap::ReportConfigEutra::MIN1:
              SerializeEnum (16, 8);
              break;
            case LteRrcSap::ReportConfigEutra::MIN6:
              SerializeEnum (16, 9);
              break;
            case LteRrcSap::ReportConfigEutra::MIN12:
              SerializeEnum (16, 10);
              break;
            case LteRrcSap::ReportConfigEutra::MIN30:
              SerializeEnum (16, 11);
              break;
            case LteRrcSap::ReportConfigEutra::MIN60:
              SerializeEnum (16, 12);
              break;
            case LteRrcSap::ReportConfigEutra::SPARE3:
              SerializeEnum (16, 13);
              break;
            case LteRrcSap::ReportConfigEutra::SPARE2:
              SerializeEnum (16, 14);
              break;
            case LteRrcSap::ReportConfigEutra::SPARE1:
            default:
              SerializeEnum (16, 15);
            }

          // Serialize reportAmount
          switch (it->reportConfigEutra.reportAmount)
            {
            case 1:
              SerializeEnum (8, 0);
              break;
            case 2:
              SerializeEnum (8, 1);
              break;
            case 4:
              SerializeEnum (8, 2);
              break;
            case 8:
              SerializeEnum (8, 3);
              break;
            case 16:
              SerializeEnum (8, 4);
              break;
            case 32:
              SerializeEnum (8, 5);
              break;
            case 64:
              SerializeEnum (8, 6);
              break;
            default:
              SerializeEnum (8, 7);
            }
        }
    }

  if (!measConfig.measIdToRemoveList.empty () )
    {
      SerializeSequenceOf (measConfig.measIdToRemoveList.size (), MAX_MEAS_ID, 1);
      for (std::list<uint8_t>::iterator it = measConfig.measIdToRemoveList.begin (); it != measConfig.measIdToRemoveList.end (); it++)
        {
          SerializeInteger (*it, 1, MAX_MEAS_ID);
        }
    }

  if (!measConfig.measIdToAddModList.empty () )
    {
      SerializeSequenceOf ( measConfig.measIdToAddModList.size (), MAX_MEAS_ID, 1);
      for (std::list<LteRrcSap::MeasIdToAddMod>::iterator it = measConfig.measIdToAddModList.begin (); it != measConfig.measIdToAddModList.end (); it++)
        {
          SerializeInteger (it->measId, 1, MAX_MEAS_ID);
          SerializeInteger (it->measObjectId, 1, MAX_OBJECT_ID);
          SerializeInteger (it->reportConfigId, 1, MAX_REPORT_CONFIG_ID);
        }
    }

  if (measConfig.haveQuantityConfig )
    {
      // QuantityConfig sequence
      // 4 optional fields, only first (EUTRA) present. Extension marker yes.
      std::bitset<4> quantityConfigOpts (0);
      quantityConfigOpts.set (3,1);
      SerializeSequence (quantityConfigOpts, true);
      SerializeSequence (std::bitset<0> (), false);

      switch (measConfig.quantityConfig.filterCoefficientRSRP)
        {
        case 0:
          SerializeEnum (16, 0);
          break;
        case 1:
          SerializeEnum (16, 1);
          break;
        case 2:
          SerializeEnum (16, 2);
          break;
        case 3:
          SerializeEnum (16, 3);
          break;
        case 4:
          SerializeEnum (16, 4);
          break;
        case 5:
          SerializeEnum (16, 5);
          break;
        case 6:
          SerializeEnum (16, 6);
          break;
        case 7:
          SerializeEnum (16, 7);
          break;
        case 8:
          SerializeEnum (16, 8);
          break;
        case 9:
          SerializeEnum (16, 9);
          break;
        case 11:
          SerializeEnum (16, 10);
          break;
        case 13:
          SerializeEnum (16, 11);
          break;
        case 15:
          SerializeEnum (16, 12);
          break;
        case 17:
          SerializeEnum (16, 13);
          break;
        case 19:
          SerializeEnum (16, 14);
          break;
        default:
          SerializeEnum (16, 4);
        }

      switch (measConfig.quantityConfig.filterCoefficientRSRQ)
        {
        case 0:
          SerializeEnum (16, 0);
          break;
        case 1:
          SerializeEnum (16, 1);
          break;
        case 2:
          SerializeEnum (16, 2);
          break;
        case 3:
          SerializeEnum (16, 3);
          break;
        case 4:
          SerializeEnum (16, 4);
          break;
        case 5:
          SerializeEnum (16, 5);
          break;
        case 6:
          SerializeEnum (16, 6);
          break;
        case 7:
          SerializeEnum (16, 7);
          break;
        case 8:
          SerializeEnum (16, 8);
          break;
        case 9:
          SerializeEnum (16, 9);
          break;
        case 11:
          SerializeEnum (16, 10);
          break;
        case 13:
          SerializeEnum (16, 11);
          break;
        case 15:
          SerializeEnum (16, 12);
          break;
        case 17:
          SerializeEnum (16, 13);
          break;
        case 19:
          SerializeEnum (16, 14);
          break;
        default:
          SerializeEnum (16, 4);
        }
    }

  if (measConfig.haveMeasGapConfig )
    {
      switch (measConfig.measGapConfig.type)
        {
        case LteRrcSap::MeasGapConfig::RESET:
          SerializeChoice (2, 0, false);
          SerializeNull ();
          break;
        case LteRrcSap::MeasGapConfig::SETUP:
        default:
          SerializeChoice (2, 1, false);
          SerializeSequence (std::bitset<0> (),false);
          switch (measConfig.measGapConfig.gapOffsetChoice)
            {
            case LteRrcSap::MeasGapConfig::GP0:
              SerializeChoice (2, 0, true);
              SerializeInteger (measConfig.measGapConfig.gapOffsetValue, 0, 39);
              break;
            case LteRrcSap::MeasGapConfig::GP1:
            default:
              SerializeChoice (2, 1, true);
              SerializeInteger (measConfig.measGapConfig.gapOffsetValue, 0, 79);
            }
        }
    }

  if (measConfig.haveSmeasure )
    {
      SerializeInteger (measConfig.sMeasure, 0, 97);
    }

  // ...Here preRegistrationInfoHRPD would be serialized

  if (measConfig.haveSpeedStatePars )
    {
      switch (measConfig.speedStatePars.type)
        {
        case LteRrcSap::SpeedStatePars::RESET:
          SerializeChoice (2, 0, false);
          SerializeNull ();
          break;
        case LteRrcSap::SpeedStatePars::SETUP:
        default:
          SerializeChoice (2, 1, false);
          SerializeSequence (std::bitset<0> (), false);
          switch (measConfig.speedStatePars.mobilityStateParameters.tEvaluation)
            {
            case 30:
              SerializeEnum (8, 0);
              break;
            case 60:
              SerializeEnum (8, 1);
              break;
            case 120:
              SerializeEnum (8, 2);
              break;
            case 180:
              SerializeEnum (8, 3);
              break;
            case 240:
              SerializeEnum (8, 4);
              break;
            default:
              SerializeEnum (8, 5);
              break;
            }

          switch (measConfig.speedStatePars.mobilityStateParameters.tHystNormal)
            {
            case 30:
              SerializeEnum (8, 0);
              break;
            case 60:
              SerializeEnum (8, 1);
              break;
            case 120:
              SerializeEnum (8, 2);
              break;
            case 180:
              SerializeEnum (8, 3);
              break;
            case 240:
              SerializeEnum (8, 4);
              break;
            default:
              SerializeEnum (8, 5);
              break;
            }

          SerializeInteger (measConfig.speedStatePars.mobilityStateParameters.nCellChangeMedium, 1, 16);
          SerializeInteger (measConfig.speedStatePars.mobilityStateParameters.nCellChangeHigh, 1, 16);

          SerializeSequence (std::bitset<0> (), false);
          switch (measConfig.speedStatePars.timeToTriggerSf.sfMedium)
            {
            case 25:
              SerializeEnum (4, 0);
              break;
            case 50:
              SerializeEnum (4, 1);
              break;
            case 75:
              SerializeEnum (4, 2);
              break;
            case 100:
            default:
              SerializeEnum (4, 3);
            }

          switch (measConfig.speedStatePars.timeToTriggerSf.sfHigh)
            {
            case 25:
              SerializeEnum (4, 0);
              break;
            case 50:
              SerializeEnum (4, 1);
              break;
            case 75:
              SerializeEnum (4, 2);
              break;
            case 100:
            default:
              SerializeEnum (4, 3);
            }
        }
    }
}
  void
  RrcAsn1Header::SerializeNonCriticalExtensionConfiguration (LteRrcSap::NonCriticalExtensionConfiguration nonCriticalExtension) const
  {
    // 3 optional fields. Extension marker not present.
    std::bitset<3> noncriticalExtension_v1020;
    noncriticalExtension_v1020.set (2,0); // No sCellToRealeaseList-r10
    noncriticalExtension_v1020.set (1,1); // sCellToAddModList-r10
    noncriticalExtension_v1020.set (0,0); // No nonCriticalExtension RRCConnectionReconfiguration-v1130-IEs
    SerializeSequence (noncriticalExtension_v1020,false);
    if (!nonCriticalExtension.sCellsToAddModList.empty ())
      {
        SerializeSequenceOf (nonCriticalExtension.sCellsToAddModList.size (),MAX_OBJECT_ID,1);
        for (std::list<LteRrcSap::SCellToAddMod>::iterator it = nonCriticalExtension.sCellsToAddModList.begin (); it != nonCriticalExtension.sCellsToAddModList.end (); it++)
          {
            std::bitset<4> sCellToAddMod_r10;
            sCellToAddMod_r10.set (3,1); // sCellIndex
            sCellToAddMod_r10.set (2,1); // CellIdentification
            sCellToAddMod_r10.set (1,1); // RadioResourceConfigCommonSCell
            sCellToAddMod_r10.set (0,it->haveRadioResourceConfigDedicatedSCell); // No nonCriticalExtension RRC
            SerializeSequence (sCellToAddMod_r10, false);
            SerializeInteger (it->sCellIndex,1,MAX_OBJECT_ID); //sCellIndex

            // Serialize CellIdentification
            std::bitset<2> cellIdentification_r10;
            cellIdentification_r10.set(1,1); // phyCellId-r10
            cellIdentification_r10.set(0,1); // dl-CarrierFreq-r10
            SerializeSequence (cellIdentification_r10, false);

            SerializeInteger (it->cellIdentification.physCellId,1,65536);
            SerializeInteger (it->cellIdentification.dlCarrierFreq,1,MAX_EARFCN);
            
            //Serialize RadioResourceConfigCommonSCell
            SerializeRadioResourceConfigCommonSCell (it->radioResourceConfigCommonSCell);
            
            if (it->haveRadioResourceConfigDedicatedSCell)
              {
                //Serialize RadioResourceConfigDedicatedSCell
                SerializeRadioResourceDedicatedSCell (it->radioResourceConfigDedicateSCell);
              }
            
          }
      }
    else
      {
        //        NS_ASSERT_MSG ( this << "NonCriticalExtension.sCellsToAddModList cannot be empty ", false);
      }
  
  }
  void
  RrcAsn1Header::SerializeRadioResourceConfigCommonSCell (LteRrcSap::RadioResourceConfigCommonSCell rrccsc) const
  {
    // 2 optional fields. Extension marker not present.
    std::bitset<2> radioResourceConfigCommonSCell_r10;
    radioResourceConfigCommonSCell_r10.set (1,rrccsc.haveNonUlConfiguration); // NonUlConfiguration
    radioResourceConfigCommonSCell_r10.set (0,rrccsc.haveUlConfiguration); // UlConfiguration
    SerializeSequence (radioResourceConfigCommonSCell_r10,false);
     
    if (rrccsc.haveNonUlConfiguration)
      {
        // 5 optional fields. Extension marker not present.
        std::bitset<5> nonUlConfiguration_r10;
        nonUlConfiguration_r10.set (4,1); // Dl- bandwidth --> convert in enum
        nonUlConfiguration_r10.set (3,1); // AntennaInfoCommon-r10
        nonUlConfiguration_r10.set (2,0); // phich-Config-r10 Not Implemented
        nonUlConfiguration_r10.set (1,1); // pdschConfigCommon
        nonUlConfiguration_r10.set (0,0); // Tdd-Config-r10 Not Implemented
        SerializeSequence (nonUlConfiguration_r10,false);

        SerializeInteger (rrccsc.nonUlConfiguration.dlBandwidth,6,100); 
        
        std::bitset<1> antennaInfoCommon_r10;
        antennaInfoCommon_r10.set (0,1);
        SerializeSequence (antennaInfoCommon_r10,false);
        SerializeInteger (rrccsc.nonUlConfiguration.antennaInfoCommon.antennaPortsCount,0,65536);
        
        std::bitset<2> pdschConfigCommon_r10;
        pdschConfigCommon_r10.set (1,1);
        pdschConfigCommon_r10.set (0,1);
        SerializeSequence (pdschConfigCommon_r10,false);
        
        SerializeInteger (rrccsc.nonUlConfiguration.pdschConfigCommon.referenceSignalPower,-60,50);
        SerializeInteger (rrccsc.nonUlConfiguration.pdschConfigCommon.pb,0,3); 
        
      }
    if (rrccsc.haveUlConfiguration)
      {
        //Serialize Ul Configuration
        // 7 optional fields. Extension marker present.
        std::bitset<7> UlConfiguration_r10;
        UlConfiguration_r10.set (6,1); // ul-Configuration-r10
        UlConfiguration_r10.set (5,0); // p-Max-r10 Not Implemented
        UlConfiguration_r10.set (4,1); // uplinkPowerControlCommonSCell-r10
        UlConfiguration_r10.set (3,0); // soundingRS-UL-ConfigCommon-r10
        UlConfiguration_r10.set (2,0); // ul-CyclicPrefixLength-r10
        UlConfiguration_r10.set (1,1); // prach-ConfigSCell-r10
        UlConfiguration_r10.set (0,0); // pusch-ConfigCommon-r10 Not Implemented
        SerializeSequence (UlConfiguration_r10,true);

        //Serialize ulFreqInfo
         std::bitset<3> FreqInfo_r10;
         FreqInfo_r10.set (2,1); // ulCarrierFreq
         FreqInfo_r10.set (1,1); // UlBandwidth
         FreqInfo_r10.set (0,0); // additionalSpectrumEmissionSCell-r10 Not Implemented
         SerializeSequence (FreqInfo_r10,false);
         
         SerializeInteger (rrccsc.ulConfiguration.ulFreqInfo.ulCarrierFreq,0,MAX_EARFCN);
         SerializeInteger (rrccsc.ulConfiguration.ulFreqInfo.ulBandwidth,6,100);

         //Serialize UlPowerControllCommonSCell
         std::bitset<2> UlPowerControlCommonSCell_r10;
         UlPowerControlCommonSCell_r10.set (1,0); // p0-NominalPUSCH-r10 Not Implemented       
         UlPowerControlCommonSCell_r10.set (0,1); // alpha
         SerializeSequence (UlPowerControlCommonSCell_r10,false);
         
         SerializeInteger (rrccsc.ulConfiguration.ulPowerControlCommonSCell.alpha,0,65536);

         //Serialize soundingRs-UlConfigCommon
         //Not Implemented

         //Serialize PrachConfigSCell
         std::bitset<1> prachConfigSCell_r10;
         prachConfigSCell_r10.set(0,1);
         SerializeSequence(prachConfigSCell_r10,false);
         SerializeInteger (rrccsc.ulConfiguration.prachConfigSCell.index,0,256);          
      }

     
  }
  void
  RrcAsn1Header::SerializeRadioResourceDedicatedSCell (LteRrcSap::RadioResourceConfigDedicatedSCell rrcdsc) const
  {
    //Serialize RadioResourceConfigDedicatedSCell
    std::bitset<1> RadioResourceConfigDedicatedSCell_r10;
    RadioResourceConfigDedicatedSCell_r10.set (0,1);
    SerializeSequence (RadioResourceConfigDedicatedSCell_r10,false);

    LteRrcSap::PhysicalConfigDedicatedSCell pcdsc = rrcdsc.physicalConfigDedicatedSCell;
    SerializePhysicalConfigDedicatedSCell (pcdsc);
  }
  
  void
  RrcAsn1Header::SerializePhysicalConfigDedicatedSCell (LteRrcSap::PhysicalConfigDedicatedSCell pcdsc) const
  {
    std::bitset<2> pcdscOpt;
    pcdscOpt.set (1,pcdsc.haveNonUlConfiguration);
    pcdscOpt.set (0,pcdsc.haveUlConfiguration);
    SerializeSequence (pcdscOpt, true);

    if (pcdsc.haveNonUlConfiguration)
      {
        //Serialize NonUl configuration
        std::bitset<4> nulOpt;
        nulOpt.set (3,pcdsc.haveAntennaInfoDedicated);
        nulOpt.set (2,0);  // crossCarrierSchedulingConfig-r10 Not Implemented
        nulOpt.set (1,0);  // csi-RS-Config-r10 Not Implemented
        nulOpt.set (0, pcdsc.havePdschConfigDedicated); // pdsch-ConfigDedicated-r10
        SerializeSequence (nulOpt,false);
        
        if (pcdsc.haveAntennaInfoDedicated)
          {
            // Serialize antennaInfo choice
            // 2 options. Selected: 0 ("explicitValue" of type "AntennaInfoDedicated")
            SerializeChoice (2,0,false);

            // Serialize AntennaInfoDedicated sequence
            // 1 optional parameter, not present. No extension marker.
            SerializeSequence (std::bitset<1> (0),false);

            // Serialize transmissionMode
            // Assuming the value in the struct is the enum index
            SerializeEnum (8,pcdsc.antennaInfo.transmissionMode);

            // Serialize ue-TransmitAntennaSelection choice
            SerializeChoice (2,0,false);

            // Serialize release
            SerializeNull ();
          }
        if (pcdsc.havePdschConfigDedicated)
          {
            // Serialize Pdsch-ConfigDedicated Sequence:
            // 0 optional / default fields, no extension marker.
            SerializeSequence (std::bitset<0> (),false);

            // Serialize  p-a
            // Assuming the value in the struct is the enum index
            SerializeEnum (8,pcdsc.pdschConfigDedicated.pa);

            // Serialize release
            SerializeNull ();
          }


      }
    if (pcdsc.haveUlConfiguration)
      {
        //Serialize Ul Configuration
        std::bitset<7> ulOpt;
        ulOpt.set (6, pcdsc.haveAntennaInfoUlDedicated);// antennaInfoUL-r10
        ulOpt.set (5,0); // pusch-ConfigDedicatedSCell-r10 not present 
        ulOpt.set (4,0); // uplinkPowerControlDedicatedSCell-r10 not present
        ulOpt.set (3,0); // cqi-ReportConfigSCell-r10 not present
        ulOpt.set (2,pcdsc.haveSoundingRsUlConfigDedicated);// soundingRS-UL-ConfigDedicated-r10
        ulOpt.set (1,0);  // soundingRS-UL-ConfigDedicated-v1020 not present
        ulOpt.set (0,0); // soundingRS-UL-ConfigDedicatedAperiodic-r10 not present
        SerializeSequence (ulOpt,false);
        
        if (pcdsc.haveAntennaInfoUlDedicated)
          {
            // Serialize antennaInfo choice
            // 2 options. Selected: 0 ("explicitValue" of type "AntennaInfoDedicated")
            SerializeChoice (2,0,false);

            // Serialize AntennaInfoDedicated sequence
            // 1 optional parameter, not present. No extension marker.
            SerializeSequence (std::bitset<1> (0),false);

            // Serialize transmissionMode
            // Assuming the value in the struct is the enum index
            SerializeEnum (8,pcdsc.antennaInfoUl.transmissionMode);

            // Serialize ue-TransmitAntennaSelection choice
            SerializeChoice (2,0,false);

            // Serialize release
            SerializeNull ();
          }
        if (pcdsc.haveSoundingRsUlConfigDedicated)
          {
            // Serialize SoundingRS-UL-ConfigDedicated choice:
            switch (pcdsc.soundingRsUlConfigDedicated.type)
              {
              case LteRrcSap::SoundingRsUlConfigDedicated::RESET:
                SerializeChoice (2,0,false);
                SerializeNull ();
                break;

              case LteRrcSap::SoundingRsUlConfigDedicated::SETUP:
              default:
                // 2 options, selected: 1 (setup)
                SerializeChoice (2,1,false);

                // Serialize setup sequence
                // 0 optional / default fields, no extension marker.
                SerializeSequence (std::bitset<0> (),false);

                // Serialize srs-Bandwidth
                SerializeEnum (4,pcdsc.soundingRsUlConfigDedicated.srsBandwidth);

                // Serialize  srs-HoppingBandwidth
                SerializeEnum (4,0);

                // Serialize freqDomainPosition
                SerializeInteger (0,0,23);

                // Serialize duration
                SerializeBoolean (false);

                // Serialize srs-ConfigIndex
                SerializeInteger (pcdsc.soundingRsUlConfigDedicated.srsConfigIndex,0,1023);

                // Serialize transmissionComb
                SerializeInteger (0,0,1);

                // Serialize cyclicShift
                SerializeEnum (8,0);

                break;
              }
              
          }
      

      }
  }

Buffer::Iterator
RrcAsn1Header::DeserializeThresholdEutra (LteRrcSap::ThresholdEutra * thresholdEutra, Buffer::Iterator bIterator)
{
  int thresholdEutraChoice, range;
  bIterator = DeserializeChoice (2, false, &thresholdEutraChoice, bIterator);

  switch (thresholdEutraChoice)
    {
    case 0:
      thresholdEutra->choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
      bIterator = DeserializeInteger (&range, 0, 97, bIterator);
      thresholdEutra->range = range;
      break;
    case 1:
    default:
      thresholdEutra->choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRQ;
      bIterator = DeserializeInteger (&range, 0, 34, bIterator);
      thresholdEutra->range = range;
    }

  return bIterator;
}

Buffer::Iterator
RrcAsn1Header::DeserializeQoffsetRange (int8_t * qOffsetRange, Buffer::Iterator bIterator)
{
  int n;
  bIterator = DeserializeEnum (31, &n, bIterator);
  switch (n)
    {
    case 0:
      *qOffsetRange = -24;
      break;
    case 1:
      *qOffsetRange = -22;
      break;
    case 2:
      *qOffsetRange = -20;
      break;
    case 3:
      *qOffsetRange = -18;
      break;
    case 4:
      *qOffsetRange = -16;
      break;
    case 5:
      *qOffsetRange = -14;
      break;
    case 6:
      *qOffsetRange = -12;
      break;
    case 7:
      *qOffsetRange = -10;
      break;
    case 8:
      *qOffsetRange = -8;
      break;
    case 9:
      *qOffsetRange = -6;
      break;
    case 10:
      *qOffsetRange = -5;
      break;
    case 11:
      *qOffsetRange = -4;
      break;
    case 12:
      *qOffsetRange = -3;
      break;
    case 13:
      *qOffsetRange = -2;
      break;
    case 14:
      *qOffsetRange = -1;
      break;
    case 15:
      *qOffsetRange = 0;
      break;
    case 16:
      *qOffsetRange = 1;
      break;
    case 17:
      *qOffsetRange = 2;
      break;
    case 18:
      *qOffsetRange = 3;
      break;
    case 19:
      *qOffsetRange = 4;
      break;
    case 20:
      *qOffsetRange = 5;
      break;
    case 21:
      *qOffsetRange = 6;
      break;
    case 22:
      *qOffsetRange = 8;
      break;
    case 23:
      *qOffsetRange = 10;
      break;
    case 24:
      *qOffsetRange = 12;
      break;
    case 25:
      *qOffsetRange = 14;
      break;
    case 26:
      *qOffsetRange = 16;
      break;
    case 27:
      *qOffsetRange = 18;
      break;
    case 28:
      *qOffsetRange = 20;
      break;
    case 29:
      *qOffsetRange = 22;
      break;
    case 30:
    default:
      *qOffsetRange = 24;
    }
  return bIterator;
}

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,false,&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,true,&chosen,bIterator);

          int sel;
          std::bitset<0> bitset0;
          switch (chosen)
            {
            case 0:
              drbToAddMod.rlcConfig.choice = LteRrcSap::RlcConfig::AM;

              // Deserialize UL-AM-RLC
              bIterator = DeserializeSequence (&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 (&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 (&bitset0,false, bIterator);
              bIterator = DeserializeEnum (2,&sel, bIterator); // sn-FieldLength

              // Deserialize DL-UM-RLC
              bIterator = DeserializeSequence (&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 (&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 (&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, extension marker is present.
  std::bitset<1> bitset1;
  bIterator = DeserializeSequence (&bitset1,true,bIterator);

  if (bitset1[0])
    {
      // Deserialize ul-SpecificParameters sequence
      bIterator = DeserializeSequence (&bitset1,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;
        default:
          prioritizedBitRateKbps = 10000;
        }
      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;
        default:
          bucketSizeDurationMs = 1000;
        }
      logicalChannelConfig->bucketSizeDurationMs = bucketSizeDurationMs;

      if (bitset1[0])
        {
          // 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);

  physicalConfigDedicated->havePdschConfigDedicated = optionalFieldPresent[9];
  if (optionalFieldPresent[9])
    {
      // Deserialize pdsch-ConfigDedicated
      std::bitset<0> bitset0;
      bIterator = DeserializeSequence (&bitset0,false,bIterator);

      int slct;

      // Deserialize p-a
      bIterator = DeserializeEnum (8,&slct,bIterator);
      physicalConfigDedicated->pdschConfigDedicated.pa = slct;

      bIterator = DeserializeNull (bIterator);

    }
  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,false,&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,false,&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,false,&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) const
{
  NS_LOG_FUNCTION (this << &os);
  NS_FATAL_ERROR ("RrcAsn1Header Print() function must also specify LteRrcSap::RadioResourceConfigDedicated as a second argument");
}

  Buffer::Iterator
  RrcAsn1Header::DeserializeNonCriticalExtensionConfig (LteRrcSap::NonCriticalExtensionConfiguration *nonCriticalExtension, Buffer::Iterator bIterator)
  {
    NS_LOG_FUNCTION (this);
    std::bitset<2> nonCriticalExtension_v890;
    bIterator = DeserializeSequence (&nonCriticalExtension_v890, false,bIterator);
    
    if (nonCriticalExtension_v890[0])
      {
        // Continue to analyze future Release optional fields
        std::bitset<3> nonCriticalExtension_v920;
        bIterator = DeserializeSequence (&nonCriticalExtension_v920, false, bIterator);
        if (nonCriticalExtension_v920[0])
          {
            // Continue to deserialize futere Release optional fields
            std::bitset<3> nonCriticalExtension_v1020;
            bIterator = DeserializeSequence (&nonCriticalExtension_v1020, false, bIterator);
            NS_ASSERT (!nonCriticalExtension_v1020[2]); // No sCellToRealeaseList-r10
            NS_ASSERT (nonCriticalExtension_v1020[1]); // sCellToAddModList-r10
            NS_ASSERT (!nonCriticalExtension_v1020[0]); // No nonCriticalExtension RRCConnectionReconfiguration-v1130-IEs

            int numElems;
            bIterator = DeserializeSequenceOf (&numElems,MAX_OBJECT_ID,1,bIterator);
            nonCriticalExtension->sCellsToAddModList.clear ();
            // Deserialize SCellToAddMod
            for (int i = 0; i < numElems; i++)
              {
                std::bitset<4> sCellToAddMod_r10;
                bIterator = DeserializeSequence (&sCellToAddMod_r10, false, bIterator); 
                
                LteRrcSap::SCellToAddMod sctam;
                // Deserialize sCellIndex
                NS_ASSERT (sCellToAddMod_r10[3]); // sCellIndex
                int n;
                bIterator = DeserializeInteger (&n,1,MAX_OBJECT_ID,bIterator);
                sctam.sCellIndex = n;
                // Deserialize CellIdentification
                NS_ASSERT (sCellToAddMod_r10[2]); // CellIdentification
                bIterator = DeserializeCellIdentification (&sctam.cellIdentification, bIterator);

                // Deserialize RadioResourceConfigCommonSCell
                NS_ASSERT (sCellToAddMod_r10[1]);
                bIterator = DeserializeRadioResourceConfigCommonSCell (&sctam.radioResourceConfigCommonSCell, bIterator);
                sctam.haveRadioResourceConfigDedicatedSCell = sCellToAddMod_r10[0];
                if (sCellToAddMod_r10[0])
                  {
                    //Deserialize RadioResourceConfigDedicatedSCell
                    bIterator = DeserializeRadioResourceConfigDedicatedSCell (&sctam.radioResourceConfigDedicateSCell, bIterator);
                  }

                nonCriticalExtension->sCellsToAddModList.insert (nonCriticalExtension->sCellsToAddModList.end (), sctam);
              }
          }
      }

    return bIterator;
  }

  Buffer::Iterator 
  RrcAsn1Header::DeserializeCellIdentification (LteRrcSap::CellIdentification *ci, Buffer::Iterator bIterator)
  {
    NS_LOG_FUNCTION (this);
    std::bitset<2> cellIdentification_r10;
    bIterator = DeserializeSequence (&cellIdentification_r10,false,bIterator);
    NS_ASSERT(cellIdentification_r10[1]); // phyCellId-r10
    int n1;
    bIterator = DeserializeInteger (&n1,1,65536,bIterator);
    ci->physCellId = n1;
    int n2;
    NS_ASSERT (cellIdentification_r10[0]); // dl-CarrierFreq-r10
    bIterator = DeserializeInteger (&n2,1,MAX_EARFCN,bIterator);
    ci->dlCarrierFreq = n2;

    return bIterator;
  }

  Buffer::Iterator 
  RrcAsn1Header::DeserializeRadioResourceConfigCommonSCell (LteRrcSap::RadioResourceConfigCommonSCell *rrccsc, Buffer::Iterator bIterator)
  {
    NS_LOG_FUNCTION (this);
    std::bitset<2> radioResourceConfigCommonSCell_r10;
    bIterator = DeserializeSequence (&radioResourceConfigCommonSCell_r10,false,bIterator);
    rrccsc->haveNonUlConfiguration = radioResourceConfigCommonSCell_r10[1];
    rrccsc->haveUlConfiguration = radioResourceConfigCommonSCell_r10[0];
    if (rrccsc->haveNonUlConfiguration)
      {
        std::bitset<5> nonUlConfiguration_r10;
        bIterator = DeserializeSequence (&nonUlConfiguration_r10,false,bIterator);
        int n;
        bIterator = DeserializeInteger (&n,6,100,bIterator);
        rrccsc->nonUlConfiguration.dlBandwidth = n;

        std::bitset<1> antennaInfoCommon_r10;
        bIterator = DeserializeSequence (&antennaInfoCommon_r10,false,bIterator);
        bIterator = DeserializeInteger (&n,0,65536,bIterator);
        rrccsc->nonUlConfiguration.antennaInfoCommon.antennaPortsCount = n;

        std::bitset<2> pdschConfigCommon_r10;
        bIterator = DeserializeSequence (&pdschConfigCommon_r10,false,bIterator);
        bIterator = DeserializeInteger (&n,-60,50,bIterator);
        rrccsc->nonUlConfiguration.pdschConfigCommon.referenceSignalPower = n;
        bIterator = DeserializeInteger (&n,0,3,bIterator);
        rrccsc->nonUlConfiguration.pdschConfigCommon.pb = n;
      }
    if (rrccsc->haveUlConfiguration)
      {
        std::bitset<7> UlConfiguration_r10;
        bIterator = DeserializeSequence (&UlConfiguration_r10,true,bIterator);
        
        std::bitset<3> FreqInfo_r10;
        bIterator = DeserializeSequence (&FreqInfo_r10,false,bIterator);
        int n;
        bIterator = DeserializeInteger (&n,0,MAX_EARFCN,bIterator);
        rrccsc->ulConfiguration.ulFreqInfo.ulCarrierFreq = n;
        bIterator = DeserializeInteger (&n,6,100,bIterator);
        rrccsc->ulConfiguration.ulFreqInfo.ulBandwidth = n;

        std::bitset<2> UlPowerControlCommonSCell_r10;
        bIterator = DeserializeSequence (&UlPowerControlCommonSCell_r10,false,bIterator);
        bIterator = DeserializeInteger (&n,0,65536,bIterator);
        rrccsc->ulConfiguration.ulPowerControlCommonSCell.alpha = n;
         
        std::bitset<1> prachConfigSCell_r10;
        bIterator = DeserializeSequence (&prachConfigSCell_r10,false,bIterator);
        bIterator = DeserializeInteger (&n,0,256,bIterator);
        rrccsc->ulConfiguration.prachConfigSCell.index = n;
      }    
    
    return bIterator;
  }

  Buffer::Iterator 
  RrcAsn1Header::DeserializeRadioResourceConfigDedicatedSCell (LteRrcSap::RadioResourceConfigDedicatedSCell *rrcdsc, Buffer::Iterator bIterator)
  {
    NS_LOG_FUNCTION (this);
    std::bitset<1> RadioResourceConfigDedicatedSCell_r10;
    bIterator = DeserializeSequence (&RadioResourceConfigDedicatedSCell_r10,false,bIterator);
    bIterator = DeserializePhysicalConfigDedicatedSCell (&rrcdsc->physicalConfigDedicatedSCell, bIterator);

    return bIterator;
  }

  Buffer::Iterator 
  RrcAsn1Header::DeserializePhysicalConfigDedicatedSCell (LteRrcSap::PhysicalConfigDedicatedSCell *pcdsc, Buffer::Iterator bIterator)
  {
    NS_LOG_FUNCTION (this);
    std::bitset<2> pcdscOpt;
    bIterator = DeserializeSequence (&pcdscOpt,true,bIterator);
    pcdsc->haveNonUlConfiguration = pcdscOpt[1];
    pcdsc->haveUlConfiguration = pcdscOpt[0];    
    if (pcdsc->haveNonUlConfiguration)
      {
         std::bitset<4> nulOpt;
         bIterator = DeserializeSequence (&nulOpt,false,bIterator);
         pcdsc->haveAntennaInfoDedicated = nulOpt[3];  
         NS_ASSERT(!nulOpt[2]); // crossCarrierSchedulingConfig-r10 Not Implemented
         NS_ASSERT(!nulOpt[1]); // csi-RS-Config-r10 Not Implemented
         pcdsc->havePdschConfigDedicated = nulOpt[0];  

         if (pcdsc->haveAntennaInfoDedicated)
           {
             // Deserialize antennaInfo
             int sel;
             bIterator = DeserializeChoice (2,false,&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);
                 pcdsc->antennaInfo.transmissionMode = txmode;

                 if (codebookSubsetRestrictionPresent[0])
                   {
                     // Deserialize codebookSubsetRestriction
                     NS_FATAL_ERROR ("Not implemented yet");
                     // ...
                   }

                 int txantennaselchosen;
                 bIterator = DeserializeChoice (2,false,&txantennaselchosen,bIterator);
                 if (txantennaselchosen == 0)
                   {
                     // Deserialize ue-TransmitAntennaSelection release
                     bIterator = DeserializeNull (bIterator);
                   }
                 else if (txantennaselchosen == 1)
                   {
                     // Deserialize ue-TransmitAntennaSelection setup
                     NS_FATAL_ERROR ("Not implemented yet");
                     // ...
                   }
               }
           }
         if (pcdsc->havePdschConfigDedicated)
           {
             // Deserialize pdsch-ConfigDedicated
             std::bitset<0> bitset0;
             bIterator = DeserializeSequence (&bitset0,false,bIterator);

             int slct;

             // Deserialize p-a
             bIterator = DeserializeEnum (8,&slct,bIterator);
             pcdsc->pdschConfigDedicated.pa = slct;

             bIterator = DeserializeNull (bIterator);
           }
        
      }
    if (pcdsc->haveUlConfiguration)
      {
         std::bitset<7> ulOpt;
         bIterator = DeserializeSequence (&ulOpt,false,bIterator);
         pcdsc->haveAntennaInfoUlDedicated = ulOpt[6];
         NS_ASSERT(!ulOpt[5]); // pusch-ConfigDedicatedSCell-r10 not present
         NS_ASSERT(!ulOpt[4]); // uplinkPowerControlDedicatedSCell-r10 not present
         NS_ASSERT(!ulOpt[3]); // cqi-ReportConfigSCell-r10 not present
         pcdsc->haveSoundingRsUlConfigDedicated = ulOpt[2];
         NS_ASSERT(!ulOpt[1]); // soundingRS-UL-ConfigDedicated-v1020 not present
         NS_ASSERT(!ulOpt[0]); // soundingRS-UL-ConfigDedicatedAperiodic-r10 not present
         
         if (pcdsc->haveAntennaInfoUlDedicated)
           {
             // Deserialize antennaInfo
             int sel;
             bIterator = DeserializeChoice (2,false,&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);
                 pcdsc->antennaInfoUl.transmissionMode = txmode;

                 if (codebookSubsetRestrictionPresent[0])
                   {
                     // Deserialize codebookSubsetRestriction
                     NS_FATAL_ERROR ("Not implemented yet");
                     // ...
                   }

                 int txantennaselchosen;
                 bIterator = DeserializeChoice (2,false,&txantennaselchosen,bIterator);
                 if (txantennaselchosen == 0)
                   {
                     // Deserialize ue-TransmitAntennaSelection release
                     bIterator = DeserializeNull (bIterator);
                   }
                 else if (txantennaselchosen == 1)
                   {
                     // Deserialize ue-TransmitAntennaSelection setup
                     NS_FATAL_ERROR ("Not implemented yet");
                     // ...
                   }
               }
           }
         if (pcdsc->haveSoundingRsUlConfigDedicated)
           {
             // Deserialize soundingRS-UL-ConfigDedicated
             int sel;
             bIterator = DeserializeChoice (2,false,&sel,bIterator);

             if (sel == 0)
               {
                 pcdsc->soundingRsUlConfigDedicated.type = LteRrcSap::SoundingRsUlConfigDedicated::RESET;

                 bIterator = DeserializeNull (bIterator);
               }

             else if (sel == 1)
               {
                 pcdsc->soundingRsUlConfigDedicated.type = LteRrcSap::SoundingRsUlConfigDedicated::SETUP;

                 std::bitset<0> bitset0;
                 bIterator = DeserializeSequence (&bitset0,false,bIterator);

                 int slct;

                 // Deserialize srs-Bandwidth
                 bIterator = DeserializeEnum (4,&slct,bIterator);
                 pcdsc->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);
                 pcdsc->soundingRsUlConfigDedicated.srsConfigIndex = slct;

                 // Deserialize transmissionComb
                 bIterator = DeserializeInteger (&slct,0,1,bIterator);

                 // Deserialize cyclicShift
                 bIterator = DeserializeEnum (8,&slct,bIterator);
               }
           }


      }

    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
      bIterator = DeserializePlmnIdentity (&systemInformationBlockType1->cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity,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 (LteRrcSap::SystemInformationBlockType2 *systemInformationBlockType2, 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 (&systemInformationBlockType2->radioResourceConfigCommon, 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
      bIterator = DeserializeInteger (&n, 0, MAX_EARFCN, bIterator);
      systemInformationBlockType2->freqInfo.ulCarrierFreq = n;
    }
  if (freqInfoOpts[0])
    {
      // Deserialize ul-Bandwidth
      bIterator = DeserializeEnum (6, &n, bIterator);
      systemInformationBlockType2->freqInfo.ulBandwidth = EnumToBandwidth (n);
    }

  // additionalSpectrumEmission
  bIterator = DeserializeInteger (&n,1,32,bIterator);

  if (sysInfoBlkT2Opts[0])
    {
      // Deserialize mbsfn-SubframeConfigList
      // ...
    }

  // Deserialize timeAlignmentTimerCommon
  bIterator = DeserializeEnum (8,&n,bIterator);

  return bIterator;
}


Buffer::Iterator
RrcAsn1Header::DeserializeRadioResourceConfigCommon (LteRrcSap::RadioResourceConfigCommon * radioResourceConfigCommon, Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;
  int n;

  std::bitset<9> rrCfgCommOptions;
  bIterator = DeserializeSequence (&rrCfgCommOptions,true,bIterator);

  // rach-ConfigCommon
  if (rrCfgCommOptions[8])
    {
      bIterator = DeserializeRachConfigCommon (&radioResourceConfigCommon->rachConfigCommon, bIterator);
    }

  // 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::DeserializeRachConfigCommon (LteRrcSap::RachConfigCommon * rachConfigCommon, Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;
  int n;

  bIterator = DeserializeSequence (&bitset0,true,bIterator);

  // preambleInfo
  std::bitset<1> preamblesGroupAConfigPresent;
  bIterator = DeserializeSequence (&preamblesGroupAConfigPresent,false,bIterator);

  // numberOfRA-Preambles
  bIterator = DeserializeEnum (16,&n,bIterator);
  switch (n)
    {
    case 0:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 4;
      break;
    case 1:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 8;
      break;
    case 2:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 12;
      break;
    case 3:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 16;
      break;
    case 4:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 20;
      break;
    case 5:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 24;
      break;
    case 6:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 28;
      break;
    case 7:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 32;
      break;
    case 8:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 36;
      break;
    case 9:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 40;
      break;
    case 10:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 44;
      break;
    case 11:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 48;
      break;
    case 12:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 52;
      break;
    case 13:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 56;
      break;
    case 14:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 60;
      break;
    case 15:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 64;
      break;
    default:
      rachConfigCommon->preambleInfo.numberOfRaPreambles = 4;
    }

  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
  switch (n)
    {
    case 0:
      rachConfigCommon->raSupervisionInfo.preambleTransMax = 3;
      break;
    case 1:
      rachConfigCommon->raSupervisionInfo.preambleTransMax = 4;
      break;
    case 2:
      rachConfigCommon->raSupervisionInfo.preambleTransMax = 5;
      break;
    case 3:
      rachConfigCommon->raSupervisionInfo.preambleTransMax = 6;
      break;
    case 4:
      rachConfigCommon->raSupervisionInfo.preambleTransMax = 7;
      break;
    case 5:
      rachConfigCommon->raSupervisionInfo.preambleTransMax = 8;
      break;
    case 6:
      rachConfigCommon->raSupervisionInfo.preambleTransMax = 10;
      break;
    case 7:
      rachConfigCommon->raSupervisionInfo.preambleTransMax = 20;
      break;
    case 8:
      rachConfigCommon->raSupervisionInfo.preambleTransMax = 50;
      break;
    case 9:
      rachConfigCommon->raSupervisionInfo.preambleTransMax = 100;
      break;
    case 10:
      rachConfigCommon->raSupervisionInfo.preambleTransMax = 200;
      break;
    default:
      rachConfigCommon->raSupervisionInfo.preambleTransMax = 0;
    }

  // ra-ResponseWindowSize
  bIterator = DeserializeEnum (8,&n,bIterator);
  switch (n)
    {
    case 0:
      rachConfigCommon->raSupervisionInfo.raResponseWindowSize = 2;
      break;
    case 1:
      rachConfigCommon->raSupervisionInfo.raResponseWindowSize = 3;
      break;
    case 2:
      rachConfigCommon->raSupervisionInfo.raResponseWindowSize = 4;
      break;
    case 3:
      rachConfigCommon->raSupervisionInfo.raResponseWindowSize = 5;
      break;
    case 4:
      rachConfigCommon->raSupervisionInfo.raResponseWindowSize = 6;
      break;
    case 5:
      rachConfigCommon->raSupervisionInfo.raResponseWindowSize = 7;
      break;
    case 6:
      rachConfigCommon->raSupervisionInfo.raResponseWindowSize = 8;
      break;
    case 7:
      rachConfigCommon->raSupervisionInfo.raResponseWindowSize = 10;
      break;
    default:
      rachConfigCommon->raSupervisionInfo.raResponseWindowSize = 0;
    }

  bIterator = DeserializeEnum (8,&n,bIterator); // mac-ContentionResolutionTimer
  bIterator = DeserializeInteger (&n,1,8,bIterator); //maxHARQ-Msg3Tx

  // connEstFailCount
  bIterator = DeserializeEnum (8,&n,bIterator);
  switch (n)
    {
    case 1:
      rachConfigCommon->txFailParam.connEstFailCount = 1;
      break;
    case 2:
      rachConfigCommon->txFailParam.connEstFailCount = 2;
      break;
    case 3:
      rachConfigCommon->txFailParam.connEstFailCount = 3;
      break;
    case 4:
      rachConfigCommon->txFailParam.connEstFailCount = 4;
      break;
    default:
      rachConfigCommon->txFailParam.connEstFailCount = 1;
    }
  return bIterator;
}

Buffer::Iterator
RrcAsn1Header::DeserializeRadioResourceConfigCommonSib (LteRrcSap::RadioResourceConfigCommonSib * radioResourceConfigCommonSib, Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;
  int n;

  bIterator = DeserializeSequence (&bitset0,true,bIterator);

  // rach-ConfigCommon
  bIterator = DeserializeRachConfigCommon (&radioResourceConfigCommonSib->rachConfigCommon, bIterator);

  // 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,false,&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;
}

Buffer::Iterator
RrcAsn1Header::DeserializeMeasResults (LteRrcSap::MeasResults *measResults, Buffer::Iterator bIterator)
{
  int n;
  std::bitset<0> b0;
  std::bitset<4> measResultOptionalPresent;
  //    bIterator = DeserializeSequence (&measResultNeighCellsPresent,true,bIterator);
  bIterator = DeserializeSequence (&measResultOptionalPresent,true,bIterator);

  // Deserialize measId
  bIterator = DeserializeInteger (&n, 1, MAX_MEAS_ID, bIterator);
  measResults->measId = n;

  // Deserialize measResultServCell
  bIterator = DeserializeSequence (&b0,false,bIterator);

  // Deserialize rsrpResult
  bIterator = DeserializeInteger (&n, 0, 97, bIterator);
  measResults->rsrpResult = n;

  // Deserialize rsrqResult
  bIterator = DeserializeInteger (&n, 0, 34, bIterator);
  measResults->rsrqResult = n;

  measResults->haveMeasResultNeighCells = measResultOptionalPresent[0];
  measResults->haveScellsMeas = measResultOptionalPresent[3];
  if ( measResults->haveMeasResultNeighCells)
    {
      int measResultNeighCellsChoice;

      // Deserialize measResultNeighCells
      bIterator = DeserializeChoice (4,false,&measResultNeighCellsChoice,bIterator);

      if (measResultNeighCellsChoice == 0)
        {
          // Deserialize measResultListEUTRA
          int numElems;
          bIterator = DeserializeSequenceOf (&numElems,MAX_CELL_REPORT,1,bIterator);

          for (int i = 0; i < numElems; i++)
            {
              LteRrcSap::MeasResultEutra measResultEutra;

              std::bitset<1> isCgiInfoPresent;
              bIterator = DeserializeSequence (&isCgiInfoPresent,false,bIterator);

              // PhysCellId
              bIterator = DeserializeInteger (&n,0,503,bIterator);
              measResultEutra.physCellId = n;

              measResultEutra.haveCgiInfo = isCgiInfoPresent[0];
              if (isCgiInfoPresent[0])
                {
                  std::bitset<1> havePlmnIdentityList;
                  bIterator = DeserializeSequence (&havePlmnIdentityList,false,bIterator);

                  // Deserialize cellGlobalId
                  bIterator = DeserializeSequence (&b0,false,bIterator);

                  // Deserialize plmn-Identity
                  bIterator = DeserializePlmnIdentity (&measResultEutra.cgiInfo.plmnIdentity,bIterator);

                  // Deserialize CellIdentity
                  std::bitset<28> cellId;
                  bIterator = DeserializeBitstring (&cellId,bIterator);
                  measResultEutra.cgiInfo.cellIdentity = cellId.to_ulong ();

                  // Deserialize trackingAreaCode
                  std::bitset<16> trArCo;
                  bIterator = DeserializeBitstring (&trArCo,bIterator);
                  measResultEutra.cgiInfo.trackingAreaCode = trArCo.to_ulong ();

                  // Deserialize plmn-IdentityList
                  if (havePlmnIdentityList[0])
                    {
                      int numPlmnElems;
                      bIterator = DeserializeSequenceOf (&numPlmnElems, 5, 1, bIterator);

                      for ( int j = 0; j < numPlmnElems; j++)
                        {
                          uint32_t plmnId;
                          bIterator = DeserializePlmnIdentity (&plmnId,bIterator);
                          measResultEutra.cgiInfo.plmnIdentityList.push_back (plmnId);
                        }
                    }
                }

              // Deserialize measResult
              std::bitset<2> measResultOpts;
              bIterator = DeserializeSequence (&measResultOpts, true, bIterator);

              measResultEutra.haveRsrpResult = measResultOpts[1];
              if (measResultOpts[1])
                {
                  // Deserialize rsrpResult
                  bIterator = DeserializeInteger (&n,0,97,bIterator);
                  measResultEutra.rsrpResult = n;
                }

              measResultEutra.haveRsrqResult = measResultOpts[0];
              if (measResultOpts[0])
                {
                  // Deserialize rsrqResult
                  bIterator = DeserializeInteger (&n,0,34,bIterator);
                  measResultEutra.rsrqResult = n;
                }

              measResults->measResultListEutra.push_back (measResultEutra);
            }
        }

      if (measResultNeighCellsChoice == 1)
        {
          // Deserialize measResultListUTRA
          // ...
        }

      if (measResultNeighCellsChoice == 2)
        {
          // Deserialize measResultListGERAN
          // ...
        }
      if (measResultNeighCellsChoice == 3)
        {
          // Deserialize measResultsCDMA2000
          // ...
        }
    }
    if (measResults->haveScellsMeas)
      {

        int numElems;
        bIterator = DeserializeSequenceOf (&numElems,MAX_SCELL_REPORT,1,bIterator);
        for (int i = 0; i < numElems; i++)
          {
            LteRrcSap::MeasResultScell measResultScell;
            int measScellId;
            // Deserialize measId
            bIterator = DeserializeInteger (&measScellId, 1,MAX_SCELL_REPORT,bIterator);
            measResultScell.servFreqId = measScellId;
            std::bitset<2> measResultScellPresent;
            bIterator = DeserializeSequence (&measResultScellPresent,true,bIterator);
            measResults->measScellResultList.haveMeasurementResultsServingSCells = measResultScellPresent[0];
           measResults->measScellResultList.haveMeasurementResultsNeighCell = measResultScellPresent[1];
           if (measResults->measScellResultList.haveMeasurementResultsServingSCells)
             {
               // Deserialize measResult
               std::bitset<2> measResultOpts;
               bIterator = DeserializeSequence (&measResultOpts, true, bIterator);

               measResultScell.haveRsrpResult = measResultOpts[1];
               if (measResultOpts[1])
                 {
                   // Deserialize rsrpResult
                   bIterator = DeserializeInteger (&n,0,97,bIterator);
                   measResultScell.rsrpResult = n;
                 }

               measResultScell.haveRsrqResult = measResultOpts[0];
               if (measResultOpts[0])
                 {
                   // Deserialize rsrqResult
                   bIterator = DeserializeInteger (&n,0,34,bIterator);
                   measResultScell.rsrqResult = n;
                 }
             }
           if (measResults->measScellResultList.haveMeasurementResultsNeighCell)
             {
               // Deserialize measResultBestNeighCell
             }
           measResults->measScellResultList.measResultScell.push_back (measResultScell);
          }
        
      }
  return bIterator;
}

Buffer::Iterator
RrcAsn1Header::DeserializePlmnIdentity (uint32_t *plmnId, Buffer::Iterator bIterator)
{
  int n;
  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);
    }

  *plmnId = mnc;

  // cellReservedForOperatorUse
  bIterator = DeserializeEnum (2,&n,bIterator);
  return bIterator;
}

Buffer::Iterator
RrcAsn1Header::DeserializeMeasConfig (LteRrcSap::MeasConfig * measConfig, Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;
  std::bitset<2> bitset2;
  std::bitset<11> bitset11;
  int n;

  // measConfig
  bIterator = DeserializeSequence (&bitset11,true,bIterator);

  if (bitset11[10])
    {
      // measObjectToRemoveList
      int measObjectToRemoveListElems;
      bIterator = DeserializeSequenceOf (&measObjectToRemoveListElems, MAX_OBJECT_ID, 1, bIterator);

      for (int i = 0; i < measObjectToRemoveListElems; i++)
        {
          bIterator = DeserializeInteger (&n, 1, MAX_OBJECT_ID, bIterator);
          measConfig->measObjectToRemoveList.push_back (n);
        }
    }

  if (bitset11[9])
    {
      // measObjectToAddModList
      int measObjectToAddModListElems;
      bIterator = DeserializeSequenceOf (&measObjectToAddModListElems, MAX_OBJECT_ID, 1, bIterator);

      for (int i = 0; i < measObjectToAddModListElems; i++)
        {
          LteRrcSap::MeasObjectToAddMod elem;

          bIterator = DeserializeSequence (&bitset0, false, bIterator);

          bIterator = DeserializeInteger (&n, 1, MAX_OBJECT_ID, bIterator);
          elem.measObjectId = n;

          int measObjectChoice;
          bIterator = DeserializeChoice (4, true, &measObjectChoice, bIterator);

          switch (measObjectChoice)
            {
            case 1:
              // Deserialize measObjectUTRA
              // ...
              break;

            case 2:
              // Deserialize measObjectGERAN
              // ...
              break;

            case 3:
              // Deserialize measObjectCDMA2000
              // ...
              break;

            case 0:
            default:
              // Deserialize measObjectEUTRA
              std::bitset<5> measObjectEutraOpts;
              bIterator = DeserializeSequence (&measObjectEutraOpts, true, bIterator);

              // carrierFreq
              bIterator = DeserializeInteger (&n, 0, MAX_EARFCN, bIterator);
              elem.measObjectEutra.carrierFreq = n;

              // allowedMeasBandwidth
              bIterator = DeserializeEnum (6, &n, bIterator);
              elem.measObjectEutra.allowedMeasBandwidth = EnumToBandwidth (n);

              // presenceAntennaPort1
              bIterator = DeserializeBoolean (&elem.measObjectEutra.presenceAntennaPort1, bIterator);

              // neighCellConfig
              bIterator = DeserializeBitstring (&bitset2, bIterator);
              elem.measObjectEutra.neighCellConfig = bitset2.to_ulong ();

              // offsetFreq
              bIterator = DeserializeQoffsetRange (&elem.measObjectEutra.offsetFreq, bIterator);

              if (measObjectEutraOpts[4])
                {
                  // cellsToRemoveList
                  int numElems;
                  bIterator = DeserializeSequenceOf (&numElems, MAX_CELL_MEAS, 1, bIterator);

                  for (int i = 0; i < numElems; i++)
                    {
                      bIterator = DeserializeInteger (&n, 1, MAX_CELL_MEAS, bIterator);
                      elem.measObjectEutra.cellsToRemoveList.push_back (n);
                    }
                }

              if (measObjectEutraOpts[3])
                {
                  // cellsToAddModList
                  int numElems;
                  bIterator = DeserializeSequenceOf (&numElems, MAX_CELL_MEAS, 1, bIterator);

                  for (int i = 0; i < numElems; i++)
                    {
                      LteRrcSap::CellsToAddMod cellsToAddMod;

                      bIterator = DeserializeSequence (&bitset0, false, bIterator);

                      // cellIndex
                      bIterator = DeserializeInteger (&n, 1, MAX_CELL_MEAS, bIterator);
                      cellsToAddMod.cellIndex = n;

                      // PhysCellId
                      bIterator = DeserializeInteger (&n, 0, 503, bIterator);
                      cellsToAddMod.physCellId = n;

                      // cellIndividualOffset
                      bIterator = DeserializeQoffsetRange ( &cellsToAddMod.cellIndividualOffset, bIterator);

                      elem.measObjectEutra.cellsToAddModList.push_back (cellsToAddMod);
                    }
                }

              if (measObjectEutraOpts[2])
                {
                  // blackCellsToRemoveList
                  int numElems;
                  bIterator = DeserializeSequenceOf (&numElems, MAX_CELL_MEAS, 1, bIterator);

                  for (int i = 0; i < numElems; i++)
                    {
                      bIterator = DeserializeInteger (&n, 1, MAX_CELL_MEAS, bIterator);
                      elem.measObjectEutra.blackCellsToRemoveList.push_back (n);
                    }
                }


              if (measObjectEutraOpts[1])
                {
                  // blackCellsToAddModList
                  int numElems;
                  bIterator = DeserializeSequenceOf (&numElems, MAX_CELL_MEAS, 1, bIterator);

                  for (int i = 0; i < numElems; i++)
                    {
                      LteRrcSap::BlackCellsToAddMod blackCellsToAddMod;
                      bIterator = DeserializeSequence (&bitset0, false, bIterator);

                      bIterator = DeserializeInteger (&n, 1, MAX_CELL_MEAS, bIterator);
                      blackCellsToAddMod.cellIndex = n;

                      // PhysCellIdRange
                      std::bitset<1> isRangePresent;
                      bIterator = DeserializeSequence (&isRangePresent, false, bIterator);

                      // start
                      bIterator = DeserializeInteger (&n, 0, 503, bIterator);
                      blackCellsToAddMod.physCellIdRange.start = n;

                      blackCellsToAddMod.physCellIdRange.haveRange = isRangePresent[0];
                      // initialize range to silence compiler warning
                      blackCellsToAddMod.physCellIdRange.range = 0;
                      if (blackCellsToAddMod.physCellIdRange.haveRange)
                        {
                          // range
                          bIterator = DeserializeEnum (16, &n, bIterator);
                          switch (n)
                            {
                            case 0:
                              blackCellsToAddMod.physCellIdRange.range = 4;
                              break;
                            case 1:
                              blackCellsToAddMod.physCellIdRange.range = 8;
                              break;
                            case 2:
                              blackCellsToAddMod.physCellIdRange.range = 12;
                              break;
                            case 3:
                              blackCellsToAddMod.physCellIdRange.range = 16;
                              break;
                            case 4:
                              blackCellsToAddMod.physCellIdRange.range = 24;
                              break;
                            case 5:
                              blackCellsToAddMod.physCellIdRange.range = 32;
                              break;
                            case 6:
                              blackCellsToAddMod.physCellIdRange.range = 48;
                              break;
                            case 7:
                              blackCellsToAddMod.physCellIdRange.range = 64;
                              break;
                            case 8:
                              blackCellsToAddMod.physCellIdRange.range = 84;
                              break;
                            case 9:
                              blackCellsToAddMod.physCellIdRange.range = 96;
                              break;
                            case 10:
                              blackCellsToAddMod.physCellIdRange.range = 128;
                              break;
                            case 11:
                              blackCellsToAddMod.physCellIdRange.range = 168;
                              break;
                            case 12:
                              blackCellsToAddMod.physCellIdRange.range = 252;
                              break;
                            case 13:
                              blackCellsToAddMod.physCellIdRange.range = 504;
                              break;
                            default:
                              blackCellsToAddMod.physCellIdRange.range = 0;
                            }
                        }

                      elem.measObjectEutra.blackCellsToAddModList.push_back (blackCellsToAddMod);
                    }
                }

              elem.measObjectEutra.haveCellForWhichToReportCGI = measObjectEutraOpts[0];
              if (measObjectEutraOpts[0])
                {
                  // cellForWhichToReportCGI
                  bIterator = DeserializeInteger (&n, 0, 503, bIterator);
                  elem.measObjectEutra.cellForWhichToReportCGI = n;
                }
            }
          measConfig->measObjectToAddModList.push_back (elem);
        }
    }

  if (bitset11[8])
    {
      // reportConfigToRemoveList
      int reportConfigToRemoveListElems;
      bIterator = DeserializeSequenceOf (&reportConfigToRemoveListElems, MAX_REPORT_CONFIG_ID, 1, bIterator);

      for (int i = 0; i < reportConfigToRemoveListElems; i++)
        {
          bIterator = DeserializeInteger (&n, 1, MAX_REPORT_CONFIG_ID, bIterator);
          measConfig->reportConfigToRemoveList.push_back (n);
        }
    }

  if (bitset11[7])
    {
      // reportConfigToAddModList
      int reportConfigToAddModListElems;
      bIterator = DeserializeSequenceOf (&reportConfigToAddModListElems, MAX_REPORT_CONFIG_ID, 1, bIterator);

      for (int i = 0; i < reportConfigToAddModListElems; i++)
        {
          LteRrcSap::ReportConfigToAddMod elem;

          bIterator = DeserializeSequence (&bitset0, false, bIterator);
          bIterator = DeserializeInteger (&n, 1, MAX_REPORT_CONFIG_ID, bIterator);
          elem.reportConfigId = n;

          // Deserialize reportConfig
          int reportConfigChoice;
          bIterator = DeserializeChoice (2, false, &reportConfigChoice, bIterator);

          if (reportConfigChoice == 0)
            {
              // reportConfigEUTRA
              bIterator = DeserializeSequence (&bitset0, true, bIterator);

              // triggerType
              int triggerTypeChoice;
              bIterator = DeserializeChoice (2, false, &triggerTypeChoice, bIterator);

              if (triggerTypeChoice == 0)
                {
                  // event
                  elem.reportConfigEutra.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
                  bIterator = DeserializeSequence (&bitset0, false, bIterator);

                  // eventId
                  int eventIdChoice;
                  bIterator = DeserializeChoice (5, true, &eventIdChoice, bIterator);

                  switch (eventIdChoice)
                    {
                    case 0:
                      elem.reportConfigEutra.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
                      bIterator = DeserializeSequence (&bitset0, false, bIterator);
                      bIterator = DeserializeThresholdEutra (&elem.reportConfigEutra.threshold1, bIterator);
                      break;

                    case 1:
                      elem.reportConfigEutra.eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
                      bIterator = DeserializeSequence (&bitset0, false, bIterator);
                      bIterator = DeserializeThresholdEutra (&elem.reportConfigEutra.threshold1, bIterator);
                      break;

                    case 2:
                      elem.reportConfigEutra.eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
                      bIterator = DeserializeSequence (&bitset0, false, bIterator);
                      bIterator = DeserializeInteger (&n, -30, 30, bIterator);
                      elem.reportConfigEutra.a3Offset = n;
                      bIterator = DeserializeBoolean (&elem.reportConfigEutra.reportOnLeave, bIterator);
                      break;

                    case 3:
                      elem.reportConfigEutra.eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
                      bIterator = DeserializeSequence (&bitset0, false, bIterator);
                      bIterator = DeserializeThresholdEutra (&elem.reportConfigEutra.threshold1, bIterator);
                      break;

                    case 4:
                    default:
                      elem.reportConfigEutra.eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
                      bIterator = DeserializeSequence (&bitset0, false, bIterator);
                      bIterator = DeserializeThresholdEutra (&elem.reportConfigEutra.threshold1, bIterator);
                      bIterator = DeserializeThresholdEutra (&elem.reportConfigEutra.threshold2, bIterator);
                    }

                  bIterator = DeserializeInteger (&n, 0, 30, bIterator);
                  elem.reportConfigEutra.hysteresis = n;

                  bIterator = DeserializeEnum (16, &n, bIterator);
                  switch (n)
                    {
                    case 0:
                      elem.reportConfigEutra.timeToTrigger = 0;
                      break;
                    case 1:
                      elem.reportConfigEutra.timeToTrigger = 40;
                      break;
                    case 2:
                      elem.reportConfigEutra.timeToTrigger = 64;
                      break;
                    case 3:
                      elem.reportConfigEutra.timeToTrigger = 80;
                      break;
                    case 4:
                      elem.reportConfigEutra.timeToTrigger = 100;
                      break;
                    case 5:
                      elem.reportConfigEutra.timeToTrigger = 128;
                      break;
                    case 6:
                      elem.reportConfigEutra.timeToTrigger = 160;
                      break;
                    case 7:
                      elem.reportConfigEutra.timeToTrigger = 256;
                      break;
                    case 8:
                      elem.reportConfigEutra.timeToTrigger = 320;
                      break;
                    case 9:
                      elem.reportConfigEutra.timeToTrigger = 480;
                      break;
                    case 10:
                      elem.reportConfigEutra.timeToTrigger = 512;
                      break;
                    case 11:
                      elem.reportConfigEutra.timeToTrigger = 640;
                      break;
                    case 12:
                      elem.reportConfigEutra.timeToTrigger = 1024;
                      break;
                    case 13:
                      elem.reportConfigEutra.timeToTrigger = 1280;
                      break;
                    case 14:
                      elem.reportConfigEutra.timeToTrigger = 2560;
                      break;
                    case 15:
                    default:
                      elem.reportConfigEutra.timeToTrigger = 5120;
                      break;
                    }
                }

              if (triggerTypeChoice == 1)
                {
                  // periodical
                  elem.reportConfigEutra.triggerType = LteRrcSap::ReportConfigEutra::PERIODICAL;

                  bIterator = DeserializeSequence (&bitset0, false, bIterator);
                  bIterator = DeserializeEnum (2, &n, bIterator);
                  if (n == 0)
                    {
                      elem.reportConfigEutra.purpose = LteRrcSap::ReportConfigEutra::REPORT_STRONGEST_CELLS;
                    }
                  else
                    {
                      elem.reportConfigEutra.purpose = LteRrcSap::ReportConfigEutra::REPORT_CGI;
                    }
                }

              // triggerQuantity
              bIterator = DeserializeEnum (2, &n, bIterator);
              if (n == 0)
                {
                  elem.reportConfigEutra.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
                }
              else
                {
                  elem.reportConfigEutra.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRQ;
                }

              // reportQuantity
              bIterator = DeserializeEnum (2, &n, bIterator);
              if (n == 0)
                {
                  elem.reportConfigEutra.reportQuantity = LteRrcSap::ReportConfigEutra::SAME_AS_TRIGGER_QUANTITY;
                }
              else
                {
                  elem.reportConfigEutra.reportQuantity = LteRrcSap::ReportConfigEutra::BOTH;
                }

              // maxReportCells
              bIterator = DeserializeInteger (&n, 1, MAX_CELL_REPORT, bIterator);
              elem.reportConfigEutra.maxReportCells = n;

              // reportInterval
              bIterator = DeserializeEnum (16, &n, bIterator);
              switch (n)
                {
                case 0:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MS120;
                  break;
                case 1:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
                  break;
                case 2:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MS480;
                  break;
                case 3:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MS640;
                  break;
                case 4:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MS1024;
                  break;
                case 5:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MS2048;
                  break;
                case 6:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MS5120;
                  break;
                case 7:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MS10240;
                  break;
                case 8:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MIN1;
                  break;
                case 9:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MIN6;
                  break;
                case 10:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MIN12;
                  break;
                case 11:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MIN30;
                  break;
                case 12:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::MIN60;
                  break;
                case 13:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::SPARE3;
                  break;
                case 14:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::SPARE2;
                  break;
                case 15:
                default:
                  elem.reportConfigEutra.reportInterval = LteRrcSap::ReportConfigEutra::SPARE1;
                }

              // reportAmount
              bIterator = DeserializeEnum (8, &n, bIterator);
              switch (n)
                {
                case 0:
                  elem.reportConfigEutra.reportAmount = 1;
                  break;
                case 1:
                  elem.reportConfigEutra.reportAmount = 2;
                  break;
                case 2:
                  elem.reportConfigEutra.reportAmount = 4;
                  break;
                case 3:
                  elem.reportConfigEutra.reportAmount = 8;
                  break;
                case 4:
                  elem.reportConfigEutra.reportAmount = 16;
                  break;
                case 5:
                  elem.reportConfigEutra.reportAmount = 32;
                  break;
                case 6:
                  elem.reportConfigEutra.reportAmount = 64;
                  break;
                default:
                  elem.reportConfigEutra.reportAmount = 0;
                }
            }

          if (reportConfigChoice == 1)
            {
              // ReportConfigInterRAT
              // ...
            }

          measConfig->reportConfigToAddModList.push_back (elem);
        }
    }

  if (bitset11[6])
    {
      // measIdToRemoveList
      int measIdToRemoveListElems;
      bIterator = DeserializeSequenceOf (&measIdToRemoveListElems, MAX_MEAS_ID, 1, bIterator);

      for (int i = 0; i < measIdToRemoveListElems; i++)
        {
          bIterator = DeserializeInteger (&n, 1, MAX_MEAS_ID, bIterator);
          measConfig->measIdToRemoveList.push_back (n);
        }
    }

  if (bitset11[5])
    {
      // measIdToAddModList
      int measIdToAddModListElems;
      bIterator = DeserializeSequenceOf (&measIdToAddModListElems, MAX_MEAS_ID, 1, bIterator);

      for (int i = 0; i < measIdToAddModListElems; i++)
        {
          LteRrcSap::MeasIdToAddMod elem;

          bIterator = DeserializeSequence (&bitset0, false, bIterator);

          bIterator = DeserializeInteger (&n, 1, MAX_MEAS_ID, bIterator);
          elem.measId = n;

          bIterator = DeserializeInteger (&n, 1, MAX_OBJECT_ID, bIterator);
          elem.measObjectId = n;

          bIterator = DeserializeInteger (&n, 1, MAX_REPORT_CONFIG_ID, bIterator);
          elem.reportConfigId = n;

          measConfig->measIdToAddModList.push_back (elem);
        }
    }

  measConfig->haveQuantityConfig = bitset11[4];
  if (measConfig->haveQuantityConfig)
    {
      // quantityConfig
      std::bitset<4> quantityConfigOpts;
      bIterator = DeserializeSequence (&quantityConfigOpts, true, bIterator);

      if (quantityConfigOpts[3])
        {
          // quantityConfigEUTRA
          bIterator = DeserializeSequence (&bitset0,false,bIterator);
          bIterator = DeserializeEnum (16, &n, bIterator);
          switch (n)
            {
            case 0:
              measConfig->quantityConfig.filterCoefficientRSRP = 0;
              break;
            case 1:
              measConfig->quantityConfig.filterCoefficientRSRP = 1;
              break;
            case 2:
              measConfig->quantityConfig.filterCoefficientRSRP = 2;
              break;
            case 3:
              measConfig->quantityConfig.filterCoefficientRSRP = 3;
              break;
            case 4:
              measConfig->quantityConfig.filterCoefficientRSRP = 4;
              break;
            case 5:
              measConfig->quantityConfig.filterCoefficientRSRP = 5;
              break;
            case 6:
              measConfig->quantityConfig.filterCoefficientRSRP = 6;
              break;
            case 7:
              measConfig->quantityConfig.filterCoefficientRSRP = 7;
              break;
            case 8:
              measConfig->quantityConfig.filterCoefficientRSRP = 8;
              break;
            case 9:
              measConfig->quantityConfig.filterCoefficientRSRP = 9;
              break;
            case 10:
              measConfig->quantityConfig.filterCoefficientRSRP = 11;
              break;
            case 11:
              measConfig->quantityConfig.filterCoefficientRSRP = 13;
              break;
            case 12:
              measConfig->quantityConfig.filterCoefficientRSRP = 15;
              break;
            case 13:
              measConfig->quantityConfig.filterCoefficientRSRP = 17;
              break;
            case 14:
              measConfig->quantityConfig.filterCoefficientRSRP = 19;
              break;
            case 15:
              measConfig->quantityConfig.filterCoefficientRSRP = 0;
              break;
            default:
              measConfig->quantityConfig.filterCoefficientRSRP = 4;
            }
          bIterator = DeserializeEnum (16, &n, bIterator);
          switch (n)
            {
            case 0:
              measConfig->quantityConfig.filterCoefficientRSRQ = 0;
              break;
            case 1:
              measConfig->quantityConfig.filterCoefficientRSRQ = 1;
              break;
            case 2:
              measConfig->quantityConfig.filterCoefficientRSRQ = 2;
              break;
            case 3:
              measConfig->quantityConfig.filterCoefficientRSRQ = 3;
              break;
            case 4:
              measConfig->quantityConfig.filterCoefficientRSRQ = 4;
              break;
            case 5:
              measConfig->quantityConfig.filterCoefficientRSRQ = 5;
              break;
            case 6:
              measConfig->quantityConfig.filterCoefficientRSRQ = 6;
              break;
            case 7:
              measConfig->quantityConfig.filterCoefficientRSRQ = 7;
              break;
            case 8:
              measConfig->quantityConfig.filterCoefficientRSRQ = 8;
              break;
            case 9:
              measConfig->quantityConfig.filterCoefficientRSRQ = 9;
              break;
            case 10:
              measConfig->quantityConfig.filterCoefficientRSRQ = 11;
              break;
            case 11:
              measConfig->quantityConfig.filterCoefficientRSRQ = 13;
              break;
            case 12:
              measConfig->quantityConfig.filterCoefficientRSRQ = 15;
              break;
            case 13:
              measConfig->quantityConfig.filterCoefficientRSRQ = 17;
              break;
            case 14:
              measConfig->quantityConfig.filterCoefficientRSRQ = 19;
              break;
            case 15:
              measConfig->quantityConfig.filterCoefficientRSRQ = 0;
              break;
            default:
              measConfig->quantityConfig.filterCoefficientRSRQ = 4;
            }
        }
      if (quantityConfigOpts[2])
        {
          // quantityConfigUTRA
          // ...
        }
      if (quantityConfigOpts[1])
        {
          // quantityConfigGERAN
          // ...
        }
      if (quantityConfigOpts[0])
        {
          // quantityConfigCDMA2000
          // ...
        }
    }

  measConfig->haveMeasGapConfig = bitset11[3];
  if (measConfig->haveMeasGapConfig)
    {
      // measGapConfig
      int measGapConfigChoice;
      bIterator = DeserializeChoice (2, false, &measGapConfigChoice, bIterator);
      switch (measGapConfigChoice)
        {
        case 0:
          measConfig->measGapConfig.type = LteRrcSap::MeasGapConfig::RESET;
          bIterator = DeserializeNull (bIterator);
          break;
        case 1:
        default:
          measConfig->measGapConfig.type = LteRrcSap::MeasGapConfig::SETUP;
          bIterator = DeserializeSequence (&bitset0, false, bIterator);

          int gapOffsetChoice;
          bIterator = DeserializeChoice (2, true, &gapOffsetChoice, bIterator);
          switch (gapOffsetChoice)
            {
            case 0:
              measConfig->measGapConfig.gapOffsetChoice = LteRrcSap::MeasGapConfig::GP0;
              bIterator = DeserializeInteger (&n, 0, 39, bIterator);
              measConfig->measGapConfig.gapOffsetValue = n;
              break;
            case 1:
            default:
              measConfig->measGapConfig.gapOffsetChoice = LteRrcSap::MeasGapConfig::GP1;
              bIterator = DeserializeInteger (&n, 0, 79, bIterator);
              measConfig->measGapConfig.gapOffsetValue = n;
            }
        }
    }

  measConfig->haveSmeasure = bitset11[2];
  if (measConfig->haveSmeasure)
    {
      // s-Measure
      bIterator = DeserializeInteger (&n, 0, 97, bIterator);
      measConfig->sMeasure = n;
    }

  if (bitset11[1])
    {
      // preRegistrationInfoHRPD
      // ...
    }

  measConfig->haveSpeedStatePars = bitset11[0];
  if (measConfig->haveSpeedStatePars)
    {
      // speedStatePars
      int speedStateParsChoice;
      bIterator = DeserializeChoice (2, false, &speedStateParsChoice, bIterator);
      switch (speedStateParsChoice)
        {
        case 0:
          measConfig->speedStatePars.type = LteRrcSap::SpeedStatePars::RESET;
          bIterator = DeserializeNull (bIterator);
          break;
        case 1:
        default:
          measConfig->speedStatePars.type = LteRrcSap::SpeedStatePars::SETUP;
          bIterator = DeserializeSequence (&bitset0, false, bIterator);

          // Deserialize mobilityStateParameters
          // Deserialize t-Evaluation
          bIterator = DeserializeEnum (8, &n, bIterator);
          switch (n)
            {
            case 0:
              measConfig->speedStatePars.mobilityStateParameters.tEvaluation = 30;
              break;
            case 1:
              measConfig->speedStatePars.mobilityStateParameters.tEvaluation = 60;
              break;
            case 2:
              measConfig->speedStatePars.mobilityStateParameters.tEvaluation = 120;
              break;
            case 3:
              measConfig->speedStatePars.mobilityStateParameters.tEvaluation = 180;
              break;
            case 4:
              measConfig->speedStatePars.mobilityStateParameters.tEvaluation = 240;
              break;
            default:
              measConfig->speedStatePars.mobilityStateParameters.tEvaluation = 0;
            }
          // Deserialize t-HystNormal
          bIterator = DeserializeEnum (8, &n, bIterator);
          switch (n)
            {
            case 0:
              measConfig->speedStatePars.mobilityStateParameters.tHystNormal = 30;
              break;
            case 1:
              measConfig->speedStatePars.mobilityStateParameters.tHystNormal = 60;
              break;
            case 2:
              measConfig->speedStatePars.mobilityStateParameters.tHystNormal = 120;
              break;
            case 3:
              measConfig->speedStatePars.mobilityStateParameters.tHystNormal = 180;
              break;
            case 4:
              measConfig->speedStatePars.mobilityStateParameters.tHystNormal = 240;
              break;
            default:
              measConfig->speedStatePars.mobilityStateParameters.tHystNormal = 0;
            }

          bIterator = DeserializeInteger (&n, 1, 16, bIterator);
          measConfig->speedStatePars.mobilityStateParameters.nCellChangeMedium = n;

          bIterator = DeserializeInteger (&n, 1, 16, bIterator);
          measConfig->speedStatePars.mobilityStateParameters.nCellChangeHigh = n;

          // Deserialize timeToTriggerSf
          bIterator = DeserializeEnum (4, &n, bIterator);
          measConfig->speedStatePars.timeToTriggerSf.sfMedium = (n + 1) * 25;
          bIterator = DeserializeEnum (4, &n, bIterator);
          measConfig->speedStatePars.timeToTriggerSf.sfHigh = (n + 1) * 25;
        }
    }
  return bIterator;
}

//////////////////// RrcConnectionRequest class ////////////////////////

// Constructor
RrcConnectionRequestHeader::RrcConnectionRequestHeader () : RrcUlCcchMessage ()
{
  m_mmec = std::bitset<8> (0ul);
  m_mTmsi = std::bitset<32> (0ul);
  m_establishmentCause = MO_SIGNALLING;
  m_spare = std::bitset<1> (0ul);
}

// Destructor
RrcConnectionRequestHeader::~RrcConnectionRequestHeader ()
{
}

TypeId
RrcConnectionRequestHeader::GetTypeId (void)
{
  static TypeId tid = TypeId ("ns3::RrcConnectionRequestHeader")
    .SetParent<Header> ()
    .SetGroupName("Lte")
  ;
  return tid;
}

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 ();

  SerializeUlCcchMessage (1);

  // Serialize RRCConnectionRequest sequence:
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize criticalExtensions choice:
  // 2 options, selected: 0 (option: rrcConnectionRequest-r8)
  SerializeChoice (2,0,false);

  // Serialize RRCConnectionRequest-r8-IEs sequence:
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize InitialUE-Identity choice:
  // 2 options, selected: 0 (option: s-TMSI)
  SerializeChoice (2,0,false);

  // Serialize S-TMSI sequence:
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize mmec : MMEC ::= BIT STRING (SIZE (8))
  SerializeBitstring (m_mmec);

  // Serialize m-TMSI ::= BIT STRING (SIZE (32))
  SerializeBitstring (m_mTmsi);

  // Serialize establishmentCause : EstablishmentCause ::= ENUMERATED
  SerializeEnum (8,m_establishmentCause);

  // Serialize spare : BIT STRING (SIZE (1))
  SerializeBitstring (std::bitset<1> ());

  // Finish serialization
  FinalizeSerialization ();
}

uint32_t
RrcConnectionRequestHeader::Deserialize (Buffer::Iterator bIterator)
{
  std::bitset<1> dummy;
  std::bitset<0> optionalOrDefaultMask;
  int selectedOption;

  bIterator = DeserializeUlCcchMessage (bIterator);

  // Deserialize RCConnectionRequest sequence
  bIterator = DeserializeSequence (&optionalOrDefaultMask,false,bIterator);

  // Deserialize criticalExtensions choice:
  bIterator = DeserializeChoice (2,false,&selectedOption,bIterator);

  // Deserialize RRCConnectionRequest-r8-IEs sequence
  bIterator = DeserializeSequence (&optionalOrDefaultMask,false,bIterator);

  // Deserialize InitialUE-Identity choice
  bIterator = DeserializeChoice (2,false,&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 (LteRrcSap::RrcConnectionRequest msg)
{
  m_mTmsi = std::bitset<32> ((uint32_t)msg.ueIdentity);
  m_mmec = std::bitset<8> ((uint32_t)(msg.ueIdentity >> 32));
  m_isDataSerialized = false;
}

LteRrcSap::RrcConnectionRequest
RrcConnectionRequestHeader::GetMessage () const
{
  LteRrcSap::RrcConnectionRequest msg;
  msg.ueIdentity = (((uint64_t) m_mmec.to_ulong ()) << 32) | (m_mTmsi.to_ulong ());

  return msg;
}

std::bitset<8>
RrcConnectionRequestHeader::GetMmec () const
{
  return m_mmec;
}

std::bitset<32>
RrcConnectionRequestHeader::GetMtmsi () const
{
  return m_mTmsi;
}


//////////////////// RrcConnectionSetup class ////////////////////////
RrcConnectionSetupHeader::RrcConnectionSetupHeader ()
{
}
 
RrcConnectionSetupHeader::~RrcConnectionSetupHeader ()
{
}
 
void
RrcConnectionSetupHeader::Print (std::ostream &os) const
{
  os << "rrcTransactionIdentifier: " << (int)m_rrcTransactionIdentifier << std::endl;
  os << "radioResourceConfigDedicated:" << std::endl;
  RrcAsn1Header::Print (os,m_radioResourceConfigDedicated);
}

void
RrcConnectionSetupHeader::PreSerialize () const
{
  m_serializationResult = Buffer ();

  SerializeDlCcchMessage (3);

  SerializeInteger (15,0,15);

  // Serialize RRCConnectionSetup sequence:
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize rrc-TransactionIdentifier ::=INTEGER (0..3)
  SerializeInteger (m_rrcTransactionIdentifier,0,3);

  // Serialize criticalExtensions choice:
  // 2 options, selected: 0 (option: c1)
  SerializeChoice (2,0,false);

  // Serialize c1 choice:
  // 8 options, selected: 0 (option: rrcConnectionSetup-r8)
  SerializeChoice (8,0,false);

  // Serialize rrcConnectionSetup-r8 sequence
  // 1 optional fields (not present). Extension marker not present.
  SerializeSequence (std::bitset<1> (0),false);

  // Serialize RadioResourceConfigDedicated sequence
  SerializeRadioResourceConfigDedicated (m_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)
{
  int n;

  std::bitset<0> bitset0;
  std::bitset<1> bitset1;
  std::bitset<2> bitset2;

  bIterator = DeserializeDlCcchMessage (bIterator);

  bIterator = DeserializeInteger (&n,0,15,bIterator);

  // Deserialize RRCConnectionSetup sequence
  bIterator = DeserializeSequence (&bitset0,false,bIterator);

  // Deserialize rrc-TransactionIdentifier ::=INTEGER (0..3)
  bIterator = DeserializeInteger (&n,0,3,bIterator);
  m_rrcTransactionIdentifier = n;

  // Deserialize criticalExtensions choice
  int criticalExtensionChoice;
  bIterator = DeserializeChoice (2,false,&criticalExtensionChoice,bIterator);
  if (criticalExtensionChoice == 1)
    {
      // Deserialize criticalExtensionsFuture
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
    }
  else if (criticalExtensionChoice == 0)
    {
      // Deserialize c1
      int c1;
      bIterator = DeserializeChoice (8,false,&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 (&m_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 (LteRrcSap::RrcConnectionSetup msg)
{
  m_rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
  m_radioResourceConfigDedicated = msg.radioResourceConfigDedicated;
  m_isDataSerialized = false;
}

LteRrcSap::RrcConnectionSetup
RrcConnectionSetupHeader::GetMessage () const
{
  LteRrcSap::RrcConnectionSetup msg;
  msg.rrcTransactionIdentifier = m_rrcTransactionIdentifier;
  msg.radioResourceConfigDedicated = m_radioResourceConfigDedicated; 
  return msg;
}

uint8_t
RrcConnectionSetupHeader::GetRrcTransactionIdentifier () const
{
  return m_rrcTransactionIdentifier;
}

bool
RrcConnectionSetupHeader::HavePhysicalConfigDedicated () const
{
  return m_radioResourceConfigDedicated.havePhysicalConfigDedicated;
}

std::list<LteRrcSap::SrbToAddMod>
RrcConnectionSetupHeader::GetSrbToAddModList () const
{
  return m_radioResourceConfigDedicated.srbToAddModList;
}

std::list<LteRrcSap::DrbToAddMod>
RrcConnectionSetupHeader::GetDrbToAddModList () const
{
  return m_radioResourceConfigDedicated.drbToAddModList;
} 

std::list<uint8_t>
RrcConnectionSetupHeader::GetDrbToReleaseList () const
{
  return m_radioResourceConfigDedicated.drbToReleaseList;
}

LteRrcSap::PhysicalConfigDedicated
RrcConnectionSetupHeader::GetPhysicalConfigDedicated () const
{
  return m_radioResourceConfigDedicated.physicalConfigDedicated;
}

LteRrcSap::RadioResourceConfigDedicated
RrcConnectionSetupHeader::GetRadioResourceConfigDedicated () const
{
  return m_radioResourceConfigDedicated;
}

//////////////////// RrcConnectionSetupCompleteHeader class ////////////////////////

RrcConnectionSetupCompleteHeader::RrcConnectionSetupCompleteHeader ()
{
}

RrcConnectionSetupCompleteHeader::~RrcConnectionSetupCompleteHeader ()
{
}

void
RrcConnectionSetupCompleteHeader::PreSerialize () const
{
  m_serializationResult = Buffer ();

  // Serialize DCCH message
  SerializeUlDcchMessage (4);

  // Serialize RRCConnectionSetupComplete sequence:
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize rrc-TransactionIdentifier
  SerializeInteger (m_rrcTransactionIdentifier,0,3);

  // Serialize criticalExtensions choice
  // 2 options, selected 0 (c1)
  SerializeChoice (2,0,false);

  // Choose spare3 NULL
  SerializeChoice (4,1,false);

  // Serialize spare3 NULL
  SerializeNull ();

  // Finish serialization
  FinalizeSerialization ();
}

uint32_t
RrcConnectionSetupCompleteHeader::Deserialize (Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;

  bIterator = DeserializeUlDcchMessage (bIterator);

  bIterator = DeserializeSequence (&bitset0,false,bIterator);

  int n;
  bIterator = DeserializeInteger (&n,0,3,bIterator);
  m_rrcTransactionIdentifier = n;

  bIterator = DeserializeChoice (2,false,&n,bIterator);

  if (n == 1)
    {
      // Deserialize criticalExtensionsFuture
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
    }
  else if (n == 0)
    {
      // Deserialize c1
      int c1Chosen;
      bIterator = DeserializeChoice (4,false,&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 (LteRrcSap::RrcConnectionSetupCompleted msg)
{
  m_rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
  m_isDataSerialized = false;
}

uint8_t
RrcConnectionSetupCompleteHeader::GetRrcTransactionIdentifier () const
{
  return m_rrcTransactionIdentifier;
}

LteRrcSap::RrcConnectionSetupCompleted
RrcConnectionSetupCompleteHeader::GetMessage () const
{
  LteRrcSap::RrcConnectionSetupCompleted msg;
  msg.rrcTransactionIdentifier = m_rrcTransactionIdentifier;
  return msg;
}

//////////////////// RrcConnectionReconfigurationCompleteHeader class ////////////////////////

RrcConnectionReconfigurationCompleteHeader::RrcConnectionReconfigurationCompleteHeader ()
{
}

RrcConnectionReconfigurationCompleteHeader::~RrcConnectionReconfigurationCompleteHeader ()
{
}

void
RrcConnectionReconfigurationCompleteHeader::PreSerialize () const
{
  m_serializationResult = Buffer ();

  // Serialize DCCH message
  SerializeUlDcchMessage (2);

  // Serialize RRCConnectionSetupComplete sequence:
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize rrc-TransactionIdentifier
  SerializeInteger (m_rrcTransactionIdentifier,0,3);

  // Serialize criticalExtensions choice
  // 2 options, selected 1 (criticalExtensionsFuture)
  SerializeChoice (2,1,false);

  // Choose criticalExtensionsFuture
  SerializeSequence (std::bitset<0> (),false);

  // Finish serialization
  FinalizeSerialization ();
}

uint32_t
RrcConnectionReconfigurationCompleteHeader::Deserialize (Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;
  int n;

  bIterator = DeserializeUlDcchMessage (bIterator);
  bIterator = DeserializeSequence (&bitset0,false,bIterator);

  bIterator = DeserializeInteger (&n,0,3,bIterator);
  m_rrcTransactionIdentifier = n;

  bIterator = DeserializeChoice (2,false,&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 (LteRrcSap::RrcConnectionReconfigurationCompleted msg)
{
  m_rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
  m_isDataSerialized = false;
}

LteRrcSap::RrcConnectionReconfigurationCompleted
RrcConnectionReconfigurationCompleteHeader::GetMessage () const
{
  LteRrcSap::RrcConnectionReconfigurationCompleted msg;
  msg.rrcTransactionIdentifier = m_rrcTransactionIdentifier;
  return msg;
}

uint8_t
RrcConnectionReconfigurationCompleteHeader::GetRrcTransactionIdentifier () const
{
  return m_rrcTransactionIdentifier;
}

//////////////////// RrcConnectionReconfigurationHeader class ////////////////////////

RrcConnectionReconfigurationHeader::RrcConnectionReconfigurationHeader ()
{
}

RrcConnectionReconfigurationHeader::~RrcConnectionReconfigurationHeader ()
{
}

void
RrcConnectionReconfigurationHeader::PreSerialize () const
{
  m_serializationResult = Buffer ();

  SerializeDlDcchMessage (4);

  // Serialize RRCConnectionSetupComplete sequence:
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize rrc-TransactionIdentifier
  SerializeInteger (m_rrcTransactionIdentifier,0,3);

  // Serialize criticalExtensions choice
  // 2 options, selected 0 (c1)
  SerializeChoice (2,0,false);

  // Serialize c1 choice
  // 8 options, selected 0 (rrcConnectionReconfiguration-r8)
  SerializeChoice (8,0,false);

  // 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,m_haveNonCriticalExtension); // Implemented nonCriticalExtension because compatibility with R10 - CA
  SerializeSequence (options,false);

  if (m_haveMeasConfig)
    {
      SerializeMeasConfig (m_measConfig);
    }

  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);

          // Serialize dl-Bandwidth
          SerializeEnum (16, BandwidthToEnum (m_mobilityControlInfo.carrierBandwidth.dlBandwidth));

          // Serialize ul-Bandwidth
          SerializeEnum (16, BandwidthToEnum (m_mobilityControlInfo.carrierBandwidth.ulBandwidth));
        }

      // Serialize t304
      SerializeEnum (8,0);

      // Serialize newUE-Identitiy
      SerializeBitstring (std::bitset<16> (m_mobilityControlInfo.newUeIdentity));

      // Serialize radioResourceConfigCommon
      SerializeRadioResourceConfigCommon (m_mobilityControlInfo.radioResourceConfigCommon);

      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);
      }

    if (m_haveNonCriticalExtension)
      {
        // Serialize NonCriticalExtension RRCConnectionReconfiguration-v890-IEs sequence:
        // 2 optional fields. Extension marker not present.
        std::bitset<2> noncriticalExtension_v890;
        noncriticalExtension_v890.set (1,0); // No lateNonCriticalExtension
        noncriticalExtension_v890.set (0,m_haveNonCriticalExtension); // Implemented nonCriticalExtension because compatibility with R10 - CA
        //Enable RRCCoonectionReconfiguration-v920-IEs
        SerializeSequence (noncriticalExtension_v890,false);
  	  
        // Serialize NonCriticalExtension RRCConnectionReconfiguration-v920-IEs sequence:
        // 3 optional fields. Extension marker not present.
        std::bitset<3> noncriticalExtension_v920;
        noncriticalExtension_v920.set (1,0); // No otehrConfig-r9
        noncriticalExtension_v920.set (1,0); // No fullConfig-r9
        //Enable RRCCoonectionReconfiguration-v1020-IEs
        noncriticalExtension_v920.set (0,m_haveNonCriticalExtension); // Implemented nonCriticalExtension because compatibility with R10 - CA
        SerializeSequence (noncriticalExtension_v920,false);
  	  
        SerializeNonCriticalExtensionConfiguration (m_nonCriticalExtension); //Serializing RRCConnectionReconfiguration-r8-IEs
    }

  // Finish serialization
  FinalizeSerialization ();
}

uint32_t
RrcConnectionReconfigurationHeader::Deserialize (Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;

  bIterator = DeserializeDlDcchMessage (bIterator);

  // 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,false,&sel,bIterator);
  if (sel == 1)
    {
      // criticalExtensionsFuture
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
    }
  else if (sel == 0)
    {
      // c1
      int c1Chosen;
      bIterator = DeserializeChoice (8,false,&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)
            {
              bIterator = DeserializeMeasConfig (&m_measConfig, bIterator);
            }

          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 = EnumToBandwidth (n);

                  if (ulBandwidthPresent[0])
                    {
                      bIterator = DeserializeEnum (16,&n,bIterator);
                      m_mobilityControlInfo.carrierBandwidth.ulBandwidth = EnumToBandwidth (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 (&m_mobilityControlInfo.radioResourceConfigCommon, 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
            m_haveNonCriticalExtension = rrcConnRecOpts[0];
            if (m_haveNonCriticalExtension)
            {
                bIterator = DeserializeNonCriticalExtensionConfig (&m_nonCriticalExtension,bIterator);
              // ...
            }
        }
    }

  return GetSerializedSize ();
}

void
RrcConnectionReconfigurationHeader::Print (std::ostream &os) const
{
  os << "rrcTransactionIdentifier: " << (int) m_rrcTransactionIdentifier << std::endl;
  os << "haveMeasConfig: " << m_haveMeasConfig << std::endl;
  if (m_haveMeasConfig)
    {
      if (!m_measConfig.measObjectToRemoveList.empty ())
        {
          os << "  measObjectToRemoveList: ";
          std::list<uint8_t> auxList = m_measConfig.measObjectToRemoveList;
          std::list<uint8_t>::iterator it = auxList.begin ();
          for (; it != auxList.end (); it++)
            {
              os << (int) *it << ", ";
            }
          os << std::endl;
        }
      if (!m_measConfig.reportConfigToRemoveList.empty ())
        {
          os << "  reportConfigToRemoveList: ";
          std::list<uint8_t> auxList = m_measConfig.reportConfigToRemoveList;
          std::list<uint8_t>::iterator it = auxList.begin ();
          for (; it != auxList.end (); it++)
            {
              os << (int) *it << ", ";
            }
          os << std::endl;
        }
      if (!m_measConfig.measIdToRemoveList.empty ())
        {
          os << "  measIdToRemoveList: ";
          std::list<uint8_t> auxList = m_measConfig.measIdToRemoveList;
          std::list<uint8_t>::iterator it = auxList.begin ();
          for (; it != auxList.end (); it++)
            {
              os << (int) *it << ", ";
            }
          os << std::endl;
        }

      if (!m_measConfig.measObjectToAddModList.empty ())
        {
          os << "  measObjectToAddMod: " << std::endl;
          std::list<LteRrcSap::MeasObjectToAddMod> auxList = m_measConfig.measObjectToAddModList;
          std::list<LteRrcSap::MeasObjectToAddMod>::iterator it = auxList.begin ();
          for (; it != auxList.end (); it++)
            {
              os << "    measObjectId: " << (int)it->measObjectId << std::endl;
              os << "    carrierFreq: " << (int)it->measObjectEutra.carrierFreq << std::endl;
              os << "    allowedMeasBandwidth: " <<  (int)it->measObjectEutra.allowedMeasBandwidth << std::endl;
              os << "    presenceAntennaPort1: " <<  it->measObjectEutra.presenceAntennaPort1  << std::endl;
              os << "    neighCellConfig: " << (int) it->measObjectEutra.neighCellConfig  << std::endl;
              os << "    offsetFreq: " <<  (int)it->measObjectEutra.offsetFreq  << std::endl;


              if (!it->measObjectEutra.cellsToRemoveList.empty ())
                {
                  os << "    cellsToRemoveList: ";
                  std::list<uint8_t> auxList = it->measObjectEutra.cellsToRemoveList;
                  std::list<uint8_t>::iterator it = auxList.begin ();
                  for (; it != auxList.end (); it++)
                    {
                      os << (int) *it << ", ";
                    }
                  os << std::endl;
                }

              if (!it->measObjectEutra.blackCellsToRemoveList.empty ())
                {
                  os << "    blackCellsToRemoveList: ";
                  std::list<uint8_t> auxList = it->measObjectEutra.blackCellsToRemoveList;
                  std::list<uint8_t>::iterator it = auxList.begin ();
                  for (; it != auxList.end (); it++)
                    {
                      os << (int) *it << ", ";
                    }
                  os << std::endl;
                }

              if (!it->measObjectEutra.cellsToAddModList.empty ())
                {
                  os << "    cellsToAddModList: " << std::endl;
                  std::list<LteRrcSap::CellsToAddMod> auxList = it->measObjectEutra.cellsToAddModList;
                  std::list<LteRrcSap::CellsToAddMod>::iterator it = auxList.begin ();
                  for (; it != auxList.end (); it++)
                    {
                      os << "      cellIndex: " <<  (int)it->cellIndex << std::endl;
                      os << "      physCellId: " <<  (int)it->physCellId  << std::endl;
                      os << "      cellIndividualOffset: " <<  (int)it->cellIndividualOffset << std::endl;
                      os << "      ------ " << std::endl;
                    }
                }

              if (!it->measObjectEutra.blackCellsToAddModList.empty ())
                {
                  os << "    blackCellsToAddModList: " << std::endl;
                  std::list<LteRrcSap::BlackCellsToAddMod> auxList = it->measObjectEutra.blackCellsToAddModList;
                  std::list<LteRrcSap::BlackCellsToAddMod>::iterator it = auxList.begin ();
                  for (; it != auxList.end (); it++)
                    {
                      os << "      cellIndex: " <<  (int)it->cellIndex << std::endl;
                      os << "      physCellIdRange.start: " <<  (int)it->physCellIdRange.start  << std::endl;
                      os << "      physCellIdRange.haveRange: " <<  it->physCellIdRange.haveRange << std::endl;
                      os << "      physCellIdRange.range: " <<  (int)it->physCellIdRange.range << std::endl;
                      os << "      ------ " << std::endl;
                    }
                }

              os << "    haveCellForWhichToReportCGI: " <<  it->measObjectEutra.haveCellForWhichToReportCGI  << std::endl;
              os << "    cellForWhichToReportCGI: " <<  (int)it->measObjectEutra.cellForWhichToReportCGI  << std::endl;
              os << "    ------------- " << std::endl;
            }

        }

      if (!m_measConfig.reportConfigToAddModList.empty ())
        {
          os << "  reportConfigToAddModList: " << std::endl;
          std::list<LteRrcSap::ReportConfigToAddMod> auxList = m_measConfig.reportConfigToAddModList;
          std::list<LteRrcSap::ReportConfigToAddMod>::iterator it = auxList.begin ();
          for (; it != auxList.end (); it++)
            {
              os << "    reportConfigId: " << (int)it->reportConfigId << std::endl;
              os << "    reportConfigEutra.triggerType  " <<  (int)it->reportConfigEutra.triggerType << std::endl;
              if (it->reportConfigEutra.triggerType == LteRrcSap::ReportConfigEutra::EVENT)
                {
                  os << "    reportConfigEutra.eventId  " <<  (int)it->reportConfigEutra.eventId << std::endl;
                  if (it->reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A3)
                    {
                      os << "    reportConfigEutra.reportOnLeave  " <<  (int)it->reportConfigEutra.reportOnLeave << std::endl;
                      os << "    reportConfigEutra.a3Offset  " <<  (int)it->reportConfigEutra.a3Offset << std::endl;
                    }
                  else
                    {
                      os << "    reportConfigEutra.threshold1.choice  " <<  (int)it->reportConfigEutra.threshold1.choice << std::endl;
                      os << "    reportConfigEutra.threshold1.range  " <<  (int)it->reportConfigEutra.threshold1.range << std::endl;
                      if (it->reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A5)
                        {
                          os << "    reportConfigEutra.threshold2.choice  " <<  (int)it->reportConfigEutra.threshold2.choice << std::endl;
                          os << "    reportConfigEutra.threshold2.range  " <<  (int)it->reportConfigEutra.threshold2.range << std::endl;
                        }
                    }
                  os << "    reportConfigEutra.hysteresis  " <<  (int)it->reportConfigEutra.hysteresis << std::endl;
                  os << "    reportConfigEutra.timeToTrigger  " <<  (int)it->reportConfigEutra.timeToTrigger << std::endl;
                }
              else
                {
                  os << "    reportConfigEutra.purpose  " <<  (int)it->reportConfigEutra.purpose << std::endl;
                }
              os << "    reportConfigEutra.triggerQuantity  " <<  (int)it->reportConfigEutra.triggerQuantity << std::endl;
              os << "    reportConfigEutra.reportQuantity  " <<  (int)it->reportConfigEutra.reportQuantity << std::endl;
              os << "    reportConfigEutra.maxReportCells  " <<  (int)it->reportConfigEutra.maxReportCells << std::endl;
              os << "    reportConfigEutra.reportInterval  " <<  (int)it->reportConfigEutra.reportInterval << std::endl;
              os << "    reportConfigEutra.reportAmount  " <<  (int)it->reportConfigEutra.reportAmount << std::endl;
            }
        }

      if (!m_measConfig.measIdToAddModList.empty ())
        {
          os << "  measIdToAddModList: " << std::endl;
          std::list<LteRrcSap::MeasIdToAddMod> auxList = m_measConfig.measIdToAddModList;
          std::list<LteRrcSap::MeasIdToAddMod>::iterator it = auxList.begin ();
          for (; it != auxList.end (); it++)
            {
              os << "    measId: " << (int)it->measId << std::endl;
              os << "    measObjectId: " << (int)it->measObjectId << std::endl;
              os << "    reportConfigId: " << (int)it->reportConfigId << std::endl;
              os << "    ------ " << std::endl;
            }
        }

      os << "  haveQuantityConfig: " << m_measConfig.haveQuantityConfig << std::endl;
      if (m_measConfig.haveQuantityConfig)
        {
          os << "    filterCoefficientRSRP: " << (int)m_measConfig.quantityConfig.filterCoefficientRSRP << std::endl;
          os << "    filterCoefficientRSRQ:" << (int)m_measConfig.quantityConfig.filterCoefficientRSRQ  << std::endl;
        }

      os << "  haveMeasGapConfig: " << m_measConfig.haveMeasGapConfig << std::endl;
      if (m_measConfig.haveMeasGapConfig)
        {
          os << "    measGapConfig.type: " << m_measConfig.measGapConfig.type << std::endl;
          os << "    measGapConfig.gap (gap0/1,value): (" << m_measConfig.measGapConfig.gapOffsetChoice
             << "," << (int) m_measConfig.measGapConfig.gapOffsetValue << ")" << std::endl;
        }

      os << "  haveSmeasure: " << m_measConfig.haveSmeasure << std::endl;
      if (m_measConfig.haveSmeasure)
        {
          os << "    sMeasure: " << (int) m_measConfig.sMeasure  << std::endl;
        }

      os << "  haveSpeedStatePars: " << m_measConfig.haveSpeedStatePars << std::endl;
      if (m_measConfig.haveSpeedStatePars)
        {
          os << "    speedStatePars.type: " << m_measConfig.speedStatePars.type << std::endl;
          os << "    speedStatePars.mobilityStateParameters.tEvaluation: " << (int)m_measConfig.speedStatePars.mobilityStateParameters.tEvaluation << std::endl;
          os << "    speedStatePars.mobilityStateParameters.tHystNormal: " << (int)m_measConfig.speedStatePars.mobilityStateParameters.tHystNormal << std::endl;
          os << "    speedStatePars.mobilityStateParameters.nCellChangeMedium: " << (int)m_measConfig.speedStatePars.mobilityStateParameters.nCellChangeMedium << std::endl;
          os << "    speedStatePars.mobilityStateParameters.nCellChangeHigh: " << (int)m_measConfig.speedStatePars.mobilityStateParameters.nCellChangeHigh << std::endl;
          os << "    speedStatePars.timeToTriggerSf.sfMedium: " << (int)m_measConfig.speedStatePars.timeToTriggerSf.sfMedium << std::endl;
          os << "    speedStatePars.timeToTriggerSf.sfHigh: " << (int)m_measConfig.speedStatePars.timeToTriggerSf.sfHigh << 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 (LteRrcSap::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_haveNonCriticalExtension = msg.haveNonCriticalExtension;
  m_nonCriticalExtension = msg.nonCriticalExtension;

  m_isDataSerialized = false;
}

LteRrcSap::RrcConnectionReconfiguration
RrcConnectionReconfigurationHeader::GetMessage () const
{
  LteRrcSap::RrcConnectionReconfiguration msg;

  msg.rrcTransactionIdentifier = m_rrcTransactionIdentifier;
  msg.haveMeasConfig = m_haveMeasConfig;
  msg.measConfig = m_measConfig;
  msg.haveMobilityControlInfo = m_haveMobilityControlInfo;
  msg.mobilityControlInfo = m_mobilityControlInfo;
  msg.haveRadioResourceConfigDedicated = m_haveRadioResourceConfigDedicated;
  msg.radioResourceConfigDedicated = m_radioResourceConfigDedicated;
  msg.haveNonCriticalExtension = m_haveNonCriticalExtension;
  msg.nonCriticalExtension = m_nonCriticalExtension;

  return msg;
}

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::GetHaveNonCriticalExtensionConfig ()
  {
    return m_haveNonCriticalExtension;
  }

  LteRrcSap::NonCriticalExtensionConfiguration
  RrcConnectionReconfigurationHeader::GetNonCriticalExtensionConfig ()
  {
    return m_nonCriticalExtension;
}

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 (std::bitset<0> (),false);

  // Serialize criticalExtensions choice
  // 2 options, selected 0 (c1)
  SerializeChoice (2,0,false);

  // Serialize c1 choice
  // 8 options, selected 0 (handoverPreparationInformation-r8)
  SerializeChoice (8,0,false);

  // 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
  SerializeMeasConfig (m_asConfig.sourceMeasConfig);

  // 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, BandwidthToEnum (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 (m_asConfig.sourceSystemInformationBlockType2);

  // 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,false,&criticalExtensionsChosen,bIterator);

  if (criticalExtensionsChosen == 1)
    {
      // Deserialize criticalExtensionsFuture
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
    }
  else if (criticalExtensionsChosen == 0)
    {
      // Deserialize c1 choice
      int c1Chosen;
      bIterator = DeserializeChoice (8,false,&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
              bIterator = DeserializeMeasConfig (&m_asConfig.sourceMeasConfig, bIterator);

              // 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 = EnumToBandwidth (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 (&m_asConfig.sourceSystemInformationBlockType2,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 (LteRrcSap::HandoverPreparationInfo msg)
{
  m_asConfig = msg.asConfig;
  m_isDataSerialized = false;
}

LteRrcSap::HandoverPreparationInfo
HandoverPreparationInfoHeader::GetMessage () const
{
  LteRrcSap::HandoverPreparationInfo msg;
  msg.asConfig = m_asConfig;

  return msg;
}

LteRrcSap::AsConfig
HandoverPreparationInfoHeader::GetAsConfig () const
{
  return m_asConfig;
}

//////////////////// RrcConnectionReestablishmentRequestHeader class ////////////////////////

RrcConnectionReestablishmentRequestHeader::RrcConnectionReestablishmentRequestHeader ()
{
}

RrcConnectionReestablishmentRequestHeader::~RrcConnectionReestablishmentRequestHeader ()
{
}

void
RrcConnectionReestablishmentRequestHeader::PreSerialize () const
{
  m_serializationResult = Buffer ();

  SerializeUlCcchMessage (0);

  // Serialize RrcConnectionReestablishmentReques sequence:
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize criticalExtensions choice
  // chosen: rrcConnectionReestablishmentRequest-r8
  SerializeChoice (2,0,false);

  // Serialize RRCConnectionReestablishmentRequest-r8-IEs sequence
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize ue-Identity
  SerializeSequence (std::bitset<0> (),false);
  // Serialize c-RNTI
  SerializeBitstring (std::bitset<16> (m_ueIdentity.cRnti));
  // Serialize physCellId
  SerializeInteger (m_ueIdentity.physCellId,0,503);
  // Serialize shortMAC-I
  SerializeBitstring (std::bitset<16> (0));

  // Serialize ReestablishmentCause
  switch (m_reestablishmentCause)
    {
    case LteRrcSap::RECONFIGURATION_FAILURE:
      SerializeEnum (4,0);
      break;
    case LteRrcSap::HANDOVER_FAILURE:
      SerializeEnum (4,1);
      break;
    case LteRrcSap::OTHER_FAILURE:
      SerializeEnum (4,2);
      break;
    default:
      SerializeEnum (4,3);
    }

  // Serialize spare
  SerializeBitstring (std::bitset<2> (0));

  // Finish serialization
  FinalizeSerialization ();
}

uint32_t
RrcConnectionReestablishmentRequestHeader::Deserialize (Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;
  int n;

  bIterator = DeserializeUlCcchMessage (bIterator);

  // Deserialize RrcConnectionReestablishmentRequest sequence
  // 0 optional fields, no extension marker
  bIterator = DeserializeSequence (&bitset0,false,bIterator);

  // Deserialize criticalExtensions choice
  bIterator = DeserializeChoice (2,false,&n,bIterator);
  if ( n == 1)
    {
      // Deserialize criticalExtensionsFuture
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
    }
  else if ( n == 0)
    {
      // Deserialize RRCConnectionReestablishmentRequest-r8-IEs
      bIterator = DeserializeSequence (&bitset0,false,bIterator);

      // Deserialize ReestabUE-Identity sequence
      bIterator = DeserializeSequence (&bitset0,false,bIterator);

      // Deserialize c-RNTI
      std::bitset<16> cRnti;
      bIterator = DeserializeBitstring (&cRnti,bIterator);
      m_ueIdentity.cRnti = cRnti.to_ulong ();

      // Deserialize physCellId
      int physCellId;
      bIterator = DeserializeInteger (&physCellId,0,503,bIterator);
      m_ueIdentity.physCellId = physCellId;

      // Deserialize shortMAC-I
      std::bitset<16> shortMacI;
      bIterator = DeserializeBitstring (&shortMacI,bIterator);

      // Deserialize ReestablishmentCause
      int reestCs;
      bIterator = DeserializeEnum (4,&reestCs,bIterator);
      switch (reestCs)
        {
        case 0:
          m_reestablishmentCause = LteRrcSap::RECONFIGURATION_FAILURE;
          break;
        case 1:
          m_reestablishmentCause = LteRrcSap::HANDOVER_FAILURE;
          break;
        case 2:
          m_reestablishmentCause = LteRrcSap::OTHER_FAILURE;
          break;
        case 3:
          break;
        }

      // Deserialize spare
      std::bitset<2> spare;
      bIterator = DeserializeBitstring (&spare,bIterator);
    }

  return GetSerializedSize ();
}

void
RrcConnectionReestablishmentRequestHeader::Print (std::ostream &os) const
{
  os << "ueIdentity.cRnti: " << (int)m_ueIdentity.cRnti << std::endl;
  os << "ueIdentity.physCellId: " << (int)m_ueIdentity.physCellId << std::endl;
  os << "m_reestablishmentCause: " << m_reestablishmentCause << std::endl;
}

void
RrcConnectionReestablishmentRequestHeader::SetMessage (LteRrcSap::RrcConnectionReestablishmentRequest msg)
{
  m_ueIdentity = msg.ueIdentity;
  m_reestablishmentCause = msg.reestablishmentCause;
  m_isDataSerialized = false;
}

LteRrcSap::RrcConnectionReestablishmentRequest
RrcConnectionReestablishmentRequestHeader::GetMessage () const
{
  LteRrcSap::RrcConnectionReestablishmentRequest msg;
  msg.ueIdentity = m_ueIdentity;
  msg.reestablishmentCause = m_reestablishmentCause;

  return msg;
}

LteRrcSap::ReestabUeIdentity
RrcConnectionReestablishmentRequestHeader::GetUeIdentity () const
{
  return m_ueIdentity;
}

LteRrcSap::ReestablishmentCause
RrcConnectionReestablishmentRequestHeader::GetReestablishmentCause () const
{
  return m_reestablishmentCause;
}

//////////////////// RrcConnectionReestablishmentHeader class ////////////////////////

RrcConnectionReestablishmentHeader::RrcConnectionReestablishmentHeader ()
{
}

RrcConnectionReestablishmentHeader::~RrcConnectionReestablishmentHeader ()
{
}

void
RrcConnectionReestablishmentHeader::PreSerialize () const
{
  m_serializationResult = Buffer ();

  SerializeDlCcchMessage (0);

  // Serialize RrcConnectionReestablishment sequence:
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize rrc-TransactionIdentifier
  SerializeInteger (m_rrcTransactionIdentifier,0,3);

  // Serialize criticalExtensions choice
  SerializeChoice (2,0,false);

  // Serialize c1 choice
  SerializeChoice (8,0,false);

  // Serialize RRCConnectionReestablishment-r8-IEs sequence
  // 1 optional field, no extension marker
  SerializeSequence (std::bitset<1> (0),false);

  // Serialize radioResourceConfigDedicated
  SerializeRadioResourceConfigDedicated (m_radioResourceConfigDedicated);

  // Serialize nextHopChainingCount
  SerializeInteger (0,0,7);

  // Finish serialization
  FinalizeSerialization ();
}

uint32_t
RrcConnectionReestablishmentHeader::Deserialize (Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;
  int n;

  bIterator = DeserializeDlCcchMessage (bIterator);

  // Deserialize RrcConnectionReestablishment sequence
  // 0 optional fields, no extension marker
  bIterator = DeserializeSequence (&bitset0,false,bIterator);

  // Deserialize rrc-TransactionIdentifier
  bIterator = DeserializeInteger (&n,0,3,bIterator);
  m_rrcTransactionIdentifier = n;

  // Deserialize criticalExtensions choice
  int criticalExtensionsChoice;
  bIterator = DeserializeChoice (2,false,&criticalExtensionsChoice,bIterator);
  if (criticalExtensionsChoice == 1)
    {
      // Deserialize criticalExtensionsFuture
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
    }
  else if (criticalExtensionsChoice == 0)
    {
      // Deserialize c1
      int c1;
      bIterator = DeserializeChoice (8,false,&c1,bIterator);
      if (c1 > 0)
        {
          bIterator = DeserializeNull (bIterator);
        }
      else if (c1 == 0)
        {
          // Deserialize rrcConnectionReestablishment-r8
          // 1 optional field
          std::bitset<1> nonCriticalExtensionPresent;
          bIterator = DeserializeSequence (&nonCriticalExtensionPresent,false,bIterator);

          // Deserialize RadioResourceConfigDedicated
          bIterator = DeserializeRadioResourceConfigDedicated (&m_radioResourceConfigDedicated,bIterator);

          // Deserialize nextHopChainingCount
          bIterator = DeserializeInteger (&n,0,7,bIterator);
        }
    }

  return GetSerializedSize ();
}

void
RrcConnectionReestablishmentHeader::Print (std::ostream &os) const
{
  os << "rrcTransactionIdentifier: " << (int)m_rrcTransactionIdentifier << std::endl;
  os << "RadioResourceConfigDedicated: " << std::endl;
  RrcAsn1Header::Print (os,m_radioResourceConfigDedicated);
}

void
RrcConnectionReestablishmentHeader::SetMessage (LteRrcSap::RrcConnectionReestablishment msg)
{
  m_rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
  m_radioResourceConfigDedicated = msg.radioResourceConfigDedicated;
  m_isDataSerialized = false;
}

LteRrcSap::RrcConnectionReestablishment
RrcConnectionReestablishmentHeader::GetMessage () const
{
  LteRrcSap::RrcConnectionReestablishment msg;
  msg.rrcTransactionIdentifier = m_rrcTransactionIdentifier;
  msg.radioResourceConfigDedicated = m_radioResourceConfigDedicated;
  return msg;
}

uint8_t
RrcConnectionReestablishmentHeader::GetRrcTransactionIdentifier () const
{
  return m_rrcTransactionIdentifier;
}

LteRrcSap::RadioResourceConfigDedicated
RrcConnectionReestablishmentHeader::GetRadioResourceConfigDedicated () const
{
  return m_radioResourceConfigDedicated;
}

//////////////////// RrcConnectionReestablishmentCompleteHeader class ////////////////////////

RrcConnectionReestablishmentCompleteHeader::RrcConnectionReestablishmentCompleteHeader ()
{
}

void
RrcConnectionReestablishmentCompleteHeader::PreSerialize () const
{
  m_serializationResult = Buffer ();

  // Serialize DCCH message
  SerializeUlDcchMessage (3);

  // Serialize RrcConnectionReestablishmentComplete sequence:
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize rrc-TransactionIdentifier
  SerializeInteger (m_rrcTransactionIdentifier,0,3);

  // Serialize criticalExtensions choice
  SerializeChoice (2,0,false);

  // Serialize rrcConnectionReestablishmentComplete-r8 sequence
  // 1 optional field (not present), no extension marker.
  SerializeSequence (std::bitset<1> (0),false);

  // Finish serialization
  FinalizeSerialization ();
}

uint32_t
RrcConnectionReestablishmentCompleteHeader::Deserialize (Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;
  int n;

  bIterator = DeserializeUlDcchMessage (bIterator);

  // Deserialize RrcConnectionReestablishmentComplete sequence
  // 0 optional fields, no extension marker
  bIterator = DeserializeSequence (&bitset0,false,bIterator);

  // Deserialize rrc-TransactionIdentifier
  bIterator = DeserializeInteger (&n,0,3,bIterator);
  m_rrcTransactionIdentifier = n;

  // Deserialize criticalExtensions choice
  int criticalExtensionsChoice;
  bIterator = DeserializeChoice (2,false,&criticalExtensionsChoice,bIterator);
  if (criticalExtensionsChoice == 1)
    {
      // Deserialize criticalExtensionsFuture
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
    }
  else if (criticalExtensionsChoice == 0)
    {
      // Deserialize rrcConnectionReestablishmentComplete-r8
      std::bitset<1> opts;
      bIterator = DeserializeSequence (&opts,false,bIterator);
      if (opts[0])
        {
          // Deserialize RRCConnectionReestablishmentComplete-v920-IEs
          // ...
        }
    }

  return GetSerializedSize ();
}

void
RrcConnectionReestablishmentCompleteHeader::Print (std::ostream &os) const
{
  os << "rrcTransactionIdentifier: " << (int)m_rrcTransactionIdentifier << std::endl;
}

void
RrcConnectionReestablishmentCompleteHeader::SetMessage (LteRrcSap::RrcConnectionReestablishmentComplete msg)
{
  m_rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
  m_isDataSerialized = false;
}

LteRrcSap::RrcConnectionReestablishmentComplete
RrcConnectionReestablishmentCompleteHeader::GetMessage () const
{
  LteRrcSap::RrcConnectionReestablishmentComplete msg;
  msg.rrcTransactionIdentifier = m_rrcTransactionIdentifier;
  return msg;
}

uint8_t
RrcConnectionReestablishmentCompleteHeader::GetRrcTransactionIdentifier () const
{
  return m_rrcTransactionIdentifier;
}

//////////////////// RrcConnectionReestablishmentRejectHeader class ////////////////////////

RrcConnectionReestablishmentRejectHeader::RrcConnectionReestablishmentRejectHeader ()
{
}

RrcConnectionReestablishmentRejectHeader::~RrcConnectionReestablishmentRejectHeader ()
{
}

void
RrcConnectionReestablishmentRejectHeader::PreSerialize () const
{
  m_serializationResult = Buffer ();

  // Serialize CCCH message
  SerializeDlCcchMessage (1);

  // Serialize RrcConnectionReestablishmentReject sequence:
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize criticalExtensions choice
  SerializeChoice (2,0,false);

  // Serialize RRCConnectionReestablishmentReject-r8-IEs sequence
  // 1 optional field (not present), no extension marker.
  SerializeSequence (std::bitset<1> (0),false);

  // Finish serialization
  FinalizeSerialization ();
}

uint32_t
RrcConnectionReestablishmentRejectHeader::Deserialize (Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;

  bIterator = DeserializeDlCcchMessage (bIterator);

  // Deserialize RrcConnectionReestablishmentReject sequence
  // 0 optional fields, no extension marker
  bIterator = DeserializeSequence (&bitset0,false,bIterator);

  // Deserialize criticalExtensions choice
  int criticalExtensionsChoice;
  bIterator = DeserializeChoice (2,false,&criticalExtensionsChoice,bIterator);
  if (criticalExtensionsChoice == 1)
    {
      // Deserialize criticalExtensionsFuture
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
    }
  else if (criticalExtensionsChoice == 0)
    {
      // Deserialize rrcConnectionReestablishmentReject-r8
      std::bitset<1> opts;
      bIterator = DeserializeSequence (&opts,false,bIterator);
      if (opts[0])
        {
          // Deserialize RRCConnectionReestablishmentReject-v8a0-IEs
          // ...
        }
    }

  return GetSerializedSize ();
}

void
RrcConnectionReestablishmentRejectHeader::Print (std::ostream &os) const
{
}

void
RrcConnectionReestablishmentRejectHeader::SetMessage (LteRrcSap::RrcConnectionReestablishmentReject msg)
{
  m_rrcConnectionReestablishmentReject = msg;
  m_isDataSerialized = false;
}

LteRrcSap::RrcConnectionReestablishmentReject
RrcConnectionReestablishmentRejectHeader::GetMessage () const
{
  return m_rrcConnectionReestablishmentReject;
}

//////////////////// RrcConnectionReleaseHeader class ////////////////////////

RrcConnectionReleaseHeader::RrcConnectionReleaseHeader ()
{
}

RrcConnectionReleaseHeader::~RrcConnectionReleaseHeader ()
{
}

void
RrcConnectionReleaseHeader::PreSerialize () const
{
  m_serializationResult = Buffer ();

  // Serialize DCCH message
  SerializeDlDcchMessage (5);

  // Serialize RrcConnectionRelease sequence:
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize rrc-TransactionIdentifier
  SerializeInteger (m_rrcConnectionRelease.rrcTransactionIdentifier,0,3);

  // Serialize criticalExtensions choice
  SerializeChoice (2,0,false);

  // Serialize c1 choice
  SerializeChoice (4,0,false);

  // Serialize RRCConnectionRelease-r8-IEs sequence
  // 3 optional field (not present), no extension marker.
  SerializeSequence (std::bitset<3> (0),false);

  // Serialize ReleaseCause
  SerializeEnum (4,1);

  // Finish serialization
  FinalizeSerialization ();
}

uint32_t
RrcConnectionReleaseHeader::Deserialize (Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;
  int n;

  bIterator = DeserializeDlDcchMessage (bIterator);

  // Deserialize RrcConnectionRelease sequence
  // 0 optional fields, no extension marker
  bIterator = DeserializeSequence (&bitset0,false,bIterator);

  // Deserialize rrc-TransactionIdentifier
  bIterator = DeserializeInteger (&n,0,3,bIterator);
  m_rrcConnectionRelease.rrcTransactionIdentifier = n;

  // Deserialize criticalExtensions choice
  int criticalExtensionsChoice;
  bIterator = DeserializeChoice (2,false,&criticalExtensionsChoice,bIterator);
  if (criticalExtensionsChoice == 1)
    {
      // Deserialize criticalExtensionsFuture
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
    }
  else if (criticalExtensionsChoice == 0)
    {
      // Deserialize c1
      int c1Choice;
      bIterator = DeserializeChoice (4,false,&c1Choice,bIterator);

      if (c1Choice == 0)
        {
          // Deserialize RRCConnectionRelease-r8-IEs
          std::bitset<3> opts;
          bIterator = DeserializeSequence (&opts,false,bIterator);

          // Deserialize releaseCause
          bIterator = DeserializeEnum (4,&n,bIterator);

          if (opts[2])
            {
              // Deserialize redirectedCarrierInfo
              // ...
            }
          if (opts[1])
            {
              // Deserialize idleModeMobilityControlInfo
              // ...
            }
          if (opts[0])
            {
              // Deserialize nonCriticalExtension
              // ...
            }
        }

      else
        {
          bIterator = DeserializeNull (bIterator);
        }
    }

  return GetSerializedSize ();
}

void
RrcConnectionReleaseHeader::Print (std::ostream &os) const
{
}

void
RrcConnectionReleaseHeader::SetMessage (LteRrcSap::RrcConnectionRelease msg)
{
  m_rrcConnectionRelease = msg;
  m_isDataSerialized = false;
}

LteRrcSap::RrcConnectionRelease
RrcConnectionReleaseHeader::GetMessage () const
{
  return m_rrcConnectionRelease;
}

//////////////////// RrcConnectionRejectHeader class ////////////////////////

RrcConnectionRejectHeader::RrcConnectionRejectHeader ()
{
}

RrcConnectionRejectHeader::~RrcConnectionRejectHeader ()
{
}

void
RrcConnectionRejectHeader::PreSerialize () const
{
  m_serializationResult = Buffer ();

  // Serialize CCCH message
  SerializeDlCcchMessage (2);

  // Serialize RrcConnectionReject sequence:
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize criticalExtensions choice
  SerializeChoice (2,0,false);

  // Serialize c1 choice
  SerializeChoice (4,0,false);

  // Serialize rrcConnectionReject-r8 sequence
  // 1 optional field (not present), no extension marker.
  SerializeSequence (std::bitset<1> (0),false);

  // Serialize waitTime
  SerializeInteger (m_rrcConnectionReject.waitTime, 1, 16);

  // Finish serialization
  FinalizeSerialization ();
}

uint32_t
RrcConnectionRejectHeader::Deserialize (Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;
  int n;

  bIterator = DeserializeDlCcchMessage (bIterator);

  // Deserialize RrcConnectionReject sequence
  // 0 optional fields, no extension marker
  bIterator = DeserializeSequence (&bitset0,false,bIterator);

  // Deserialize criticalExtensions choice
  int criticalExtensionsChoice;
  bIterator = DeserializeChoice (2,false,&criticalExtensionsChoice,bIterator);
  if (criticalExtensionsChoice == 1)
    {
      // Deserialize criticalExtensionsFuture
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
    }
  else if (criticalExtensionsChoice == 0)
    {
      // Deserialize c1 choice
      int c1Choice;
      bIterator = DeserializeChoice (4,false,&c1Choice,bIterator);

      if (c1Choice > 0)
        {
          bIterator = DeserializeNull (bIterator);
        }
      else if (c1Choice == 0)
        {
          // Deserialize rrcConnectionReject-r8
          std::bitset<1> opts;
          bIterator = DeserializeSequence (&opts,false,bIterator);

          bIterator = DeserializeInteger (&n,1,16,bIterator);
          m_rrcConnectionReject.waitTime = n;

          if (opts[0])
            {
              // Deserialize RRCConnectionReject-v8a0-IEs
              // ...
            }
        }
    }

  return GetSerializedSize ();
}

void
RrcConnectionRejectHeader::Print (std::ostream &os) const
{
  os << "wait time: " << (int)m_rrcConnectionReject.waitTime << std::endl;
}

void
RrcConnectionRejectHeader::SetMessage (LteRrcSap::RrcConnectionReject msg)
{
  m_rrcConnectionReject = msg;
  m_isDataSerialized = false;
}

LteRrcSap::RrcConnectionReject
RrcConnectionRejectHeader::GetMessage () const
{
  return m_rrcConnectionReject;
}

//////////////////// MeasurementReportHeader class ////////////////////////

MeasurementReportHeader::MeasurementReportHeader ()
{
}

MeasurementReportHeader::~MeasurementReportHeader ()
{
}

void
MeasurementReportHeader::PreSerialize () const
{
  m_serializationResult = Buffer ();

  // Serialize DCCH message
  SerializeUlDcchMessage (1);

  // Serialize MeasurementReport sequence:
  // no default or optional fields. Extension marker not present.
  SerializeSequence (std::bitset<0> (),false);

  // Serialize criticalExtensions choice:
  // c1 chosen
  SerializeChoice (2,0,false);

  // Serialize c1 choice
  // measurementReport-r8 chosen
  SerializeChoice (8,0,false);

  // Serialize MeasurementReport-r8-IEs sequence:
  // 1 optional fields, not present. Extension marker not present.
  SerializeSequence (std::bitset<1> (0),false);

  // Serialize measResults
  SerializeMeasResults (m_measurementReport.measResults);

  // Finish serialization
  FinalizeSerialization ();
}

uint32_t
MeasurementReportHeader::Deserialize (Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;

  bIterator = DeserializeSequence (&bitset0,false,bIterator);

  bIterator = DeserializeUlDcchMessage (bIterator);

  int criticalExtensionsChoice;
  bIterator = DeserializeChoice (2,false,&criticalExtensionsChoice,bIterator);

  if (criticalExtensionsChoice == 1)
    {
      // Deserialize criticalExtensionsFuture
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
    }
  else if (criticalExtensionsChoice == 0)
    {
      // Deserialize c1
      int c1Choice;
      bIterator = DeserializeChoice (8,false,&c1Choice,bIterator);

      if (c1Choice > 0)
        {
          bIterator = DeserializeNull (bIterator);
        }
      else
        {
          // Deserialize measurementReport-r8
          std::bitset<1> isNonCriticalExtensionPresent;
          bIterator = DeserializeSequence (&isNonCriticalExtensionPresent,false,bIterator);

          // Deserialize measResults
          bIterator = DeserializeMeasResults (&m_measurementReport.measResults, bIterator);

          if (isNonCriticalExtensionPresent[0])
            {
              // Deserialize nonCriticalExtension MeasurementReport-v8a0-IEs
              // ...
            }

        }
    }

  return GetSerializedSize ();
}

void
MeasurementReportHeader::Print (std::ostream &os) const
{
  os << "measId = " << (int)m_measurementReport.measResults.measId << std::endl;
  os << "rsrpResult = " << (int)m_measurementReport.measResults.rsrpResult << std::endl;
  os << "rsrqResult = " << (int)m_measurementReport.measResults.rsrqResult << std::endl;
  os << "haveMeasResultNeighCells = " << (int)m_measurementReport.measResults.haveMeasResultNeighCells << std::endl;

  if (m_measurementReport.measResults.haveMeasResultNeighCells)
    {
      std::list<LteRrcSap::MeasResultEutra> measResultListEutra = m_measurementReport.measResults.measResultListEutra;
      std::list<LteRrcSap::MeasResultEutra>::iterator it = measResultListEutra.begin ();
      for (; it != measResultListEutra.end (); it++)
        {
          os << "   physCellId =" << (int) it->physCellId << std::endl;
          os << "   haveCgiInfo =" << it->haveCgiInfo << std::endl;
          if (it->haveCgiInfo)
            {
              os << "      plmnIdentity = " << (int) it->cgiInfo.plmnIdentity << std::endl;
              os << "      cellIdentity = " << (int) it->cgiInfo.cellIdentity << std::endl;
              os << "      trackingAreaCode = " << (int) it->cgiInfo.trackingAreaCode << std::endl;
              os << "      havePlmnIdentityList = " << !it->cgiInfo.plmnIdentityList.empty () << std::endl;
              if (!it->cgiInfo.plmnIdentityList.empty ())
                {
                  for (std::list<uint32_t>::iterator it2 = it->cgiInfo.plmnIdentityList.begin (); it2 != it->cgiInfo.plmnIdentityList.end (); it2++)
                    {
                      os << "         plmnId : " << *it2 << std::endl;
                    }
                }
            }

          os << "   haveRsrpResult =" << it->haveRsrpResult << std::endl;
          if (it->haveRsrpResult)
            {
              os << "   rsrpResult =" << (int) it->rsrpResult << std::endl;
            }

          os << "   haveRsrqResult =" << it->haveRsrqResult << std::endl;
          if (it->haveRsrqResult)
            {
              os << "   rsrqResult =" << (int) it->rsrqResult << std::endl;
            }

        }
    }
}

void
MeasurementReportHeader::SetMessage (LteRrcSap::MeasurementReport msg)
{
  m_measurementReport = msg;
  m_isDataSerialized = false;
}

LteRrcSap::MeasurementReport
MeasurementReportHeader::GetMessage () const
{
  LteRrcSap::MeasurementReport msg;
  msg = m_measurementReport;
  return msg;
}

///////////////////  RrcUlDcchMessage //////////////////////////////////
RrcUlDcchMessage::RrcUlDcchMessage () : RrcAsn1Header ()
{
}

RrcUlDcchMessage::~RrcUlDcchMessage ()
{
}

uint32_t
RrcUlDcchMessage::Deserialize (Buffer::Iterator bIterator)
{
  DeserializeUlDcchMessage (bIterator);
  return 1;
}

void
RrcUlDcchMessage::Print (std::ostream &os) const
{
  std::cout << "UL DCCH MSG TYPE: " << m_messageType << std::endl;
}

void
RrcUlDcchMessage::PreSerialize () const
{
  SerializeUlDcchMessage (m_messageType);
}

Buffer::Iterator
RrcUlDcchMessage::DeserializeUlDcchMessage (Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;
  int n;

  bIterator = DeserializeSequence (&bitset0,false,bIterator);
  bIterator = DeserializeChoice (2,false,&n,bIterator);
  if (n == 1)
    {
      // Deserialize messageClassExtension
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
      m_messageType = -1;
    }
  else if (n == 0)
    {
      // Deserialize c1
      bIterator = DeserializeChoice (16,false,&m_messageType,bIterator);
    }

  return bIterator;
}

void
RrcUlDcchMessage::SerializeUlDcchMessage (int messageType) const
{
  SerializeSequence (std::bitset<0> (),false);
  // Choose c1
  SerializeChoice (2,0,false);
  // Choose message type
  SerializeChoice (16,messageType,false);
}

///////////////////  RrcDlDcchMessage //////////////////////////////////
RrcDlDcchMessage::RrcDlDcchMessage () : RrcAsn1Header ()
{
}

RrcDlDcchMessage::~RrcDlDcchMessage ()
{
}

uint32_t
RrcDlDcchMessage::Deserialize (Buffer::Iterator bIterator)
{
  DeserializeDlDcchMessage (bIterator);
  return 1;
}

void
RrcDlDcchMessage::Print (std::ostream &os) const
{
  std::cout << "DL DCCH MSG TYPE: " << m_messageType << std::endl;
}

void
RrcDlDcchMessage::PreSerialize () const
{
  SerializeDlDcchMessage (m_messageType);
}

Buffer::Iterator
RrcDlDcchMessage::DeserializeDlDcchMessage (Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;
  int n;

  bIterator = DeserializeSequence (&bitset0,false,bIterator);
  bIterator = DeserializeChoice (2,false,&n,bIterator);
  if (n == 1)
    {
      // Deserialize messageClassExtension
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
      m_messageType = -1;
    }
  else if (n == 0)
    {
      // Deserialize c1
      bIterator = DeserializeChoice (16,false,&m_messageType,bIterator);
    }

  return bIterator;
}

void
RrcDlDcchMessage::SerializeDlDcchMessage (int messageType) const
{
  SerializeSequence (std::bitset<0> (),false);
  // Choose c1
  SerializeChoice (2,0,false);
  // Choose message type
  SerializeChoice (16,messageType,false);
}

///////////////////  RrcUlCcchMessage //////////////////////////////////
RrcUlCcchMessage::RrcUlCcchMessage () : RrcAsn1Header ()
{
}

RrcUlCcchMessage::~RrcUlCcchMessage ()
{
}

uint32_t
RrcUlCcchMessage::Deserialize (Buffer::Iterator bIterator)
{
  DeserializeUlCcchMessage (bIterator);
  return 1;
}

void
RrcUlCcchMessage::Print (std::ostream &os) const
{
  std::cout << "UL CCCH MSG TYPE: " << m_messageType << std::endl;
}

void
RrcUlCcchMessage::PreSerialize () const
{
  SerializeUlCcchMessage (m_messageType);
}

Buffer::Iterator
RrcUlCcchMessage::DeserializeUlCcchMessage (Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;
  int n;

  bIterator = DeserializeSequence (&bitset0,false,bIterator);
  bIterator = DeserializeChoice (2,false,&n,bIterator);
  if (n == 1)
    {
      // Deserialize messageClassExtension
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
      m_messageType = -1;
    }
  else if (n == 0)
    {
      // Deserialize c1
      bIterator = DeserializeChoice (2,false,&m_messageType,bIterator);
    }

  return bIterator;
}

void
RrcUlCcchMessage::SerializeUlCcchMessage (int messageType) const
{
  SerializeSequence (std::bitset<0> (),false);
  // Choose c1
  SerializeChoice (2,0,false);
  // Choose message type
  SerializeChoice (2,messageType,false);
}

///////////////////  RrcDlCcchMessage //////////////////////////////////
RrcDlCcchMessage::RrcDlCcchMessage () : RrcAsn1Header ()
{
}

RrcDlCcchMessage::~RrcDlCcchMessage ()
{
}

uint32_t
RrcDlCcchMessage::Deserialize (Buffer::Iterator bIterator)
{
  DeserializeDlCcchMessage (bIterator);
  return 1;
}

void
RrcDlCcchMessage::Print (std::ostream &os) const
{
  std::cout << "DL CCCH MSG TYPE: " << m_messageType << std::endl;
}

void
RrcDlCcchMessage::PreSerialize () const
{
  SerializeDlCcchMessage (m_messageType);
}

Buffer::Iterator
RrcDlCcchMessage::DeserializeDlCcchMessage (Buffer::Iterator bIterator)
{
  std::bitset<0> bitset0;
  int n;

  bIterator = DeserializeSequence (&bitset0,false,bIterator);
  bIterator = DeserializeChoice (2,false,&n,bIterator);
  if (n == 1)
    {
      // Deserialize messageClassExtension
      bIterator = DeserializeSequence (&bitset0,false,bIterator);
      m_messageType = -1;
    }
  else if (n == 0)
    {
      // Deserialize c1
      bIterator = DeserializeChoice (4,false,&m_messageType,bIterator);
    }

  return bIterator;
}

void
RrcDlCcchMessage::SerializeDlCcchMessage (int messageType) const
{
  SerializeSequence (std::bitset<0> (),false);
  // Choose c1
  SerializeChoice (2,0,false);
  // Choose message type
  SerializeChoice (4,messageType,false);
}

} // namespace ns3

