added stub of LteRrcProtocolReal with corresponding tests

This commit is contained in:
Nicola Baldo
2012-11-30 15:37:55 +01:00
parent 31a6582f0a
commit 35e62e96c9
6 changed files with 931 additions and 55 deletions

View File

@@ -47,6 +47,7 @@
#include <ns3/lte-rlc-am.h>
#include <ns3/epc-enb-s1-sap.h>
#include <ns3/lte-rrc-protocol-ideal.h>
#include <ns3/lte-rrc-protocol-real.h>
#include <ns3/epc-helper.h>
#include <iostream>
@@ -150,6 +151,12 @@ TypeId LteHelper::GetTypeId (void)
StringValue (""), // fake module -> no fading
MakeStringAccessor (&LteHelper::SetFadingModel),
MakeStringChecker ())
.AddAttribute ("UseIdealRrc",
"If true, LteRrcProtocolIdeal will be used for RRC signaling. "
"If false, LteRrcProtocolReal will be used.",
BooleanValue (true),
MakeBooleanAccessor (&LteHelper::m_useIdealRrc),
MakeBooleanChecker ())
;
return tid;
}
@@ -306,6 +313,10 @@ LteHelper::InstallUeDevice (NodeContainer c)
Ptr<NetDevice>
LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
{
NS_ABORT_MSG_IF (m_cellIdCounter == 65535, "max num eNBs exceeded");
uint16_t cellId = ++m_cellIdCounter;
Ptr<LteSpectrumPhy> dlPhy = CreateObject<LteSpectrumPhy> ();
Ptr<LteSpectrumPhy> ulPhy = CreateObject<LteSpectrumPhy> ();
@@ -341,8 +352,23 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
Ptr<LteEnbMac> mac = CreateObject<LteEnbMac> ();
Ptr<FfMacScheduler> sched = m_schedulerFactory.Create<FfMacScheduler> ();
Ptr<LteEnbRrc> rrc = CreateObject<LteEnbRrc> ();
Ptr<LteEnbRrcProtocolIdeal> rrcProtocol = CreateObject<LteEnbRrcProtocolIdeal> ();
rrc->AggregateObject (rrcProtocol);
if (m_useIdealRrc)
{
Ptr<LteEnbRrcProtocolIdeal> rrcProtocol = CreateObject<LteEnbRrcProtocolIdeal> ();
rrcProtocol->SetLteEnbRrcSapProvider (rrc->GetLteEnbRrcSapProvider ());
rrc->SetLteEnbRrcSapUser (rrcProtocol->GetLteEnbRrcSapUser ());
rrc->AggregateObject (rrcProtocol);
rrcProtocol->SetCellId (cellId);
}
else
{
Ptr<LteEnbRrcProtocolReal> rrcProtocol = CreateObject<LteEnbRrcProtocolReal> ();
rrcProtocol->SetLteEnbRrcSapProvider (rrc->GetLteEnbRrcSapProvider ());
rrc->SetLteEnbRrcSapUser (rrcProtocol->GetLteEnbRrcSapUser ());
rrc->AggregateObject (rrcProtocol);
rrcProtocol->SetCellId (cellId);
}
if (m_epcHelper != 0)
{
@@ -355,10 +381,6 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
}
}
// connect SAPs
rrcProtocol->SetLteEnbRrcSapProvider (rrc->GetLteEnbRrcSapProvider ());
rrc->SetLteEnbRrcSapUser (rrcProtocol->GetLteEnbRrcSapUser ());
rrc->SetLteEnbCmacSapProvider (mac->GetLteEnbCmacSapProvider ());
mac->SetLteEnbCmacSapUser (rrc->GetLteEnbCmacSapUser ());
rrc->SetLteMacSapProvider (mac->GetLteMacSapProvider ());
@@ -375,9 +397,6 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
phy->SetLteEnbCphySapUser (rrc->GetLteEnbCphySapUser ());
rrc->SetLteEnbCphySapProvider (phy->GetLteEnbCphySapProvider ());
NS_ABORT_MSG_IF (m_cellIdCounter == 65535, "max num eNBs exceeded");
uint16_t cellId = ++m_cellIdCounter;
Ptr<LteEnbNetDevice> dev = m_enbNetDeviceFactory.Create<LteEnbNetDevice> ();
dev->SetNode (n);
@@ -414,10 +433,7 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
}
dev->Start ();
rrcProtocol->SetCellId (dev->GetCellId ());
dev->Start ();
m_uplinkChannel->AddRx (ulPhy);
@@ -476,9 +492,23 @@ LteHelper::InstallSingleUeDevice (Ptr<Node> n)
Ptr<LteUeMac> mac = CreateObject<LteUeMac> ();
Ptr<LteUeRrc> rrc = CreateObject<LteUeRrc> ();
Ptr<LteUeRrcProtocolIdeal> rrcProtocol = CreateObject<LteUeRrcProtocolIdeal> ();
rrc->AggregateObject (rrcProtocol);
rrcProtocol->SetUeRrc (rrc);
if (m_useIdealRrc)
{
Ptr<LteUeRrcProtocolIdeal> rrcProtocol = CreateObject<LteUeRrcProtocolIdeal> ();
rrcProtocol->SetUeRrc (rrc);
rrc->AggregateObject (rrcProtocol);
rrcProtocol->SetLteUeRrcSapProvider (rrc->GetLteUeRrcSapProvider ());
rrc->SetLteUeRrcSapUser (rrcProtocol->GetLteUeRrcSapUser ());
}
else
{
Ptr<LteUeRrcProtocolReal> rrcProtocol = CreateObject<LteUeRrcProtocolReal> ();
rrcProtocol->SetUeRrc (rrc);
rrc->AggregateObject (rrcProtocol);
rrcProtocol->SetLteUeRrcSapProvider (rrc->GetLteUeRrcSapProvider ());
rrc->SetLteUeRrcSapUser (rrcProtocol->GetLteUeRrcSapUser ());
}
if (m_epcHelper != 0)
{
@@ -486,13 +516,9 @@ LteHelper::InstallSingleUeDevice (Ptr<Node> n)
}
Ptr<EpcUeNas> nas = CreateObject<EpcUeNas> ();
// connect SAPs
nas->SetAsSapProvider (rrc->GetAsSapProvider ());
rrc->SetAsSapUser (nas->GetAsSapUser ());
rrcProtocol->SetLteUeRrcSapProvider (rrc->GetLteUeRrcSapProvider ());
rrc->SetLteUeRrcSapUser (rrcProtocol->GetLteUeRrcSapUser ());
rrc->SetLteUeCmacSapProvider (mac->GetLteUeCmacSapProvider ());
mac->SetLteUeCmacSapUser (rrc->GetLteUeCmacSapUser ());
rrc->SetLteMacSapProvider (mac->GetLteMacSapProvider ());

View File

@@ -409,7 +409,7 @@ private:
uint64_t m_imsiCounter;
uint16_t m_cellIdCounter;
bool m_useIdealRrc;
};

View File

@@ -0,0 +1,687 @@
/* -*- 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: Nicola Baldo <nbaldo@cttc.es>
*/
#include <ns3/fatal-error.h>
#include <ns3/log.h>
#include <ns3/nstime.h>
#include <ns3/node-list.h>
#include <ns3/node.h>
#include <ns3/simulator.h>
#include "lte-rrc-protocol-real.h"
#include "lte-ue-rrc.h"
#include "lte-enb-rrc.h"
#include "lte-enb-net-device.h"
#include "lte-ue-net-device.h"
NS_LOG_COMPONENT_DEFINE ("LteRrcProtocolReal");
namespace ns3 {
const Time RRC_REAL_MSG_DELAY = MilliSeconds (0);
NS_OBJECT_ENSURE_REGISTERED (LteUeRrcProtocolReal);
LteUeRrcProtocolReal::LteUeRrcProtocolReal ()
: m_ueRrcSapProvider (0),
m_enbRrcSapProvider (0)
{
m_ueRrcSapUser = new MemberLteUeRrcSapUser<LteUeRrcProtocolReal> (this);
}
LteUeRrcProtocolReal::~LteUeRrcProtocolReal ()
{
}
void
LteUeRrcProtocolReal::DoDispose ()
{
NS_LOG_FUNCTION (this);
delete m_ueRrcSapUser;
m_rrc = 0;
}
TypeId
LteUeRrcProtocolReal::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::LteUeRrcProtocolReal")
.SetParent<Object> ()
.AddConstructor<LteUeRrcProtocolReal> ()
;
return tid;
}
void
LteUeRrcProtocolReal::SetLteUeRrcSapProvider (LteUeRrcSapProvider* p)
{
m_ueRrcSapProvider = p;
}
LteUeRrcSapUser*
LteUeRrcProtocolReal::GetLteUeRrcSapUser ()
{
return m_ueRrcSapUser;
}
void
LteUeRrcProtocolReal::SetUeRrc (Ptr<LteUeRrc> rrc)
{
m_rrc = rrc;
}
void
LteUeRrcProtocolReal::DoSetup (LteUeRrcSapUser::SetupParameters params)
{
NS_LOG_FUNCTION (this);
// Trick: we use this as a trigger to initialize the RNTI and cellID,
// and to make sure we are talking to the appropriate eNB (e.g.,
// after handover). We don't care about SRB0/SRB1 since we use real
// RRC messages.
DoReestablish ();
}
void
LteUeRrcProtocolReal::DoReestablish ()
{
NS_LOG_FUNCTION (this);
// // initialize the RNTI and get the EnbLteRrcSapProvider for the
// // eNB we are currently attached to
// m_rnti = m_rrc->GetRnti ();
// SetEnbRrcSapProvider ();
// if (m_havePendingRrcConnectionRequest == true)
// {
// Simulator::Schedule (RRC_REAL_MSG_DELAY,
// &LteEnbRrcSapProvider::RecvRrcConnectionRequest,
// m_enbRrcSapProvider,
// m_rnti,
// m_pendingRrcConnectionRequest);
// }
}
void
LteUeRrcProtocolReal::DoSendRrcConnectionRequest (LteRrcSap::RrcConnectionRequest msg)
{
// initialize the RNTI and get the EnbLteRrcSapProvider for the
// eNB we are currently attached to
m_rnti = m_rrc->GetRnti ();
SetEnbRrcSapProvider ();
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteEnbRrcSapProvider::RecvRrcConnectionRequest,
m_enbRrcSapProvider,
m_rnti,
msg);
}
void
LteUeRrcProtocolReal::DoSendRrcConnectionSetupCompleted (LteRrcSap::RrcConnectionSetupCompleted msg)
{
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteEnbRrcSapProvider::RecvRrcConnectionSetupCompleted,
m_enbRrcSapProvider,
m_rnti,
msg);
}
void
LteUeRrcProtocolReal::DoSendRrcConnectionReconfigurationCompleted (LteRrcSap::RrcConnectionReconfigurationCompleted msg)
{
// re-initialize the RNTI and get the EnbLteRrcSapProvider for the
// eNB we are currently attached to
m_rnti = m_rrc->GetRnti ();
SetEnbRrcSapProvider ();
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteEnbRrcSapProvider::RecvRrcConnectionReconfigurationCompleted,
m_enbRrcSapProvider,
m_rnti,
msg);
}
void
LteUeRrcProtocolReal::DoSendRrcConnectionReestablishmentRequest (LteRrcSap::RrcConnectionReestablishmentRequest msg)
{
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteEnbRrcSapProvider::RecvRrcConnectionReestablishmentRequest,
m_enbRrcSapProvider,
m_rnti,
msg);
}
void
LteUeRrcProtocolReal::DoSendRrcConnectionReestablishmentComplete (LteRrcSap::RrcConnectionReestablishmentComplete msg)
{
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteEnbRrcSapProvider::RecvRrcConnectionReestablishmentComplete,
m_enbRrcSapProvider,
m_rnti,
msg);
}
void
LteUeRrcProtocolReal::SetEnbRrcSapProvider ()
{
uint16_t cellId = m_rrc->GetCellId ();
// walk list of all nodes to get the peer eNB
Ptr<LteEnbNetDevice> enbDev;
NodeList::Iterator listEnd = NodeList::End ();
bool found = false;
for (NodeList::Iterator i = NodeList::Begin ();
(i != listEnd) && (!found);
++i)
{
Ptr<Node> node = *i;
int nDevs = node->GetNDevices ();
for (int j = 0;
(j < nDevs) && (!found);
j++)
{
enbDev = node->GetDevice (j)->GetObject <LteEnbNetDevice> ();
if (enbDev == 0)
{
continue;
}
else
{
if (enbDev->GetCellId () == cellId)
{
found = true;
break;
}
}
}
}
NS_ASSERT_MSG (found, " Unable to find eNB with CellId =" << cellId);
m_enbRrcSapProvider = enbDev->GetRrc ()->GetLteEnbRrcSapProvider ();
Ptr<LteEnbRrcProtocolReal> enbRrcProtocolReal = enbDev->GetRrc ()->GetObject<LteEnbRrcProtocolReal> ();
enbRrcProtocolReal->SetUeRrcSapProvider (m_rnti, m_ueRrcSapProvider);
}
NS_OBJECT_ENSURE_REGISTERED (LteEnbRrcProtocolReal);
LteEnbRrcProtocolReal::LteEnbRrcProtocolReal ()
: m_enbRrcSapProvider (0)
{
NS_LOG_FUNCTION (this);
m_enbRrcSapUser = new MemberLteEnbRrcSapUser<LteEnbRrcProtocolReal> (this);
}
LteEnbRrcProtocolReal::~LteEnbRrcProtocolReal ()
{
NS_LOG_FUNCTION (this);
}
void
LteEnbRrcProtocolReal::DoDispose ()
{
NS_LOG_FUNCTION (this);
delete m_enbRrcSapUser;
}
TypeId
LteEnbRrcProtocolReal::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::LteEnbRrcProtocolReal")
.SetParent<Object> ()
.AddConstructor<LteEnbRrcProtocolReal> ()
;
return tid;
}
void
LteEnbRrcProtocolReal::SetLteEnbRrcSapProvider (LteEnbRrcSapProvider* p)
{
m_enbRrcSapProvider = p;
}
LteEnbRrcSapUser*
LteEnbRrcProtocolReal::GetLteEnbRrcSapUser ()
{
return m_enbRrcSapUser;
}
void
LteEnbRrcProtocolReal::SetCellId (uint16_t cellId)
{
m_cellId = cellId;
}
LteUeRrcSapProvider*
LteEnbRrcProtocolReal::GetUeRrcSapProvider (uint16_t rnti)
{
std::map<uint16_t, LteUeRrcSapProvider*>::const_iterator it;
it = m_enbRrcSapProviderMap.find (rnti);
NS_ASSERT_MSG (it != m_enbRrcSapProviderMap.end (), "could not find RNTI = " << rnti);
return it->second;
}
void
LteEnbRrcProtocolReal::SetUeRrcSapProvider (uint16_t rnti, LteUeRrcSapProvider* p)
{
std::map<uint16_t, LteUeRrcSapProvider*>::iterator it;
it = m_enbRrcSapProviderMap.find (rnti);
NS_ASSERT_MSG (it != m_enbRrcSapProviderMap.end (), "could not find RNTI = " << rnti);
it->second = p;
}
void
LteEnbRrcProtocolReal::DoSetupUe (uint16_t rnti, LteEnbRrcSapUser::SetupUeParameters params)
{
NS_LOG_FUNCTION (this << rnti);
// // walk list of all nodes to get the peer UE RRC SAP Provider
// Ptr<LteUeRrc> ueRrc;
// NodeList::Iterator listEnd = NodeList::End ();
// bool found = false;
// for (NodeList::Iterator i = NodeList::Begin (); (i != listEnd) && (found == false); i++)
// {
// Ptr<Node> node = *i;
// int nDevs = node->GetNDevices ();
// for (int j = 0; j < nDevs; j++)
// {
// Ptr<LteUeNetDevice> ueDev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
// if (!ueDev)
// {
// continue;
// }
// else
// {
// ueRrc = ueDev->GetRrc ();
// if ((ueRrc->GetRnti () == rnti) && (ueRrc->GetCellId () == m_cellId))
// {
// found = true;
// break;
// }
// }
// }
// }
// NS_ASSERT_MSG (found , " Unable to find UE with RNTI=" << rnti << " cellId=" << m_cellId);
// m_enbRrcSapProviderMap[rnti] = ueRrc->GetLteUeRrcSapProvider ();
// just create empty entry, the UeRrcSapProvider will be set by the
// ue upon connection request or connection reconfiguration
// completed
m_enbRrcSapProviderMap[rnti] = 0;
}
void
LteEnbRrcProtocolReal::DoRemoveUe (uint16_t rnti)
{
NS_LOG_FUNCTION (this << rnti);
m_enbRrcSapProviderMap.erase (rnti);
}
void
LteEnbRrcProtocolReal::DoSendMasterInformationBlock (LteRrcSap::MasterInformationBlock msg)
{
NS_LOG_FUNCTION (this);
for (std::map<uint16_t, LteUeRrcSapProvider*>::const_iterator it = m_enbRrcSapProviderMap.begin ();
it != m_enbRrcSapProviderMap.end ();
++it)
{
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteUeRrcSapProvider::RecvMasterInformationBlock,
it->second,
msg);
}
}
void
LteEnbRrcProtocolReal::DoSendSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 msg)
{
NS_LOG_FUNCTION (this << m_cellId);
// walk list of all nodes to get UEs with this cellId
Ptr<LteUeRrc> ueRrc;
for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
{
Ptr<Node> node = *i;
int nDevs = node->GetNDevices ();
for (int j = 0; j < nDevs; ++j)
{
Ptr<LteUeNetDevice> ueDev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
if (ueDev != 0)
{
NS_LOG_LOGIC ("considering UE " << ueDev->GetImsi ());
Ptr<LteUeRrc> ueRrc = ueDev->GetRrc ();
if (ueRrc->GetCellId () == m_cellId)
{
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteUeRrcSapProvider::RecvSystemInformationBlockType1,
ueRrc->GetLteUeRrcSapProvider (),
msg);
}
}
}
}
}
void
LteEnbRrcProtocolReal::DoSendSystemInformation (LteRrcSap::SystemInformation msg)
{
NS_LOG_FUNCTION (this << m_cellId);
// walk list of all nodes to get UEs with this cellId
Ptr<LteUeRrc> ueRrc;
for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
{
Ptr<Node> node = *i;
int nDevs = node->GetNDevices ();
for (int j = 0; j < nDevs; ++j)
{
Ptr<LteUeNetDevice> ueDev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
if (ueDev != 0)
{
Ptr<LteUeRrc> ueRrc = ueDev->GetRrc ();
NS_LOG_LOGIC ("considering UE IMSI " << ueDev->GetImsi () << " that has cellId " << ueRrc->GetCellId ());
if (ueRrc->GetCellId () == m_cellId)
{
NS_LOG_LOGIC ("sending SI to IMSI " << ueDev->GetImsi ());
ueRrc->GetLteUeRrcSapProvider ()->RecvSystemInformation (msg);
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteUeRrcSapProvider::RecvSystemInformation,
ueRrc->GetLteUeRrcSapProvider (),
msg);
}
}
}
}
}
void
LteEnbRrcProtocolReal::DoSendRrcConnectionSetup (uint16_t rnti, LteRrcSap::RrcConnectionSetup msg)
{
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteUeRrcSapProvider::RecvRrcConnectionSetup,
GetUeRrcSapProvider (rnti),
msg);
}
void
LteEnbRrcProtocolReal::DoSendRrcConnectionReconfiguration (uint16_t rnti, LteRrcSap::RrcConnectionReconfiguration msg)
{
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteUeRrcSapProvider::RecvRrcConnectionReconfiguration,
GetUeRrcSapProvider (rnti),
msg);
}
void
LteEnbRrcProtocolReal::DoSendRrcConnectionReestablishment (uint16_t rnti, LteRrcSap::RrcConnectionReestablishment msg)
{
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteUeRrcSapProvider::RecvRrcConnectionReestablishment,
GetUeRrcSapProvider (rnti),
msg);
}
void
LteEnbRrcProtocolReal::DoSendRrcConnectionReestablishmentReject (uint16_t rnti, LteRrcSap::RrcConnectionReestablishmentReject msg)
{
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteUeRrcSapProvider::RecvRrcConnectionReestablishmentReject,
GetUeRrcSapProvider (rnti),
msg);
}
void
LteEnbRrcProtocolReal::DoSendRrcConnectionRelease (uint16_t rnti, LteRrcSap::RrcConnectionRelease msg)
{
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteUeRrcSapProvider::RecvRrcConnectionRelease,
GetUeRrcSapProvider (rnti),
msg);
}
/*
* The purpose of LteEnbRrcProtocolReal is to avoid encoding
* messages. In order to do so, we need to have some form of encoding for
* inter-node RRC messages like HandoverPreparationInfo and HandoverCommand. Doing so
* directly is not practical (these messages includes a lot of
* information elements, so encoding all of them would defeat the
* purpose of LteEnbRrcProtocolReal. The workaround is to store the
* actual message in a global map, so that then we can just encode the
* key in a header and send that between eNBs over X2.
*
*/
std::map<uint32_t, LteRrcSap::HandoverPreparationInfo> g_handoverPreparationInfoMsgMap2;
uint32_t g_handoverPreparationInfoMsgIdCounter2 = 0;
/*
* This header encodes the map key discussed above. We keep this
* private since it should not be used outside this file.
*
*/
class RealHandoverPreparationInfoHeader : public Header
{
public:
uint32_t GetMsgId ();
void SetMsgId (uint32_t id);
static TypeId GetTypeId (void);
virtual TypeId GetInstanceTypeId (void) const;
virtual void Print (std::ostream &os) const;
virtual uint32_t GetSerializedSize (void) const;
virtual void Serialize (Buffer::Iterator start) const;
virtual uint32_t Deserialize (Buffer::Iterator start);
private:
uint32_t m_msgId;
};
uint32_t
RealHandoverPreparationInfoHeader::GetMsgId ()
{
return m_msgId;
}
void
RealHandoverPreparationInfoHeader::SetMsgId (uint32_t id)
{
m_msgId = id;
}
TypeId
RealHandoverPreparationInfoHeader::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::RealHandoverPreparationInfoHeader")
.SetParent<Header> ()
.AddConstructor<RealHandoverPreparationInfoHeader> ()
;
return tid;
}
TypeId
RealHandoverPreparationInfoHeader::GetInstanceTypeId (void) const
{
return GetTypeId ();
}
void RealHandoverPreparationInfoHeader::Print (std::ostream &os) const
{
os << " msgId=" << m_msgId;
}
uint32_t RealHandoverPreparationInfoHeader::GetSerializedSize (void) const
{
return 4;
}
void RealHandoverPreparationInfoHeader::Serialize (Buffer::Iterator start) const
{
start.WriteU32 (m_msgId);
}
uint32_t RealHandoverPreparationInfoHeader::Deserialize (Buffer::Iterator start)
{
m_msgId = start.ReadU32 ();
return GetSerializedSize ();
}
Ptr<Packet>
LteEnbRrcProtocolReal::DoEncodeHandoverPreparationInformation (LteRrcSap::HandoverPreparationInfo msg)
{
uint32_t msgId = ++g_handoverPreparationInfoMsgIdCounter2;
NS_ASSERT_MSG (g_handoverPreparationInfoMsgMap2.find (msgId) == g_handoverPreparationInfoMsgMap2.end (), "msgId " << msgId << " already in use");
NS_LOG_INFO (" encoding msgId = " << msgId);
g_handoverPreparationInfoMsgMap2.insert (std::pair<uint32_t, LteRrcSap::HandoverPreparationInfo> (msgId, msg));
RealHandoverPreparationInfoHeader h;
h.SetMsgId (msgId);
Ptr<Packet> p = Create<Packet> ();
p->AddHeader (h);
return p;
}
LteRrcSap::HandoverPreparationInfo
LteEnbRrcProtocolReal::DoDecodeHandoverPreparationInformation (Ptr<Packet> p)
{
RealHandoverPreparationInfoHeader h;
p->RemoveHeader (h);
uint32_t msgId = h.GetMsgId ();
NS_LOG_INFO (" decoding msgId = " << msgId);
std::map<uint32_t, LteRrcSap::HandoverPreparationInfo>::iterator it = g_handoverPreparationInfoMsgMap2.find (msgId);
NS_ASSERT_MSG (it != g_handoverPreparationInfoMsgMap2.end (), "msgId " << msgId << " not found");
LteRrcSap::HandoverPreparationInfo msg = it->second;
g_handoverPreparationInfoMsgMap2.erase (it);
return msg;
}
std::map<uint32_t, LteRrcSap::RrcConnectionReconfiguration> g_handoverCommandMsgMap2;
uint32_t g_handoverCommandMsgIdCounter2 = 0;
/*
* This header encodes the map key discussed above. We keep this
* private since it should not be used outside this file.
*
*/
class RealHandoverCommandHeader : public Header
{
public:
uint32_t GetMsgId ();
void SetMsgId (uint32_t id);
static TypeId GetTypeId (void);
virtual TypeId GetInstanceTypeId (void) const;
virtual void Print (std::ostream &os) const;
virtual uint32_t GetSerializedSize (void) const;
virtual void Serialize (Buffer::Iterator start) const;
virtual uint32_t Deserialize (Buffer::Iterator start);
private:
uint32_t m_msgId;
};
uint32_t
RealHandoverCommandHeader::GetMsgId ()
{
return m_msgId;
}
void
RealHandoverCommandHeader::SetMsgId (uint32_t id)
{
m_msgId = id;
}
TypeId
RealHandoverCommandHeader::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::RealHandoverCommandHeader")
.SetParent<Header> ()
.AddConstructor<RealHandoverCommandHeader> ()
;
return tid;
}
TypeId
RealHandoverCommandHeader::GetInstanceTypeId (void) const
{
return GetTypeId ();
}
void RealHandoverCommandHeader::Print (std::ostream &os) const
{
os << " msgId=" << m_msgId;
}
uint32_t RealHandoverCommandHeader::GetSerializedSize (void) const
{
return 4;
}
void RealHandoverCommandHeader::Serialize (Buffer::Iterator start) const
{
start.WriteU32 (m_msgId);
}
uint32_t RealHandoverCommandHeader::Deserialize (Buffer::Iterator start)
{
m_msgId = start.ReadU32 ();
return GetSerializedSize ();
}
Ptr<Packet>
LteEnbRrcProtocolReal::DoEncodeHandoverCommand (LteRrcSap::RrcConnectionReconfiguration msg)
{
uint32_t msgId = ++g_handoverCommandMsgIdCounter2;
NS_ASSERT_MSG (g_handoverCommandMsgMap2.find (msgId) == g_handoverCommandMsgMap2.end (), "msgId " << msgId << " already in use");
NS_LOG_INFO (" encoding msgId = " << msgId);
g_handoverCommandMsgMap2.insert (std::pair<uint32_t, LteRrcSap::RrcConnectionReconfiguration> (msgId, msg));
RealHandoverCommandHeader h;
h.SetMsgId (msgId);
Ptr<Packet> p = Create<Packet> ();
p->AddHeader (h);
return p;
}
LteRrcSap::RrcConnectionReconfiguration
LteEnbRrcProtocolReal::DoDecodeHandoverCommand (Ptr<Packet> p)
{
RealHandoverCommandHeader h;
p->RemoveHeader (h);
uint32_t msgId = h.GetMsgId ();
NS_LOG_INFO (" decoding msgId = " << msgId);
std::map<uint32_t, LteRrcSap::RrcConnectionReconfiguration>::iterator it = g_handoverCommandMsgMap2.find (msgId);
NS_ASSERT_MSG (it != g_handoverCommandMsgMap2.end (), "msgId " << msgId << " not found");
LteRrcSap::RrcConnectionReconfiguration msg = it->second;
g_handoverCommandMsgMap2.erase (it);
return msg;
}
} // namespace ns3

View File

@@ -0,0 +1,149 @@
/* -*- 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: Nicola Baldo <nbaldo@cttc.es>
*/
#ifndef LTE_RRC_PROTOCOL_REAL_H
#define LTE_RRC_PROTOCOL_REAL_H
#include <stdint.h>
#include <map>
#include <ns3/ptr.h>
#include <ns3/object.h>
#include <ns3/lte-rrc-sap.h>
namespace ns3 {
class LteUeRrcSapProvider;
class LteUeRrcSapUser;
class LteEnbRrcSapProvider;
class LteUeRrc;
/**
* Models the transmission of RRC messages from the UE to the eNB in
* a real fashion, by creating real RRC PDUs and transmitting them
* over Signaling Radio Bearers using radio resources allocated by the
* LTE MAC scheduler.
*
*/
class LteUeRrcProtocolReal : public Object
{
friend class MemberLteUeRrcSapUser<LteUeRrcProtocolReal>;
public:
LteUeRrcProtocolReal ();
virtual ~LteUeRrcProtocolReal ();
// inherited from Object
virtual void DoDispose (void);
static TypeId GetTypeId (void);
void SetLteUeRrcSapProvider (LteUeRrcSapProvider* p);
LteUeRrcSapUser* GetLteUeRrcSapUser ();
void SetUeRrc (Ptr<LteUeRrc> rrc);
private:
// methods forwarded from LteUeRrcSapUser
void DoSetup (LteUeRrcSapUser::SetupParameters params);
void DoReestablish ();
void DoSendRrcConnectionRequest (LteRrcSap::RrcConnectionRequest msg);
void DoSendRrcConnectionSetupCompleted (LteRrcSap::RrcConnectionSetupCompleted msg);
void DoSendRrcConnectionReconfigurationCompleted (LteRrcSap::RrcConnectionReconfigurationCompleted msg);
void DoSendRrcConnectionReestablishmentRequest (LteRrcSap::RrcConnectionReestablishmentRequest msg);
void DoSendRrcConnectionReestablishmentComplete (LteRrcSap::RrcConnectionReestablishmentComplete msg);
void SetEnbRrcSapProvider ();
Ptr<LteUeRrc> m_rrc;
uint16_t m_rnti;
LteUeRrcSapProvider* m_ueRrcSapProvider;
LteUeRrcSapUser* m_ueRrcSapUser;
LteEnbRrcSapProvider* m_enbRrcSapProvider;
};
/**
* Models the transmission of RRC messages from the UE to the eNB in
* a real fashion, by creating real RRC PDUs and transmitting them
* over Signaling Radio Bearers using radio resources allocated by the
* LTE MAC scheduler.
*
*/
class LteEnbRrcProtocolReal : public Object
{
friend class MemberLteEnbRrcSapUser<LteEnbRrcProtocolReal>;
public:
LteEnbRrcProtocolReal ();
virtual ~LteEnbRrcProtocolReal ();
// inherited from Object
virtual void DoDispose (void);
static TypeId GetTypeId (void);
void SetLteEnbRrcSapProvider (LteEnbRrcSapProvider* p);
LteEnbRrcSapUser* GetLteEnbRrcSapUser ();
void SetCellId (uint16_t cellId);
LteUeRrcSapProvider* GetUeRrcSapProvider (uint16_t rnti);
void SetUeRrcSapProvider (uint16_t rnti, LteUeRrcSapProvider* p);
private:
// methods forwarded from LteEnbRrcSapUser
void DoSetupUe (uint16_t rnti, LteEnbRrcSapUser::SetupUeParameters params);
void DoRemoveUe (uint16_t rnti);
void DoSendMasterInformationBlock (LteRrcSap::MasterInformationBlock msg);
void DoSendSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 msg);
void DoSendSystemInformation (LteRrcSap::SystemInformation msg);
void SendSystemInformation (LteRrcSap::SystemInformation msg);
void DoSendRrcConnectionSetup (uint16_t rnti, LteRrcSap::RrcConnectionSetup msg);
void DoSendRrcConnectionReconfiguration (uint16_t rnti, LteRrcSap::RrcConnectionReconfiguration msg);
void DoSendRrcConnectionReestablishment (uint16_t rnti, LteRrcSap::RrcConnectionReestablishment msg);
void DoSendRrcConnectionReestablishmentReject (uint16_t rnti, LteRrcSap::RrcConnectionReestablishmentReject msg);
void DoSendRrcConnectionRelease (uint16_t rnti, LteRrcSap::RrcConnectionRelease msg);
Ptr<Packet> DoEncodeHandoverPreparationInformation (LteRrcSap::HandoverPreparationInfo msg);
LteRrcSap::HandoverPreparationInfo DoDecodeHandoverPreparationInformation (Ptr<Packet> p);
Ptr<Packet> DoEncodeHandoverCommand (LteRrcSap::RrcConnectionReconfiguration msg);
LteRrcSap::RrcConnectionReconfiguration DoDecodeHandoverCommand (Ptr<Packet> p);
uint16_t m_rnti;
uint16_t m_cellId;
LteEnbRrcSapProvider* m_enbRrcSapProvider;
LteEnbRrcSapUser* m_enbRrcSapUser;
std::map<uint16_t, LteUeRrcSapProvider*> m_enbRrcSapProviderMap;
};
}
#endif // LTE_RRC_PROTOCOL_REAL_H

View File

@@ -42,10 +42,10 @@ public:
* \param delayDiscStart expected duration to perform connection establishment in ms
*
*/
LteRrcConnectionEstablishmentTestCase (uint32_t nUes, uint32_t nBearers, uint32_t tc, uint32_t tConnIncrPerUe, uint32_t delayDiscStart);
LteRrcConnectionEstablishmentTestCase (uint32_t nUes, uint32_t nBearers, uint32_t tc, uint32_t tConnIncrPerUe, uint32_t delayDiscStart, bool useIdealRrc);
private:
static std::string BuildNameString (uint32_t nUes, uint32_t nBearers, uint32_t tc, uint32_t tConnIncrPerUe, uint32_t delayDiscStart);
static std::string BuildNameString (uint32_t nUes, uint32_t nBearers, uint32_t tc, uint32_t tConnIncrPerUe, uint32_t delayDiscStart, bool useIdealRrc);
virtual void DoRun (void);
void Connect (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
void CheckConnected (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
@@ -58,12 +58,13 @@ private:
uint32_t m_delayConnEnd; // expected duration to perform connection establishment in ms
uint32_t m_delayDiscStart; // delay between connection completed and disconnection request in ms
uint32_t m_delayDiscEnd; // expected duration to complete disconnection in ms
bool m_useIdealRrc;
Ptr<LteHelper> m_lteHelper;
};
std::string LteRrcConnectionEstablishmentTestCase::BuildNameString (uint32_t nUes, uint32_t nBearers, uint32_t tConnBase, uint32_t tConnIncrPerUe, uint32_t delayDiscStart)
std::string LteRrcConnectionEstablishmentTestCase::BuildNameString (uint32_t nUes, uint32_t nBearers, uint32_t tConnBase, uint32_t tConnIncrPerUe, uint32_t delayDiscStart, bool useIdealRrc)
{
std::ostringstream oss;
oss << "nUes=" << nUes
@@ -71,10 +72,18 @@ std::string LteRrcConnectionEstablishmentTestCase::BuildNameString (uint32_t nUe
<< ", tConnBase=" << tConnBase
<< ", tConnIncrPerUe=" << tConnIncrPerUe
<< ", delayDiscStart=" << delayDiscStart;
if (useIdealRrc)
{
oss << ", ideal RRC";
}
else
{
oss << ", real RRC";
}
return oss.str ();
}
LteRrcConnectionEstablishmentTestCase::LteRrcConnectionEstablishmentTestCase (uint32_t nUes, uint32_t nBearers, uint32_t tConnBase, uint32_t tConnIncrPerUe, uint32_t delayDiscStart)
LteRrcConnectionEstablishmentTestCase::LteRrcConnectionEstablishmentTestCase (uint32_t nUes, uint32_t nBearers, uint32_t tConnBase, uint32_t tConnIncrPerUe, uint32_t delayDiscStart, bool useIdealRrc)
: TestCase ("RRC connection establishment"),
m_nUes (nUes),
m_nBearers (nBearers),
@@ -82,7 +91,8 @@ LteRrcConnectionEstablishmentTestCase::LteRrcConnectionEstablishmentTestCase (ui
m_tConnIncrPerUe (tConnIncrPerUe),
m_delayConnEnd (150), // includes: time to receive system information, time for Random Access (RACH preamble, RAR response), time to send and receive RRC connection request+setup+completed. Value should be slightly higher than T300 in TS 36.331
m_delayDiscStart (delayDiscStart),
m_delayDiscEnd (10)
m_delayDiscEnd (10),
m_useIdealRrc (useIdealRrc)
{
}
@@ -92,6 +102,7 @@ LteRrcConnectionEstablishmentTestCase::DoRun ()
// normal code
m_lteHelper = CreateObject<LteHelper> ();
m_lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (m_useIdealRrc));
NodeContainer enbNodes;
enbNodes.Create (1);
@@ -241,36 +252,37 @@ LteRrcTestSuite::LteRrcTestSuite ()
: TestSuite ("lte-rrc", SYSTEM)
{
NS_LOG_FUNCTION (this);
for (uint32_t useIdealRrc = 0; useIdealRrc <= 1; ++useIdealRrc)
{
// <----- all times in ms ----------------->
// nUes, nBearers, tConnBase, tConnIncrPerUe, delayDiscStart, useIdealRrc
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 0, 0, 0, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 0, 100, 0, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 1, 0, 0, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 1, 100, 0, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 2, 0, 0, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 2, 100, 0, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 0, 20, 0, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 0, 20, 10, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 0, 20, 100, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 1, 20, 0, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 1, 20, 10, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 1, 20, 100, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 2, 20, 0, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 2, 20, 10, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 2, 20, 100, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 3, 0, 20, 0, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 4, 0, 20, 0, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 4, 0, 20, 300, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 20, 0, 10, 1, 1, useIdealRrc));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 50, 0, 10, 0, 1, useIdealRrc));
// <----- all times in ms ----------------->
// nUes, nBearers, tConnBase, tConnIncrPerUe, delayDiscStart
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 0, 0, 0, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 0, 100, 0, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 1, 0, 0, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 1, 100, 0, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 2, 0, 0, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 1, 2, 100, 0, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 0, 20, 0, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 0, 20, 10, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 0, 20, 100, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 1, 20, 0, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 1, 20, 10, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 1, 20, 100, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 2, 20, 0, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 2, 20, 10, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 2, 2, 20, 100, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 3, 0, 20, 0, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 4, 0, 20, 0, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 4, 0, 20, 300, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 20, 0, 10, 1, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 50, 0, 10, 0, 1));
// // time consuming tests with a lot of UEs
// AddTestCase (new LteRrcConnectionEstablishmentTestCase (100, 0, 10, 0, 1));
// AddTestCase (new LteRrcConnectionEstablishmentTestCase (100, 0, 10, 1, 1));
// AddTestCase (new LteRrcConnectionEstablishmentTestCase (200, 0, 10, 0, 1));
// AddTestCase (new LteRrcConnectionEstablishmentTestCase (200, 0, 10, 1, 1));
// // time consuming tests with a lot of UEs
// AddTestCase (new LteRrcConnectionEstablishmentTestCase (100, 0, 10, 0, 1));
// AddTestCase (new LteRrcConnectionEstablishmentTestCase (100, 0, 10, 1, 1));
// AddTestCase (new LteRrcConnectionEstablishmentTestCase (200, 0, 10, 0, 1));
// AddTestCase (new LteRrcConnectionEstablishmentTestCase (200, 0, 10, 1, 1));
}
}
static LteRrcTestSuite g_lteRrcTestSuiteInstance;

View File

@@ -16,6 +16,7 @@ def build(bld):
'model/lte-ue-rrc.cc',
'model/lte-rrc-sap.cc',
'model/lte-rrc-protocol-ideal.cc',
'model/lte-rrc-protocol-real.cc',
'model/lte-rlc-sap.cc',
'model/lte-rlc.cc',
'model/lte-rlc-sequence-number.cc',
@@ -135,6 +136,7 @@ def build(bld):
'model/lte-ue-rrc.h',
'model/lte-rrc-sap.h',
'model/lte-rrc-protocol-ideal.h',
'model/lte-rrc-protocol-real.h',
'model/lte-rlc-sap.h',
'model/lte-rlc.h',
'model/lte-rlc-header.h',