LTE-EPC end-to-end data plane imlemented and partially working

This commit is contained in:
Nicola Baldo
2011-11-04 13:29:20 +00:00
parent 5fbb0fb9db
commit 46cd08db25
22 changed files with 913 additions and 342 deletions

View File

@@ -24,6 +24,7 @@
#include <ns3/string.h>
#include <ns3/log.h>
#include <ns3/abort.h>
#include <ns3/lte-enb-rrc.h>
#include <ns3/lte-ue-rrc.h>
@@ -42,6 +43,10 @@
#include <ns3/lte-ue-net-device.h>
#include <ns3/ff-mac-scheduler.h>
#include <ns3/lte-rlc.h>
#include <ns3/lte-rlc-um.h>
#include <ns3/epc-helper.h>
#include <iostream>
@@ -55,6 +60,7 @@ NS_OBJECT_ENSURE_REGISTERED (LenaHelper);
LenaHelper::LenaHelper (void)
{
NS_LOG_FUNCTION (this);
m_enbNetDeviceFactory.SetTypeId (LteEnbNetDevice::GetTypeId ());
}
void
@@ -77,16 +83,6 @@ LenaHelper::~LenaHelper (void)
NS_LOG_FUNCTION (this);
}
void
LenaHelper::DoDispose ()
{
NS_LOG_FUNCTION (this);
m_downlinkChannel = 0;
m_uplinkChannel = 0;
Object::DoDispose ();
}
TypeId LenaHelper::GetTypeId (void)
{
static TypeId
@@ -104,10 +100,40 @@ TypeId LenaHelper::GetTypeId (void)
StringValue ("ns3::FriisSpectrumPropagationLossModel"),
MakeStringAccessor (&LenaHelper::SetPropagationModelType),
MakeStringChecker ())
.AddAttribute ("EpsBearerToRlcMapping",
"Specify which type of RLC will be used for each type of EPS bearer. ",
EnumValue (RLC_SM_ALWAYS),
MakeEnumAccessor (&LenaHelper::m_epsBearerToRlcMapping),
MakeEnumChecker (RLC_SM_ALWAYS, "RlcSmAlways",
RLC_UM_ALWAYS, "RlcUmAlways",
RLC_AM_ALWAYS, "RlcAmAlways",
PER_BASED, "PacketErrorRateBased"))
;
return tid;
}
void
LenaHelper::DoDispose ()
{
NS_LOG_FUNCTION (this);
m_downlinkChannel = 0;
m_uplinkChannel = 0;
Object::DoDispose ();
}
void
LenaHelper::SetEpcHelper (Ptr<EpcHelper> h)
{
NS_LOG_FUNCTION (this << h);
m_epcHelper = h;
// it does not make sense to use RLC/SM when also using the EPC
if (m_epsBearerToRlcMapping == RLC_SM_ALWAYS)
{
m_epsBearerToRlcMapping = RLC_UM_ALWAYS;
}
}
void
LenaHelper::SetSchedulerType (std::string type)
{
@@ -139,6 +165,12 @@ LenaHelper::SetPropagationModelAttribute (std::string n, const AttributeValue &v
m_propagationModelFactory.Set (n, v);
}
void
LenaHelper::SetEnbDeviceAttribute (std::string n, const AttributeValue &v)
{
NS_LOG_FUNCTION (this);
m_enbNetDeviceFactory.Set (n, v);
}
NetDeviceContainer
LenaHelper::InstallEnbDevice (NodeContainer c)
@@ -169,22 +201,6 @@ LenaHelper::InstallUeDevice (NodeContainer c)
return devices;
}
void
LenaHelper::SetEnbDeviceAttribute (std::string name, const AttributeValue &value)
{
NS_LOG_FUNCTION (this);
NS_FATAL_ERROR ("not implemented yet");
}
void
LenaHelper::SetUeDeviceAttribute (std::string name, const AttributeValue &value)
{
NS_LOG_FUNCTION (this);
NS_FATAL_ERROR ("not implemented yet");
}
Ptr<NetDevice>
LenaHelper::InstallSingleEnbDevice (Ptr<Node> n)
{
@@ -232,8 +248,16 @@ LenaHelper::InstallSingleEnbDevice (Ptr<Node> n)
n->AddDevice (dev);
ulPhy->SetGenericPhyRxEndOkCallback (MakeCallback (&LteEnbPhy::PhyPduReceived, phy));
rrc->SetForwardUpCallback (MakeCallback (&LteEnbNetDevice::Receive, dev));
dev->Start ();
if (m_epcHelper != 0)
{
NS_LOG_INFO ("adding this eNB to the EPC");
m_epcHelper->AddEnb (n, dev);
}
return dev;
}
@@ -265,6 +289,7 @@ LenaHelper::InstallSingleUeDevice (Ptr<Node> n)
rrc->SetLteUeCmacSapProvider (mac->GetLteUeCmacSapProvider ());
mac->SetLteUeCmacSapUser (rrc->GetLteUeCmacSapUser ());
rrc->SetLteMacSapProvider (mac->GetLteMacSapProvider ());
phy->SetLteUePhySapUser (mac->GetLteUePhySapUser ());
mac->SetLteUePhySapProvider (phy->GetLteUePhySapProvider ());
@@ -275,6 +300,7 @@ LenaHelper::InstallSingleUeDevice (Ptr<Node> n)
n->AddDevice (dev);
dlPhy->SetGenericPhyRxEndOkCallback (MakeCallback (&LteUePhy::PhyPduReceived, phy));
rrc->SetForwardUpCallback (MakeCallback (&LteUeNetDevice::Receive, dev));
return dev;
}
@@ -332,18 +358,58 @@ LenaHelper::ActivateEpsBearer (NetDeviceContainer ueDevices, EpsBearer bearer, P
void
LenaHelper::ActivateEpsBearer (Ptr<NetDevice> ueDevice, EpsBearer bearer, Ptr<LteTft> tft)
{
// setup RadioBearer first
NS_LOG_INFO (" setting up Radio Bearer");
Ptr<LteEnbNetDevice> enbDevice = ueDevice->GetObject<LteUeNetDevice> ()->GetTargetEnb ();
Ptr<LteEnbRrc> enbRrc = enbDevice->GetObject<LteEnbNetDevice> ()->GetRrc ();
Ptr<LteUeRrc> ueRrc = ueDevice->GetObject<LteUeNetDevice> ()->GetRrc ();
uint16_t rnti = ueRrc->GetRnti ();
uint8_t lcid = enbRrc->SetupRadioBearer (rnti, bearer);
ueRrc->SetupRadioBearer (rnti, bearer, lcid);
TypeId rlcTypeId = GetRlcType (bearer);
uint8_t lcid = enbRrc->SetupRadioBearer (rnti, bearer, rlcTypeId);
ueRrc->SetupRadioBearer (rnti, bearer, rlcTypeId, lcid, tft);
// then setup S1 Bearer
if (m_epcHelper != 0)
{
NS_LOG_INFO (" setting up S1 Bearer");
m_epcHelper->ActivateEpsBearer (ueDevice, enbDevice, tft, rnti, lcid);
}
}
TypeId
LenaHelper::GetRlcType (EpsBearer bearer)
{
switch (m_epsBearerToRlcMapping)
{
case RLC_SM_ALWAYS:
return LteRlcSm::GetTypeId ();
break;
case RLC_UM_ALWAYS:
return LteRlcUm::GetTypeId ();
break;
case RLC_AM_ALWAYS:
NS_ABORT_MSG ("RLC/AM not supported yet");
//return LteRlcAm::GetTypeId ();
break;
case PER_BASED:
if (bearer.GetPacketErrorLossRate () > 1.0e-5)
{
return LteRlcUm::GetTypeId ();
}
else
{
NS_ABORT_MSG ("RLC/AM not supported yet");
//return LteRlcAm::GetTypeId ();
}
break;
default:
return LteRlcSm::GetTypeId ();
break;
}
}
void
LenaHelper::EnableLogComponents (void)

View File

@@ -40,6 +40,7 @@ namespace ns3 {
class LteUePhy;
class LteEnbPhy;
class SpectrumChannel;
class EpcHelper;
/**
@@ -55,22 +56,58 @@ public:
static TypeId GetTypeId (void);
virtual void DoDispose (void);
/**
* \todo to be implemented
/**
* Set the EpcHelper to be used to setup the EPC network in
* conjunction with the setup of the LTE radio access network
*
* \param name
* \param value
* \note if no EpcHelper is ever set, then LenaHelper will default
* to creating an LTE-only simulation with no EPC, using LteRlcSm as
* the RLC model, and without supporting any IP networking. In other
* words, it will be a radio-level simulation involving only LTE PHY
* and MAC and the FF Scheduler, with a saturation traffic model for
* the RLC.
*
* \param h a pointer to the EpcHelper to be used
*/
void SetEnbDeviceAttribute (std::string name, const AttributeValue &value);
void SetEpcHelper (Ptr<EpcHelper> h);
/**
*
*
* \param type the type of propagation model to be used for the eNBs
*/
void SetPropagationModelType (std::string type);
/**
* \todo to be implemented
*
* \param name
* \param value
* set an attribute for the propagation model to be created
*
* \param n the name of the attribute
* \param v the value of the attribute
*/
void SetUeDeviceAttribute (std::string name, const AttributeValue &value);
void SetPropagationModelAttribute (std::string n, const AttributeValue &v);
/**
*
* \param type the type of scheduler to be used for the eNBs
*/
void SetSchedulerType (std::string type);
/**
* set an attribute for the scheduler to be created
*
* \param n the name of the attribute
* \param v the value of the attribute
*/
void SetSchedulerAttribute (std::string n, const AttributeValue &v);
/**
* set an attribute for the LteEnbNetDevice to be created
*
* \param n the name of the attribute
* \param v the value of the attribute
*/
void SetEnbDeviceAttribute (std::string n, const AttributeValue &v);
/**
* create a set of eNB devices
@@ -126,28 +163,11 @@ public:
/**
*
* \param bearer the specification of an EPS bearer
*
* \param type the type of scheduler to be used for the eNBs
* \return the type of RLC that is to be created for the given EPS bearer
*/
void SetSchedulerType (std::string type);
/**
* set an attribute for the scheduler to be created
*/
void SetSchedulerAttribute (std::string n, const AttributeValue &v);
/**
*
*
* \param type the type of propagation model to be used for the eNBs
*/
void SetPropagationModelType (std::string type);
/**
* set an attribute for the propagation model to be created
*/
void SetPropagationModelAttribute (std::string n, const AttributeValue &v);
TypeId GetRlcType (EpsBearer bearer);
/**
* Enables logging for all components of the LENA architecture
@@ -202,10 +222,19 @@ private:
ObjectFactory m_schedulerFactory;
ObjectFactory m_propagationModelFactory;
ObjectFactory m_enbNetDeviceFactory;
Ptr<MacStatsCalculator> m_macStats;
Ptr<RlcStatsCalculator> m_rlcStats;
enum LteEpsBearerToRlcMapping_t {RLC_SM_ALWAYS = 1,
RLC_UM_ALWAYS = 2,
RLC_AM_ALWAYS = 3,
PER_BASED = 4} m_epsBearerToRlcMapping;
Ptr<EpcHelper> m_epcHelper;
};

View File

@@ -38,7 +38,7 @@
#include <ns3/lte-ue-net-device.h>
#include <ns3/lte-enb-phy.h>
#include <ns3/ff-mac-scheduler.h>
#include <ns3/ipv4-l3-protocol.h>
NS_LOG_COMPONENT_DEFINE ("LteEnbNetDevice");
@@ -270,41 +270,14 @@ LteEnbNetDevice::DoStart (void)
bool
LteEnbNetDevice::DoSend (Ptr<Packet> packet, const Mac48Address& source,
const Mac48Address& dest, uint16_t protocolNumber)
LteEnbNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
{
NS_LOG_FUNCTION (this << source << dest << protocolNumber);
NS_FATAL_ERROR ("IP connectivity not implemented yet");
/*
* The classification of traffic in DL is done by the PGW (not
* by the eNB).
* Hovever, the core network is not implemented yet.
* For now the classification is managed by the eNB.
*/
// if (protocolNumber == 2048)
// {
// // it is an IP packet
// }
// if (protocolNumber != 2048 || bearer == 0)
// {
// }
return true;
NS_LOG_FUNCTION (this << packet << dest << protocolNumber);
NS_ASSERT_MSG (protocolNumber == Ipv4L3Protocol::PROT_NUMBER, "unsupported protocol " << protocolNumber << ", only IPv4 is supported");
return m_rrc->Send (packet);
}
void
LteEnbNetDevice::DoReceive (Ptr<Packet> p)
{
NS_LOG_FUNCTION (this << p);
ForwardUp (p->Copy ());
}
void

View File

@@ -67,6 +67,9 @@ public:
virtual ~LteEnbNetDevice (void);
virtual void DoDispose (void);
// inherited from NetDevice
virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
/**
* \return a pointer to the MAC
*/
@@ -134,12 +137,6 @@ protected:
private:
bool DoSend (Ptr<Packet> packet,
const Mac48Address& source,
const Mac48Address& dest,
uint16_t protocolNumber);
void DoReceive (Ptr<Packet> p);
/**
* Several attributes (e.g., the bandwidth) are exported as

View File

@@ -20,12 +20,17 @@
#include <ns3/fatal-error.h>
#include <ns3/log.h>
#include <ns3/abort.h>
#include "ns3/pointer.h"
#include "ns3/object-map.h"
#include "ns3/object-factory.h"
#include "lte-enb-rrc.h"
#include "lte-rlc.h"
#include "ns3/object-map.h"
#include "lte-pdcp.h"
#include "lte-pdcp-sap.h"
#include "lte-radio-bearer-info.h"
#include "lte-mac-tag.h"
NS_LOG_COMPONENT_DEFINE ("LteEnbRrc");
@@ -62,57 +67,38 @@ EnbRrcMemberLteEnbCmacSapUser::NotifyLcConfigResult (uint16_t rnti, uint8_t lcid
}
////////////////////////////////
// PDCP SAP Forwarder
////////////////////////////////
// /////////////////////////////////////////
// per-UE radio bearer info management
// /////////////////////////////////////////
// not needed any more if the template works
class EnbRadioBearerInfo : public Object
{
// class EnbRrcMemberLtePdcpSapUser : public LtePdcpSapUser
// {
// public:
// MemberLtePdcpSapUser (LteEnbRrc* rrc);
// virtual void ReceiveRrcPdu (Ptr<Packet> p);
// private:
// LteEnbRrc* m_rrc;
// };
public:
EnbRadioBearerInfo (void);
virtual ~EnbRadioBearerInfo (void);
static TypeId GetTypeId (void);
void SetRlc (Ptr<LteRlc> rlc);
// EnbRrcMemberLtePdcpSapUser::EnbRrcMemberLtePdcpSapUser (LteEnbRrc* rrc)
// : m_rrc (rrc)
// {
// }
private:
Ptr<LteRlc> m_rlc;
// void EnbRrcMemberLtePdcpSapUser::ReceiveRrcPdu (Ptr<Packet> p)
// {
// m_rrc->DoReceiveRrcPdu (p);
// }
};
NS_OBJECT_ENSURE_REGISTERED (EnbRadioBearerInfo);
EnbRadioBearerInfo::EnbRadioBearerInfo (void)
{
// Nothing to do here
}
EnbRadioBearerInfo::~EnbRadioBearerInfo (void)
{
// Nothing to do here
}
TypeId EnbRadioBearerInfo::GetTypeId (void)
{
static TypeId
tid =
TypeId ("ns3::EnbRadioBearerInfo")
.SetParent<Object> ()
.AddConstructor<EnbRadioBearerInfo> ()
.AddAttribute ("LteRlc", "RLC instance of the radio bearer.",
PointerValue (),
MakePointerAccessor (&EnbRadioBearerInfo::m_rlc),
MakePointerChecker<LteRlc> ())
;
return tid;
}
void EnbRadioBearerInfo::SetRlc (Ptr<LteRlc> rlc)
{
m_rlc = rlc;
}
///////////////////////////////////////////
// UeInfo
///////////////////////////////////////////
NS_OBJECT_ENSURE_REGISTERED (UeInfo);
@@ -144,12 +130,7 @@ TypeId UeInfo::GetTypeId (void)
.AddAttribute ("RadioBearerMap", "List of UE RadioBearerInfo by LCID.",
ObjectMapValue (),
MakeObjectMapAccessor (&UeInfo::m_rbMap),
MakeObjectMapChecker<EnbRadioBearerInfo> ())
/* .AddAttribute("Imsi",
"International Mobile Subscriber Identity assigned to this UE",
UintegerValue (1),
MakeUintegerAccessor (&UeInfo::m_imsi),
MakeUintegerChecker<uint64_t> ())*/
MakeObjectMapChecker<LteRadioBearerInfo> ())
;
return tid;
}
@@ -161,7 +142,7 @@ UeInfo::GetImsi (void)
}
uint8_t
UeInfo::AddRadioBearer (Ptr<EnbRadioBearerInfo> rbi)
UeInfo::AddRadioBearer (Ptr<LteRadioBearerInfo> rbi)
{
NS_LOG_FUNCTION (this);
for (uint8_t lcid = m_lastAllocatedId; lcid != m_lastAllocatedId - 1; ++lcid)
@@ -170,7 +151,7 @@ UeInfo::AddRadioBearer (Ptr<EnbRadioBearerInfo> rbi)
{
if (m_rbMap.find (lcid) == m_rbMap.end ())
{
m_rbMap.insert (std::pair<uint8_t, Ptr<EnbRadioBearerInfo> > (lcid, rbi));
m_rbMap.insert (std::pair<uint8_t, Ptr<LteRadioBearerInfo> > (lcid, rbi));
m_lastAllocatedId = lcid;
return lcid;
}
@@ -180,12 +161,14 @@ UeInfo::AddRadioBearer (Ptr<EnbRadioBearerInfo> rbi)
return 0;
}
Ptr<EnbRadioBearerInfo>
Ptr<LteRadioBearerInfo>
UeInfo::GetRadioBearer (uint8_t lcid)
{
NS_LOG_FUNCTION (this << (uint32_t) lcid);
NS_ASSERT (0 != lcid);
return m_rbMap.find (lcid)->second;
std::map<uint8_t, Ptr<LteRadioBearerInfo> >::iterator it = m_rbMap.find (lcid);
NS_ABORT_IF (it == m_rbMap.end ());
return it->second;
}
@@ -193,7 +176,7 @@ void
UeInfo::RemoveRadioBearer (uint8_t lcid)
{
NS_LOG_FUNCTION (this << (uint32_t) lcid);
std::map <uint8_t, Ptr<EnbRadioBearerInfo> >::iterator it = m_rbMap.find (lcid);
std::map <uint8_t, Ptr<LteRadioBearerInfo> >::iterator it = m_rbMap.find (lcid);
NS_ASSERT_MSG (it != m_rbMap.end (), "request to remove radio bearer with unknown lcid " << lcid);
m_rbMap.erase (it);
}
@@ -217,6 +200,7 @@ LteEnbRrc::LteEnbRrc ()
{
NS_LOG_FUNCTION (this);
m_cmacSapUser = new EnbRrcMemberLteEnbCmacSapUser (this);
m_pdcpSapUser = new LtePdcpSpecificLtePdcpSapUser<LteEnbRrc> (this);
}
@@ -231,6 +215,7 @@ LteEnbRrc::DoDispose ()
{
NS_LOG_FUNCTION (this);
delete m_cmacSapUser;
delete m_pdcpSapUser;
}
TypeId
@@ -303,6 +288,11 @@ LteEnbRrc::SetLteMacSapProvider (LteMacSapProvider * s)
m_macSapProvider = s;
}
LtePdcpSapProvider*
LteEnbRrc::GetLtePdcpSapProvider (uint16_t rnti, uint8_t lcid)
{
return GetUeInfo (rnti)->GetRadioBearer (lcid)->m_pdcp->GetLtePdcpSapProvider ();
}
void
LteEnbRrc::ConfigureCell (uint8_t ulBandwidth, uint8_t dlBandwidth)
@@ -333,23 +323,37 @@ LteEnbRrc::RemoveUe (uint16_t rnti)
}
uint8_t
LteEnbRrc::SetupRadioBearer (uint16_t rnti, EpsBearer bearer)
LteEnbRrc::SetupRadioBearer (uint16_t rnti, EpsBearer bearer, TypeId rlcTypeId)
{
NS_LOG_FUNCTION (this << (uint32_t) rnti);
Ptr<UeInfo> ueInfo = GetUeInfo (rnti);
// create RLC instance
// for now we support RLC SM only
Ptr<LteRlc> rlc = CreateObject<LteRlcSm> ();
ObjectFactory rlcObjectFactory;
rlcObjectFactory.SetTypeId (rlcTypeId);
Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
rlc->SetLteMacSapProvider (m_macSapProvider);
rlc->SetRnti (rnti);
Ptr<EnbRadioBearerInfo> rbInfo = CreateObject<EnbRadioBearerInfo> ();
rbInfo->SetRlc (rlc);
Ptr<LteRadioBearerInfo> rbInfo = CreateObject<LteRadioBearerInfo> ();
rbInfo->m_rlc = rlc;
uint8_t lcid = ueInfo->AddRadioBearer (rbInfo);
rlc->SetLcId (lcid);
// we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
// if we are using RLC/SM we don't care of anything above RLC
if (rlcTypeId != LteRlcSm::GetTypeId ())
{
Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
pdcp->SetRnti (rnti);
pdcp->SetLcId (lcid);
pdcp->SetLtePdcpSapUser (m_pdcpSapUser);
pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
rbInfo->m_pdcp = pdcp;
}
LteEnbCmacSapProvider::LcInfo lcinfo;
lcinfo.rnti = rnti;
lcinfo.lcId = lcid;
@@ -373,6 +377,48 @@ LteEnbRrc::ReleaseRadioBearer (uint16_t rnti, uint8_t lcId)
ueInfo->RemoveRadioBearer (lcId);
}
bool
LteEnbRrc::Send (Ptr<Packet> packet)
{
NS_LOG_FUNCTION (this << packet);
LteMacTag tag;
bool found = packet->RemovePacketTag (tag);
NS_ASSERT (found);
LtePdcpSapProvider::TransmitRrcPduParameters params;
params.rrcPdu = packet;
params.rnti = tag.GetRnti ();
params.lcid = tag.GetLcid ();
LtePdcpSapProvider* pdcpSapProvider = GetLtePdcpSapProvider (tag.GetRnti (), tag.GetLcid ());
pdcpSapProvider->TransmitRrcPdu (params);
return true;
}
void
LteEnbRrc::SetForwardUpCallback (Callback <void, Ptr<Packet> > cb)
{
m_forwardUpCallback = cb;
}
void
LteEnbRrc::DoReceiveRrcPdu (LtePdcpSapUser::ReceiveRrcPduParameters params)
{
NS_LOG_FUNCTION (this);
// this tag is needed by the EpcEnbApplication to determine the S1 bearer that corresponds to this radio bearer
LteMacTag tag;
tag.SetRnti (params.rnti);
tag.SetLcid (params.lcid);
params.rrcPdu->AddPacketTag (tag);
m_forwardUpCallback (params.rrcPdu);
}
void
LteEnbRrc::DoNotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success)
{
@@ -411,7 +457,9 @@ LteEnbRrc::GetUeInfo (uint16_t rnti)
{
NS_LOG_FUNCTION (this << (uint32_t) rnti);
NS_ASSERT (0 != rnti);
return m_ueMap.find (rnti)->second;
std::map<uint16_t, Ptr<UeInfo> >::iterator it = m_ueMap.find (rnti);
NS_ABORT_IF (it == m_ueMap.end ());
return it->second;
}
void

View File

@@ -25,6 +25,7 @@
#include <ns3/packet.h>
#include <ns3/lte-enb-cmac-sap.h>
#include <ns3/ff-mac-common.h>
#include <ns3/lte-pdcp-sap.h>
#include <map>
@@ -32,7 +33,9 @@ namespace ns3 {
class FfMacSchedSapProvider;
class LteMacSapProvider;
class EnbRadioBearerInfo;
class LteRadioBearerInfo;
class LtePdcpSapUser;
class LtePdcpSapProvider;
/**
@@ -46,20 +49,20 @@ public:
/**
*
*
* \param EnbRadioBearerInfo
* \param radioBearerInfo
*
* \return the allocated logical channel id; 0 is returned if it is not possible to allocate a channel id (e.g., id space exausted).
*/
uint8_t AddRadioBearer (Ptr<EnbRadioBearerInfo> enbRadioBearerInfo);
uint8_t AddRadioBearer (Ptr<LteRadioBearerInfo> radioBearerInfo);
/**
*
*
* \param uint8_t the logical channel id
*
* \return the EnbRadioBearerInfo of the selected radio bearer
* \return the LteRadioBearerInfo of the selected radio bearer
*/
Ptr<EnbRadioBearerInfo> GetRadioBearer (uint8_t lcid);
Ptr<LteRadioBearerInfo> GetRadioBearer (uint8_t lcid);
/**
@@ -78,7 +81,7 @@ public:
uint64_t GetImsi (void);
private:
std::map <uint8_t, Ptr<EnbRadioBearerInfo> > m_rbMap;
std::map <uint8_t, Ptr<LteRadioBearerInfo> > m_rbMap;
uint8_t m_lastAllocatedId;
uint64_t m_imsi;
};
@@ -92,6 +95,7 @@ class LteEnbRrc : public Object
{
friend class EnbRrcMemberLteEnbCmacSapUser;
friend class LtePdcpSpecificLtePdcpSapUser<LteEnbRrc>;
public:
/**
@@ -119,7 +123,7 @@ public:
void SetLteEnbCmacSapProvider (LteEnbCmacSapProvider * s);
/**
* Get the CMAC SAP this RRC should interact with
* Get the CMAC SAP offered by this RRC
* \return s the CMAC SAP User interface offered to the MAC by this RRC
*/
LteEnbCmacSapUser* GetLteEnbCmacSapUser ();
@@ -145,6 +149,7 @@ public:
void SetLteMacSapProvider (LteMacSapProvider* s);
/**
* configure cell-specific parameters
*
@@ -179,10 +184,11 @@ public:
*
* \param rnti the RNTI of the user
* \param bearer the characteristics of the bearer to be activated
* \param rlcTypeId the TypeId identifying the type of RLC to be used for this bearer.
*
* \return the logical channel identifier of the radio bearer for the considered user
*/
uint8_t SetupRadioBearer (uint16_t rnti, EpsBearer bearer);
uint8_t SetupRadioBearer (uint16_t rnti, EpsBearer bearer, TypeId rlcTypeId);
/**
@@ -194,19 +200,45 @@ public:
*/
void ReleaseRadioBearer (uint16_t rnti, uint8_t lcId);
/**
* Enqueue an IP packet on the proper bearer for downlink transmission
*
* \param p the packet
*
* \return true if successful, false if an error occurred
*/
bool Send (Ptr<Packet> p);
/**
* set the callback used to forward data packets up the stack
*
* \param void
* \param cb
*/
void SetForwardUpCallback (Callback <void, Ptr<Packet> > cb);
private:
void DoReceiveRrcPdu (LtePdcpSapUser::ReceiveRrcPduParameters params);
void DoNotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success);
LtePdcpSapProvider* GetLtePdcpSapProvider (uint16_t rnti, uint8_t lcid);
// management of multiple UE info instances
uint16_t CreateUeInfo (uint64_t imsi);
Ptr<UeInfo> GetUeInfo (uint16_t rnti);
void RemoveUeInfo (uint16_t rnti);
Callback <void, Ptr<Packet> > m_forwardUpCallback;
LteEnbCmacSapUser* m_cmacSapUser;
LteEnbCmacSapProvider* m_cmacSapProvider;
FfMacSchedSapProvider* m_ffMacSchedSapProvider;
LteMacSapProvider* m_macSapProvider;
LtePdcpSapUser* m_pdcpSapUser;
bool m_configured;
uint16_t m_lastAllocatedRnti;

View File

@@ -68,6 +68,12 @@ LteMacTag::SetRnti (uint16_t rnti)
m_rnti = rnti;
}
void
LteMacTag::SetLcid (uint8_t lcid)
{
m_lcid = lcid;
}
uint32_t
LteMacTag::GetSerializedSize (void) const
{

View File

@@ -33,6 +33,7 @@
#include "lte-amc.h"
#include "ns3/ipv4-header.h"
#include <ns3/lte-mac-tag.h>
#include <ns3/ipv4-l3-protocol.h>
NS_LOG_COMPONENT_DEFINE ("LteNetDevice");
@@ -40,6 +41,9 @@ namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED ( LteNetDevice);
////////////////////////////////
// LteNetDevice
////////////////////////////////
TypeId LteNetDevice::GetTypeId (void)
{
@@ -129,49 +133,11 @@ LteNetDevice::SetReceiveCallback (ReceiveCallback cb)
}
void
LteNetDevice::ForwardUp (Ptr<Packet> packet, const Mac48Address &source, const Mac48Address &dest)
{
}
void
LteNetDevice::ForwardUp (Ptr<Packet> packet)
{
NS_LOG_FUNCTION (this << packet);
m_macRxTrace (packet);
LlcSnapHeader llc;
packet->RemoveHeader (llc);
m_rxCallback (this, packet, llc.GetType (), Address ());
}
bool
LteNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
{
NS_LOG_FUNCTION (packet << dest << protocolNumber);
return SendFrom (packet, m_address, dest, protocolNumber);
}
bool
LteNetDevice::SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
{
NS_LOG_FUNCTION (packet << source << dest << protocolNumber);
LlcSnapHeader llcHdr;
llcHdr.SetType (protocolNumber);
packet->AddHeader (llcHdr);
NS_FATAL_ERROR ("IP connectivity not implemented yet");
return true;
NS_FATAL_ERROR ("SendFrom () not supported");
return false;
}
@@ -183,15 +149,6 @@ LteNetDevice::SupportsSendFrom (void) const
}
void
LteNetDevice::Receive (Ptr<Packet> p)
{
NS_LOG_FUNCTION (this << p);
Ptr<Packet> packet = p->Copy ();
DoReceive (packet);
}
bool
LteNetDevice::SetMtu (const uint16_t mtu)
@@ -321,23 +278,17 @@ void
LteNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb)
{
NS_LOG_FUNCTION (this);
m_promiscRxCallback = cb;
NS_LOG_WARN ("Promisc mode not supported");
}
void
LteNetDevice::SetPacketToSend (Ptr<PacketBurst> p)
LteNetDevice::Receive (Ptr<Packet> p)
{
m_packetToSend = p;
NS_LOG_FUNCTION (this << p);
m_rxCallback (this, p, Ipv4L3Protocol::PROT_NUMBER, Address ());
}
Ptr<PacketBurst>
LteNetDevice::GetPacketToSend (void)
{
return m_packetToSend;
}
}

View File

@@ -35,8 +35,6 @@ namespace ns3 {
class Node;
class Packet;
class PacketBurst;
/**
* \defgroup lte LTE Models
@@ -80,66 +78,29 @@ public:
virtual Address GetMulticast (Ipv4Address addr) const;
virtual Address GetMulticast (Ipv6Address addr) const;
virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
virtual bool SupportsSendFrom (void) const;
/**
* \brief Receive the packet from the phy layer
* \param p the received packet
/**
* receive a packet from the lower layers in order to forward it to the upper layers
*
* \param p the packet
*/
void Receive (Ptr<Packet> p);
/**
* \brief Forward packet to the uppar layer.
* If is called by DoReceive method
* \param packet packet sent from Network Device to the upper layer
* \param source source mac address
* \param dest mac address of the destination
*/
void ForwardUp (Ptr<Packet> packet, const Mac48Address &source, const Mac48Address &dest);
/**
* \brief Forward packet to the uppar layer.
* If is called by DoReceive method
* \param packet packet sent from Network Device to the upper layer
*/
void ForwardUp (Ptr<Packet> packet);
/**
* \brief Set packets to send
* \param p the burst of packets to send
*/
void SetPacketToSend (Ptr<PacketBurst> p);
/**
* \brief Get packets to send
* \return the pointer to the burst of packets to send
*/
Ptr<PacketBurst> GetPacketToSend (void);
protected:
NetDevice::ReceiveCallback m_rxCallback;
private:
LteNetDevice (const LteNetDevice &);
LteNetDevice & operator= (const LteNetDevice &);
static const uint16_t MAX_MSDU_SIZE = 1500;
virtual bool DoSend (Ptr<Packet> packet,
const Mac48Address& source,
const Mac48Address& dest,
uint16_t protocolNumber) = 0;
virtual void DoReceive (Ptr<Packet> p) = 0;
Ptr<Node> m_node;
TracedCallback<Ptr<const Packet> > m_macTxTrace;
TracedCallback<Ptr<const Packet> > m_macTxDropTrace;
TracedCallback<Ptr<const Packet> > m_macPromiscRxTrace;
TracedCallback<Ptr<const Packet> > m_macRxTrace;
NetDevice::ReceiveCallback m_rxCallback;
NetDevice::PromiscReceiveCallback m_promiscRxCallback;
TracedCallback<> m_linkChangeCallbacks;
uint32_t m_ifIndex;
@@ -147,8 +108,6 @@ private:
mutable uint16_t m_mtu;
Mac48Address m_address;
Ptr<PacketBurst> m_packetToSend;
};

View File

@@ -50,7 +50,9 @@ public:
/**
* Send a RRC PDU to the RDCP for transmission
* This method is to be called
* when upper RRC entity has a RRC PDU ready to send
* when upper RRC entity has a RRC PDU ready to send
*
* \param params
*/
virtual void TransmitRrcPdu (TransmitRrcPduParameters params) = 0;
};
@@ -68,12 +70,22 @@ class LtePdcpSapUser
public:
virtual ~LtePdcpSapUser ();
/**
* Parameters for LtePdcpSapUser::ReceiveRrcPdu
*/
struct ReceiveRrcPduParameters
{
Ptr<Packet> rrcPdu; /**< the RRC PDU */
uint16_t rnti; /**< the C-RNTI identifying the UE */
uint8_t lcid; /**< the logical channel id corresponding to the sending RLC instance */
};
/**
* Called by the PDCP entity to notify the RRC entity of the reception of a new RRC PDU
*
* \param p the RRC PDU
* \param params
*/
virtual void ReceiveRrcPdu (Ptr<Packet> p) = 0;
virtual void ReceiveRrcPdu (ReceiveRrcPduParameters params) = 0;
};
///////////////////////////////////////
@@ -118,7 +130,7 @@ public:
LtePdcpSpecificLtePdcpSapUser (C* rrc);
// Interface implemented from LtePdcpSapUser
virtual void ReceiveRrcPdu (Ptr<Packet> p);
virtual void ReceiveRrcPdu (ReceiveRrcPduParameters params);
private:
LtePdcpSpecificLtePdcpSapUser ();
@@ -137,9 +149,9 @@ LtePdcpSpecificLtePdcpSapUser<C>::LtePdcpSpecificLtePdcpSapUser ()
}
template <class C>
void LtePdcpSpecificLtePdcpSapUser<C>::ReceiveRrcPdu (Ptr<Packet> p)
void LtePdcpSpecificLtePdcpSapUser<C>::ReceiveRrcPdu (ReceiveRrcPduParameters params)
{
m_rrc->DoReceiveRrcPdu (p);
m_rrc->DoReceiveRrcPdu (params);
}

View File

@@ -184,8 +184,11 @@ LtePdcp::DoReceivePdu (Ptr<Packet> p)
{
m_rxSequenceNumber = 0;
}
m_pdcpSapUser->ReceiveRrcPdu (p);
LtePdcpSapUser::ReceiveRrcPduParameters params;
params.rrcPdu = p;
params.rnti = m_rnti;
params.lcid = m_lcid;
m_pdcpSapUser->ReceiveRrcPdu (params);
}

View File

@@ -0,0 +1,64 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 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 "lte-radio-bearer-info.h"
#include "lte-ue-rrc.h"
#include "lte-rlc.h"
#include "lte-pdcp.h"
#include <ns3/log.h>
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (LteRadioBearerInfo);
LteRadioBearerInfo::LteRadioBearerInfo (void)
{
}
LteRadioBearerInfo::~LteRadioBearerInfo (void)
{
}
TypeId LteRadioBearerInfo::GetTypeId (void)
{
static TypeId
tid =
TypeId ("ns3::LteRadioBearerInfo")
.SetParent<Object> ()
.AddConstructor<LteRadioBearerInfo> ()
.AddAttribute ("LteRlc", "RLC instance of the radio bearer.",
PointerValue (),
MakePointerAccessor (&LteRadioBearerInfo::m_rlc),
MakePointerChecker<LteRlc> ())
.AddAttribute ("LtePdcp", "PDCP instance of the radio bearer.",
PointerValue (),
MakePointerAccessor (&LteRadioBearerInfo::m_pdcp),
MakePointerChecker<LtePdcp> ())
;
return tid;
}
} // namespace ns3

View File

@@ -0,0 +1,48 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 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/object.h>
#include <ns3/pointer.h>
namespace ns3 {
class LteRlc;
class LtePdcp;
/**
* store information on active radio bearer instance
*
*/
class LteRadioBearerInfo : public Object
{
public:
LteRadioBearerInfo (void);
virtual ~LteRadioBearerInfo (void);
static TypeId GetTypeId (void);
Ptr<LteRlc> m_rlc;
Ptr<LtePdcp> m_pdcp;
};
} // namespace ns3

View File

@@ -101,6 +101,8 @@ public:
// TODO MRE What is the sense to duplicate all the interfaces here???
// NB to avoid the use of multiple inheritance
protected:
// Interface forwarded by LteRlcSapProvider
virtual void DoTransmitPdcpPdu (Ptr<Packet> p) = 0;

View File

@@ -38,8 +38,8 @@
#include "ns3/ipv4-header.h"
#include "ns3/ipv4.h"
#include "lte-amc.h"
// #include "ideal-control-messages.h"
#include <ns3/lte-ue-phy.h>
#include <ns3/ipv4-l3-protocol.h>
NS_LOG_COMPONENT_DEFINE ("LteUeNetDevice");
@@ -176,33 +176,13 @@ LteUeNetDevice::DoStart (void)
m_rrc->Start ();
}
bool
LteUeNetDevice::DoSend (Ptr<Packet> packet, const Mac48Address& source,
const Mac48Address& dest, uint16_t protocolNumber)
LteUeNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
{
NS_LOG_FUNCTION (this);
NS_FATAL_ERROR ("IP connectivity not implemented yet");
return (true);
}
void
LteUeNetDevice::DoReceive (Ptr<Packet> p)
{
NS_LOG_FUNCTION (this << p);
NS_FATAL_ERROR ("IP connectivity not implemented yet");
Ptr<Packet> packet = p->Copy ();
LlcSnapHeader llcHdr;
packet->RemoveHeader (llcHdr);
NS_LOG_FUNCTION (this << llcHdr);
ForwardUp (packet);
NS_LOG_FUNCTION (this << dest << protocolNumber);
NS_ASSERT_MSG (protocolNumber == Ipv4L3Protocol::PROT_NUMBER, "unsupported protocol " << protocolNumber << ", only IPv4 is supported");
return m_rrc->Send (packet);
}

View File

@@ -49,6 +49,7 @@ class LteUeRrc;
*/
class LteUeNetDevice : public LteNetDevice
{
public:
static TypeId GetTypeId (void);
@@ -64,6 +65,10 @@ public:
virtual void DoDispose ();
// inherited from NetDevice
virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
Ptr<LteUeMac> GetMac (void);
Ptr<LteUeRrc> GetRrc ();
@@ -90,13 +95,15 @@ protected:
private:
bool DoSend (Ptr<Packet> packet,
const Mac48Address& source,
const Mac48Address& dest,
uint16_t protocolNumber);
void DoReceive (Ptr<Packet> p);
/**
* Some attributes are exported as
* attributes of the LteUeNetDevice from a user perspective, but
* are actually used also in other modules as well (the RRC, the
* PHY...). This methods takes care of updating the
* configuration of all modules so that their copy of the attribute
* values is in sync with the one in the LteUeNetDevice.
*/
void UpdateConfig (void);
Ptr<LteEnbNetDevice> m_targetEnb;
@@ -108,7 +115,7 @@ private:
uint64_t m_imsi;
static uint64_t m_imsiCounter;
};
} // namespace ns3

View File

@@ -21,9 +21,13 @@
#include <ns3/fatal-error.h>
#include <ns3/log.h>
#include "ns3/object-map.h"
#include "ns3/object-factory.h"
#include "lte-ue-rrc.h"
#include "lte-rlc.h"
#include "lte-pdcp.h"
#include "lte-pdcp-sap.h"
#include "lte-radio-bearer-info.h"
NS_LOG_COMPONENT_DEFINE ("LteUeRrc");
@@ -59,7 +63,29 @@ UeMemberLteUeCmacSapUser::LcConfigCompleted ()
}
////////////////////////////////
// PDCP SAP Forwarder
////////////////////////////////
// class UeRrcMemberLtePdcpSapUser : public LtePdcpSapUser
// {
// public:
// MemberLtePdcpSapUser (LteUeRrc* rrc);
// virtual void ReceiveRrcPdu (Ptr<Packet> p);
// private:
// LteUeRrc* m_rrc;EnbRrc
// };
// UeRrcMemberLtePdcpSapUser::UeRrcMemberLtePdcpSapUser (LteUeRrc* rrc)
// : m_rrc (rrc)
// {
// }
// void UeRrcMemberLtePdcpSapUser::ReceiveRrcPdu (Ptr<Packet> p)
// {
// m_rrc->DoReceiveRrcPdu (p);
// }
@@ -77,6 +103,7 @@ LteUeRrc::LteUeRrc ()
{
NS_LOG_FUNCTION (this);
m_cmacSapUser = new UeMemberLteUeCmacSapUser (this);
m_pdcpSapUser = new LtePdcpSpecificLtePdcpSapUser<LteUeRrc> (this);
}
@@ -90,7 +117,8 @@ LteUeRrc::DoDispose ()
{
NS_LOG_FUNCTION (this);
delete m_cmacSapUser;
m_rlcMap.clear ();
delete m_pdcpSapUser;
m_rbMap.clear ();
}
TypeId
@@ -99,10 +127,10 @@ LteUeRrc::GetTypeId (void)
static TypeId tid = TypeId ("ns3::LteUeRrc")
.SetParent<Object> ()
.AddConstructor<LteUeRrc> ()
.AddAttribute ("RlcMap", "List of UE RadioBearerInfo by LCID.",
.AddAttribute ("RadioBearerMap", "List of UE RadioBearerInfo by LCID.",
ObjectMapValue (),
MakeObjectMapAccessor (&LteUeRrc::m_rlcMap),
MakeObjectMapChecker<LteRlc> ())
MakeObjectMapAccessor (&LteUeRrc::m_rbMap),
MakeObjectMapChecker<LteRadioBearerInfo> ())
.AddAttribute ("CellId",
"Serving cell identifier",
UintegerValue (1),
@@ -150,21 +178,39 @@ LteUeRrc::ConfigureUe (uint16_t rnti, uint16_t cellId)
}
void
LteUeRrc::SetupRadioBearer (uint16_t rnti, EpsBearer bearer, uint8_t lcid)
LteUeRrc::SetupRadioBearer (uint16_t rnti, EpsBearer bearer, TypeId rlcTypeId, uint8_t lcid, Ptr<LteTft> tft)
{
NS_LOG_FUNCTION (this << (uint32_t) rnti << (uint32_t) lcid);
// create RLC instance
// for now we support RLC SM only
Ptr<LteRlc> rlc = CreateObject<LteRlcSm> ();
ObjectFactory rlcObjectFactory;
rlcObjectFactory.SetTypeId (rlcTypeId);
Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
rlc->SetLteMacSapProvider (m_macSapProvider);
rlc->SetRnti (rnti);
rlc->SetLcId (lcid);
std::map<uint8_t, Ptr<LteRlc> >::iterator it = m_rlcMap.find (lcid);
NS_ASSERT_MSG (it == m_rlcMap.end (), "bearer with same lcid already existing");
m_rlcMap.insert (std::pair<uint8_t, Ptr<LteRlc> > (lcid, rlc));
Ptr<LteRadioBearerInfo> rbInfo = CreateObject<LteRadioBearerInfo> ();
rbInfo->m_rlc = rlc;
// we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
// if we are using RLC/SM we don't care of anything above RLC
if (rlcTypeId != LteRlcSm::GetTypeId ())
{
Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
pdcp->SetRnti (rnti);
pdcp->SetLcId (lcid);
pdcp->SetLtePdcpSapUser (m_pdcpSapUser);
pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
rbInfo->m_pdcp = pdcp;
}
NS_ASSERT_MSG (m_rbMap.find (lcid) == m_rbMap.end (), "bearer with same lcid already existing");
m_rbMap.insert (std::pair<uint8_t, Ptr<LteRadioBearerInfo> > (lcid, rbInfo));
m_tftClassifier.Add (tft, lcid);
m_cmacSapProvider->AddLc (lcid, rlc->GetLteMacSapUser ());
}
@@ -172,11 +218,53 @@ void
LteUeRrc::ReleaseRadioBearer (uint16_t rnti, uint8_t lcid)
{
NS_LOG_FUNCTION (this << (uint32_t) rnti << (uint32_t) lcid);
std::map<uint8_t, Ptr<LteRlc> >::iterator it = m_rlcMap.find (lcid);
NS_ASSERT_MSG (it != m_rlcMap.end (), "could not find bearer with given lcid");
m_rlcMap.erase (it);
std::map<uint8_t, Ptr<LteRadioBearerInfo> >::iterator it = m_rbMap.find (lcid);
NS_ASSERT_MSG (it != m_rbMap.end (), "could not find bearer with given lcid");
m_rbMap.erase (it);
NS_FATAL_ERROR ("need to remove entry from TFT classifier, but this is not implemented yet");
}
bool
LteUeRrc::Send (Ptr<Packet> packet)
{
NS_LOG_FUNCTION (this << packet);
uint8_t lcid = m_tftClassifier.Classify (packet, LteTft::UPLINK);
LtePdcpSapProvider::TransmitRrcPduParameters params;
params.rrcPdu = packet;
params.rnti = m_rnti;
params.lcid = lcid;
std::map<uint8_t, Ptr<LteRadioBearerInfo> >::iterator it = m_rbMap.find (lcid);
if (it == m_rbMap.end ())
{
NS_LOG_WARN ("could not find bearer with lcid == " << lcid);
return false;
}
else
{
it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitRrcPdu (params);
return true;
}
}
void
LteUeRrc::SetForwardUpCallback (Callback <void, Ptr<Packet> > cb)
{
m_forwardUpCallback = cb;
}
void
LteUeRrc::DoReceiveRrcPdu (LtePdcpSapUser::ReceiveRrcPduParameters params)
{
NS_LOG_FUNCTION (this);
m_forwardUpCallback (params.rrcPdu);
}
void
LteUeRrc::DoLcConfigCompleted ()
{
@@ -202,7 +290,7 @@ std::vector<uint8_t>
LteUeRrc::GetLcIdVector ()
{
std::vector<uint8_t> v;
for (std::map<uint8_t, Ptr<LteRlc> >::iterator it = m_rlcMap.begin (); it != m_rlcMap.end (); ++it)
for (std::map<uint8_t, Ptr<LteRadioBearerInfo> >::iterator it = m_rbMap.begin (); it != m_rbMap.end (); ++it)
{
v.push_back (it->first);
}

View File

@@ -24,6 +24,8 @@
#include <ns3/object.h>
#include <ns3/packet.h>
#include <ns3/lte-ue-cmac-sap.h>
#include <ns3/eps-tft-classifier.h>
#include <ns3/lte-pdcp-sap.h>
#include <map>
@@ -33,7 +35,10 @@ class LteRlc;
class LteMacSapProvider;
class LteUeCmacSapUser;
class LteUeCmacSapProvider;
class UeInfo;
class LteRadioBearerInfo;
class LtePdcpSapUser;
class LtePdcpSapProvider;
/**
*
@@ -43,6 +48,8 @@ class LteUeRrc : public Object
{
friend class UeMemberLteUeCmacSapUser;
friend class UeRrcMemberLteEnbCmacSapUser;
friend class LtePdcpSpecificLtePdcpSapUser<LteUeRrc>;
public:
/**
@@ -100,10 +107,12 @@ public:
*
* \param rnti the RNTI of the user
* \param bearer the characteristics of the bearer to be activated
* \param rlcTypeId the TypeId identifying the type of RLC to be used for this bearer.
* \param lcid the logical channel id allocated for this bearer by the eNB
* \param tft the Traffic Flow Template identifying this bearer
*
*/
void SetupRadioBearer (uint16_t rnti, EpsBearer bearer, uint8_t lcid);
void SetupRadioBearer (uint16_t rnti, EpsBearer bearer, TypeId rlcTypeId, uint8_t lcid, Ptr<LteTft> tft);
/**
@@ -135,20 +144,46 @@ public:
*/
std::vector<uint8_t> GetLcIdVector ();
/**
* Enqueue an IP packet on the proper bearer for uplink transmission
*
* \param p the packet
*
* \return true if successful, false if an error occurred
*/
bool Send (Ptr<Packet> p);
/**
* set the callback used to forward data packets up the stack
*
* \param void
* \param cb
*/
void SetForwardUpCallback (Callback <void, Ptr<Packet> > cb);
private:
void DoReceiveRrcPdu (LtePdcpSapUser::ReceiveRrcPduParameters params);
// forwarded from CMAC SAP user
void DoLcConfigCompleted ();
Callback <void, Ptr<Packet> > m_forwardUpCallback;
LteUeCmacSapUser* m_cmacSapUser;
LteUeCmacSapProvider* m_cmacSapProvider;
LteMacSapProvider* m_macSapProvider;
LtePdcpSapUser* m_pdcpSapUser;
uint16_t m_rnti;
uint16_t m_cellId;
std::map<uint8_t, Ptr<LteRlc> > m_rlcMap;
std::map <uint8_t, Ptr<LteRadioBearerInfo> > m_rbMap;
EpsTftClassifier m_tftClassifier;
};

View File

@@ -90,9 +90,10 @@ LteTestRrc::GetDataReceived (void)
*/
void
LteTestRrc::DoReceiveRrcPdu (Ptr<Packet> p)
LteTestRrc::DoReceiveRrcPdu (LtePdcpSapUser::ReceiveRrcPduParameters params)
{
NS_LOG_FUNCTION (this);
Ptr<Packet> p = params.rrcPdu;
NS_LOG_LOGIC ("PDU received = " << (*p));
uint32_t dataLen = p->GetSize ();

View File

@@ -70,7 +70,7 @@ class LteTestRrc : public Object
private:
// Interface forwarded by LtePdcpSapUser
virtual void DoReceiveRrcPdu (Ptr<Packet> p);
virtual void DoReceiveRrcPdu (LtePdcpSapUser::ReceiveRrcPduParameters params);
LtePdcpSapUser* m_pdcpSapUser;
LtePdcpSapProvider* m_pdcpSapProvider;
@@ -119,7 +119,7 @@ class LteTestPdcp : public Object
private:
// Interface forwarded by LteRlcSapUser
virtual void DoReceivePdcpPdu (Ptr<Packet> p);
virtual void DoReceivePdcpPdu (Ptr<Packet> p);
LteRlcSapUser* m_rlcSapUser;
LteRlcSapProvider* m_rlcSapProvider;

View File

@@ -0,0 +1,267 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2011 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/simulator.h"
#include "ns3/log.h"
#include "ns3/test.h"
#include "ns3/lena-helper.h"
#include "ns3/epc-helper.h"
#include "ns3/packet-sink-helper.h"
#include "ns3/udp-client-server-helper.h"
#include "ns3/point-to-point-helper.h"
#include "ns3/internet-stack-helper.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/inet-socket-address.h"
#include "ns3/packet-sink.h"
#include <ns3/ipv4-static-routing-helper.h>
#include <ns3/ipv4-static-routing.h>
#include "ns3/boolean.h"
#include "ns3/uinteger.h"
#include "ns3/abort.h"
#include "ns3/mobility-helper.h"
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("LteEpcE2eData");
struct UeTestData
{
UeTestData (uint32_t n, uint32_t s);
uint32_t numPkts;
uint32_t pktSize;
EpsBearer epsBearer;
Ptr<PacketSink> serverApp;
Ptr<Application> clientApp;
};
UeTestData::UeTestData (uint32_t n, uint32_t s)
: numPkts (n),
pktSize (s),
epsBearer (EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT))
{
}
struct EnbTestData
{
std::vector<UeTestData> ues;
};
class LteEpcE2eDataTestCase : public TestCase
{
public:
LteEpcE2eDataTestCase (std::string name, std::vector<EnbTestData> v);
virtual ~LteEpcE2eDataTestCase ();
private:
virtual void DoRun (void);
std::vector<EnbTestData> m_enbTestData;
};
LteEpcE2eDataTestCase::LteEpcE2eDataTestCase (std::string name, std::vector<EnbTestData> v)
: TestCase (name),
m_enbTestData (v)
{
}
LteEpcE2eDataTestCase::~LteEpcE2eDataTestCase ()
{
}
void
LteEpcE2eDataTestCase::DoRun ()
{
Ptr<LenaHelper> lteHelper = CreateObject<LenaHelper> ();
Ptr<EpcHelper> epcHelper = CreateObject<EpcHelper> ();
lteHelper->SetEpcHelper (epcHelper);
Ptr<Node> pgw = epcHelper->GetPgwNode ();
// Create a single RemoteHost
NodeContainer remoteHostContainer;
remoteHostContainer.Create (1);
Ptr<Node> remoteHost = remoteHostContainer.Get (0);
InternetStackHelper internet;
internet.Install (remoteHostContainer);
// Create the internet
PointToPointHelper p2ph;
NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
Ipv4AddressHelper ipv4h;
ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
ipv4h.Assign (internetDevices);
// setup default gateway for the remote hosts
Ipv4StaticRoutingHelper ipv4RoutingHelper;
Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
// hardcoded UE addresses for now
remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.255.255.0"), 1);
NodeContainer enbs;
enbs.Create (m_enbTestData.size ());
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (enbs);
NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice (enbs);
NetDeviceContainer::Iterator enbLteDevIt = enbLteDevs.Begin ();
for (std::vector<EnbTestData>::iterator enbit = m_enbTestData.begin ();
enbit < m_enbTestData.end ();
++enbit, ++enbLteDevIt)
{
NS_ABORT_IF (enbLteDevIt == enbLteDevs.End ());
NodeContainer ues;
ues.Create (enbit->ues.size ());
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (ues);
NetDeviceContainer ueLteDevs = lteHelper->InstallUeDevice (ues);
lteHelper->Attach (ueLteDevs, *enbLteDevIt);
// we install the IP stack on the UEs
InternetStackHelper internet;
internet.Install (ues);
// assign IP address to UEs, and install applications
for (uint32_t u = 0; u < ues.GetN (); ++u)
{
Ptr<NetDevice> ueLteDevice = ueLteDevs.Get (u);
Ipv4InterfaceContainer ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueLteDevice));
Ptr<Node> ue = ues.Get (u);
uint16_t port = 1234;
PacketSinkHelper packetSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
ApplicationContainer apps = packetSinkHelper.Install (ue);
apps.Start (Seconds (0.1));
apps.Stop (Seconds (10.0));
enbit->ues[u].serverApp = apps.Get (0)->GetObject<PacketSink> ();
Time interPacketInterval = Seconds (0.01);
UdpClientHelper client (ueIpIface.GetAddress (0), port);
client.SetAttribute ("MaxPackets", UintegerValue (enbit->ues[u].numPkts));
client.SetAttribute ("Interval", TimeValue (interPacketInterval));
client.SetAttribute ("PacketSize", UintegerValue (enbit->ues[u].pktSize));
apps = client.Install (remoteHost);
apps.Start (Seconds (0.1));
apps.Stop (Seconds (10.0));
enbit->ues[u].clientApp = apps.Get (0);
lteHelper->ActivateEpsBearer (ueLteDevice, enbit->ues[u].epsBearer, LteTft::Default ());
}
}
Simulator::Stop (Seconds (3.0));
Simulator::Run ();
for (std::vector<EnbTestData>::iterator enbit = m_enbTestData.begin ();
enbit < m_enbTestData.end ();
++enbit)
{
for (std::vector<UeTestData>::iterator ueit = enbit->ues.begin ();
ueit < enbit->ues.end ();
++ueit)
{
NS_TEST_ASSERT_MSG_EQ (ueit->serverApp->GetTotalRx (), (ueit->numPkts) * (ueit->pktSize), "wrong total received bytes");
}
}
Simulator::Destroy ();
}
/**
* Test that the S1-U interface implementation works correctly
*/
class LteEpcE2eDataTestSuite : public TestSuite
{
public:
LteEpcE2eDataTestSuite ();
} g_lteEpcE2eDataTestSuite;
LteEpcE2eDataTestSuite::LteEpcE2eDataTestSuite ()
: TestSuite ("lte-epc-e2e-data", SYSTEM)
{
std::vector<EnbTestData> v1;
EnbTestData e1;
UeTestData f1 (1, 100);
e1.ues.push_back (f1);
v1.push_back (e1);
AddTestCase (new LteEpcE2eDataTestCase ("1 eNB, 1UE", v1));
std::vector<EnbTestData> v2;
EnbTestData e2;
UeTestData f2_1 (1, 100);
e2.ues.push_back (f2_1);
UeTestData f2_2 (2, 200);
e2.ues.push_back (f2_2);
v2.push_back (e2);
AddTestCase (new LteEpcE2eDataTestCase ("1 eNB, 2UEs", v2));
std::vector<EnbTestData> v3;
v3.push_back (e1);
v3.push_back (e2);
AddTestCase (new LteEpcE2eDataTestCase ("2 eNBs", v3));
EnbTestData e3;
UeTestData f3_1 (3, 50);
e3.ues.push_back (f3_1);
UeTestData f3_2 (5, 1472);
e3.ues.push_back (f3_2);
UeTestData f3_3 (1, 1);
e3.ues.push_back (f3_2);
std::vector<EnbTestData> v4;
v4.push_back (e3);
v4.push_back (e1);
v4.push_back (e2);
AddTestCase (new LteEpcE2eDataTestCase ("3 eNBs with big packet", v4));
}
} // namespace ns3

View File

@@ -30,6 +30,7 @@ def build(bld):
'model/lte-pdcp.cc',
'model/lte-pdcp-header.cc',
'model/eps-bearer.cc',
'model/lte-radio-bearer-info.cc',
'model/lte-net-device.cc',
'model/lte-enb-net-device.cc',
'model/lte-ue-net-device.cc',
@@ -82,6 +83,7 @@ def build(bld):
'test/test-eps-tft-classifier.cc',
'test/epc-test-s1u-downlink.cc',
'test/epc-test-s1u-uplink.cc',
'test/test-lte-epc-e2e-data.cc',
]
headers = bld.new_task_gen('ns3header')
@@ -113,6 +115,7 @@ def build(bld):
'model/lte-pdcp.h',
'model/lte-pdcp-header.h',
'model/eps-bearer.h',
'model/lte-radio-bearer-info.h',
'model/lte-net-device.h',
'model/lte-enb-net-device.h',
'model/lte-ue-net-device.h',