lte: merge branch 'lte-nr-prereq-v2' (MR !31)

* lte-nr-prereq-v2:
  spectrum: Add API to retrieve Values size and a single value at any position
  lte: Managing SR at SAP interface level.
  lte: Making SimpleUeComponentCarrierManager inheritable
  lte: Do not assume that the helper is setting all the vectors
  lte: ComponentCarrier subclasses can override Set{Dl,Ul}Bandwidth
  lte: ComponentCarrier with cellId is now ComponentCarrierBaseStation
  lte: LteMacSap constructors for ReceivePduParameters and TxOpportunityParameters created
  lte: (fixed #2893) GetPgw in helpers must be const
  lte: EpsBearer support run-time switching between Rel. 11 and Rel. 15
  lte: Added EpsBearer new values (updating it to Rel. 15)
  lte: EpsBearer uses a lookup table
This commit is contained in:
Natale Patriciello
2019-03-07 22:01:51 +01:00
25 changed files with 674 additions and 234 deletions

View File

@@ -54,6 +54,7 @@ us a note on ns-developers mailing list.</p>
<h1>Changes from ns-3.29 to ns-3.30</h1>
<h2>New API:</h2>
<ul>
<li>Added the attribute <b>Release</b> to the class <b>EpsBearer</b>, to select the release (e.g., release 15)</li>
<li>The attributes <b>RegularWifiMac::HtSupported</b>, <b>RegularWifiMac::VhtSupported</b>, <b>RegularWifiMac::HeSupported</b>, <b>RegularWifiMac::RifsSupported</b>, <b>WifiPhy::ShortGuardEnabled</b>, <b>WifiPhy::GuardInterval</b> and <b>WifiPhy::GreenfieldEnabled</b> have been deprecated. Intead, it is advised to use <b>WifiNetDevice::HtConfiguration</b>, <b>WifiNetDevice::VhtConfiguration</b> and <b>WifiNetDevice::HeConfiguration</b>.</li>
<li>A new attribute <b>WifiPhy::PostReceptionErrorModel</b> has been added to force specific packet drops.</li>
<li>A new attribute <b>WifiPhy::PreambleDetectionModel</b> has been added to decide whether PHY preambles are successfully detected.</li>
@@ -75,6 +76,10 @@ us a note on ns-developers mailing list.</p>
The WifiPhy attribute "CcaMode1Threshold" has been renamed to "CcaEdThreshold",
and the WifiPhy attribute "EnergyDetectionThreshold" has been replaced by a new attribute called "RxSensitivity"
</li>
<li>
It is now possible to know the size of the SpectrumValue underlying std::vector, as well as
accessing read-only every element of it.
</li>
</ul>
<h2>Changes to build system:</h2>
<ul>

View File

@@ -32,6 +32,7 @@ Bugs fixed
- Bug 2992 - lte: Send method of the LteUeNetDevice doesn't use protocolNumber parameter
- Bug 2997 - lte: EpcTft::PacketFilter::Matches does not use ipv6 address to match an IP packet
- Bug 2860 - mobility: Set Z coordinate for position-allocation classes
- Bug 2893 - lte: GetPgw in helper should be const
- Bug 3027 - lte: S1 signalling is done before RRC connection establishment is finished
Known issues

View File

@@ -402,7 +402,7 @@ EmuEpcHelper::ActivateEpsBearer (Ptr<NetDevice> ueDevice, uint64_t imsi, Ptr<Epc
Ptr<Node>
EmuEpcHelper::GetPgwNode ()
EmuEpcHelper::GetPgwNode () const
{
return m_sgwPgw;
}

View File

@@ -80,7 +80,7 @@ public:
virtual void AddUe (Ptr<NetDevice> ueLteDevice, uint64_t imsi);
virtual void AddX2Interface (Ptr<Node> enbNode1, Ptr<Node> enbNode2);
virtual uint8_t ActivateEpsBearer (Ptr<NetDevice> ueLteDevice, uint64_t imsi, Ptr<EpcTft> tft, EpsBearer bearer);
virtual Ptr<Node> GetPgwNode ();
virtual Ptr<Node> GetPgwNode () const;
virtual Ipv4InterfaceContainer AssignUeIpv4Address (NetDeviceContainer ueDevices);
virtual Ipv6InterfaceContainer AssignUeIpv6Address (NetDeviceContainer ueDevices);
virtual Ipv4Address GetUeDefaultGatewayAddress ();

View File

@@ -120,7 +120,7 @@ public:
* intended for this method is to allow the user to configure the Gi
* interface of the PGW, i.e., to connect the PGW to the internet.
*/
virtual Ptr<Node> GetPgwNode () = 0;
virtual Ptr<Node> GetPgwNode () const = 0;
/**
* Assign IPv4 addresses to UE devices

View File

@@ -518,7 +518,7 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
m_noOfCcs << ")");
// create component carrier map for this eNb device
std::map<uint8_t,Ptr<ComponentCarrierEnb> > ccMap;
std::map<uint8_t,Ptr<ComponentCarrierBaseStation> > ccMap;
for (std::map<uint8_t, ComponentCarrier >::iterator it = m_componentCarrierPhyParams.begin ();
it != m_componentCarrierPhyParams.end ();
++it)
@@ -539,7 +539,7 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
NS_ABORT_MSG_IF (m_useCa && ccMap.size()<2, "You have to either specify carriers or disable carrier aggregation");
NS_ASSERT (ccMap.size () == m_noOfCcs);
for (std::map<uint8_t,Ptr<ComponentCarrierEnb> >::iterator it = ccMap.begin (); it != ccMap.end (); ++it)
for (auto it = ccMap.begin (); it != ccMap.end (); ++it)
{
NS_LOG_DEBUG (this << "component carrier map size " << (uint16_t) ccMap.size ());
Ptr<LteSpectrumPhy> dlPhy = CreateObject<LteSpectrumPhy> ();
@@ -580,12 +580,10 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
Ptr<LteEnbMac> mac = CreateObject<LteEnbMac> ();
Ptr<FfMacScheduler> sched = m_schedulerFactory.Create<FfMacScheduler> ();
Ptr<LteFfrAlgorithm> ffrAlgorithm = m_ffrAlgorithmFactory.Create<LteFfrAlgorithm> ();
it->second->SetMac (mac);
it->second->SetFfMacScheduler (sched);
it->second->SetFfrAlgorithm (ffrAlgorithm);
it->second->SetPhy (phy);
DynamicCast<ComponentCarrierEnb> (it->second)->SetMac (mac);
DynamicCast<ComponentCarrierEnb> (it->second)->SetFfMacScheduler (sched);
DynamicCast<ComponentCarrierEnb> (it->second)->SetFfrAlgorithm (ffrAlgorithm);
DynamicCast<ComponentCarrierEnb> (it->second)->SetPhy (phy);
}
Ptr<LteEnbRrc> rrc = CreateObject<LteEnbRrc> ();
@@ -642,41 +640,41 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
rrc->SetLteMacSapProvider (ccmEnbManager->GetLteMacSapProvider ());
bool ccmTest;
for (std::map<uint8_t,Ptr<ComponentCarrierEnb> >::iterator it = ccMap.begin (); it != ccMap.end (); ++it)
for (auto it = ccMap.begin (); it != ccMap.end (); ++it)
{
it->second->GetPhy ()->SetLteEnbCphySapUser (rrc->GetLteEnbCphySapUser (it->first));
rrc->SetLteEnbCphySapProvider (it->second->GetPhy ()->GetLteEnbCphySapProvider (), it->first);
DynamicCast<ComponentCarrierEnb> (it->second)->GetPhy ()->SetLteEnbCphySapUser (rrc->GetLteEnbCphySapUser (it->first));
rrc->SetLteEnbCphySapProvider (DynamicCast<ComponentCarrierEnb> (it->second)->GetPhy ()->GetLteEnbCphySapProvider (), it->first);
rrc->SetLteEnbCmacSapProvider (it->second->GetMac ()->GetLteEnbCmacSapProvider (),it->first );
it->second->GetMac ()->SetLteEnbCmacSapUser (rrc->GetLteEnbCmacSapUser (it->first));
rrc->SetLteEnbCmacSapProvider (DynamicCast<ComponentCarrierEnb> (it->second)->GetMac ()->GetLteEnbCmacSapProvider (),it->first );
DynamicCast<ComponentCarrierEnb> (it->second)->GetMac ()->SetLteEnbCmacSapUser (rrc->GetLteEnbCmacSapUser (it->first));
it->second->GetPhy ()->SetComponentCarrierId (it->first);
it->second->GetMac ()->SetComponentCarrierId (it->first);
DynamicCast<ComponentCarrierEnb> (it->second)->GetPhy ()->SetComponentCarrierId (it->first);
DynamicCast<ComponentCarrierEnb> (it->second)->GetMac ()->SetComponentCarrierId (it->first);
//FFR SAP
it->second->GetFfMacScheduler ()->SetLteFfrSapProvider (it->second->GetFfrAlgorithm ()->GetLteFfrSapProvider ());
it->second->GetFfrAlgorithm ()->SetLteFfrSapUser (it->second->GetFfMacScheduler ()->GetLteFfrSapUser ());
rrc->SetLteFfrRrcSapProvider (it->second->GetFfrAlgorithm ()->GetLteFfrRrcSapProvider (), it->first);
it->second->GetFfrAlgorithm ()->SetLteFfrRrcSapUser (rrc->GetLteFfrRrcSapUser (it->first));
DynamicCast<ComponentCarrierEnb> (it->second)->GetFfMacScheduler ()->SetLteFfrSapProvider (DynamicCast<ComponentCarrierEnb> (it->second)->GetFfrAlgorithm ()->GetLteFfrSapProvider ());
DynamicCast<ComponentCarrierEnb> (it->second)->GetFfrAlgorithm ()->SetLteFfrSapUser (DynamicCast<ComponentCarrierEnb> (it->second)->GetFfMacScheduler ()->GetLteFfrSapUser ());
rrc->SetLteFfrRrcSapProvider (DynamicCast<ComponentCarrierEnb> (it->second)->GetFfrAlgorithm ()->GetLteFfrRrcSapProvider (), it->first);
DynamicCast<ComponentCarrierEnb> (it->second)->GetFfrAlgorithm ()->SetLteFfrRrcSapUser (rrc->GetLteFfrRrcSapUser (it->first));
//FFR SAP END
// PHY <--> MAC SAP
it->second->GetPhy ()->SetLteEnbPhySapUser (it->second->GetMac ()->GetLteEnbPhySapUser ());
it->second->GetMac ()->SetLteEnbPhySapProvider (it->second->GetPhy ()->GetLteEnbPhySapProvider ());
DynamicCast<ComponentCarrierEnb> (it->second)->GetPhy ()->SetLteEnbPhySapUser (DynamicCast<ComponentCarrierEnb> (it->second)->GetMac ()->GetLteEnbPhySapUser ());
DynamicCast<ComponentCarrierEnb> (it->second)->GetMac ()->SetLteEnbPhySapProvider (DynamicCast<ComponentCarrierEnb> (it->second)->GetPhy ()->GetLteEnbPhySapProvider ());
// PHY <--> MAC SAP END
//Scheduler SAP
it->second->GetMac ()->SetFfMacSchedSapProvider (it->second->GetFfMacScheduler ()->GetFfMacSchedSapProvider ());
it->second->GetMac ()->SetFfMacCschedSapProvider (it->second->GetFfMacScheduler ()->GetFfMacCschedSapProvider ());
DynamicCast<ComponentCarrierEnb> (it->second)->GetMac ()->SetFfMacSchedSapProvider (DynamicCast<ComponentCarrierEnb> (it->second)->GetFfMacScheduler ()->GetFfMacSchedSapProvider ());
DynamicCast<ComponentCarrierEnb> (it->second)->GetMac ()->SetFfMacCschedSapProvider (DynamicCast<ComponentCarrierEnb> (it->second)->GetFfMacScheduler ()->GetFfMacCschedSapProvider ());
it->second->GetFfMacScheduler ()->SetFfMacSchedSapUser (it->second->GetMac ()->GetFfMacSchedSapUser ());
it->second->GetFfMacScheduler ()->SetFfMacCschedSapUser (it->second->GetMac ()->GetFfMacCschedSapUser ());
DynamicCast<ComponentCarrierEnb> (it->second)->GetFfMacScheduler ()->SetFfMacSchedSapUser (DynamicCast<ComponentCarrierEnb> (it->second)->GetMac ()->GetFfMacSchedSapUser ());
DynamicCast<ComponentCarrierEnb> (it->second)->GetFfMacScheduler ()->SetFfMacCschedSapUser (DynamicCast<ComponentCarrierEnb> (it->second)->GetMac ()->GetFfMacCschedSapUser ());
// Scheduler SAP END
it->second->GetMac ()->SetLteCcmMacSapUser (ccmEnbManager->GetLteCcmMacSapUser ());
ccmEnbManager->SetCcmMacSapProviders (it->first, it->second->GetMac ()->GetLteCcmMacSapProvider ());
DynamicCast<ComponentCarrierEnb> (it->second)->GetMac ()->SetLteCcmMacSapUser (ccmEnbManager->GetLteCcmMacSapUser ());
ccmEnbManager->SetCcmMacSapProviders (it->first, DynamicCast<ComponentCarrierEnb> (it->second)->GetMac ()->GetLteCcmMacSapProvider ());
// insert the pointer to the LteMacSapProvider interface of the MAC layer of the specific component carrier
ccmTest = ccmEnbManager->SetMacSapProvider (it->first, it->second->GetMac ()->GetLteMacSapProvider());
ccmTest = ccmEnbManager->SetMacSapProvider (it->first, DynamicCast<ComponentCarrierEnb> (it->second)->GetMac ()->GetLteMacSapProvider());
if (ccmTest == false)
{
@@ -690,10 +688,10 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
dev->SetAttribute ("CellId", UintegerValue (cellId));
dev->SetAttribute ("LteEnbComponentCarrierManager", PointerValue (ccmEnbManager));
dev->SetCcMap (ccMap);
std::map<uint8_t,Ptr<ComponentCarrierEnb> >::iterator it = ccMap.begin ();
std::map<uint8_t,Ptr<ComponentCarrierBaseStation> >::iterator it = ccMap.begin ();
dev->SetAttribute ("LteEnbRrc", PointerValue (rrc));
dev->SetAttribute ("LteHandoverAlgorithm", PointerValue (handoverAlgorithm));
dev->SetAttribute ("LteFfrAlgorithm", PointerValue (it->second->GetFfrAlgorithm ()));
dev->SetAttribute ("LteFfrAlgorithm", PointerValue (DynamicCast<ComponentCarrierEnb> (it->second)->GetFfrAlgorithm ()));
if (m_isAnrEnabled)
{
@@ -705,7 +703,7 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
for (it = ccMap.begin (); it != ccMap.end (); ++it)
{
Ptr<LteEnbPhy> ccPhy = it->second->GetPhy ();
Ptr<LteEnbPhy> ccPhy = DynamicCast<ComponentCarrierEnb> (it->second)->GetPhy ();
ccPhy->SetDevice (dev);
ccPhy->GetUlSpectrumPhy ()->SetDevice (dev);
ccPhy->GetDlSpectrumPhy ()->SetDevice (dev);
@@ -736,7 +734,7 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
for (it = ccMap.begin (); it != ccMap.end (); ++it)
{
m_uplinkChannel->AddRx (it->second->GetPhy ()->GetUlSpectrumPhy ());
m_uplinkChannel->AddRx (DynamicCast<ComponentCarrierEnb>(it->second)->GetPhy ()->GetUlSpectrumPhy ());
}
if (m_epcHelper != 0)
@@ -1459,11 +1457,11 @@ LteHelper::AssignStreams (NetDeviceContainer c, int64_t stream)
Ptr<LteEnbNetDevice> lteEnb = DynamicCast<LteEnbNetDevice> (netDevice);
if (lteEnb)
{
std::map< uint8_t, Ptr <ComponentCarrierEnb> > tmpMap = lteEnb->GetCcMap ();
std::map< uint8_t, Ptr <ComponentCarrierEnb> >::iterator it;
std::map< uint8_t, Ptr <ComponentCarrierBaseStation> > tmpMap = lteEnb->GetCcMap ();
std::map< uint8_t, Ptr <ComponentCarrierBaseStation> >::iterator it;
it = tmpMap.begin ();
Ptr<LteSpectrumPhy> dlPhy = it->second->GetPhy ()->GetDownlinkSpectrumPhy ();
Ptr<LteSpectrumPhy> ulPhy = it->second->GetPhy ()->GetUplinkSpectrumPhy ();
Ptr<LteSpectrumPhy> dlPhy = DynamicCast<ComponentCarrierEnb> (it->second)->GetPhy ()->GetDownlinkSpectrumPhy ();
Ptr<LteSpectrumPhy> ulPhy = DynamicCast<ComponentCarrierEnb> (it->second)->GetPhy ()->GetUplinkSpectrumPhy ();
currentStream += dlPhy->AssignStreams (currentStream);
currentStream += ulPhy->AssignStreams (currentStream);
}

View File

@@ -546,7 +546,7 @@ PointToPointEpcHelper::ActivateEpsBearer (Ptr<NetDevice> ueDevice, uint64_t imsi
}
Ptr<Node>
PointToPointEpcHelper::GetPgwNode ()
PointToPointEpcHelper::GetPgwNode () const
{
return m_pgw;
}

View File

@@ -77,7 +77,7 @@ public:
virtual void AddUe (Ptr<NetDevice> ueLteDevice, uint64_t imsi);
virtual void AddX2Interface (Ptr<Node> enbNode1, Ptr<Node> enbNode2);
virtual uint8_t ActivateEpsBearer (Ptr<NetDevice> ueLteDevice, uint64_t imsi, Ptr<EpcTft> tft, EpsBearer bearer);
virtual Ptr<Node> GetPgwNode ();
virtual Ptr<Node> GetPgwNode () const;
virtual Ipv4InterfaceContainer AssignUeIpv4Address (NetDeviceContainer ueDevices);
virtual Ipv6InterfaceContainer AssignUeIpv6Address (NetDeviceContainer ueDevices);
virtual Ipv4Address GetUeDefaultGatewayAddress ();

View File

@@ -116,12 +116,6 @@ ComponentCarrierEnb::DoInitialize (void)
}
uint16_t
ComponentCarrierEnb::GetCellId ()
{
return m_cellId;
}
Ptr<LteEnbPhy>
ComponentCarrierEnb::GetPhy ()
{
@@ -129,12 +123,6 @@ ComponentCarrierEnb::GetPhy ()
return m_phy;
}
void
ComponentCarrierEnb::SetCellId (uint16_t cellId)
{
NS_LOG_FUNCTION (this << cellId);
m_cellId = cellId;
}
void
ComponentCarrierEnb::SetPhy (Ptr<LteEnbPhy> s)
@@ -184,6 +172,40 @@ ComponentCarrierEnb::SetFfMacScheduler (Ptr<FfMacScheduler> s)
m_scheduler = s;
}
TypeId ComponentCarrierBaseStation::GetTypeId (void)
{
static TypeId
tid =
TypeId ("ns3::ComponentCarrierBaseStation")
.SetParent<ComponentCarrier> ()
.AddConstructor<ComponentCarrierBaseStation> ()
;
return tid;
}
ComponentCarrierBaseStation::ComponentCarrierBaseStation ()
{
NS_LOG_FUNCTION (this);
}
ComponentCarrierBaseStation::~ComponentCarrierBaseStation (void)
{
NS_LOG_FUNCTION (this);
}
uint16_t
ComponentCarrierBaseStation::GetCellId ()
{
return m_cellId;
}
void
ComponentCarrierBaseStation::SetCellId (uint16_t cellId)
{
NS_LOG_FUNCTION (this << cellId);
m_cellId = cellId;
}
} // namespace ns3

View File

@@ -45,7 +45,7 @@ class LteFfrAlgorithm;
* LteEnbMac, LteFfrAlgorithm, and FfMacScheduler objects.
*
*/
class ComponentCarrierEnb : public ComponentCarrier
class ComponentCarrierEnb : public ComponentCarrierBaseStation
{
public:
/**
@@ -59,12 +59,6 @@ public:
virtual ~ComponentCarrierEnb (void);
virtual void DoDispose (void);
/**
* Get cell identifier
* \return cell identifier
*/
uint16_t GetCellId ();
/**
* \return a pointer to the physical layer.
*/
@@ -85,12 +79,6 @@ public:
*/
Ptr<FfMacScheduler> GetFfMacScheduler ();
/**
* Set physical cell identifier
* \param cellId cell identifier
*/
void SetCellId (uint16_t cellId);
/**
* Set the LteEnbPhy
* \param s a pointer to the LteEnbPhy
@@ -119,18 +107,12 @@ protected:
virtual void DoInitialize (void);
private:
uint16_t m_cellId; ///< Cell identifier
Ptr<LteEnbPhy> m_phy; ///< the Phy instance of this eNodeB component carrier
Ptr<LteEnbMac> m_mac; ///< the MAC instance of this eNodeB component carrier
Ptr<FfMacScheduler> m_scheduler; ///< the scheduler instance of this eNodeB component carrier
Ptr<LteFfrAlgorithm> m_ffrAlgorithm; ///< the FFR algorithm instance of this eNodeB component carrier
};
} // namespace ns3
#endif /* COMPONENT_CARRIER_H */

View File

@@ -35,12 +35,11 @@ namespace ns3 {
* \ingroup lte
*
* ComponentCarrier Object, it defines a single Carrier
* This is the parent class for both ComponentCarrierEnb
* This is the parent class for both ComponentCarrierBaseStation
* and ComponentCarrierUe.
* This class contains the main physical configuration
* parameters for a carrier. Does not contain pointers to
* the MAC/PHY objects of the carrier.
*/
class ComponentCarrier : public Object
{
@@ -64,7 +63,7 @@ public:
/**
* \param bw the uplink bandwidth in RBs
*/
void SetUlBandwidth (uint8_t bw);
virtual void SetUlBandwidth (uint8_t bw);
/**
* \return the downlink bandwidth in RBs
@@ -74,7 +73,7 @@ public:
/**
* \param bw the downlink bandwidth in RBs
*/
void SetDlBandwidth (uint8_t bw);
virtual void SetDlBandwidth (uint8_t bw);
/**
* \return the downlink carrier frequency (EARFCN)
@@ -172,7 +171,40 @@ protected:
};
/**
* \ingroup lte
*
* Defines a Base station, that is a ComponentCarrier but with a cell Id.
*
*/
class ComponentCarrierBaseStation : public ComponentCarrier
{
public:
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId (void);
ComponentCarrierBaseStation ();
virtual ~ComponentCarrierBaseStation (void);
/**
* Get cell identifier
* \return cell identifier
*/
uint16_t GetCellId ();
/**
* Set physical cell identifier
* \param cellId cell identifier
*/
void SetCellId (uint16_t cellId);
protected:
uint16_t m_cellId; ///< Cell identifier
};
} // namespace ns3

View File

@@ -18,14 +18,13 @@
* Author: Nicola Baldo <nbaldo@cttc.es>
*/
#include "eps-bearer.h"
#include <ns3/fatal-error.h>
#include <ns3/attribute-construction-list.h>
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (EpsBearer);
GbrQosInformation::GbrQosInformation ()
: gbrDl (0),
@@ -42,134 +41,166 @@ AllocationRetentionPriority::AllocationRetentionPriority ()
{
}
EpsBearer::EpsBearer ()
: qci (NGBR_VIDEO_TCP_DEFAULT)
TypeId
EpsBearer::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::EpsBearer")
.SetParent<ObjectBase> ()
.SetGroupName("Lte")
.AddConstructor<EpsBearer> ()
.AddAttribute ("Release", "Change from 11 to 15 if you need bearer definition as per Release 15."
" Reference document: TS 23.203. The change does not impact other LTE code than "
" bearers definition.",
UintegerValue (11),
MakeUintegerAccessor (&EpsBearer::GetRelease,
&EpsBearer::SetRelease),
MakeUintegerChecker<uint32_t> ())
;
return tid;
}
TypeId
EpsBearer::GetInstanceTypeId () const
{
return EpsBearer::GetTypeId ();
}
EpsBearer::EpsBearer ()
: ObjectBase (),
qci (NGBR_VIDEO_TCP_DEFAULT)
{
ObjectBase::ConstructSelf (AttributeConstructionList ());
}
EpsBearer::EpsBearer (Qci x)
: qci (x)
: ObjectBase (),
qci (x)
{
ObjectBase::ConstructSelf (AttributeConstructionList ());
}
EpsBearer::EpsBearer (Qci x, struct GbrQosInformation y)
: qci (x), gbrQosInfo (y)
: ObjectBase (),
qci (x), gbrQosInfo (y)
{
ObjectBase::ConstructSelf (AttributeConstructionList ());
}
EpsBearer::EpsBearer (const EpsBearer &o) : ObjectBase (o)
{
qci = o.qci;
gbrQosInfo = o.gbrQosInfo;
ObjectBase::ConstructSelf (AttributeConstructionList ());
}
void
EpsBearer::SetRelease(uint8_t release)
{
switch (release)
{
case 8:
case 9:
case 10:
case 11:
m_requirements = GetRequirementsRel11 ();
break;
case 15:
m_requirements = GetRequirementsRel15 ();
break;
default:
NS_FATAL_ERROR ("Not recognized release " << static_cast<uint32_t> (release) <<
" please use a value between 8 and 11, or 15");
}
m_release = release;
}
bool
EpsBearer::IsGbr () const
{
// 3GPP 23.203 Section 6.1.7.2
switch (qci)
{
case GBR_CONV_VOICE:
case GBR_CONV_VIDEO:
case GBR_GAMING:
case GBR_NON_CONV_VIDEO:
return true;
case NGBR_IMS:
case NGBR_VIDEO_TCP_OPERATOR:
case NGBR_VOICE_VIDEO_GAMING:
case NGBR_VIDEO_TCP_PREMIUM:
case NGBR_VIDEO_TCP_DEFAULT:
return false;
default:
NS_FATAL_ERROR ("unknown QCI value " << qci);
return false;
}
return IsGbr (*m_requirements, qci);
}
uint8_t
EpsBearer::GetPriority () const
{
// 3GPP 23.203 Section 6.1.7.2
switch (qci)
{
case GBR_CONV_VOICE:
return 2;
case GBR_CONV_VIDEO:
return 4;
case GBR_GAMING:
return 3;
case GBR_NON_CONV_VIDEO:
return 5;
case NGBR_IMS:
return 1;
case NGBR_VIDEO_TCP_OPERATOR:
return 6;
case NGBR_VOICE_VIDEO_GAMING:
return 7;
case NGBR_VIDEO_TCP_PREMIUM:
return 8;
case NGBR_VIDEO_TCP_DEFAULT:
return 9;
default:
NS_FATAL_ERROR ("unknown QCI value " << qci);
return 0;
}
return GetPriority (*m_requirements, qci);
}
uint16_t
EpsBearer::GetPacketDelayBudgetMs () const
{
// 3GPP 23.203 Section 6.1.7.2
switch (qci)
{
case GBR_CONV_VOICE:
return 100;
case GBR_CONV_VIDEO:
return 150;
case GBR_GAMING:
return 50;
case GBR_NON_CONV_VIDEO:
return 300;
case NGBR_IMS:
return 100;
case NGBR_VIDEO_TCP_OPERATOR:
return 300;
case NGBR_VOICE_VIDEO_GAMING:
return 100;
case NGBR_VIDEO_TCP_PREMIUM:
return 300;
case NGBR_VIDEO_TCP_DEFAULT:
return 300;
default:
NS_FATAL_ERROR ("unknown QCI value " << qci);
return 0;
}
return GetPacketDelayBudgetMs (*m_requirements, qci);
}
double
EpsBearer::GetPacketErrorLossRate () const
{
// 3GPP 23.203 Section 6.1.7.2
switch (qci)
{
case GBR_CONV_VOICE:
return 1.0e-2;
case GBR_CONV_VIDEO:
return 1.0e-3;
case GBR_GAMING:
return 1.0e-3;
case GBR_NON_CONV_VIDEO:
return 1.0e-6;
case NGBR_IMS:
return 1.0e-6;
case NGBR_VIDEO_TCP_OPERATOR:
return 1.0e-6;
case NGBR_VOICE_VIDEO_GAMING:
return 1.0e-3;
case NGBR_VIDEO_TCP_PREMIUM:
return 1.0e-6;
case NGBR_VIDEO_TCP_DEFAULT:
return 1.0e-6;
default:
NS_FATAL_ERROR ("unknown QCI value " << qci);
return 0;
}
return GetPacketErrorLossRate (*m_requirements, qci);
}
EpsBearer::BearerRequirementsMap *
EpsBearer::GetRequirementsRel11 ()
{
/* Needed to support GCC 4.9. Otherwise, use list constructors, for example:
* EpsBearer::BearerRequirementsMap
* EpsBearer::GetRequirementsRel15 ()
* {
* return
* {
* { GBR_CONV_VOICE , { true, 20, 100, 1.0e-2, 0, 2000} },
* ...
* };
* }
*/
static EpsBearer::BearerRequirementsMap ret;
if (ret.size () == 0)
{
ret.insert (std::make_pair (GBR_CONV_VOICE, std::make_tuple (true, 2, 100, 1.0e-2, 0, 0)));
ret.insert (std::make_pair (GBR_CONV_VIDEO, std::make_tuple (true, 4, 150, 1.0e-3, 0, 0)));
ret.insert (std::make_pair (GBR_GAMING, std::make_tuple (true, 3, 50, 1.0e-3, 0, 0)));
ret.insert (std::make_pair (GBR_NON_CONV_VIDEO, std::make_tuple (true, 5, 300, 1.0e-6, 0, 0)));
ret.insert (std::make_pair (NGBR_IMS, std::make_tuple (false, 1, 100, 1.0e-6, 0, 0)));
ret.insert (std::make_pair (NGBR_VIDEO_TCP_OPERATOR, std::make_tuple (false, 6, 300, 1.0e-6, 0, 0)));
ret.insert (std::make_pair (NGBR_VOICE_VIDEO_GAMING, std::make_tuple (false, 7, 100, 1.0e-3, 0, 0)));
ret.insert (std::make_pair (NGBR_VIDEO_TCP_PREMIUM, std::make_tuple (false, 8, 300, 1.0e-6, 0, 0)));
ret.insert (std::make_pair (NGBR_VIDEO_TCP_DEFAULT, std::make_tuple (false, 9, 300, 1.0e-6, 0, 0)));
}
return &ret;
}
EpsBearer::BearerRequirementsMap *
EpsBearer::GetRequirementsRel15 ()
{
// Needed to support GCC 4.9. Otherwise, use list constructors (see GetRequirementsRel10)
static EpsBearer::BearerRequirementsMap ret;
if (ret.size () == 0)
{
ret.insert (std::make_pair (GBR_CONV_VOICE, std::make_tuple (true, 20, 100, 1.0e-2, 0, 2000)));
ret.insert (std::make_pair (GBR_CONV_VIDEO, std::make_tuple (true, 40, 150, 1.0e-3, 0, 2000)));
ret.insert (std::make_pair (GBR_GAMING, std::make_tuple (true, 30, 50, 1.0e-3, 0, 2000)));
ret.insert (std::make_pair (GBR_NON_CONV_VIDEO, std::make_tuple (true, 50, 300, 1.0e-6, 0, 2000)));
ret.insert (std::make_pair (GBR_MC_PUSH_TO_TALK, std::make_tuple (true, 7, 75, 1.0e-2, 0, 2000)));
ret.insert (std::make_pair (GBR_NMC_PUSH_TO_TALK, std::make_tuple (true, 20, 100, 1.0e-2, 0, 2000)));
ret.insert (std::make_pair (GBR_MC_VIDEO, std::make_tuple (true, 15, 100, 1.0e-3, 0, 2000)));
ret.insert (std::make_pair (GBR_V2X, std::make_tuple (true, 25, 50, 1.0e-2, 0, 2000)));
ret.insert (std::make_pair (NGBR_IMS, std::make_tuple (false, 10, 100, 1.0e-6, 0, 0)));
ret.insert (std::make_pair (NGBR_VIDEO_TCP_OPERATOR, std::make_tuple (false, 60, 300, 1.0e-6, 0, 0)));
ret.insert (std::make_pair (NGBR_VOICE_VIDEO_GAMING, std::make_tuple (false, 70, 100, 1.0e-3, 0, 0)));
ret.insert (std::make_pair (NGBR_VIDEO_TCP_PREMIUM, std::make_tuple (false, 80, 300, 1.0e-6, 0, 0)));
ret.insert (std::make_pair (NGBR_VIDEO_TCP_DEFAULT, std::make_tuple (false, 90, 300, 1.0e-6, 0, 0)));
ret.insert (std::make_pair (NGBR_MC_DELAY_SIGNAL, std::make_tuple (false, 5, 60, 1.0e-6, 0, 0)));
ret.insert (std::make_pair (NGBR_MC_DATA, std::make_tuple (false, 55, 200, 1.0e-6, 0, 0)));
ret.insert (std::make_pair (NGBR_V2X, std::make_tuple (false, 65, 5, 1.0e-2, 0, 0)));
ret.insert (std::make_pair (NGBR_LOW_LAT_EMBB, std::make_tuple (false, 68, 10, 1.0e-6, 0, 0)));
ret.insert (std::make_pair (DGBR_DISCRETE_AUT_SMALL, std::make_tuple (false, 19, 10, 1.0e-4, 255, 2000)));
ret.insert (std::make_pair (DGBR_DISCRETE_AUT_LARGE, std::make_tuple (false, 22, 10, 1.0e-4, 1358, 2000)));
ret.insert (std::make_pair (DGBR_ITS, std::make_tuple (false, 24, 30, 1.0e-5, 1354, 2000)));
ret.insert (std::make_pair (DGBR_ELECTRICITY, std::make_tuple (false, 21, 5, 1.0e-5, 255, 2000)));
}
return &ret;
}
} // namespace ns3

View File

@@ -23,6 +23,8 @@
#define EPS_BEARER
#include <ns3/uinteger.h>
#include <ns3/object-base.h>
#include <unordered_map>
namespace ns3 {
@@ -60,31 +62,70 @@ struct AllocationRetentionPriority
};
/**
* This class contains the specification of EPS Bearers.
* \brief This class contains the specification of EPS Bearers.
*
* See the following references:
* 3GPP TS 23.203, Section 4.7.2 The EPS bearer
* 3GPP TS 23.203, Section 4.7.3 Bearer level QoS parameters
* 3GPP TS 36.413 Section 9.2.1.15 E-RAB Level QoS Parameters
*
* It supports the selection of different specifications depending on the
* release. To change the release, change the attribute "Release". Please remember
* that we must expose to all releases the most recent Qci. Asking for Qci parameters
* for a release in which it has not been created will result in a crash.
*
* For example, if you select Release 11 (or if you don't select anything, as
* it is the default selection) and then ask for the packet error rate of
* the NGBR_MC_DELAY_SIGNAL Qci, the program will crash.
*
* Please note that from Release 8 (the latest when the LENA project finished)
* to Release 11, the bearers ID and requirements are the same. From Release 12,
* they started to change, and the latest version is now Release 15. However,
* we do not support intermediate types: in other words, you can select from
* Release 8 to Release 11, or Release 15. Any other value will result in a
* program crash.
*
* The release version only affect Bearer definitions. Other part of the LTE
* module are not affected when changing the Release attribute.
*/
struct EpsBearer
class EpsBearer : public ObjectBase
{
public:
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId (void);
virtual TypeId GetInstanceTypeId (void) const override;
/**
* QoS Class Indicator. See 3GPP 23.203 Section 6.1.7.2 for standard values.
* Updated to Release 15.
*/
enum Qci
enum Qci : uint8_t
{
GBR_CONV_VOICE = 1,
GBR_CONV_VIDEO = 2,
GBR_GAMING = 3,
GBR_NON_CONV_VIDEO = 4,
NGBR_IMS = 5,
NGBR_VIDEO_TCP_OPERATOR = 6,
NGBR_VOICE_VIDEO_GAMING = 7,
NGBR_VIDEO_TCP_PREMIUM = 8,
NGBR_VIDEO_TCP_DEFAULT = 9,
GBR_CONV_VOICE = 1, ///< GBR Conversational Voice
GBR_CONV_VIDEO = 2, ///< GBR Conversational Video (Live streaming)
GBR_GAMING = 3, ///< GBR Real Time Gaming
GBR_NON_CONV_VIDEO = 4, ///< GBR Non-Conversational Video (Buffered Streaming)
GBR_MC_PUSH_TO_TALK = 65, ///< GBR Mission Critical User Plane Push To Talk voice
GBR_NMC_PUSH_TO_TALK = 66, ///< GBR Non-Mission-Critical User Plane Push To Talk voice
GBR_MC_VIDEO = 67, ///< GBR Mission Critical Video User Plane
GBR_V2X = 75, ///< GBR V2X Messages
NGBR_IMS = 5, ///< Non-GBR IMS Signalling
NGBR_VIDEO_TCP_OPERATOR = 6, ///< Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
NGBR_VOICE_VIDEO_GAMING = 7, ///< Non-GBR Voice, Video, Interactive Streaming
NGBR_VIDEO_TCP_PREMIUM = 8, ///< Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
NGBR_VIDEO_TCP_DEFAULT = 9, ///< Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
NGBR_MC_DELAY_SIGNAL = 69, ///< Non-GBR Mission Critical Delay Sensitive Signalling (e.g., MC-PTT)
NGBR_MC_DATA = 70, ///< Non-GBR Mission Critical Data
NGBR_V2X = 79, ///< Non-GBR V2X Messages
NGBR_LOW_LAT_EMBB = 80, ///< Non-GBR Low Latency eMBB applications
DGBR_DISCRETE_AUT_SMALL = 82, ///< Delay-Critical GBR Discrete Automation Small Packets (TS 22.261)
DGBR_DISCRETE_AUT_LARGE = 83, ///< Delay-Critical GBR Discrete Automation Large Packets (TS 22.261)
DGBR_ITS = 84, ///< Delay-Critical GBR Intelligent Transport Systems (TS 22.261)
DGBR_ELECTRICITY = 85, ///< Delay-Critical GBR Electricity Distribution High Voltage (TS 22.261)
} qci; ///< Qos class indicator
GbrQosInformation gbrQosInfo; ///< GBR QOS information
@@ -111,6 +152,37 @@ struct EpsBearer
*/
EpsBearer (Qci x, GbrQosInformation y);
/**
* \brief EpsBearer copy constructor
* \param o other instance
*/
EpsBearer (const EpsBearer &o);
/**
* \brief Deconstructor
*/
virtual ~EpsBearer () { }
/**
* \brief SetRelease
* \param release The release the user want for this bearer
*
* Releases introduces new types, and change values for existing ones.
* While we can't do much for the added type (we must expose them even
* if the user want to work with older releases) by calling this method
* we can, at least, select the specific parameters value the bearer returns.
*
* For instance, if the user select release 10 (the default) the priority
* of CONV_VIDEO will be 2. With release 15, such priority will be 20.
*/
void SetRelease (uint8_t release);
/**
* \brief GetRelease
* \return The release currently set for this bearer type
*/
uint8_t GetRelease () const { return m_release; }
/**
*
* @return true if the EPS Bearer is a Guaranteed Bit Rate bearer, false otherwise
@@ -139,6 +211,119 @@ struct EpsBearer
*/
double GetPacketErrorLossRate () const;
private:
/**
* \brief Hashing QCI
*
* Qci are just uint8_t, so that's how we calculate the hash. Unfortunately,
* we have to provide this struct because gcc 4.9 would not compile otherwise.
*/
struct QciHash
{
/**
* \brief Hash the QCI like a normal uint8_t
* \param s Qci to hash
* \return Hash of Qci
*/
std::size_t
operator () (Qci const& s) const noexcept
{
return std::hash<uint8_t> {} (s);
}
};
/**
* \brief Map between QCI and requirements
*
* The tuple is formed by: isGbr, priority, packet delay budget, packet error rate,
* default maximum data burst, default averaging window (0 when does not apply)
*/
typedef std::unordered_map<Qci, std::tuple<bool, uint8_t, uint16_t, double, uint32_t, uint32_t>, QciHash > BearerRequirementsMap;
/**
* \brief Is the selected QCI GBR?
* \param map Map between QCI and requirements
* \param qci QCI to look for
* \return GBR flag for the selected CQI
*/
static uint32_t
IsGbr (const BearerRequirementsMap &map, Qci qci) {return std::get<0> (map.at (qci));}
/**
* \brief Get priority for the selected QCI
* \param map Map between QCI and requirements
* \param qci QCI to look for
* \return priority for the selected QCI
*/
static uint8_t
GetPriority (const BearerRequirementsMap &map, Qci qci) {return std::get<1> (map.at (qci));}
/**
* \brief Get packet delay in ms for the selected QCI
* \param map Map between QCI and requirements
* \param qci QCI to look for
* \return packet delay in ms for the selected QCI
*/
static uint16_t
GetPacketDelayBudgetMs (const BearerRequirementsMap &map, Qci qci) {return std::get<2> (map.at (qci));}
/**
* \brief Get packet error rate for the selected QCI
* \param map Map between QCI and requirements
* \param qci QCI to look for
* \return packet error rate for the selected QCI
*/
static double
GetPacketErrorLossRate (const BearerRequirementsMap &map, Qci qci) {return std::get<3> (map.at (qci));}
/**
* \brief Get maximum data burst for the selected QCI
* \param map Map between QCI and requirements
* \param qci QCI to look for
* \return maximum data burst for the selected QCI
*/
static uint32_t
GetMaxDataBurst (const BearerRequirementsMap &map, Qci qci) {return std::get<4> (map.at (qci));}
/**
* \brief Get default averaging window for the selected QCI
* \param map Map between QCI and requirements
* \param qci QCI to look for
* \return default averaging window for the selected QCI
*/
static uint32_t
GetAvgWindow (const BearerRequirementsMap &map, Qci qci) {return std::get<5> (map.at (qci));}
/**
* \brief Retrieve requirements for Rel. 11
* \return the BearerRequirementsMap for Release 11
*
* It returns a pointer to a non-const static data. That is not thread-safe,
* nor safe to do in general. However, a const-correct version would have
* to initialize two static maps, and then returning either one or the other.
* But that's a huge memory increase, and EpsBearer is used everywhere.
*
* To be revisited when GCC 4.9 will not be supported anymore.
*/
static BearerRequirementsMap * GetRequirementsRel11 ();
/**
* \brief Retrieve requirements for Rel. 15
* \return the BearerRequirementsMap for Release 15
*
* It returns a pointer to a non-const static data. That is not thread-safe,
* nor safe to do in general. However, a const-correct version would have
* to initialize two static maps, and then returning either one or the other.
* But that's a huge memory increase, and EpsBearer is used everywhere.
*
* To be revisited when GCC 4.9 will not be supported anymore.
*/
static BearerRequirementsMap * GetRequirementsRel15 ();
/**
* \brief Requirements pointer per bearer
*
* It will point to a static map.
*/
BearerRequirementsMap *m_requirements;
uint8_t m_release {30}; //!< Release (10 or 15)
};
} // namespace ns3

View File

@@ -53,6 +53,14 @@ public:
*/
virtual void ReportMacCeToScheduler (MacCeListElement_s bsr) = 0;
/**
* \brief Report SR to the right scheduler
* \param rnti RNTI of the user that requested the SR
*
* \see LteCcmMacSapUser::UlReceiveSr
*/
virtual void ReportSrToScheduler (uint16_t rnti) = 0;
}; // end of class LteCcmMacSapProvider
@@ -79,6 +87,20 @@ public:
*/
virtual void UlReceiveMacCe (MacCeListElement_s bsr, uint8_t componentCarrierId) = 0;
/**
* \brief The MAC received a SR
* \param rnti RNTI of the UE that requested a SR
* \param componentCarrierId CC that received the SR
*
* NOTE: Not implemented in the LTE module. The FemtoForum API requires
* that this function gets as parameter a struct SchedUlSrInfoReqParameters.
* However, that struct has the SfnSf as a member: since it differs from
* LTE to mmwave/NR, and we don't have an effective strategy to deal with
* that, we limit the function to the only thing that the module have in
* common: the RNTI.
*/
virtual void UlReceiveSr (uint16_t rnti, uint8_t componentCarrierId) = 0;
/**
* \brief Notifies component carrier manager about physical resource block occupancy
* \param prbOccupancy The physical resource block occupancy
@@ -100,7 +122,8 @@ public:
*/
MemberLteCcmMacSapProvider (C* owner);
// inherited from LteCcmRrcSapProvider
virtual void ReportMacCeToScheduler (MacCeListElement_s bsr);
virtual void ReportMacCeToScheduler (MacCeListElement_s bsr) override;
virtual void ReportSrToScheduler (uint16_t rnti) override;
private:
C* m_owner; ///< the owner class
@@ -118,6 +141,11 @@ void MemberLteCcmMacSapProvider<C>::ReportMacCeToScheduler (MacCeListElement_s b
m_owner->DoReportMacCeToScheduler (bsr);
}
template <class C>
void MemberLteCcmMacSapProvider<C>::ReportSrToScheduler (uint16_t rnti)
{
m_owner->DoReportSrToScheduler (rnti);
}
/// MemberLteCcmMacSapUser class
template <class C>
@@ -132,6 +160,7 @@ public:
MemberLteCcmMacSapUser (C* owner);
// inherited from LteCcmRrcSapUser
virtual void UlReceiveMacCe (MacCeListElement_s bsr, uint8_t componentCarrierId);
virtual void UlReceiveSr (uint16_t rnti, uint8_t componentCarrierId);
virtual void NotifyPrbOccupancy (double prbOccupancy, uint8_t componentCarrierId);
// inherited from LteMacSapUser
virtual void NotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpParams);
@@ -155,6 +184,12 @@ void MemberLteCcmMacSapUser<C>::UlReceiveMacCe (MacCeListElement_s bsr, uint8_t
m_owner->DoUlReceiveMacCe (bsr, componentCarrierId);
}
template<class C>
void MemberLteCcmMacSapUser<C>::UlReceiveSr (uint16_t rnti, uint8_t componentCarrierId)
{
m_owner->DoUlReceiveSr (rnti, componentCarrierId);
}
template <class C>
void MemberLteCcmMacSapUser<C>::NotifyPrbOccupancy (double prbOccupancy, uint8_t componentCarrierId)
{

View File

@@ -343,6 +343,17 @@ private:
* \param bsr the BSR
*/
void DoReportMacCeToScheduler (MacCeListElement_s bsr);
/**
* \brief Report SR to scheduler
* \param rnti RNTI of the UE that requested the SR
*
* Since SR is not implemented in LTE, this method does nothing.
*/
void DoReportSrToScheduler (uint16_t rnti)
{
NS_UNUSED (rnti);
}
public:
/**

View File

@@ -187,25 +187,25 @@ LteEnbNetDevice::DoDispose ()
Ptr<LteEnbMac>
LteEnbNetDevice::GetMac () const
{
return m_ccMap.at (0)->GetMac ();
return GetMac (0);
}
Ptr<LteEnbPhy>
LteEnbNetDevice::GetPhy () const
{
return m_ccMap.at (0)->GetPhy ();
return GetPhy (0);
}
Ptr<LteEnbMac>
LteEnbNetDevice::GetMac (uint8_t index)
LteEnbNetDevice::GetMac (uint8_t index) const
{
return m_ccMap.at (index)->GetMac ();
return DynamicCast<ComponentCarrierEnb> (m_ccMap.at (index))->GetMac ();
}
Ptr<LteEnbPhy>
LteEnbNetDevice::GetPhy(uint8_t index)
LteEnbNetDevice::GetPhy(uint8_t index) const
{
return m_ccMap.at (index)->GetPhy ();
return DynamicCast<ComponentCarrierEnb> (m_ccMap.at (index))->GetPhy ();
}
Ptr<LteEnbRrc>
@@ -347,14 +347,14 @@ LteEnbNetDevice::SetCsgIndication (bool csgIndication)
UpdateConfig (); // propagate the change to RRC level
}
std::map < uint8_t, Ptr<ComponentCarrierEnb> >
LteEnbNetDevice::GetCcMap ()
std::map < uint8_t, Ptr<ComponentCarrierBaseStation> >
LteEnbNetDevice::GetCcMap () const
{
return m_ccMap;
}
void
LteEnbNetDevice::SetCcMap (std::map< uint8_t, Ptr<ComponentCarrierEnb> > ccm)
LteEnbNetDevice::SetCcMap (std::map< uint8_t, Ptr<ComponentCarrierBaseStation> > ccm)
{
NS_ASSERT_MSG (!m_isConfigured, "attempt to set CC map after configuration");
m_ccMap = ccm;
@@ -366,8 +366,7 @@ LteEnbNetDevice::DoInitialize (void)
NS_LOG_FUNCTION (this);
m_isConstructed = true;
UpdateConfig ();
std::map< uint8_t, Ptr<ComponentCarrierEnb> >::iterator it;
for (it = m_ccMap.begin (); it != m_ccMap.end (); ++it)
for (auto it = m_ccMap.begin (); it != m_ccMap.end (); ++it)
{
it->second->Initialize ();
}

View File

@@ -79,7 +79,7 @@ public:
* \param index CC index
* \return a pointer to the MAC of the CC addressed by index.
*/
Ptr<LteEnbMac> GetMac (uint8_t index);
Ptr<LteEnbMac> GetMac (uint8_t index) const;
/**
* \return a pointer to the physical layer of the PCC.
@@ -90,7 +90,7 @@ public:
* \param index SCC index
* \return a pointer to the physical layer of the SCC addressed by index.
*/
Ptr<LteEnbPhy> GetPhy (uint8_t index);
Ptr<LteEnbPhy> GetPhy (uint8_t index) const;
/**
* \return a pointer to the Radio Resource Control instance of the eNB
@@ -204,14 +204,14 @@ public:
*
*/
void SetCcMap (std::map< uint8_t, Ptr<ComponentCarrierEnb> > ccm);
void SetCcMap (std::map< uint8_t, Ptr<ComponentCarrierBaseStation> > ccm);
/**
* \returns The Component Carrier Map of the Enb.
*
*/
std::map< uint8_t, Ptr<ComponentCarrierEnb> > GetCcMap (void);
std::map< uint8_t, Ptr<ComponentCarrierBaseStation> > GetCcMap (void) const;
protected:
// inherited from Object
@@ -253,7 +253,7 @@ private:
uint16_t m_csgId; ///< CSG ID
bool m_csgIndication; ///< CSG indication
std::map < uint8_t, Ptr<ComponentCarrierEnb> > m_ccMap; /**< ComponentCarrier map */
std::map < uint8_t, Ptr<ComponentCarrierBaseStation> > m_ccMap; /**< ComponentCarrier map */
Ptr<LteEnbComponentCarrierManager> m_componentCarrierManager; ///< the component carrier manager of this eNb

View File

@@ -1108,7 +1108,7 @@ UeManager::RecvMeasurementReport (LteRrcSap::MeasurementReport msg)
m_rrc->m_anrSapProvider->ReportUeMeas (msg.measResults);
}
if ((m_rrc->m_ffrRrcSapProvider.at (0) != 0)
if ((m_rrc->m_ffrRrcSapProvider.size () > 0)
&& (m_rrc->m_ffrMeasIds.find (measId) != m_rrc->m_ffrMeasIds.end ()))
{
// this measurement was requested by the FFR function
@@ -1460,7 +1460,7 @@ UeManager::BuildNonCriticalExtentionConfigurationCa ()
ccId++;
}
Ptr<ComponentCarrierEnb> eNbCcm = it.second;
Ptr<ComponentCarrierBaseStation> eNbCcm = it.second;
LteRrcSap::SCellToAddMod component;
component.sCellIndex = ccId;
component.cellIdentification.physCellId = eNbCcm->GetCellId ();
@@ -1545,13 +1545,10 @@ LteEnbRrc::LteEnbRrc ()
m_s1SapUser = new MemberEpcEnbS1SapUser<LteEnbRrc> (this);
m_cphySapUser.push_back (new MemberLteEnbCphySapUser<LteEnbRrc> (this));
m_ccmRrcSapUser = new MemberLteCcmRrcSapUser <LteEnbRrc>(this);
m_cphySapProvider.push_back (0);
m_cmacSapProvider.push_back (0);
m_ffrRrcSapProvider.push_back (0);
}
void
LteEnbRrc::ConfigureCarriers (std::map<uint8_t, Ptr<ComponentCarrierEnb>> ccPhyConf)
LteEnbRrc::ConfigureCarriers (std::map<uint8_t, Ptr<ComponentCarrierBaseStation>> ccPhyConf)
{
NS_ASSERT_MSG (!m_carriersConfigured, "Secondary carriers can be configured only once.");
m_componentCarrierPhyConf = ccPhyConf;
@@ -1563,9 +1560,6 @@ LteEnbRrc::ConfigureCarriers (std::map<uint8_t, Ptr<ComponentCarrierEnb>> ccPhyC
m_cphySapUser.push_back (new MemberLteEnbCphySapUser<LteEnbRrc> (this));
m_cmacSapUser.push_back (new EnbRrcMemberLteEnbCmacSapUser (this, i));
m_ffrRrcSapUser.push_back (new MemberLteFfrRrcSapUser<LteEnbRrc> (this));
m_cphySapProvider.push_back (0);
m_cmacSapProvider.push_back (0);
m_ffrRrcSapProvider.push_back (0);
}
m_carriersConfigured = true;
Object::DoInitialize ();
@@ -1790,7 +1784,15 @@ void
LteEnbRrc::SetLteEnbCmacSapProvider (LteEnbCmacSapProvider * s, uint8_t pos)
{
NS_LOG_FUNCTION (this << s);
m_cmacSapProvider.at (pos) = s;
if (m_cmacSapProvider.size () > pos)
{
m_cmacSapProvider.at (pos) = s;
}
else
{
m_cmacSapProvider.push_back (s);
NS_ABORT_IF (m_cmacSapProvider.size () - 1 != pos);
}
}
LteEnbCmacSapUser*
@@ -1853,14 +1855,33 @@ void
LteEnbRrc::SetLteFfrRrcSapProvider (LteFfrRrcSapProvider * s)
{
NS_LOG_FUNCTION (this << s);
m_ffrRrcSapProvider.at (0) = s;
if (m_ffrRrcSapProvider.size () > 0)
{
m_ffrRrcSapProvider.at (0) = s;
}
else
{
m_ffrRrcSapProvider.push_back (s);
}
}
void
LteEnbRrc::SetLteFfrRrcSapProvider (LteFfrRrcSapProvider * s, uint8_t index)
{
NS_LOG_FUNCTION (this << s);
m_ffrRrcSapProvider.at (index) = s;
if (m_ffrRrcSapProvider.size () > index)
{
m_ffrRrcSapProvider.at (index) = s;
}
else
{
m_ffrRrcSapProvider.push_back (s);
NS_ABORT_MSG_IF (m_ffrRrcSapProvider.size () - 1 != index,
"You meant to store the pointer at position " <<
static_cast<uint32_t> (index) <<
" but it went to " << m_ffrRrcSapProvider.size () - 1);
}
}
LteFfrRrcSapUser*
@@ -1916,7 +1937,14 @@ void
LteEnbRrc::SetLteEnbCphySapProvider (LteEnbCphySapProvider * s)
{
NS_LOG_FUNCTION (this << s);
m_cphySapProvider.at(0) = s;
if (m_cphySapProvider.size () > 0)
{
m_cphySapProvider.at (0) = s;
}
else
{
m_cphySapProvider.push_back (s);
}
}
LteEnbCphySapUser*
@@ -1930,7 +1958,15 @@ void
LteEnbRrc::SetLteEnbCphySapProvider (LteEnbCphySapProvider * s, uint8_t pos)
{
NS_LOG_FUNCTION (this << s);
m_cphySapProvider.at(pos) = s;
if (m_cphySapProvider.size () > pos)
{
m_cphySapProvider.at(pos) = s;
}
else
{
m_cphySapProvider.push_back (s);
NS_ABORT_IF (m_cphySapProvider.size () - 1 != pos);
}
}
LteEnbCphySapUser*
@@ -2047,7 +2083,7 @@ LteEnbRrc::AddUeMeasReportConfig (LteRrcSap::ReportConfigEutra config)
}
void
LteEnbRrc::ConfigureCell (std::map<uint8_t, Ptr<ComponentCarrierEnb>> ccPhyConf)
LteEnbRrc::ConfigureCell (std::map<uint8_t, Ptr<ComponentCarrierBaseStation>> ccPhyConf)
{
auto it = ccPhyConf.begin ();
NS_ASSERT (it != ccPhyConf.end ());
@@ -2065,8 +2101,11 @@ LteEnbRrc::ConfigureCell (std::map<uint8_t, Ptr<ComponentCarrierEnb>> ccPhyConf)
m_cphySapProvider.at (it.first)->SetEarfcn (it.second->GetUlEarfcn (), it.second->GetDlEarfcn ());
m_cphySapProvider.at (it.first)->SetCellId (it.second->GetCellId ());
m_cmacSapProvider.at (it.first)->ConfigureMac (it.second->GetUlBandwidth (), it.second->GetDlBandwidth ());
m_ffrRrcSapProvider.at (it.first)->SetCellId (it.second->GetCellId ());
m_ffrRrcSapProvider.at (it.first)->SetBandwidth (it.second->GetUlBandwidth (), it.second->GetDlBandwidth ());
if (m_ffrRrcSapProvider.size () > it.first)
{
m_ffrRrcSapProvider.at (it.first)->SetCellId (it.second->GetCellId ());
m_ffrRrcSapProvider.at (it.first)->SetBandwidth (it.second->GetUlBandwidth (), it.second->GetDlBandwidth ());
}
}
m_dlEarfcn = dlEarfcn;
@@ -2481,6 +2520,7 @@ LteEnbRrc::DoRecvLoadInformation (EpcX2SapUser::LoadInformationParams params)
NS_LOG_LOGIC ("Number of cellInformationItems = " << params.cellInformationList.size ());
NS_ABORT_IF (m_ffrRrcSapProvider.size () == 0);
m_ffrRrcSapProvider.at (0)->RecvLoadInformation (params);
}

View File

@@ -863,13 +863,13 @@ public:
*
* \param ccPhyConf the component carrier configuration
*/
void ConfigureCell (std::map<uint8_t, Ptr<ComponentCarrierEnb>> ccPhyConf);
void ConfigureCell (std::map<uint8_t, Ptr<ComponentCarrierBaseStation> > ccPhyConf);
/**
* \brief Configure carriers.
* \param ccPhyConf the component carrier configuration
*/
void ConfigureCarriers (std::map<uint8_t, Ptr<ComponentCarrierEnb>> ccPhyConf);
void ConfigureCarriers (std::map<uint8_t, Ptr<ComponentCarrierBaseStation>> ccPhyConf);
/**
* set the cell id of this eNB
@@ -1591,7 +1591,7 @@ private:
bool m_carriersConfigured; ///< are carriers configured
std::map<uint8_t, Ptr<ComponentCarrierEnb>> m_componentCarrierPhyConf; ///< component carrier phy configuration
std::map<uint8_t, Ptr<ComponentCarrierBaseStation>> m_componentCarrierPhyConf; ///< component carrier phy configuration
}; // end of `class LteEnbRrc`

View File

@@ -102,6 +102,30 @@ public:
*/
struct TxOpportunityParameters
{
/**
* \brief TxOpportunityParameters constructor
* \param bytes Bytes
* \param layer Layer
* \param harqId HarqID
* \param ccId Component carrier ID
* \param rnti RNTI
* \param lcId Logical Channel ID
*/
TxOpportunityParameters (uint32_t bytes, uint8_t layer, uint8_t harqId,
uint8_t ccId, uint16_t rnti, uint8_t lcId)
{
this->bytes = bytes;
this->layer = layer;
this->harqId = harqId;
this->componentCarrierId = ccId;
this->rnti = rnti;
this->lcid = lcId;
}
/**
* \brief TxOpportunityParameters default constructor (DEPRECATED)
*/
TxOpportunityParameters () { }
uint32_t bytes; /**< the number of bytes to transmit */
uint8_t layer; /**< the layer of transmission (MIMO) */
uint8_t harqId; /**< the HARQ ID */
@@ -131,6 +155,23 @@ public:
*/
struct ReceivePduParameters
{
/**
* \brief ReceivePduParameters default constructor (DEPRECATED)
*/
ReceivePduParameters () { }
/**
* \brief ReceivePduParameters constructor
* \param p Packet
* \param rnti RNTI
* \param lcid Logical Channel ID
*/
ReceivePduParameters (const Ptr<Packet> &p, uint16_t rnti, uint8_t lcid)
{
this->p = p;
this->rnti = rnti;
this->lcid = lcid;
}
Ptr<Packet> p; /**< the RLC PDU to be received */
uint16_t rnti; /**< the C-RNTI identifying the UE */
uint8_t lcid; /**< the logical channel id */

View File

@@ -411,6 +411,18 @@ NoOpComponentCarrierManager::DoUlReceiveMacCe (MacCeListElement_s bsr, uint8_t c
}
}
void
NoOpComponentCarrierManager::DoUlReceiveSr (uint16_t rnti, uint8_t componentCarrierId)
{
NS_LOG_FUNCTION (this);
auto sapIt = m_ccmMacSapProviderMap.find (componentCarrierId);
NS_ABORT_MSG_IF (sapIt == m_ccmMacSapProviderMap.end (),
"Sap not found in the CcmMacSapProviderMap");
sapIt->second->ReportSrToScheduler (rnti);
}
//////////////////////////////////////////
@@ -515,4 +527,21 @@ RrComponentCarrierManager::DoUlReceiveMacCe (MacCeListElement_s bsr, uint8_t com
}
}
void
RrComponentCarrierManager::DoUlReceiveSr(uint16_t rnti, uint8_t componentCarrierId)
{
NS_LOG_FUNCTION (this);
NS_UNUSED (componentCarrierId);
// split traffic in uplink equally among carriers
uint32_t numberOfCarriersForUe = m_enabledComponentCarrier.find (rnti)->second;
m_ccmMacSapProviderMap.find (m_lastCcIdForSr)->second->ReportSrToScheduler (rnti);
m_lastCcIdForSr++;
if (m_lastCcIdForSr > numberOfCarriersForUe - 1)
{
m_lastCcIdForSr = 0;
}
}
} // end of namespace ns3

View File

@@ -138,6 +138,12 @@ protected:
* \param componentCarrierId the component carrier ID
*/
virtual void DoUlReceiveMacCe (MacCeListElement_s bsr, uint8_t componentCarrierId);
/**
* \brief Forward uplink SR to CCM, called by MAC through CCM SAP interface.
* \param rnti RNTI of the UE that requested SR
* \param componentCarrierId the component carrier ID that forwarded the SR
*/
virtual void DoUlReceiveSr (uint16_t rnti, uint8_t componentCarrierId);
/**
* \brief Function implements the function of the SAP interface of CCM instance which is used by MAC
* to notify the PRB occupancy reported by scheduler.
@@ -153,7 +159,7 @@ protected:
}; // end of class NoOpComponentCarrierManager
/*
/**
* \brief Component carrier manager implementation that splits traffic equally among carriers.
*/
class RrComponentCarrierManager : public NoOpComponentCarrierManager
@@ -161,7 +167,7 @@ class RrComponentCarrierManager : public NoOpComponentCarrierManager
public:
RrComponentCarrierManager ();
virtual ~RrComponentCarrierManager ();
virtual ~RrComponentCarrierManager () override;
/**
* \brief Get the type ID.
* \return the object TypeId
@@ -171,9 +177,12 @@ public:
protected:
// Inherited methods
virtual void DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params);
virtual void DoUlReceiveMacCe (MacCeListElement_s bsr, uint8_t componentCarrierId);
virtual void DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params) override;
virtual void DoUlReceiveMacCe (MacCeListElement_s bsr, uint8_t componentCarrierId) override;
virtual void DoUlReceiveSr (uint16_t rnti, uint8_t componentCarrierId) override;
private:
uint8_t m_lastCcIdForSr {0}; //!< Last CCID to which a SR was routed
}; // end of class RrComponentCarrierManager
} // end of namespace ns3

View File

@@ -87,7 +87,7 @@ protected:
* \brief Report buffer status function
* \param params LteMacSapProvider::ReportBufferStatusParameters
*/
void DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params);
virtual void DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params);
/// Notify HARQ deliver failure
void DoNotifyHarqDeliveryFailure ();
// forwarded from LteMacSapUser
@@ -111,7 +111,7 @@ protected:
* \param msu the MSU
* \returns updated LC config list
*/
std::vector<LteUeCcmRrcSapProvider::LcsConfig> DoAddLc (uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser* msu);
virtual std::vector<LteUeCcmRrcSapProvider::LcsConfig> DoAddLc (uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser* msu);
/**
* \brief Remove LC function
* \param lcid the LCID
@@ -125,14 +125,14 @@ protected:
* \param msu the MSU
* \returns LteMacSapUser *
*/
LteMacSapUser* DoConfigureSignalBearer (uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser* msu);
virtual LteMacSapUser* DoConfigureSignalBearer (uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser* msu);
/**
* \brief Reset LC map
*
*/
void DoReset ();
private:
protected:
LteMacSapUser* m_ccmMacSapUser;//!< Interface to the UE RLC instance.
LteMacSapProvider* m_ccmMacSapProvider; //!< Receive API calls from the UE RLC instance

View File

@@ -692,8 +692,17 @@ SpectrumValue::operator>> (int n) const
return res;
}
uint32_t
SpectrumValue::GetValuesN () const
{
return m_values.size ();
}
const double &
SpectrumValue::ValuesAt (uint32_t pos) const
{
return m_values.at (pos);
}
} // namespace ns3

View File

@@ -157,7 +157,18 @@ public:
*/
Values::iterator ValuesEnd ();
/**
* \brief Get the number of values stored in the array
* \return the values array size
*/
uint32_t GetValuesN () const;
/**
* \brief Get the value element at the position
* \param pos position
* \return the value element in that position (with bounds checking)
*/
const double & ValuesAt (uint32_t pos) const;
/**
* addition operator