This commit is contained in:
Nicola Baldo
2012-11-29 18:57:48 +01:00
6 changed files with 4310 additions and 0 deletions

View File

@@ -0,0 +1,735 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Lluis Parcerisa <lparcerisa@cttc.cat>
*/
#include "ns3/log.h"
#include "ns3/lte-asn1-header.h"
#include <stdio.h>
#include <sstream>
#include <math.h> // For log()
NS_LOG_COMPONENT_DEFINE ("Asn1Header");
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (Asn1Header);
TypeId
Asn1Header::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::Asn1Header")
.SetParent<Header> ()
;
return tid;
}
TypeId
Asn1Header::GetInstanceTypeId (void) const
{
return GetTypeId ();
}
// Constructor
Asn1Header::Asn1Header ()
{
m_serializationPendingBits = 0x00;
m_numSerializationPendingBits = 0;
m_isDataSerialized = false;
}
// Destructor
Asn1Header::~Asn1Header ()
{
}
uint32_t
Asn1Header::GetSerializedSize (void) const
{
if (!m_isDataSerialized)
{
PreSerialize ();
}
return m_serializationResult.GetSize ();
}
void Asn1Header::Serialize (Buffer::Iterator bIterator) const
{
if (!m_isDataSerialized)
{
PreSerialize ();
}
bIterator.Write (m_serializationResult.Begin (),m_serializationResult.End ());
}
void Asn1Header::WriteOctet (uint8_t octet) const
{
m_serializationResult.AddAtEnd (1);
Buffer::Iterator bIterator = m_serializationResult.End ();
bIterator.Prev ();
bIterator.WriteU8 (octet);
}
template <int N>
void Asn1Header::SerializeBitset (std::bitset<N> data) const
{
size_t dataSize = data.size ();
uint8_t pendingBits = dataSize;
uint8_t mask = 1;
int j;
// No extension marker (Clause 16.7 ITU-T X.691),
// as 3GPP TS 36.331 does not use it in its IE's.
// Clause 16.8 ITU-T X.691
if (dataSize == 0)
{
return;
}
// Clause 16.9 ITU-T X.691
// Clause 16.10 ITU-T X.691
if (dataSize <= 65536)
{
// If there are bits pending to be processed,
// append first bits in data to complete an octet.
if (m_numSerializationPendingBits > 0)
{
mask = 0x80 >> m_numSerializationPendingBits;
while (pendingBits > 0 && m_numSerializationPendingBits < 8)
{
m_serializationPendingBits |= (data[pendingBits - 1]) ? mask : 0;
pendingBits--;
m_numSerializationPendingBits++;
mask = (mask >> 1) & (~mask);
}
if (m_numSerializationPendingBits >= 8)
{
WriteOctet (m_serializationPendingBits);
m_numSerializationPendingBits = 0;
m_serializationPendingBits = 0;
}
}
while (pendingBits > 0)
{
mask = 1;
j = 8;
// If there are less than 8 remaining bits,
// store it to m_serializationPendingBits.
if (pendingBits < 8)
{
mask = 0x80;
m_numSerializationPendingBits = pendingBits;
while (pendingBits > 0)
{
m_serializationPendingBits |= (data[pendingBits - 1]) ? mask : 0;
mask = (mask >> 1) & (~mask);
pendingBits--;
}
}
// Write the data to buffer
else
{
uint8_t octetToWrite = 0;
for (; j > 0; j--)
{
octetToWrite |= (data[pendingBits - j]) ? mask : 0;
mask = (mask << 1) & (~mask);
}
WriteOctet (octetToWrite);
pendingBits -= 8;
}
}
}
// Clause 16.11 ITU-T X.691
else
{
printf ("FRAGMENTATION NEEDED!\n");
}
}
template <int N>
void Asn1Header::SerializeBitstring (std::bitset<N> data) const
{
SerializeBitset<N> (data);
}
void Asn1Header::SerializeBitstring (std::bitset<1> data) const
{
SerializeBitstring<1> (data);
}
void Asn1Header::SerializeBitstring (std::bitset<8> data) const
{
SerializeBitstring<8> (data);
}
void Asn1Header::SerializeBitstring (std::bitset<10> data) const
{
SerializeBitstring<10> (data);
}
void Asn1Header::SerializeBitstring (std::bitset<16> data) const
{
SerializeBitstring<16> (data);
}
void Asn1Header::SerializeBitstring (std::bitset<27> data) const
{
SerializeBitstring<27> (data);
}
void Asn1Header::SerializeBitstring (std::bitset<28> data) const
{
SerializeBitstring<28> (data);
}
void Asn1Header::SerializeBitstring (std::bitset<32> data) const
{
SerializeBitstring<32> (data);
}
void Asn1Header::SerializeBoolean (bool value) const
{
// Clause 12 ITU-T X.691
std::bitset<1> val;
(value) ? val.set () : val.reset ();
SerializeBitset<1> (val);
}
template <int N>
void Asn1Header::SerializeSequence (std::bitset<N> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
{
if (isExtensionMarkerPresent)
{
// Extension marker present, but no extension
SerializeBoolean (false);
}
SerializeBitstring<N> (optionalOrDefaultMask);
}
void Asn1Header::SerializeSequence (std::bitset<0> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
{
SerializeSequence<0> (optionalOrDefaultMask,isExtensionMarkerPresent);
}
void Asn1Header::SerializeSequence (std::bitset<1> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
{
SerializeSequence<1> (optionalOrDefaultMask,isExtensionMarkerPresent);
}
void Asn1Header::SerializeSequence (std::bitset<2> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
{
SerializeSequence<2> (optionalOrDefaultMask,isExtensionMarkerPresent);
}
void Asn1Header::SerializeSequence (std::bitset<3> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
{
SerializeSequence<3> (optionalOrDefaultMask,isExtensionMarkerPresent);
}
void Asn1Header::SerializeSequence (std::bitset<4> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
{
SerializeSequence<4> (optionalOrDefaultMask,isExtensionMarkerPresent);
}
void Asn1Header::SerializeSequence (std::bitset<5> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
{
SerializeSequence<5> (optionalOrDefaultMask,isExtensionMarkerPresent);
}
void Asn1Header::SerializeSequence (std::bitset<6> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
{
SerializeSequence<6> (optionalOrDefaultMask,isExtensionMarkerPresent);
}
void Asn1Header::SerializeSequence (std::bitset<9> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
{
SerializeSequence<9> (optionalOrDefaultMask,isExtensionMarkerPresent);
}
void Asn1Header::SerializeSequence (std::bitset<10> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
{
SerializeSequence<10> (optionalOrDefaultMask,isExtensionMarkerPresent);
}
void Asn1Header::SerializeSequence (std::bitset<11> optionalOrDefaultMask, bool isExtensionMarkerPresent) const
{
SerializeSequence<11> (optionalOrDefaultMask,isExtensionMarkerPresent);
}
void Asn1Header::SerializeSequenceOf (int numElems, int nMax, int nMin) const
{
// Clause 20.6 ITU-T X.691
SerializeInteger (numElems, nMin, nMax);
}
void Asn1Header::SerializeEnum (int numElems, int selectedElem) const
{
// Clause 14 ITU-T X.691
SerializeInteger (selectedElem, 0, numElems - 1);
}
void Asn1Header::SerializeChoice (int numOptions, int selectedOption) const
{
// Clause 23.4 ITU-T X.691
if (numOptions < 2)
{
return;
}
SerializeInteger (selectedOption,0,numOptions - 1);
}
void Asn1Header::SerializeInteger (int n, int nmin, int nmax) const
{
// Misusage check: Ensure nmax>nmin ...
if (nmin > nmax)
{
int aux = nmin;
nmin = nmax;
nmax = aux;
}
// Clause 11.5.3 ITU-T X.691
int range = nmax - nmin + 1;
// Substract nmin to n
n -= nmin;
// Clause 11.5.4 ITU-T X.691
if (range <= 1)
{
return;
}
// Clause 11.5.6 ITU-T X.691
int requiredBits = ceil (log (range) / log (2.0));
switch (requiredBits)
{
case 1:
SerializeBitset<1> (std::bitset<1> (n));
break;
case 2:
SerializeBitset<2> (std::bitset<2> (n));
break;
case 3:
SerializeBitset<3> (std::bitset<3> (n));
break;
case 4:
SerializeBitset<4> (std::bitset<4> (n));
break;
case 5:
SerializeBitset<5> (std::bitset<5> (n));
break;
case 6:
SerializeBitset<6> (std::bitset<6> (n));
break;
case 7:
SerializeBitset<7> (std::bitset<7> (n));
break;
case 8:
SerializeBitset<8> (std::bitset<8> (n));
break;
case 9:
SerializeBitset<9> (std::bitset<9> (n));
break;
case 10:
SerializeBitset<10> (std::bitset<10> (n));
break;
case 11:
SerializeBitset<11> (std::bitset<11> (n));
break;
case 12:
SerializeBitset<12> (std::bitset<12> (n));
break;
case 13:
SerializeBitset<13> (std::bitset<13> (n));
break;
case 14:
SerializeBitset<14> (std::bitset<14> (n));
break;
case 15:
SerializeBitset<15> (std::bitset<15> (n));
break;
case 16:
SerializeBitset<16> (std::bitset<16> (n));
break;
case 17:
SerializeBitset<17> (std::bitset<17> (n));
break;
case 18:
SerializeBitset<18> (std::bitset<18> (n));
break;
case 19:
SerializeBitset<19> (std::bitset<19> (n));
break;
case 20:
SerializeBitset<20> (std::bitset<20> (n));
break;
default:
{
std::cout << "SerializeInteger " << requiredBits << " Out of range!!" << std::endl;
exit (1);
}
}
}
void Asn1Header::SerializeNull () const
{
// Clause 18 ITU-T X.691
return;
}
void Asn1Header::FinalizeSerialization () const
{
if (m_numSerializationPendingBits > 0)
{
m_numSerializationPendingBits = 0;
SerializeBitset<8> (std::bitset<8> (m_serializationPendingBits));
}
m_isDataSerialized = true;
}
template <int N>
Buffer::Iterator Asn1Header::DeserializeBitset (std::bitset<N> *data, Buffer::Iterator bIterator)
{
int bitsToRead = N;
uint8_t mask;
// Read bits from pending bits
if (m_numSerializationPendingBits > 0)
{
while (bitsToRead > 0 && m_numSerializationPendingBits > 0)
{
data->set (bitsToRead - 1,(m_serializationPendingBits & 0x80) ? 1 : 0);
bitsToRead--;
m_numSerializationPendingBits--;
m_serializationPendingBits = m_serializationPendingBits << 1;
}
}
// Read bits from buffer
while (bitsToRead > 0)
{
uint8_t octet = bIterator.ReadU8 ();
// If 8 bits can be allocated to the bitset, set the bits
if (bitsToRead >= 8)
{
mask = 0x80;
for (int j = 0; j < 8; j++)
{
data->set (bitsToRead - 1,(octet & mask) ? 1 : 0);
bitsToRead--;
mask = mask >> 1;
}
}
// Otherwise, we'll have to save the remaining bits
else
{
mask = 0x80;
m_numSerializationPendingBits = 8 - bitsToRead;
m_serializationPendingBits = octet << bitsToRead;
while (bitsToRead > 0)
{
data->set (bitsToRead - 1,(octet & mask) ? 1 : 0);
bitsToRead--;
mask = mask >> 1;
}
}
}
return bIterator;
}
template <int N>
Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<N> *data, Buffer::Iterator bIterator)
{
return DeserializeBitset<N> (data,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<1> *data, Buffer::Iterator bIterator)
{
return DeserializeBitstring<1> (data,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<8> *data, Buffer::Iterator bIterator)
{
return DeserializeBitstring<8> (data,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<10> *data, Buffer::Iterator bIterator)
{
return DeserializeBitstring<10> (data,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<16> *data, Buffer::Iterator bIterator)
{
return DeserializeBitstring<16> (data,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<27> *data, Buffer::Iterator bIterator)
{
return DeserializeBitstring<27> (data,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<28> *data, Buffer::Iterator bIterator)
{
return DeserializeBitstring<28> (data,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeBitstring (std::bitset<32> *data, Buffer::Iterator bIterator)
{
return DeserializeBitstring<32> (data,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeBoolean (bool *value, Buffer::Iterator bIterator)
{
std::bitset<1> readBit;
bIterator = DeserializeBitset<1> (&readBit,bIterator);
*value = (readBit[0] == 1) ? true : false;
return bIterator;
}
Buffer::Iterator Asn1Header::DeserializeInteger (int *n, int nmin, int nmax, Buffer::Iterator bIterator)
{
// Misusage check: Ensure nmax>nmin ...
if (nmin > nmax)
{
int aux = nmin;
nmin = nmax;
nmax = aux;
}
int range = nmax - nmin + 1;
if (range == 1)
{
return bIterator;
}
int requiredBits = ceil (log (range) / log (2.0));
std::bitset<1> bitsRead1;
std::bitset<2> bitsRead2;
std::bitset<3> bitsRead3;
std::bitset<4> bitsRead4;
std::bitset<5> bitsRead5;
std::bitset<6> bitsRead6;
std::bitset<7> bitsRead7;
std::bitset<8> bitsRead8;
std::bitset<9> bitsRead9;
std::bitset<10> bitsRead10;
std::bitset<11> bitsRead11;
std::bitset<12> bitsRead12;
std::bitset<13> bitsRead13;
std::bitset<14> bitsRead14;
std::bitset<15> bitsRead15;
std::bitset<16> bitsRead16;
std::bitset<17> bitsRead17;
std::bitset<18> bitsRead18;
std::bitset<19> bitsRead19;
std::bitset<20> bitsRead20;
switch (requiredBits)
{
case 1:
bIterator = DeserializeBitset<1> (&bitsRead1,bIterator);
*n = (int)bitsRead1.to_ulong ();
break;
case 2:
bIterator = DeserializeBitset<2> (&bitsRead2,bIterator);
*n = (int)bitsRead2.to_ulong ();
break;
case 3:
bIterator = DeserializeBitset<3> (&bitsRead3,bIterator);
*n = (int)bitsRead3.to_ulong ();
break;
case 4:
bIterator = DeserializeBitset<4> (&bitsRead4,bIterator);
*n = (int)bitsRead4.to_ulong ();
break;
case 5:
bIterator = DeserializeBitset<5> (&bitsRead5,bIterator);
*n = (int)bitsRead5.to_ulong ();
break;
case 6:
bIterator = DeserializeBitset<6> (&bitsRead6,bIterator);
*n = (int)bitsRead6.to_ulong ();
break;
case 7:
bIterator = DeserializeBitset<7> (&bitsRead7,bIterator);
*n = (int)bitsRead7.to_ulong ();
break;
case 8:
bIterator = DeserializeBitset<8> (&bitsRead8,bIterator);
*n = (int)bitsRead8.to_ulong ();
break;
case 9:
bIterator = DeserializeBitset<9> (&bitsRead9,bIterator);
*n = (int)bitsRead9.to_ulong ();
break;
case 10:
bIterator = DeserializeBitset<10> (&bitsRead10,bIterator);
*n = (int)bitsRead10.to_ulong ();
break;
case 11:
bIterator = DeserializeBitset<11> (&bitsRead11,bIterator);
*n = (int)bitsRead11.to_ulong ();
break;
case 12:
bIterator = DeserializeBitset<12> (&bitsRead12,bIterator);
*n = (int)bitsRead12.to_ulong ();
break;
case 13:
bIterator = DeserializeBitset<13> (&bitsRead13,bIterator);
*n = (int)bitsRead13.to_ulong ();
break;
case 14:
bIterator = DeserializeBitset<14> (&bitsRead14,bIterator);
*n = (int)bitsRead14.to_ulong ();
break;
case 15:
bIterator = DeserializeBitset<15> (&bitsRead15,bIterator);
*n = (int)bitsRead15.to_ulong ();
break;
case 16:
bIterator = DeserializeBitset<16> (&bitsRead16,bIterator);
*n = (int)bitsRead16.to_ulong ();
break;
case 17:
bIterator = DeserializeBitset<17> (&bitsRead17,bIterator);
*n = (int)bitsRead17.to_ulong ();
break;
case 18:
bIterator = DeserializeBitset<18> (&bitsRead18,bIterator);
*n = (int)bitsRead18.to_ulong ();
break;
case 19:
bIterator = DeserializeBitset<19> (&bitsRead19,bIterator);
*n = (int)bitsRead19.to_ulong ();
break;
case 20:
bIterator = DeserializeBitset<20> (&bitsRead20,bIterator);
*n = (int)bitsRead20.to_ulong ();
break;
default:
{
std::cout << "SerializeInteger Out of range!!" << std::endl;
exit (1);
}
}
*n += nmin;
return bIterator;
}
Buffer::Iterator Asn1Header::DeserializeChoice (int numOptions, int *selectedOption, Buffer::Iterator bIterator)
{
return DeserializeInteger (selectedOption,0,numOptions - 1,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeEnum (int numElems, int *selectedElem, Buffer::Iterator bIterator)
{
return DeserializeInteger (selectedElem,0,numElems - 1,bIterator);
}
template <int N>
Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<N> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
{
if (isExtensionMarkerPresent)
{
bool dummy;
bIterator = DeserializeBoolean (&dummy,bIterator);
}
bIterator = DeserializeBitset<N> (optionalOrDefaultMask,bIterator);
return bIterator;
}
Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<0> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
{
return DeserializeSequence<0> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<1> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
{
return DeserializeSequence<1> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<2> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
{
return DeserializeSequence<2> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<3> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
{
return DeserializeSequence<3> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<4> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
{
return DeserializeSequence<4> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<5> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
{
return DeserializeSequence<5> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<6> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
{
return DeserializeSequence<6> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<9> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
{
return DeserializeSequence<9> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<10> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
{
return DeserializeSequence<10> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeSequence (std::bitset<11> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator)
{
return DeserializeSequence<11> (optionalOrDefaultMask,isExtensionMarkerPresent,bIterator);
}
Buffer::Iterator Asn1Header::DeserializeNull (Buffer::Iterator bIterator)
{
return bIterator;
}
Buffer::Iterator Asn1Header::DeserializeSequenceOf (int *numElems, int nMax, int nMin, Buffer::Iterator bIterator)
{
return DeserializeInteger (numElems,nMin,nMax,bIterator);
}
} // namespace ns3

View File

@@ -0,0 +1,139 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Lluis Parcerisa <lparcerisa@cttc.cat>
*/
#ifndef ASN1_HEADER_H
#define ASN1_HEADER_H
#include "ns3/header.h"
#include <bitset>
#include <string>
#include "ns3/lte-rrc-sap.h"
namespace ns3 {
/**
* This class has the purpose to encode Information Elements according
* to ASN.1 syntax, as defined in ITU-T X-691.
* IMPORTANT: The encoding is done following the UNALIGNED variant.
*/
class Asn1Header : public Header
{
public:
Asn1Header ();
virtual ~Asn1Header ();
static TypeId GetTypeId (void);
virtual TypeId GetInstanceTypeId (void) const;
uint32_t GetSerializedSize (void) const;
void Serialize (Buffer::Iterator bIterator) const;
// Pure virtual methods, implemented in child classes
virtual void PreSerialize (void) const = 0;
virtual uint32_t Deserialize (Buffer::Iterator bIterator) = 0;
virtual void Print (std::ostream &os) const = 0;
protected:
mutable uint8_t m_serializationPendingBits;
mutable uint8_t m_numSerializationPendingBits;
mutable bool m_isDataSerialized;
mutable Buffer m_serializationResult;
// Function to write in m_serializationResult, after resizing its size
void WriteOctet (uint8_t octet) const;
// Serialization functions
void SerializeBoolean (bool value) const;
void SerializeInteger (int n, int nmin, int nmax) const;
void SerializeOctetstring (std::string s) const;
void SerializeSequenceOf (int numElems, int nMax, int nMin) const;
void SerializeChoice (int numOptions, int selectedOption) const;
void SerializeEnum (int numElems, int selectedElem) const;
void SerializeNull () const;
void FinalizeSerialization () const;
template <int N>
void SerializeBitset (std::bitset<N> data) const;
template <int N>
void SerializeSequence (std::bitset<N> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
void SerializeSequence (std::bitset<0> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
void SerializeSequence (std::bitset<1> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
void SerializeSequence (std::bitset<2> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
void SerializeSequence (std::bitset<3> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
void SerializeSequence (std::bitset<4> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
void SerializeSequence (std::bitset<5> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
void SerializeSequence (std::bitset<6> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
void SerializeSequence (std::bitset<9> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
void SerializeSequence (std::bitset<10> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
void SerializeSequence (std::bitset<11> optionalOrDefaultMask, bool isExtensionMarkerPresent) const;
template <int N>
void SerializeBitstring (std::bitset<N> bitstring) const;
void SerializeBitstring (std::bitset<1> bitstring) const;
void SerializeBitstring (std::bitset<8> bitstring) const;
void SerializeBitstring (std::bitset<10> bitstring) const;
void SerializeBitstring (std::bitset<16> bitstring) const;
void SerializeBitstring (std::bitset<27> bitstring) const;
void SerializeBitstring (std::bitset<28> bitstring) const;
void SerializeBitstring (std::bitset<32> bitstring) const;
// Deserialization functions
template <int N>
Buffer::Iterator DeserializeBitset (std::bitset<N> *data, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeBitset (std::bitset<8> *data, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeBoolean (bool *value, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeInteger (int *n, int nmin, int nmax, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeChoice (int numOptions, int *selectedOption, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeEnum (int numElems, int *selectedElem, Buffer::Iterator bIterator);
template <int N>
Buffer::Iterator DeserializeSequence (std::bitset<N> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeSequence (std::bitset<0> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeSequence (std::bitset<1> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeSequence (std::bitset<2> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeSequence (std::bitset<3> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeSequence (std::bitset<4> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeSequence (std::bitset<5> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeSequence (std::bitset<6> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeSequence (std::bitset<9> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeSequence (std::bitset<10> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeSequence (std::bitset<11> *optionalOrDefaultMask, bool isExtensionMarkerPresent, Buffer::Iterator bIterator);
template <int N>
Buffer::Iterator DeserializeBitstring (std::bitset<N> *bitstring, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeBitstring (std::bitset<1> *bitstring, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeBitstring (std::bitset<8> *bitstring, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeBitstring (std::bitset<10> *bitstring, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeBitstring (std::bitset<16> *bitstring, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeBitstring (std::bitset<27> *bitstring, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeBitstring (std::bitset<28> *bitstring, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeBitstring (std::bitset<32> *bitstring, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeNull (Buffer::Iterator bIterator);
Buffer::Iterator DeserializeSequenceOf (int *numElems, int nMax, int nMin, Buffer::Iterator bIterator);
};
} // namespace ns3
#endif // EPC_ASN1_HEADER_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,221 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Lluis Parcerisa <lparcerisa@cttc.cat>
*/
#ifndef RRC_HEADER_H
#define RRC_HEADER_H
#include "ns3/header.h"
#include <bitset>
#include <string>
#include "ns3/lte-rrc-sap.h"
#include "ns3/lte-asn1-header.h"
namespace ns3 {
/**
* This class extends Asn1Header functions, adding serialization/deserialization
* of some Information elements defined in 3GPP TS 36.331
*/
class RrcAsn1Header : public Asn1Header
{
public:
RrcAsn1Header ();
protected:
// Serialization functions
void SerializeSrbToAddModList (std::list<LteRrcSap::SrbToAddMod> srbToAddModList) const;
void SerializeDrbToAddModList (std::list<LteRrcSap::DrbToAddMod> drbToAddModList) const;
void SerializeLogicalChannelConfig (LteRrcSap::LogicalChannelConfig logicalChannelConfig) const;
void SerializeRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated radioResourceConfigDedicated) const;
void SerializePhysicalConfigDedicated (LteRrcSap::PhysicalConfigDedicated physicalConfigDedicated) const;
void SerializeSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 systemInformationBlockType1) const;
void SerializeSystemInformationBlockType2 () const;
void SerializeRadioResourceConfigCommonSIB () const;
// Deserialization functions
Buffer::Iterator DeserializeDrbToAddModList (std::list<LteRrcSap::DrbToAddMod> *drbToAddModLis, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeSrbToAddModList (std::list<LteRrcSap::SrbToAddMod> *srbToAddModList, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeLogicalChannelConfig (LteRrcSap::LogicalChannelConfig *logicalChannelConfig, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated *radioResourceConfigDedicated, Buffer::Iterator bIterator);
Buffer::Iterator DeserializePhysicalConfigDedicated (LteRrcSap::PhysicalConfigDedicated *physicalConfigDedicated, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 *systemInformationBlockType1, Buffer::Iterator bIterator);
Buffer::Iterator DeserializeSystemInformationBlockType2 (Buffer::Iterator bIterator);
Buffer::Iterator DeserializeRadioResourceConfigCommon (Buffer::Iterator bIterator);
Buffer::Iterator DeserializeRadioResourceConfigCommonSib (Buffer::Iterator bIterator);
void Print (std::ostream &os, LteRrcSap::RadioResourceConfigDedicated radioResourceConfigDedicated) const;
};
/**
* This class manages the serialization/deserialization of RrcConnectionRequest IE
*/
class RrcConnectionRequestHeader : public RrcAsn1Header,
LteRrcSap
{
public:
RrcConnectionRequestHeader ();
void PreSerialize () const;
uint32_t Deserialize (Buffer::Iterator bIterator);
void Print (std::ostream &os) const;
void SetMessage (RrcConnectionRequest msg);
std::bitset<8> getMmec () const;
std::bitset<32> getMtmsi () const;
private:
std::bitset<8> m_mmec;
std::bitset<32> m_mTmsi;
enum
{
EMERGENCY = 0, HIGHPRIORITYACCESS, MT_ACCESS,
MO_SIGNALLING, MO_DATA, SPARE3, SPARE2, SPARE1
} m_establishmentCause;
std::bitset<1> m_spare;
};
/**
* This class manages the serialization/deserialization of RrcConnectionSetup IE
*/
class RrcConnectionSetupHeader : public RrcAsn1Header,
LteRrcSap
{
public:
RrcConnectionSetupHeader ();
void PreSerialize () const;
uint32_t Deserialize (Buffer::Iterator bIterator);
void Print (std::ostream &os) const;
void SetMessage (RrcConnectionSetup msg);
uint8_t GetRrcTransactionIdentifier () const;
bool HavePhysicalConfigDedicated () const;
std::list<LteRrcSap::SrbToAddMod> GetSrbToAddModList () const;
std::list<LteRrcSap::DrbToAddMod> GetDrbToAddModList () const;
std::list<uint8_t> GetDrbToReleaseList () const;
LteRrcSap::PhysicalConfigDedicated GetPhysicalConfigDedicated () const;
LteRrcSap::RadioResourceConfigDedicated GetRadioResourceConfigDedicated () const;
private:
uint8_t rrcTransactionIdentifier;
mutable RadioResourceConfigDedicated radioResourceConfigDedicated;
};
/**
* This class manages the serialization/deserialization of RrcConnectionSetupComplete IE
*/
class RrcConnectionSetupCompleteHeader : public RrcAsn1Header,
LteRrcSap
{
public:
RrcConnectionSetupCompleteHeader ();
void PreSerialize () const;
uint32_t Deserialize (Buffer::Iterator bIterator);
void Print (std::ostream &os) const;
void SetMessage (RrcConnectionSetupCompleted msg);
uint8_t GetRrcTransactionIdentifier () const;
private:
uint8_t m_rrcTransactionIdentifier;
};
/**
* This class manages the serialization/deserialization of RrcConnectionSetupComplete IE
*/
class RrcConnectionReconfigurationCompleteHeader : public RrcAsn1Header,
LteRrcSap
{
public:
RrcConnectionReconfigurationCompleteHeader ();
void PreSerialize () const;
uint32_t Deserialize (Buffer::Iterator bIterator);
void Print (std::ostream &os) const;
void SetMessage (RrcConnectionReconfigurationCompleted msg);
uint8_t GetRrcTransactionIdentifier () const;
private:
uint8_t m_rrcTransactionIdentifier;
};
/**
* This class manages the serialization/deserialization of RrcConnectionReconfiguration IE
*/
class RrcConnectionReconfigurationHeader : public RrcAsn1Header,
LteRrcSap
{
public:
RrcConnectionReconfigurationHeader ();
void PreSerialize () const;
uint32_t Deserialize (Buffer::Iterator bIterator);
void Print (std::ostream &os) const;
void SetMessage (RrcConnectionReconfiguration msg);
uint8_t GetRrcTransactionIdentifier () const;
bool GetHaveMeasConfig ();
MeasConfig GetMeasConfig ();
bool GetHaveMobilityControlInfo ();
MobilityControlInfo GetMobilityControlInfo ();
bool GetHaveRadioResourceConfigDedicated ();
RadioResourceConfigDedicated GetRadioResourceConfigDedicated ();
// RadioResourceConfigDedicated functions
bool HavePhysicalConfigDedicated () const;
std::list<LteRrcSap::SrbToAddMod> GetSrbToAddModList () const;
std::list<LteRrcSap::DrbToAddMod> GetDrbToAddModList () const;
std::list<uint8_t> GetDrbToReleaseList () const;
LteRrcSap::PhysicalConfigDedicated GetPhysicalConfigDedicated () const;
private:
uint8_t m_rrcTransactionIdentifier;
bool m_haveMeasConfig;
MeasConfig m_measConfig;
bool m_haveMobilityControlInfo;
MobilityControlInfo m_mobilityControlInfo;
bool m_haveRadioResourceConfigDedicated;
RadioResourceConfigDedicated m_radioResourceConfigDedicated;
};
/**
* This class manages the serialization/deserialization of HandoverPreparationInfo IE
*/
class HandoverPreparationInfoHeader : public RrcAsn1Header,
LteRrcSap
{
public:
HandoverPreparationInfoHeader ();
void PreSerialize () const;
uint32_t Deserialize (Buffer::Iterator bIterator);
void Print (std::ostream &os) const;
void SetMessage (HandoverPreparationInfo msg);
AsConfig GetAsConfig () const;
private:
AsConfig m_asConfig;
};
} // namespace ns3
#endif // EPC_ASN1_HEADER_H

View File

@@ -0,0 +1,624 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011, 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Lluis Parcerisa <lparcerisa@cttc.cat>
*/
#include "ns3/log.h"
#include "ns3/string.h"
#include "ns3/double.h"
#include "ns3/enum.h"
#include "ns3/boolean.h"
#include "ns3/test.h"
#include "ns3/ptr.h"
#include "ns3/packet.h"
#include "ns3/lte-rrc-header.h"
#include "ns3/lte-rrc-sap.h"
NS_LOG_COMPONENT_DEFINE ("Asn1EncodingTest");
namespace ns3 {
class TestUtils
{
public:
// Function to output packet contents in hex format
static void printPacketContentsHex (Packet *pkt)
{
uint32_t psize = pkt->GetSize ();
uint8_t buffer[psize];
pkt->CopyData (buffer, psize);
for (uint32_t i = 0; i < psize; i++)
{
printf ("%02x ",buffer[i]);
}
printf ("\n\n");
}
// Function to output packet contents in binary format
static void printPacketContentsBin (Packet *pkt)
{
uint32_t psize = pkt->GetSize ();
uint8_t buffer[psize];
pkt->CopyData (buffer, psize);
for (uint32_t i = 0; i < psize; i++)
{
std::cout << std::bitset<8> (buffer[i]) << " ";
}
std::cout << std::endl << std::endl;
}
};
// --------------------------- CLASS RrcHeaderTestCase -----------------------------
/**
* This class provides common functions to be inherited
* by the children TestCases
*/
class RrcHeaderTestCase : public TestCase
{
public:
RrcHeaderTestCase (std::string s);
virtual void DoRun (void) = 0;
LteRrcSap::RadioResourceConfigDedicated CreateRadioResourceConfigDedicated ();
void AssertEqualRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated rrcd1, LteRrcSap::RadioResourceConfigDedicated rrcd2);
};
RrcHeaderTestCase :: RrcHeaderTestCase (std::string s) : TestCase (s)
{
}
LteRrcSap::RadioResourceConfigDedicated
RrcHeaderTestCase :: CreateRadioResourceConfigDedicated ()
{
LteRrcSap::RadioResourceConfigDedicated rrd;
rrd.drbToReleaseList = std::list<uint8_t> (4,2);
LteRrcSap::SrbToAddMod srbToAddMod;
srbToAddMod.srbIdentity = 2;
LteRrcSap::LogicalChannelConfig logicalChannelConfig;
logicalChannelConfig.priority = 9;
logicalChannelConfig.prioritizedBitRateKbps = 128;
logicalChannelConfig.bucketSizeDurationMs = 100;
logicalChannelConfig.logicalChannelGroup = 3;
srbToAddMod.logicalChannelConfig = logicalChannelConfig;
rrd.srbToAddModList.insert (rrd.srbToAddModList.begin (),srbToAddMod);
LteRrcSap::DrbToAddMod drbToAddMod;
drbToAddMod.epsBearerIdentity = 1;
drbToAddMod.drbIdentity = 1;
drbToAddMod.logicalChannelIdentity = 5;
LteRrcSap::RlcConfig rlcConfig;
rlcConfig.choice = LteRrcSap::RlcConfig::UM_BI_DIRECTIONAL;
drbToAddMod.rlcConfig = rlcConfig;
LteRrcSap::LogicalChannelConfig logicalChannelConfig2;
logicalChannelConfig2.priority = 7;
logicalChannelConfig2.prioritizedBitRateKbps = 256;
logicalChannelConfig2.bucketSizeDurationMs = 50;
logicalChannelConfig2.logicalChannelGroup = 2;
drbToAddMod.logicalChannelConfig = logicalChannelConfig2;
rrd.drbToAddModList.insert (rrd.drbToAddModList.begin (),drbToAddMod);
rrd.havePhysicalConfigDedicated = true;
LteRrcSap::PhysicalConfigDedicated physicalConfigDedicated;
physicalConfigDedicated.haveSoundingRsUlConfigDedicated = true;
physicalConfigDedicated.soundingRsUlConfigDedicated.type = LteRrcSap::SoundingRsUlConfigDedicated::SETUP;
physicalConfigDedicated.soundingRsUlConfigDedicated.srsBandwidth = 2;
physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex = 12;
physicalConfigDedicated.haveAntennaInfoDedicated = true;
physicalConfigDedicated.antennaInfo.transmissionMode = 3;
rrd.physicalConfigDedicated = physicalConfigDedicated;
return rrd;
}
void
RrcHeaderTestCase :: AssertEqualRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated rrcd1, LteRrcSap::RadioResourceConfigDedicated rrcd2)
{
NS_TEST_ASSERT_MSG_EQ (rrcd1.srbToAddModList.size (), rrcd2.srbToAddModList.size (),"SrbToAddModList different sizes");
std::list<LteRrcSap::SrbToAddMod> srcSrbToAddModList = rrcd1.srbToAddModList;
std::list<LteRrcSap::SrbToAddMod>::iterator it1 = srcSrbToAddModList.begin ();
std::list<LteRrcSap::SrbToAddMod> dstSrbToAddModList = rrcd2.srbToAddModList;
std::list<LteRrcSap::SrbToAddMod>::iterator it2 = dstSrbToAddModList.begin ();
for (; it1 != srcSrbToAddModList.end (); it1++, it2++)
{
NS_TEST_ASSERT_MSG_EQ (it1->srbIdentity,it2->srbIdentity, "srbIdentity");
NS_TEST_ASSERT_MSG_EQ (it1->logicalChannelConfig.priority,it2->logicalChannelConfig.priority, "logicalChannelConfig.priority");
NS_TEST_ASSERT_MSG_EQ (it1->logicalChannelConfig.prioritizedBitRateKbps,it2->logicalChannelConfig.prioritizedBitRateKbps, "logicalChannelConfig.prioritizedBitRateKbps");
NS_TEST_ASSERT_MSG_EQ (it1->logicalChannelConfig.bucketSizeDurationMs,it2->logicalChannelConfig.bucketSizeDurationMs, "logicalChannelConfig.bucketSizeDurationMs");
NS_TEST_ASSERT_MSG_EQ (it1->logicalChannelConfig.logicalChannelGroup,it2->logicalChannelConfig.logicalChannelGroup, "logicalChannelConfig.logicalChannelGroup");
}
NS_TEST_ASSERT_MSG_EQ (rrcd1.drbToAddModList.size (), rrcd2.drbToAddModList.size (),"DrbToAddModList different sizes");
std::list<LteRrcSap::DrbToAddMod> srcDrbToAddModList = rrcd1.drbToAddModList;
std::list<LteRrcSap::DrbToAddMod>::iterator it3 = srcDrbToAddModList.begin ();
std::list<LteRrcSap::DrbToAddMod> dstDrbToAddModList = rrcd2.drbToAddModList;
std::list<LteRrcSap::DrbToAddMod>::iterator it4 = dstDrbToAddModList.begin ();
for (; it3 != srcDrbToAddModList.end (); it3++, it4++)
{
NS_TEST_ASSERT_MSG_EQ (it3->epsBearerIdentity,it4->epsBearerIdentity, "epsBearerIdentity");
NS_TEST_ASSERT_MSG_EQ (it3->drbIdentity,it4->drbIdentity, "drbIdentity");
NS_TEST_ASSERT_MSG_EQ (it3->rlcConfig.choice,it4->rlcConfig.choice, "rlcConfig.choice");
NS_TEST_ASSERT_MSG_EQ (it3->logicalChannelIdentity,it4->logicalChannelIdentity, "logicalChannelIdentity");
NS_TEST_ASSERT_MSG_EQ (it3->epsBearerIdentity,it4->epsBearerIdentity, "epsBearerIdentity");
NS_TEST_ASSERT_MSG_EQ (it3->logicalChannelConfig.priority,it4->logicalChannelConfig.priority, "logicalChannelConfig.priority");
NS_TEST_ASSERT_MSG_EQ (it3->logicalChannelConfig.prioritizedBitRateKbps,it4->logicalChannelConfig.prioritizedBitRateKbps, "logicalChannelConfig.prioritizedBitRateKbps");
NS_TEST_ASSERT_MSG_EQ (it3->logicalChannelConfig.bucketSizeDurationMs,it4->logicalChannelConfig.bucketSizeDurationMs, "logicalChannelConfig.bucketSizeDurationMs");
NS_TEST_ASSERT_MSG_EQ (it3->logicalChannelConfig.logicalChannelGroup,it4->logicalChannelConfig.logicalChannelGroup, "logicalChannelConfig.logicalChannelGroup");
}
NS_TEST_ASSERT_MSG_EQ (rrcd1.drbToReleaseList.size (), rrcd2.drbToReleaseList.size (),"DrbToReleaseList different sizes");
std::list<uint8_t> srcDrbToReleaseList = rrcd1.drbToReleaseList;
std::list<uint8_t> dstDrbToReleaseList = rrcd2.drbToReleaseList;
std::list<uint8_t>::iterator it5 = srcDrbToReleaseList.begin ();
std::list<uint8_t>::iterator it6 = dstDrbToReleaseList.begin ();
for (; it5 != srcDrbToReleaseList.end (); it5++, it6++)
{
NS_TEST_ASSERT_MSG_EQ (*it5, *it6,"element != in DrbToReleaseList");
}
NS_TEST_ASSERT_MSG_EQ (rrcd1.havePhysicalConfigDedicated,rrcd2.havePhysicalConfigDedicated, "HavePhysicalConfigDedicated");
if (rrcd1.havePhysicalConfigDedicated)
{
NS_TEST_ASSERT_MSG_EQ (rrcd1.physicalConfigDedicated.haveSoundingRsUlConfigDedicated,
rrcd2.physicalConfigDedicated.haveSoundingRsUlConfigDedicated,
"haveSoundingRsUlConfigDedicated");
NS_TEST_ASSERT_MSG_EQ (rrcd1.physicalConfigDedicated.soundingRsUlConfigDedicated.type,
rrcd2.physicalConfigDedicated.soundingRsUlConfigDedicated.type,
"soundingRsUlConfigDedicated.type");
NS_TEST_ASSERT_MSG_EQ (rrcd1.physicalConfigDedicated.soundingRsUlConfigDedicated.srsBandwidth,
rrcd2.physicalConfigDedicated.soundingRsUlConfigDedicated.srsBandwidth,
"soundingRsUlConfigDedicated.srsBandwidth");
NS_TEST_ASSERT_MSG_EQ (rrcd1.physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex,
rrcd2.physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex,
"soundingRsUlConfigDedicated.srsConfigIndex");
NS_TEST_ASSERT_MSG_EQ (rrcd1.physicalConfigDedicated.haveAntennaInfoDedicated,
rrcd2.physicalConfigDedicated.haveAntennaInfoDedicated,
"haveAntennaInfoDedicated");
if (rrcd1.physicalConfigDedicated.haveAntennaInfoDedicated)
{
NS_TEST_ASSERT_MSG_EQ (rrcd1.physicalConfigDedicated.antennaInfo.transmissionMode,
rrcd2.physicalConfigDedicated.antennaInfo.transmissionMode,
"antennaInfo.transmissionMode");
}
}
}
// --------------------------- CLASS RrcConnectionRequestTestCase -----------------------------
class RrcConnectionRequestTestCase : public RrcHeaderTestCase
{
public:
RrcConnectionRequestTestCase ();
virtual void DoRun (void);
};
RrcConnectionRequestTestCase::RrcConnectionRequestTestCase () : RrcHeaderTestCase ("Testing RrcConnectionRequest")
{
}
void
RrcConnectionRequestTestCase::DoRun (void)
{
std::cout << "============= RrcConnectionRequestTestCase ===========" << std::endl;
// add header
Ptr<Packet> packet = Create<Packet> ();
packet->Print (std::cout);
std::cout << std::endl;
LteRrcSap::RrcConnectionRequest msg;
msg.ueIdentity = 0x83fecafeca;
RrcConnectionRequestHeader source;
source.SetMessage (msg);
std::cout << "--------- SOURCE INFO: -------" << std::endl;
source.Print (std::cout);
packet->AddHeader (source);
std::cout << std::endl;
// print serialized packet contents
std::cout << "---- SERIALIZED PACKET CONTENTS (HEX): -------" << std::endl;
std::cout << "Hex: ";
TestUtils::printPacketContentsHex (GetPointer (packet));
std::cout << "Bin: ";
TestUtils::printPacketContentsBin (GetPointer (packet));
// remove header
RrcConnectionRequestHeader destination;
packet->RemoveHeader (destination);
std::cout << "--------- DESTINATION INFO: -------" << std::endl;
destination.Print (std::cout);
// Check that the destination and source headers contain the same values
NS_TEST_ASSERT_MSG_EQ (source.getMmec (),destination.getMmec (), "Different m_mmec!");
NS_TEST_ASSERT_MSG_EQ (source.getMtmsi (),destination.getMtmsi (), "Different m_mTmsi!");
}
// --------------------------- CLASS RrcConnectionSetupTestCase -----------------------------
class RrcConnectionSetupTestCase : public RrcHeaderTestCase
{
public:
RrcConnectionSetupTestCase ();
virtual void DoRun (void);
};
RrcConnectionSetupTestCase::RrcConnectionSetupTestCase () : RrcHeaderTestCase ("Testing RrcConnectionSetupTestCase")
{
}
void
RrcConnectionSetupTestCase::DoRun (void)
{
std::cout << "============= RrcConnectionSetupTestCase ===========" << std::endl;
// add header
Ptr<Packet> packet = Create<Packet> ();
packet->Print (std::cout);
std::cout << std::endl;
LteRrcSap::RrcConnectionSetup msg;
msg.rrcTransactionIdentifier = 3;
msg.radioResourceConfigDedicated = CreateRadioResourceConfigDedicated ();
RrcConnectionSetupHeader source;
source.SetMessage (msg);
std::cout << "--------- SOURCE INFO: -------" << std::endl;
source.Print (std::cout);
packet->AddHeader (source);
std::cout << std::endl;
// print serialized packet contents
std::cout << "---- SERIALIZED PACKET CONTENTS: -------" << std::endl;
std::cout << "Hex: ";
TestUtils::printPacketContentsHex (GetPointer (packet));
std::cout << "Bin: ";
TestUtils::printPacketContentsBin (GetPointer (packet));
// remove header
RrcConnectionSetupHeader destination;
packet->RemoveHeader (destination);
std::cout << "--------- DESTINATION INFO: -------" << std::endl;
destination.Print (std::cout);
// Check that the destination and source headers contain the same values
NS_TEST_ASSERT_MSG_EQ (source.GetRrcTransactionIdentifier (),destination.GetRrcTransactionIdentifier (), "RrcTransactionIdentifier");
AssertEqualRadioResourceConfigDedicated (source.GetRadioResourceConfigDedicated (),destination.GetRadioResourceConfigDedicated ());
}
// --------------------------- CLASS RrcConnectionSetupCompleteTestCase -----------------------------
class RrcConnectionSetupCompleteTestCase : public RrcHeaderTestCase
{
public:
RrcConnectionSetupCompleteTestCase ();
virtual void DoRun (void);
};
RrcConnectionSetupCompleteTestCase::RrcConnectionSetupCompleteTestCase () : RrcHeaderTestCase ("Testing RrcConnectionSetupCompleteTestCase")
{
}
void
RrcConnectionSetupCompleteTestCase::DoRun (void)
{
std::cout << "============= RrcConnectionSetupCompleteTestCase ===========" << std::endl;
// add header
Ptr<Packet> packet = Create<Packet> ();
packet->Print (std::cout);
std::cout << std::endl;
LteRrcSap::RrcConnectionSetupCompleted msg;
msg.rrcTransactionIdentifier = 3;
RrcConnectionSetupCompleteHeader source;
source.SetMessage (msg);
std::cout << "--------- SOURCE INFO: -------" << std::endl;
source.Print (std::cout);
packet->AddHeader (source);
std::cout << std::endl;
// print serialized packet contents
std::cout << "---- SERIALIZED PACKET CONTENTS: -------" << std::endl;
std::cout << "Hex: ";
TestUtils::printPacketContentsHex (GetPointer (packet));
std::cout << "Bin: ";
TestUtils::printPacketContentsBin (GetPointer (packet));
// remove header
RrcConnectionSetupCompleteHeader destination;
packet->RemoveHeader (destination);
std::cout << "--------- DESTINATION INFO: -------" << std::endl;
destination.Print (std::cout);
// Check that the destination and source headers contain the same values
NS_TEST_ASSERT_MSG_EQ (source.GetRrcTransactionIdentifier (),destination.GetRrcTransactionIdentifier (), "RrcTransactionIdentifier");
}
// --------------------------- CLASS RrcConnectionReconfigurationCompleteTestCase -----------------------------
class RrcConnectionReconfigurationCompleteTestCase : public RrcHeaderTestCase
{
public:
RrcConnectionReconfigurationCompleteTestCase ();
virtual void DoRun (void);
};
RrcConnectionReconfigurationCompleteTestCase::RrcConnectionReconfigurationCompleteTestCase ()
: RrcHeaderTestCase ("Testing RrcConnectionReconfigurationCompleteTestCase")
{
}
void
RrcConnectionReconfigurationCompleteTestCase::DoRun (void)
{
std::cout << "============= RrcConnectionReconfigurationCompleteTestCase ===========" << std::endl;
// add header
Ptr<Packet> packet = Create<Packet> ();
packet->Print (std::cout);
std::cout << std::endl;
LteRrcSap::RrcConnectionReconfigurationCompleted msg;
msg.rrcTransactionIdentifier = 2;
RrcConnectionReconfigurationCompleteHeader source;
source.SetMessage (msg);
std::cout << "--------- SOURCE INFO: -------" << std::endl;
source.Print (std::cout);
packet->AddHeader (source);
std::cout << std::endl;
// print serialized packet contents
std::cout << "---- SERIALIZED PACKET CONTENTS: -------" << std::endl;
std::cout << "Hex: ";
TestUtils::printPacketContentsHex (GetPointer (packet));
std::cout << "Bin: ";
TestUtils::printPacketContentsBin (GetPointer (packet));
// remove header
RrcConnectionReconfigurationCompleteHeader destination;
packet->RemoveHeader (destination);
std::cout << "--------- DESTINATION INFO: -------" << std::endl;
destination.Print (std::cout);
// Check that the destination and source headers contain the same values
NS_TEST_ASSERT_MSG_EQ (source.GetRrcTransactionIdentifier (),destination.GetRrcTransactionIdentifier (), "RrcTransactionIdentifier");
}
// --------------------------- CLASS RrcConnectionReconfigurationTestCase -----------------------------
class RrcConnectionReconfigurationTestCase : public RrcHeaderTestCase
{
public:
RrcConnectionReconfigurationTestCase ();
virtual void DoRun (void);
};
RrcConnectionReconfigurationTestCase::RrcConnectionReconfigurationTestCase ()
: RrcHeaderTestCase ("Testing RrcConnectionReconfigurationTestCase")
{
}
void
RrcConnectionReconfigurationTestCase::DoRun (void)
{
std::cout << "============= RrcConnectionReconfigurationTestCase ===========" << std::endl;
// add header
Ptr<Packet> packet = Create<Packet> ();
packet->Print (std::cout);
std::cout << std::endl;
LteRrcSap::RrcConnectionReconfiguration msg;
msg.rrcTransactionIdentifier = 2;
msg.haveMeasConfig = false;
msg.haveMobilityControlInfo = true;
msg.mobilityControlInfo.targetPhysCellId = 4;
msg.mobilityControlInfo.haveCarrierFreq = true;
msg.mobilityControlInfo.carrierFreq.dlCarrierFreq = 3;
msg.mobilityControlInfo.carrierFreq.ulCarrierFreq = 5;
msg.mobilityControlInfo.haveCarrierBandwidth = true;
msg.mobilityControlInfo.carrierBandwidth.dlBandwidth = 5;
msg.mobilityControlInfo.carrierBandwidth.ulBandwidth = 3;
msg.mobilityControlInfo.newUeIdentity = 11;
msg.mobilityControlInfo.haveRachConfigDedicated = true;
msg.mobilityControlInfo.rachConfigDedicated.raPreambleIndex = 2;
msg.mobilityControlInfo.rachConfigDedicated.raPrachMaskIndex = 2;
msg.haveRadioResourceConfigDedicated = true;
msg.radioResourceConfigDedicated = CreateRadioResourceConfigDedicated ();
RrcConnectionReconfigurationHeader source;
source.SetMessage (msg);
std::cout << "--------- SOURCE INFO: -------" << std::endl;
source.Print (std::cout);
packet->AddHeader (source);
std::cout << std::endl;
// print serialized packet contents
std::cout << "---- SERIALIZED PACKET CONTENTS: -------" << std::endl;
std::cout << "Hex: ";
TestUtils::printPacketContentsHex (GetPointer (packet));
std::cout << "Bin: ";
TestUtils::printPacketContentsBin (GetPointer (packet));
// remove header
RrcConnectionReconfigurationHeader destination;
packet->RemoveHeader (destination);
std::cout << "--------- DESTINATION INFO: -------" << std::endl;
destination.Print (std::cout);
// Check that the destination and source headers contain the same values
NS_TEST_ASSERT_MSG_EQ (source.GetRrcTransactionIdentifier (),destination.GetRrcTransactionIdentifier (), "RrcTransactionIdentifier");
NS_TEST_ASSERT_MSG_EQ (source.GetHaveMeasConfig (),destination.GetHaveMeasConfig (), "GetHaveMeasConfig");
NS_TEST_ASSERT_MSG_EQ (source.GetHaveMobilityControlInfo (),destination.GetHaveMobilityControlInfo (), "GetHaveMobilityControlInfo");
NS_TEST_ASSERT_MSG_EQ (source.GetHaveRadioResourceConfigDedicated (),destination.GetHaveRadioResourceConfigDedicated (), "GetHaveRadioResourceConfigDedicated");
if ( source.GetHaveMobilityControlInfo () )
{
NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().targetPhysCellId,destination.GetMobilityControlInfo ().targetPhysCellId, "GetMobilityControlInfo().targetPhysCellId");
NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().haveCarrierFreq,destination.GetMobilityControlInfo ().haveCarrierFreq, "GetMobilityControlInfo().haveCarrierFreq");
NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().haveCarrierBandwidth,destination.GetMobilityControlInfo ().haveCarrierBandwidth, "GetMobilityControlInfo().haveCarrierBandwidth");
NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().newUeIdentity,destination.GetMobilityControlInfo ().newUeIdentity, "GetMobilityControlInfo().newUeIdentity");
NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().haveRachConfigDedicated,destination.GetMobilityControlInfo ().haveRachConfigDedicated, "GetMobilityControlInfo().haveRachConfigDedicated");
if (source.GetMobilityControlInfo ().haveCarrierFreq)
{
NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().carrierFreq.dlCarrierFreq,
destination.GetMobilityControlInfo ().carrierFreq.dlCarrierFreq,
"GetMobilityControlInfo().carrierFreq.dlCarrierFreq");
NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().carrierFreq.ulCarrierFreq,
destination.GetMobilityControlInfo ().carrierFreq.ulCarrierFreq,
"GetMobilityControlInfo().carrierFreq.ulCarrierFreq");
}
if (source.GetMobilityControlInfo ().haveCarrierBandwidth)
{
NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().carrierBandwidth.dlBandwidth,
destination.GetMobilityControlInfo ().carrierBandwidth.dlBandwidth,
"GetMobilityControlInfo().carrierBandwidth.dlBandwidth");
NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().carrierBandwidth.ulBandwidth,
destination.GetMobilityControlInfo ().carrierBandwidth.ulBandwidth,
"GetMobilityControlInfo().carrierBandwidth.ulBandwidth");
}
if (source.GetMobilityControlInfo ().haveRachConfigDedicated)
{
NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().rachConfigDedicated.raPreambleIndex,
destination.GetMobilityControlInfo ().rachConfigDedicated.raPreambleIndex,
"GetMobilityControlInfo().rachConfigDedicated.raPreambleIndex");
NS_TEST_ASSERT_MSG_EQ (source.GetMobilityControlInfo ().rachConfigDedicated.raPrachMaskIndex,
destination.GetMobilityControlInfo ().rachConfigDedicated.raPrachMaskIndex,
"GetMobilityControlInfo().rachConfigDedicated.raPrachMaskIndex");
}
}
if (source.GetHaveRadioResourceConfigDedicated ())
{
AssertEqualRadioResourceConfigDedicated (source.GetRadioResourceConfigDedicated (), destination.GetRadioResourceConfigDedicated ());
}
}
// --------------------------- CLASS HandoverPreparationInfoTestCase -----------------------------
class HandoverPreparationInfoTestCase : public RrcHeaderTestCase
{
public:
HandoverPreparationInfoTestCase ();
virtual void DoRun (void);
};
HandoverPreparationInfoTestCase::HandoverPreparationInfoTestCase () : RrcHeaderTestCase ("Testing HandoverPreparationInfoTestCase")
{
}
void
HandoverPreparationInfoTestCase::DoRun (void)
{
std::cout << "============= HandoverPreparationInfoTestCase ===========" << std::endl;
// add header
Ptr<Packet> packet = Create<Packet> ();
packet->Print (std::cout);
std::cout << std::endl;
LteRrcSap::HandoverPreparationInfo msg;
msg.asConfig.sourceDlCarrierFreq = 3;
msg.asConfig.sourceUeIdentity = 11;
msg.asConfig.sourceRadioResourceConfig = CreateRadioResourceConfigDedicated ();
msg.asConfig.sourceMasterInformationBlock.dlBandwidth = 3;
msg.asConfig.sourceMasterInformationBlock.systemFrameNumber = 1;
msg.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIndication = true;
msg.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.cellIdentity = 5;
msg.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIdentity = 4;
msg.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity = 123;
HandoverPreparationInfoHeader source;
source.SetMessage (msg);
std::cout << "--------- SOURCE INFO: -------" << std::endl;
source.Print (std::cout);
packet->AddHeader (source);
std::cout << std::endl;
// print serialized packet contents
std::cout << "---- SERIALIZED PACKET CONTENTS: -------" << std::endl;
std::cout << "Hex: ";
TestUtils::printPacketContentsHex (GetPointer (packet));
std::cout << "Bin: ";
TestUtils::printPacketContentsBin (GetPointer (packet));
// remove header
HandoverPreparationInfoHeader destination;
packet->RemoveHeader (destination);
std::cout << "--------- DESTINATION INFO: -------" << std::endl;
destination.Print (std::cout);
// Check that the destination and source headers contain the same values
AssertEqualRadioResourceConfigDedicated (source.GetAsConfig ().sourceRadioResourceConfig, destination.GetAsConfig ().sourceRadioResourceConfig);
NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceUeIdentity, destination.GetAsConfig ().sourceUeIdentity, "sourceUeIdentity");
NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceMasterInformationBlock.dlBandwidth,destination.GetAsConfig ().sourceMasterInformationBlock.dlBandwidth, "dlBandwidth");
NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceMasterInformationBlock.systemFrameNumber, destination.GetAsConfig ().sourceMasterInformationBlock.systemFrameNumber, "systemFrameNumber");
NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity, destination.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity, "plmnIdentity");
NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIndication, destination.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIndication, "csgIndication");
NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.cellIdentity, destination.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.cellIdentity, "cellIdentity");
NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIdentity, destination.GetAsConfig ().sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIdentity, "csgIdentity");
NS_TEST_ASSERT_MSG_EQ (source.GetAsConfig ().sourceDlCarrierFreq, destination.GetAsConfig ().sourceDlCarrierFreq, "sourceDlCarrierFreq");
}
// --------------------------- CLASS Asn1EncodingSuite -----------------------------
class Asn1EncodingSuite : public TestSuite
{
public:
Asn1EncodingSuite ();
};
Asn1EncodingSuite::Asn1EncodingSuite ()
: TestSuite ("test-asn1-encoding", UNIT)
{
Packet::EnablePrinting ();
NS_LOG_FUNCTION (this);
AddTestCase (new RrcConnectionRequestTestCase);
AddTestCase (new RrcConnectionSetupTestCase);
AddTestCase (new RrcConnectionSetupCompleteTestCase);
AddTestCase (new RrcConnectionReconfigurationCompleteTestCase);
AddTestCase (new RrcConnectionReconfigurationTestCase);
AddTestCase (new HandoverPreparationInfoTestCase);
}
Asn1EncodingSuite asn1EncodingSuite;
} // namespace ns3

View File

@@ -82,6 +82,8 @@ def build(bld):
'model/epc-ue-nas.cc',
'model/lte-harq-phy.cc',
'model/epc-mme.cc',
'model/lte-asn1-header.cc',
'model/lte-rrc-header.cc',
]
module_test = bld.create_ns3_module_test_library('lte')
@@ -115,6 +117,7 @@ def build(bld):
'test/lte-test-harq.cc',
'test/test-lte-rrc.cc',
'test/test-lte-x2-handover.cc',
'test/test-asn1-encoding.cc',
]
headers = bld.new_task_gen(features=['ns3header'])
@@ -200,6 +203,8 @@ def build(bld):
'model/epc-ue-nas.h',
'model/lte-harq-phy.h',
'model/epc-mme.h',
'model/lte-asn1-header.h',
'model/lte-rrc-header.h',
]
if (bld.env['ENABLE_EXAMPLES']):