LTE-EPC end-to-end data plane imlemented and partially working
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
64
src/lte/model/lte-radio-bearer-info.cc
Normal file
64
src/lte/model/lte-radio-bearer-info.cc
Normal 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
|
||||
48
src/lte/model/lte-radio-bearer-info.h
Normal file
48
src/lte/model/lte-radio-bearer-info.h
Normal 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
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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;
|
||||
|
||||
267
src/lte/test/test-lte-epc-e2e-data.cc
Normal file
267
src/lte/test/test-lte-epc-e2e-data.cc
Normal 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
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user