--- a/src/lte/doc/source/lte-design.rst Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/doc/source/lte-design.rst Mon Apr 23 13:16:03 2012 +0200
@@ -121,6 +121,7 @@
For the sake of an easier explanation, we further divide the LTE model
in two separate parts, which are described in the following.
+The overall architecture of the LTE module is represented in the following figures.
The first part is the lower LTE radio protocol stack, which is
represented in the figures
@@ -649,6 +650,7 @@
\widehat{T}_{j}(t) = \frac{S\left( \widehat{M}_j(t), \widehat{B}_j(t)
\right)}{\tau}
+
Transport Blocks
@@ -1277,10 +1279,26 @@
+MIMO Model
+----------
+
+The use of multiple antennas both at transmitter and receiver side, known as multiple-input and multiple-output (MIMO), is a problem well studied in literature during the past years. Most of the work concentrate on evaluating analytically the gain that the different MIMO schemes might have in term of capacity; however someones provide also information of the gain in terms of received power _[CatreuxMIMO].
+
+According to the considerations above, a model more flexible can be obtained considering the gain that MIMO schemes bring in the system from a statistical point of view. As highlighted before, _[CatreuxMIMO] presents the statistical gain of several MIMO solutions respect to the SISO one. In the work the gain is presented as the cumulative distribution function (CDF) of the output SINR for what concern SISO, MIMO-Alamouti, MIMO-MMSE, MIMO-OSIC-MMSE and MIMO-ZF schemes. Elaborating the results, the output SINR distribution can be approximated with a log-normal one with different mean and variance as function of the scheme considered. However, the variances are not so different and they are approximatively equal to the one of the SISO mode already included in the shadowing component of the ``BuildingsPropagationLossModel``, in detail:
+
+ * SISO: :math:`\mu = 13.5` and :math:`\sigma = 20` [dB].
+ * MIMO-Alamouti: :math:`\mu = 17.7` and :math:`\sigma = 11.1` [dB].
+ * MIMO-MMSE: :math:`\mu = 10.7` and :math:`\sigma = 16.6` [dB].
+ * MIMO-OSIC-MMSE: :math:`\mu = 12.6` and :math:`\sigma = 15.5` [dB].
+ * MIMO-ZF: :math:`\mu = 10.3` and :math:`\sigma = 12.6` [dB].
+Therefore the PHY layer implements the MIMO model as the gain perceived by the receiver when using a MIMO scheme respect to the one obtained using SISO one. This allows to reuse the SISO PHY error model and the fading tracing scheme and apply the MIMO model in a transparent way. Moreover, new MIMO schemes can be integrated by updating the gain considered according to their statistical behavior. On this matter, considering the MIMO model defined in the standard (i.e., spatial multiplexing and transmit diversity _[TS36.211]), the gains included are:
+ * MIMO-Alamouti: :math:`+4.2` [dB].
+ * MIMO-MMSE: :math:`-2.8` [dB].
+where MIMO-Alamouti is a transmit diversity scheme, while MIMO-MMSE is an implementation of spatial multiplexity.
--- a/src/lte/doc/source/lte-references.rst Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/doc/source/lte-references.rst Mon Apr 23 13:16:03 2012 +0200
@@ -72,3 +72,15 @@
.. [mathworks] Matlab R2011b Documentation Communications System Toolbox, `Methodology for Simulating Multipath Fading Channels <http://www.mathworks.es/help/toolbox/comm/ug/a1069449399.html#bq5zk36>`_
+.. [PaduaPEM] http://mailman.isi.edu/pipermail/ns-developers/2011-November/009559.html
+
+.. [Vienna] The Vienna LTE Simulators http://www.nt.tuwien.ac.at/about-us/staff/josep-colom-ikuno/lte-simulators/
+
+.. [LozanoCost] Joan Olmos, Silvia Ruiz, Mario García-Lozano and David Martín-Sacristán, "Link Abstraction Models Based on Mutual Information for LTE Downlink", COST 2100 TD(10)11052 Report
+
+.. [CatreuxMIMO] S. Catreux, L.J. Greenstein, V. Erceg, "Some results and insights on the performance gains of MIMO systems," Selected Areas in Communications, IEEE Journal on , vol.21, no.5, pp. 839- 847, June 2003
+
+.. [ViennaPaper] J.C. Ikuno, M. Wrulich, M. Rupp, "System Level Simulation of LTE Networks," Vehicular Technology Conference (VTC 2010-Spring), 2010 IEEE 71st , vol., no., pp.1-5, 16-19 May 2010
+
+.. [TS36.211] 3GPP TS 36.211 "E-UTRA Physical Channels and Modulation"
+
--- a/src/lte/doc/source/lte-testing.rst Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/doc/source/lte-testing.rst Mon Apr 23 13:16:03 2012 +0200
@@ -404,10 +404,18 @@
BLER for test 8.
+
The test verifies that in each case the expected number of packets received correct corresponds to a Bernoulli distribution with a confidence interval of 95%, where the probability of success in each trail is :math:`1-BER` and :math:`n` is the total number of packet sent.
+MIMO Model
+----------
+The test suite ``lte-mimo`` aims at verifying both the effect of the gain considered for each Transmission Mode on the system performance and the Transmission Mode switching through the scheduler interface. The test consists on checking whether the amount of bytes received during a certain window of time (0.1 seconds in our case) corresponds to the expected ones according to the values of transport block
+size reported in table 7.1.7.2.1-1 of [TS36.213]_, similarly to what done for the tests of the schedulers.
+
+The test is performed both for Round Robin and Proportional Fair schedulers. The test passes if the measured throughput matches with the reference throughput within a relative tolerance of 0.1. This tolerance is needed to account for the
+transient behavior at the beginning of the simulation and the transition phase between the Transmission Modes.
Antenna Model integration
--- a/src/lte/doc/source/lte-user.rst Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/doc/source/lte-user.rst Mon Apr 23 13:16:03 2012 +0200
@@ -439,6 +439,41 @@
This command will go through the lists of all nodes and of all buildings, determine for each user if it is indoor or outdoor, and if indoor it will also determine the building in which the user is located and the corresponding floor and number inside the building.
+MIMO Model
+----------
+
+Is this subsection we illustrate how to configure the MIMO parameters. LTE defines 7 types of transmission modes:
+
+ * Transmission Mode 1: SISO.
+ * Transmission Mode 2: MIMO Tx Diversity.
+ * Transmission Mode 3: MIMO Spatial Multiplexity Open Loop.
+ * Transmission Mode 4: MIMO Spatial Multiplexity Closed Loop.
+ * Transmission Mode 5: MIMO Multi-User.
+ * Transmission Mode 6: Closer loop single layer precoding.
+ * Transmission Mode 7: Single antenna port 5.
+
+According to model implemented, the simulator includes the first three transmission modes types. The default one is the Transmission Mode 1 (SISO). In order to change the default Transmission Mode to be used, the attribute ``DefaultTransmissionMode`` of the ``LteEnbRrc`` can be used, as shown in the following::
+
+ Config::SetDefault ("ns3::LteEnbRrc::DefaultTransmissionMode", UintegerValue (0)); // SISO
+ Config::SetDefault ("ns3::LteEnbRrc::DefaultTransmissionMode", UintegerValue (1)); // MIMO Tx diversity (1 layer)
+ Config::SetDefault ("ns3::LteEnbRrc::DefaultTransmissionMode", UintegerValue (2)); // MIMO Spatial Multiplexity (2 layers)
+
+For changing the transmission mode of a certain user during the simulation a specific interface has been implemented in both standard schedulers::
+
+ void TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode);
+
+This method can be used both for developing transmission mode decision engine (i.e., for optimizing the transmission mode according to channel condition and/or user's requirements) and for manual switching from simulation script. In the latter case, the switching can be done as shown in the following::
+
+ Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
+ PointerValue ptrval;
+ enbNetDev->GetAttribute ("FfMacScheduler", ptrval);
+ Ptr<RrFfMacScheduler> rrsched = ptrval.Get<RrFfMacScheduler> ();
+ Simulator::Schedule (Seconds (0.2), &RrFfMacScheduler::TransmissionModeConfigurationUpdate, rrsched, rnti, 1);
+
+Finally, the model implemented can be reconfigured according to different MIMO models by updating the gain values (the only constraints is that the gain has to be constant during simulation run-time and common for the layers). The gain of each Transmission Mode can be changed according to the standard ns3 attribute system, where the attributes are: ``TxMode1Gain``, ``TxMode2Gain``, ``TxMode3Gain``, ``TxMode4Gain``, ``TxMode5Gain``, ``TxMode6Gain`` and ``TxMode7Gain``. By default only ``TxMode1Gain``, ``TxMode2Gain`` and ``TxMode3Gain`` have a meaningful value, that are the ones derived by _[CatreuxMIMO] (i.e., respectively 0.0, 4.2 and -2.8 dB).
+
+
+
--- a/src/lte/model/lte-common.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-common.cc Mon Apr 23 13:16:03 2012 +0200
@@ -74,6 +74,25 @@
}
+LteUeConfig_t::LteUeConfig_t ()
+{
+}
+
+
+
+bool
+operator == (const LteUeConfig_t &a, const LteUeConfig_t &b)
+{
+ return (a.m_rnti == b.m_rnti);
+}
+
+bool
+operator < (const LteUeConfig_t& a, const LteUeConfig_t& b)
+{
+ return (a.m_rnti < b.m_rnti);
+}
+
+
uint16_t
LteFfConverter::double2fpS11dot3 (double val)
{
@@ -147,5 +166,37 @@
}
+uint8_t
+TransmissionModesLayers::TxMode2LayerNum (uint8_t txMode)
+{
+ uint8_t nLayer = 0;
+ switch (txMode)
+ {
+ case 0: // Tx MODE 1: SISO
+ nLayer = 1;
+ break;
+ case 1: // Tx MODE 2: MIMO Tx Diversity
+ nLayer = 1;
+ break;
+ case 2: // Tx MODE 3: MIMO Spatial Multiplexity Open Loop
+ nLayer = 2;
+ break;
+ case 3: // Tx MODE 4: MIMO Spatial Multiplexity Closed Loop
+ nLayer = 2;
+ break;
+ case 4: // Tx MODE 5: MIMO Multi-User
+ nLayer = 2;
+ break;
+ case 5: // Tx MODE 6: Closer loop single layer percoding
+ nLayer = 1;
+ break;
+ case 6: // Tx MODE 7: Single antenna port 5
+ nLayer = 1;
+ break;
+ }
+ return (nLayer);
+}
+
+
}; // namespace ns3
--- a/src/lte/model/lte-common.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-common.h Mon Apr 23 13:16:03 2012 +0200
@@ -53,6 +53,19 @@
friend bool operator < (const ImsiLcidPair_t &a, const ImsiLcidPair_t &b);
};
+struct LteUeConfig_t
+{
+ uint16_t m_rnti;
+ uint8_t m_transmissionMode;
+
+ public:
+ LteUeConfig_t ();
+
+ friend bool operator == (const LteUeConfig_t &a, const LteUeConfig_t &b);
+ friend bool operator < (const LteUeConfig_t &a, const LteUeConfig_t &b);
+};
+
+
class LteFfConverter
{
@@ -78,6 +91,12 @@
};
+class TransmissionModesLayers
+{
+ public:
+ static uint8_t TxMode2LayerNum (uint8_t txMode);
+};
+
}; // namespace ns3
--- a/src/lte/model/lte-enb-cmac-sap.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-enb-cmac-sap.h Mon Apr 23 13:16:03 2012 +0200
@@ -16,6 +16,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Nicola Baldo <nbaldo@cttc.es>
+ * Marco Miozzo <mmiozzo@cttc.es>
*/
#ifndef LTE_ENB_CMAC_SAP_H
@@ -24,6 +25,8 @@
#include <ns3/packet.h>
#include <ns3/ff-mac-common.h>
#include <ns3/eps-bearer.h>
+#include <ns3/lte-common.h>
+#include <ns3/ff-mac-csched-sap.h>
namespace ns3 {
@@ -94,6 +97,8 @@
* \param lcid
*/
virtual void ReleaseLc (uint16_t rnti, uint8_t lcid) = 0;
+
+ virtual void RrcUpdateConfigurationReq (FfMacCschedSapProvider::CschedUeConfigReqParameters params) = 0;
};
@@ -118,6 +123,7 @@
* \param success true if the operation was successful, false otherwise
*/
virtual void NotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success) = 0;
+ virtual void RrcConfigurationUpdateInd (LteUeConfig_t params) = 0;
};
--- a/src/lte/model/lte-enb-mac.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-enb-mac.cc Mon Apr 23 13:16:03 2012 +0200
@@ -34,6 +34,7 @@
#include <ns3/lte-ue-phy.h>
#include "ns3/lte-mac-sap.h"
+#include <ns3/lte-common.h>
NS_LOG_COMPONENT_DEFINE ("LteEnbMac");
@@ -61,6 +62,7 @@
virtual void AddLc (LcInfo lcinfo, LteMacSapUser* msu);
virtual void ReconfigureLc (LcInfo lcinfo);
virtual void ReleaseLc (uint16_t rnti, uint8_t lcid);
+ virtual void RrcUpdateConfigurationReq (FfMacCschedSapProvider::CschedUeConfigReqParameters params);
private:
LteEnbMac* m_mac;
@@ -102,6 +104,12 @@
m_mac->DoReleaseLc (rnti, lcid);
}
+void
+EnbMacMemberLteEnbCmacSapProvider::RrcUpdateConfigurationReq (FfMacCschedSapProvider::CschedUeConfigReqParameters params)
+{
+ m_mac->DoRrcUpdateConfigurationReq (params);
+}
+
class EnbMacMemberFfMacSchedSapUser : public FfMacSchedSapUser
@@ -660,7 +668,7 @@
LteEnbMac::DoTransmitPdu (LteMacSapProvider::TransmitPduParameters params)
{
NS_LOG_FUNCTION (this);
- LteRadioBearerTag tag (params.rnti, params.lcid);
+ LteRadioBearerTag tag (params.rnti, params.lcid, params.layer);
params.pdu->AddPacketTag (tag);
// Ptr<PacketBurst> pb = CreateObject<PacketBurst> ();
// pb->AddPacket (params.pdu);
@@ -709,7 +717,8 @@
ind.m_buildDataList.at (i).m_rlcPduList.at (j).at (k).m_logicalChannelIdentity);
it = m_rlcAttached.find (flow);
NS_ASSERT_MSG (it != m_rlcAttached.end (), "rnti=" << flow.m_rnti << " lcid=" << (uint32_t) flow.m_lcId);
- (*it).second->NotifyTxOpportunity (ind.m_buildDataList.at (i).m_rlcPduList.at (j).at (k).m_size);
+ NS_LOG_DEBUG (this << " rnti= " << flow.m_rnti << " lcid= " << (uint32_t) flow.m_lcId << " layer= " << k);
+ (*it).second->NotifyTxOpportunity (ind.m_buildDataList.at (i).m_rlcPduList.at (j).at (k).m_size, k);
}
}
// send the relative DCI
@@ -817,6 +826,24 @@
LteEnbMac::DoCschedUeConfigUpdateInd (FfMacCschedSapUser::CschedUeConfigUpdateIndParameters params)
{
NS_LOG_FUNCTION (this);
+ // propagates to RRC
+ LteUeConfig_t ueConfigUpdate;
+ ueConfigUpdate.m_rnti = params.m_rnti;
+ ueConfigUpdate.m_transmissionMode = params.m_transmissionMode;
+ m_cmacSapUser->RrcConfigurationUpdateInd (ueConfigUpdate);
+}
+
+void
+LteEnbMac::DoRrcUpdateConfigurationReq (FfMacCschedSapProvider::CschedUeConfigReqParameters params)
+{
+ NS_LOG_FUNCTION (this);
+ // propagates to PHY layer
+ m_enbPhySapProvider->SetTransmissionMode (params.m_rnti, params.m_transmissionMode);
+ // propagates to scheduler
+ FfMacCschedSapProvider::CschedUeConfigReqParameters req;
+ req.m_rnti = params.m_rnti;
+ req.m_transmissionMode = params.m_transmissionMode;
+ m_cschedSapProvider->CschedUeConfigReq (req);
}
void
--- a/src/lte/model/lte-enb-mac.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-enb-mac.h Mon Apr 23 13:16:03 2012 +0200
@@ -162,6 +162,8 @@
// forwarded from FfMacSchedSapUser
void DoSchedDlConfigInd (FfMacSchedSapUser::SchedDlConfigIndParameters ind);
void DoSchedUlConfigInd (FfMacSchedSapUser::SchedUlConfigIndParameters params);
+
+ void DoRrcUpdateConfigurationReq (FfMacCschedSapProvider::CschedUeConfigReqParameters params);
/**
* \brief Forwarded from LteEnbPhySapUser: trigger the start from a new frame
--- a/src/lte/model/lte-enb-phy-sap.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-enb-phy-sap.h Mon Apr 23 13:16:03 2012 +0200
@@ -53,6 +53,12 @@
* \param dlBandwidth the DL bandwidth in RB
*/
virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth) = 0;
+
+ /**
+ * \param rnti the RNTI of the user
+ * \param txMode the transmissionMode of the user
+ */
+ virtual void SetTransmissionMode (uint16_t rnti, uint8_t txMode) = 0;
/**
*
--- a/src/lte/model/lte-enb-phy.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-enb-phy.cc Mon Apr 23 13:16:03 2012 +0200
@@ -56,6 +56,8 @@
virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth);
virtual void SetCellId (uint16_t cellId);
virtual void SendIdealControlMessage (Ptr<IdealControlMessage> msg);
+ virtual void SetTransmissionMode (uint16_t rnti, uint8_t txMode);
+
private:
LteEnbPhy* m_phy;
@@ -91,6 +93,12 @@
m_phy->DoSendIdealControlMessage (msg);
}
+void
+EnbMemberLteEnbPhySapProvider::SetTransmissionMode (uint16_t rnti, uint8_t txMode)
+{
+ m_phy->DoSetTransmissionMode (rnti, txMode);
+}
+
////////////////////////////////////////
// generic LteEnbPhy methods
@@ -407,7 +415,7 @@
{
rbMap.push_back (i);
}
- m_uplinkSpectrumPhy->AddExpectedTb (dci->GetDci ().m_rnti, dci->GetDci ().m_tbSize, dci->GetDci ().m_mcs, rbMap);
+ m_uplinkSpectrumPhy->AddExpectedTb (dci->GetDci ().m_rnti, dci->GetDci ().m_tbSize, dci->GetDci ().m_mcs, rbMap, 0 /* always SISO*/);
}
}
ctrlMsg.pop_front ();
@@ -493,4 +501,12 @@
}
+void
+LteEnbPhy::DoSetTransmissionMode (uint16_t rnti, uint8_t txMode)
+{
+ NS_LOG_FUNCTION (this << rnti << (uint16_t)txMode);
+ // UL supports only SISO MODE
+}
+
+
};
--- a/src/lte/model/lte-enb-phy.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-enb-phy.h Mon Apr 23 13:16:03 2012 +0200
@@ -151,6 +151,8 @@
bool AddUePhy (uint16_t rnti, Ptr<LteUePhy> phy);
bool DeleteUePhy (uint16_t rnti);
+
+ virtual void DoSetTransmissionMode (uint16_t rnti, uint8_t txMode);
/**
@@ -187,6 +189,7 @@
uint32_t m_nrFrames;
uint32_t m_nrSubFrames;
+
};
--- a/src/lte/model/lte-enb-rrc.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-enb-rrc.cc Mon Apr 23 13:16:03 2012 +0200
@@ -16,6 +16,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Nicola Baldo <nbaldo@cttc.es>
+ * Marco Miozzo <mmiozzo@cttc.es>
*/
#include <ns3/fatal-error.h>
@@ -32,6 +33,13 @@
#include "lte-radio-bearer-info.h"
#include "lte-radio-bearer-tag.h"
#include "ns3/object-map.h"
+#include <ns3/ff-mac-csched-sap.h>
+
+// WILD HACK for UE-RRC direct communications
+#include <ns3/node-list.h>
+#include <ns3/node.h>
+#include <ns3/lte-ue-net-device.h>
+#include <ns3/lte-ue-rrc.h>
NS_LOG_COMPONENT_DEFINE ("LteEnbRrc");
@@ -52,6 +60,7 @@
EnbRrcMemberLteEnbCmacSapUser (LteEnbRrc* rrc);
virtual void NotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success);
+ virtual void RrcConfigurationUpdateInd (LteUeConfig_t params);
private:
LteEnbRrc* m_rrc;
@@ -68,6 +77,12 @@
m_rrc->DoNotifyLcConfigResult (rnti, lcid, success);
}
+void
+EnbRrcMemberLteEnbCmacSapUser::RrcConfigurationUpdateInd (LteUeConfig_t params)
+{
+ m_rrc->DoRrcConfigurationUpdateInd (params);
+}
+
////////////////////////////////
// PDCP SAP Forwarder
@@ -231,6 +246,12 @@
ObjectMapValue (),
MakeObjectMapAccessor (&LteEnbRrc::m_ueMap),
MakeObjectMapChecker<UeInfo> ())
+ .AddAttribute ("DefaultTransmissionMode",
+ "The default UEs' transmission mode (0: SISO)",
+ UintegerValue (0), // default tx-mode
+ MakeUintegerAccessor (&LteEnbRrc::m_defaultTransmissionMode),
+ MakeUintegerChecker<uint8_t> ())
+
;
return tid;
}
@@ -367,6 +388,12 @@
lcinfo.gbrUl = bearer.gbrQosInfo.gbrUl;
lcinfo.gbrDl = bearer.gbrQosInfo.gbrDl;
m_cmacSapProvider->AddLc (lcinfo, rlc->GetLteMacSapUser ());
+
+ // Transmission mode settings
+ LteUeConfig_t ueConfig;
+ ueConfig.m_rnti = rnti;
+ ueConfig.m_transmissionMode = m_defaultTransmissionMode;
+ DoRrcConfigurationUpdateInd (ueConfig);
return lcid;
}
@@ -474,6 +501,49 @@
}
+void
+LteEnbRrc::DoRrcConfigurationUpdateInd (LteUeConfig_t params)
+{
+ NS_LOG_FUNCTION (this);
+ // up tp now only for TxMode change
+ // update the peer UE-RRC on the change
+ NodeList::Iterator listEnd = NodeList::End ();
+ bool done = false;
+ for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
+ {
+ Ptr<Node> node = *i;
+ int nDevs = node->GetNDevices ();
+ for (int j = 0; j < nDevs; j++)
+ {
+ Ptr<LteUeNetDevice> uedev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
+ if (!uedev)
+ {
+ continue;
+ }
+ else
+ {
+ Ptr<LteUeRrc> ueRrc = uedev->GetRrc ();
+ if (ueRrc->GetRnti () == params.m_rnti)
+ {
+ ueRrc->DoRrcConfigurationUpdateInd (params);
+ done = true;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+ }
+ NS_ASSERT_MSG (done , " Unable to find peer UE-RRC, RNTI " << params.m_rnti);
+ // answer to MAC (and scheduler)
+ FfMacCschedSapProvider::CschedUeConfigReqParameters req;
+ req.m_rnti = params.m_rnti;
+ req.m_transmissionMode = params.m_transmissionMode;
+ m_cmacSapProvider->RrcUpdateConfigurationReq (req);
+
+}
+
--- a/src/lte/model/lte-enb-rrc.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-enb-rrc.h Mon Apr 23 13:16:03 2012 +0200
@@ -222,7 +222,8 @@
private:
void DoReceiveRrcPdu (LtePdcpSapUser::ReceiveRrcPduParameters params);
-
+ void DoRrcConfigurationUpdateInd (LteUeConfig_t params);
+
void DoNotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success);
LtePdcpSapProvider* GetLtePdcpSapProvider (uint16_t rnti, uint8_t lcid);
@@ -244,6 +245,8 @@
uint16_t m_lastAllocatedRnti;
std::map<uint16_t, Ptr<UeInfo> > m_ueMap;
+
+ uint8_t m_defaultTransmissionMode;
};
--- a/src/lte/model/lte-mac-sap.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-mac-sap.h Mon Apr 23 13:16:03 2012 +0200
@@ -47,6 +47,7 @@
Ptr<Packet> pdu; /**< the RLC PDU */
uint16_t rnti; /**< the C-RNTI identifying the UE */
uint8_t lcid; /**< the logical channel id corresponding to the sending RLC instance */
+ uint8_t layer; /**< the layer value that was passed by the MAC in the call to NotifyTxOpportunity that generated this PDU */
};
/**
@@ -98,8 +99,9 @@
* transmission opportunity to this RLC instance.
*
* \param bytes the number of bytes to transmit
+ * \param layer the layer of transmission (MIMO)
*/
- virtual void NotifyTxOpportunity (uint32_t bytes) = 0;
+ virtual void NotifyTxOpportunity (uint32_t bytes, uint8_t layer) = 0;
/**
* Called by the MAC to notify the RLC that an HARQ process related
--- a/src/lte/model/lte-radio-bearer-tag.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-radio-bearer-tag.cc Mon Apr 23 13:16:03 2012 +0200
@@ -53,7 +53,8 @@
LteRadioBearerTag::LteRadioBearerTag ()
: m_rnti (0),
- m_lcid (0)
+ m_lcid (0),
+ m_layer (0)
{
}
LteRadioBearerTag::LteRadioBearerTag (uint16_t rnti, uint8_t lcid)
@@ -62,6 +63,13 @@
{
}
+LteRadioBearerTag::LteRadioBearerTag (uint16_t rnti, uint8_t lcid, uint8_t layer)
+: m_rnti (rnti),
+ m_lcid (lcid),
+ m_layer (layer)
+{
+}
+
void
LteRadioBearerTag::SetRnti (uint16_t rnti)
{
@@ -74,6 +82,12 @@
m_lcid = lcid;
}
+void
+LteRadioBearerTag::SetLayer (uint8_t layer)
+{
+ m_layer = layer;
+}
+
uint32_t
LteRadioBearerTag::GetSerializedSize (void) const
{
@@ -106,6 +120,12 @@
return m_lcid;
}
+uint8_t
+LteRadioBearerTag::GetLayer () const
+{
+ return m_layer;
+}
+
void
LteRadioBearerTag::Print (std::ostream &os) const
{
--- a/src/lte/model/lte-radio-bearer-tag.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-radio-bearer-tag.h Mon Apr 23 13:16:03 2012 +0200
@@ -46,6 +46,11 @@
* Create a LteRadioBearerTag with the given RNTI and LC id
*/
LteRadioBearerTag (uint16_t rnti, uint8_t lcId);
+
+ /**
+ * Create a LteRadioBearerTag with the given RNTI, LC id and layer
+ */
+ LteRadioBearerTag (uint16_t rnti, uint8_t lcId, uint8_t layer);
/**
* Set the RNTI to the given value.
@@ -60,6 +65,13 @@
* @param lcid the value of the RNTI to set
*/
void SetLcid (uint8_t lcid);
+
+ /**
+ * Set the layer id to the given value.
+ *
+ * @param layer the value of the layer to set
+ */
+ void SetLayer (uint8_t lcid);
virtual void Serialize (TagBuffer i) const;
@@ -69,10 +81,12 @@
uint16_t GetRnti (void) const;
uint8_t GetLcid (void) const;
+ uint8_t GetLayer (void) const;
private:
uint16_t m_rnti;
uint8_t m_lcid;
+ uint8_t m_layer;
};
--- a/src/lte/model/lte-rlc-am.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-rlc-am.cc Mon Apr 23 13:16:03 2012 +0200
@@ -162,7 +162,7 @@
*/
void
-LteRlcAm::DoNotifyTxOpportunity (uint32_t bytes)
+LteRlcAm::DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer)
{
NS_LOG_FUNCTION (this << bytes);
NS_ASSERT_MSG (bytes > 2, "Tx opportunity too small = " << bytes);
@@ -500,6 +500,7 @@
params.pdu = packet;
params.rnti = m_rnti;
params.lcid = m_lcid;
+ params.layer = layer;
m_macSapProvider->TransmitPdu (params);
}
--- a/src/lte/model/lte-rlc-am.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-rlc-am.h Mon Apr 23 13:16:03 2012 +0200
@@ -48,7 +48,7 @@
/**
* MAC SAP
*/
- virtual void DoNotifyTxOpportunity (uint32_t bytes);
+ virtual void DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer);
virtual void DoNotifyHarqDeliveryFailure ();
virtual void DoReceivePdu (Ptr<Packet> p);
--- a/src/lte/model/lte-rlc-um.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-rlc-um.cc Mon Apr 23 13:16:03 2012 +0200
@@ -98,7 +98,7 @@
*/
void
-LteRlcUm::DoNotifyTxOpportunity (uint32_t bytes)
+LteRlcUm::DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer)
{
NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << bytes);
@@ -354,6 +354,7 @@
params.pdu = packet;
params.rnti = m_rnti;
params.lcid = m_lcid;
+ params.layer = layer;
m_macSapProvider->TransmitPdu (params);
--- a/src/lte/model/lte-rlc-um.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-rlc-um.h Mon Apr 23 13:16:03 2012 +0200
@@ -47,7 +47,7 @@
/**
* MAC SAP
*/
- virtual void DoNotifyTxOpportunity (uint32_t bytes);
+ virtual void DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer);
virtual void DoNotifyHarqDeliveryFailure ();
virtual void DoReceivePdu (Ptr<Packet> p);
--- a/src/lte/model/lte-rlc.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-rlc.cc Mon Apr 23 13:16:03 2012 +0200
@@ -42,7 +42,7 @@
LteRlcSpecificLteMacSapUser (LteRlc* rlc);
// Interface implemented from LteMacSapUser
- virtual void NotifyTxOpportunity (uint32_t bytes);
+ virtual void NotifyTxOpportunity (uint32_t bytes, uint8_t layer);
virtual void NotifyHarqDeliveryFailure ();
virtual void ReceivePdu (Ptr<Packet> p);
@@ -61,9 +61,9 @@
}
void
-LteRlcSpecificLteMacSapUser::NotifyTxOpportunity (uint32_t bytes)
+LteRlcSpecificLteMacSapUser::NotifyTxOpportunity (uint32_t bytes, uint8_t layer)
{
- m_rlc->DoNotifyTxOpportunity (bytes);
+ m_rlc->DoNotifyTxOpportunity (bytes, layer);
}
void
@@ -210,13 +210,14 @@
}
void
-LteRlcSm::DoNotifyTxOpportunity (uint32_t bytes)
+LteRlcSm::DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer)
{
NS_LOG_FUNCTION (this << bytes);
LteMacSapProvider::TransmitPduParameters params;
params.pdu = Create<Packet> (bytes);
params.rnti = m_rnti;
params.lcid = m_lcid;
+ params.layer = layer;
// RLC Performance evaluation
RlcTag tag (Simulator::Now());
--- a/src/lte/model/lte-rlc.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-rlc.h Mon Apr 23 13:16:03 2012 +0200
@@ -111,7 +111,7 @@
LteRlcSapProvider* m_rlcSapProvider;
// Interface forwarded by LteMacSapUser
- virtual void DoNotifyTxOpportunity (uint32_t bytes) = 0;
+ virtual void DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer) = 0;
virtual void DoNotifyHarqDeliveryFailure () = 0;
virtual void DoReceivePdu (Ptr<Packet> p) = 0;
@@ -150,7 +150,7 @@
static TypeId GetTypeId (void);
virtual void DoTransmitPdcpPdu (Ptr<Packet> p);
- virtual void DoNotifyTxOpportunity (uint32_t bytes);
+ virtual void DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer);
virtual void DoNotifyHarqDeliveryFailure ();
virtual void DoReceivePdu (Ptr<Packet> p);
--- a/src/lte/model/lte-spectrum-phy.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-spectrum-phy.cc Mon Apr 23 13:16:03 2012 +0200
@@ -36,20 +36,48 @@
#include <ns3/lte-mi-error-model.h>
#include <ns3/lte-radio-bearer-tag.h>
#include <ns3/boolean.h>
+#include <ns3/double.h>
NS_LOG_COMPONENT_DEFINE ("LteSpectrumPhy");
namespace ns3 {
+
+
+TbId_t::TbId_t ()
+{
+}
+TbId_t::TbId_t (const uint16_t a, const uint8_t b)
+: m_rnti (a),
+ m_layer (b)
+{
+}
+
+bool
+operator == (const TbId_t &a, const TbId_t &b)
+{
+ return ( (a.m_rnti == b.m_rnti) && (a.m_layer == b.m_layer) );
+}
+
+bool
+operator < (const TbId_t& a, const TbId_t& b)
+{
+ return ( (a.m_rnti < b.m_rnti) || ( (a.m_rnti == b.m_rnti) && (a.m_layer < b.m_layer) ) );
+}
NS_OBJECT_ENSURE_REGISTERED (LteSpectrumPhy);
LteSpectrumPhy::LteSpectrumPhy ()
: m_state (IDLE),
- m_random (0.0, 1.0)
+ m_random (0.0, 1.0),
+ m_transmissionMode (0)
{
NS_LOG_FUNCTION (this);
m_interference = CreateObject<LteInterference> ();
+ for (uint8_t i = 0; i < 7; i++)
+ {
+ m_txModeGain.push_back (1.0);
+ }
}
@@ -57,6 +85,7 @@
{
NS_LOG_FUNCTION (this);
m_expectedTbs.clear ();
+ m_txModeGain.clear ();
}
void LteSpectrumPhy::DoDispose ()
@@ -118,7 +147,7 @@
"Activate/Deactivate the error model (by default is active).",
BooleanValue (true),
MakeBooleanAccessor (&LteSpectrumPhy::m_pemEnabled),
- MakeBooleanChecker ());
+ MakeBooleanChecker ())
;
return tid;
}
@@ -421,11 +450,14 @@
void
-LteSpectrumPhy::AddExpectedTb (uint16_t rnti, uint16_t size, uint8_t mcs, std::vector<int> map)
+LteSpectrumPhy::AddExpectedTb (uint16_t rnti, uint16_t size, uint8_t mcs, std::vector<int> map, uint8_t layer)
{
- NS_LOG_LOGIC (this << " rnti: " << rnti << " size " << size << " mcs " << (uint16_t)mcs);
+ NS_LOG_LOGIC (this << " rnti: " << rnti << " size " << size << " mcs " << (uint16_t)mcs << " layer " << (uint8_t)layer);
+ TbId_t tbId;
+ tbId.m_rnti = rnti;
+ tbId.m_layer = layer;
expectedTbs_t::iterator it;
- it = m_expectedTbs.find (rnti);
+ it = m_expectedTbs.find (tbId);
if (it != m_expectedTbs.end ())
{
// migth be a TB of an unreceived packet (due to high progpalosses)
@@ -433,7 +465,7 @@
}
// insert new entry
tbInfo_t tbInfo = {size, mcs, map, false};
- m_expectedTbs.insert (std::pair<uint16_t, tbInfo_t> (rnti,tbInfo ));
+ m_expectedTbs.insert (std::pair<TbId_t, tbInfo_t> (tbId,tbInfo ));
}
@@ -448,16 +480,22 @@
// this will trigger CQI calculation and Error Model evaluation
// as a side effect, the error model should update the error status of all TBs
m_interference->EndRx ();
- NS_LOG_INFO (this << " No. of burts " << m_rxPacketBurstList.size ());
+ NS_LOG_DEBUG (this << " No. of burts " << m_rxPacketBurstList.size ());
NS_LOG_DEBUG (this << " Expected TBs " << m_expectedTbs.size ());
expectedTbs_t::iterator itTb = m_expectedTbs.begin ();
+
+ // apply transmission mode gain
+ NS_LOG_DEBUG (this << " txMode " << (uint16_t)m_transmissionMode << " gain " << m_txModeGain.at (m_transmissionMode));
+ NS_ASSERT (m_transmissionMode < m_txModeGain.size ());
+ m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
+
while (itTb!=m_expectedTbs.end ())
{
if (m_pemEnabled)
{
double errorRate = LteMiErrorModel::GetTbError (m_sinrPerceived, (*itTb).second.rbBitmap, (*itTb).second.size, (*itTb).second.mcs);
(*itTb).second.corrupt = m_random.GetValue () > errorRate ? false : true;
- NS_LOG_DEBUG (this << "RNTI " << (*itTb).first << " size " << (*itTb).second.size << " mcs " << (uint32_t)(*itTb).second.mcs << " bitmap " << (*itTb).second.rbBitmap.size () << " ErrorRate " << errorRate << " corrupted " << (*itTb).second.corrupt);
+ NS_LOG_DEBUG (this << "RNTI " << (*itTb).first.m_rnti << " size " << (*itTb).second.size << " mcs " << (uint32_t)(*itTb).second.mcs << " bitmap " << (*itTb).second.rbBitmap.size () << " layer " << (uint16_t)(*itTb).first.m_layer << " ErrorRate " << errorRate << " corrupted " << (*itTb).second.corrupt);
}
// for (uint16_t i = 0; i < (*itTb).second.rbBitmap.size (); i++)
@@ -475,9 +513,11 @@
// retrieve TB info of this packet
LteRadioBearerTag tag;
(*j)->PeekPacketTag (tag);
- itTb = m_expectedTbs.find (tag.GetRnti ());
- //(*j)->AddPacketTag (tag);
- NS_LOG_INFO (this << " Packet of " << tag.GetRnti ());
+ TbId_t tbId;
+ tbId.m_rnti = tag.GetRnti ();
+ tbId.m_layer = tag.GetLayer ();
+ itTb = m_expectedTbs.find (tbId);
+ NS_LOG_INFO (this << " Packet of " << tbId.m_rnti << " layer " << (uint8_t) tbId.m_layer);
if (itTb!=m_expectedTbs.end ())
{
if (!(*itTb).second.corrupt)
@@ -514,5 +554,41 @@
m_interference->AddSinrChunkProcessor (p);
}
+void
+LteSpectrumPhy::SetTransmissionMode (uint8_t txMode)
+{
+ NS_LOG_FUNCTION (this << (uint16_t) txMode);
+ NS_ASSERT_MSG (txMode < m_txModeGain.size (), "TransmissionMode not available: 1.." << m_txModeGain.size ());
+ m_transmissionMode = txMode;
+}
+
+
+void
+LteSpectrumPhy::SetTxModeGain (uint8_t txMode, double gain)
+{
+ NS_LOG_FUNCTION (this << " txmode " << (uint16_t)txMode << " gain " << gain);
+ // convert to linear
+ gain = pow (10.0, (gain / 10.0));
+ if (m_txModeGain.size () < txMode)
+ {
+ m_txModeGain.resize (txMode);
+ }
+ std::vector <double> temp;
+ temp = m_txModeGain;
+ m_txModeGain.clear ();
+ for (uint8_t i = 0; i < temp.size (); i++)
+ {
+ if (i==txMode-1)
+ {
+ m_txModeGain.push_back (gain);
+ }
+ else
+ {
+ m_txModeGain.push_back (temp.at (i));
+ }
+ }
+}
+
+
} // namespace ns3
--- a/src/lte/model/lte-spectrum-phy.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-spectrum-phy.h Mon Apr 23 13:16:03 2012 +0200
@@ -41,7 +41,20 @@
namespace ns3 {
+struct TbId_t
+{
+ uint16_t m_rnti;
+ uint8_t m_layer;
+
+ public:
+ TbId_t ();
+ TbId_t (const uint16_t a, const uint8_t b);
+
+ friend bool operator == (const TbId_t &a, const TbId_t &b);
+ friend bool operator < (const TbId_t &a, const TbId_t &b);
+};
+
struct tbInfo_t
{
uint16_t size;
@@ -50,7 +63,7 @@
bool corrupt;
};
-typedef std::map<uint16_t, tbInfo_t> expectedTbs_t;
+typedef std::map<TbId_t, tbInfo_t> expectedTbs_t;
class LteNetDevice;
@@ -176,8 +189,9 @@
* \param size the size of the TB
* \param mcs the MCS of the TB
* \param map the map of RB(s) used
+ * \param layer the layer (in case of MIMO tx)
*/
- void AddExpectedTb (uint16_t rnti, uint16_t size, uint8_t mcs, std::vector<int> map);
+ void AddExpectedTb (uint16_t rnti, uint16_t size, uint8_t mcs, std::vector<int> map, uint8_t layer);
/**
*
@@ -185,11 +199,24 @@
* \param sinr vector of sinr perceived per each RB
*/
void UpdateSinrPerceived (const SpectrumValue& sinr);
+
+ /**
+ *
+ *
+ * \param txMode UE transmission mode (SISO, MIMO tx diversity, ...)
+ */
+ void SetTransmissionMode (uint8_t txMode);
+
+ friend class LteUePhy;
+
private:
void ChangeState (State newState);
void EndTx ();
void EndRx ();
+
+ void SetTxModeGain (uint8_t txMode, double gain);
+
Ptr<MobilityModel> m_mobility;
Ptr<AntennaModel> m_antenna;
@@ -225,6 +252,10 @@
UniformVariable m_random;
bool m_pemEnabled; // when true (default) the phy error model is enabled
+
+ uint8_t m_transmissionMode; // for UEs: store the transmission mode
+ std::vector <double> m_txModeGain; // duplicate value of LteUePhy
+
};
--- a/src/lte/model/lte-ue-cmac-sap.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-ue-cmac-sap.h Mon Apr 23 13:16:03 2012 +0200
@@ -24,6 +24,7 @@
#include <ns3/packet.h>
#include <ns3/ff-mac-common.h>
#include <ns3/eps-bearer.h>
+#include <ns3/lte-common.h>
namespace ns3 {
@@ -50,6 +51,8 @@
virtual void AddLc (uint8_t lcId, LteMacSapUser* msu) = 0;
virtual void RemoveLc (uint8_t lcId) = 0;
+
+ virtual void RrcUpdateConfigurationReq (LteUeConfig_t params) = 0;
};
--- a/src/lte/model/lte-ue-mac.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-ue-mac.cc Mon Apr 23 13:16:03 2012 +0200
@@ -56,6 +56,7 @@
virtual void ConfigureUe (uint16_t rnti);
virtual void AddLc (uint8_t lcId, LteMacSapUser* msu);
virtual void RemoveLc (uint8_t lcId);
+ virtual void RrcUpdateConfigurationReq (LteUeConfig_t params);
private:
LteUeMac* m_mac;
@@ -85,6 +86,11 @@
m_mac->DoRemoveLc (lcid);
}
+void
+UeMemberLteUeCmacSapProvider::RrcUpdateConfigurationReq (LteUeConfig_t params)
+{
+ m_mac->DoRrcUpdateConfigurationReq (params);
+}
class UeMemberLteMacSapProvider : public LteMacSapProvider
@@ -244,7 +250,7 @@
{
NS_LOG_FUNCTION (this);
NS_ASSERT_MSG (m_rnti == params.rnti, "RNTI mismatch between RLC and MAC");
- LteRadioBearerTag tag (params.rnti, params.lcid);
+ LteRadioBearerTag tag (params.rnti, params.lcid, 0 /* UE works in SISO mode*/);
params.pdu->AddPacketTag (tag);
// Ptr<PacketBurst> pb = CreateObject<PacketBurst> ();
// pb->AddPacket (params.pdu);
@@ -327,6 +333,14 @@
m_macSapUserMap.erase (lcId);
}
+void
+LteUeMac::DoRrcUpdateConfigurationReq (LteUeConfig_t params)
+{
+ NS_LOG_FUNCTION (this << " txMode " << (uint8_t) params.m_transmissionMode);
+ // forward info to PHY layer
+ m_uePhySapProvider->SetTransmissionMode (params.m_transmissionMode);
+}
+
void
LteUeMac::DoReceivePhyPdu (Ptr<Packet> p)
@@ -374,15 +388,8 @@
if (itBsr!=m_ulBsrReceived.end ())
{
NS_LOG_FUNCTION (this << "\t" << dci.m_tbSize / m_macSapUserMap.size () << " bytes to LC " << (uint16_t)(*it).first << " queue " << (*itBsr).second);
- (*it).second->NotifyTxOpportunity (dci.m_tbSize / activeLcs);
- if ((*itBsr).second >= dci.m_tbSize / activeLcs)
- {
- (*itBsr).second -= dci.m_tbSize / activeLcs;
- }
- else
- {
- (*itBsr).second = 0;
- }
+ (*it).second->NotifyTxOpportunity (dci.m_tbSize / activeLcs, 0); // UE works only in SISO mode
+ (*itBsr).second -= dci.m_tbSize / activeLcs;
}
}
--- a/src/lte/model/lte-ue-mac.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-ue-mac.h Mon Apr 23 13:16:03 2012 +0200
@@ -81,6 +81,7 @@
void DoConfigureUe (uint16_t rnti);
void DoAddLc (uint8_t lcId, LteMacSapUser* msu);
void DoRemoveLc (uint8_t lcId);
+ void DoRrcUpdateConfigurationReq (LteUeConfig_t params);
// forwarded from PHY SAP
void DoReceivePhyPdu (Ptr<Packet> p);
--- a/src/lte/model/lte-ue-phy-sap.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-ue-phy-sap.h Mon Apr 23 13:16:03 2012 +0200
@@ -52,6 +52,11 @@
* \param dlBandwidth the DL bandwidth in RB
*/
virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth) = 0;
+
+ /**
+ * \param txMode the transmissionMode of the user
+ */
+ virtual void SetTransmissionMode (uint8_t txMode) = 0;
/**
* \brief Send SendIdealControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel
--- a/src/lte/model/lte-ue-phy.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-ue-phy.cc Mon Apr 23 13:16:03 2012 +0200
@@ -55,6 +55,7 @@
virtual void SendMacPdu (Ptr<Packet> p);
virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth);
virtual void SendIdealControlMessage (Ptr<IdealControlMessage> msg);
+ virtual void SetTransmissionMode (uint8_t txMode);
private:
LteUePhy* m_phy;
@@ -84,6 +85,12 @@
m_phy->DoSendIdealControlMessage (msg);
}
+void
+UeMemberLteUePhySapProvider::SetTransmissionMode (uint8_t txMode)
+{
+ m_phy->DoSetTransmissionMode (txMode);
+}
+
////////////////////////////////////////
@@ -116,6 +123,7 @@
LteUePhy::~LteUePhy ()
{
+ m_txModeGain.clear ();
}
void
@@ -152,12 +160,41 @@
MakeDoubleAccessor (&LteUePhy::SetNoiseFigure,
&LteUePhy::GetNoiseFigure),
MakeDoubleChecker<double> ())
- .AddAttribute ("MacToChannelDelay",
- "The delay in TTI units that occurs between a scheduling decision in the MAC and the actual start of the transmission by the PHY. This is intended to be used to model the latency of real PHY and MAC implementations.",
- UintegerValue (1),
- MakeUintegerAccessor (&LteUePhy::SetMacChDelay,
- &LteUePhy::GetMacChDelay),
- MakeUintegerChecker<uint8_t> ())
+ .AddAttribute ("TxMode1Gain",
+ "Transmission mode 1 gain in dBm",
+ DoubleValue (0.0),
+ MakeDoubleAccessor (&LteUePhy::SetTxMode1Gain ),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TxMode2Gain",
+ "Transmission mode 2 gain in dBm",
+ DoubleValue (4.2),
+ MakeDoubleAccessor (&LteUePhy::SetTxMode2Gain ),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TxMode3Gain",
+ "Transmission mode 3 gain in dBm",
+ DoubleValue (-2.8),
+ MakeDoubleAccessor (&LteUePhy::SetTxMode3Gain ),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TxMode4Gain",
+ "Transmission mode 4 gain in dBm",
+ DoubleValue (0.0),
+ MakeDoubleAccessor (&LteUePhy::SetTxMode4Gain ),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TxMode5Gain",
+ "Transmission mode 5 gain in dBm",
+ DoubleValue (0.0),
+ MakeDoubleAccessor (&LteUePhy::SetTxMode5Gain ),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TxMode6Gain",
+ "Transmission mode 6 gain in dBm",
+ DoubleValue (0.0),
+ MakeDoubleAccessor (&LteUePhy::SetTxMode6Gain ),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TxMode7Gain",
+ "Transmission mode 7 gain in dBm",
+ DoubleValue (0.0),
+ MakeDoubleAccessor (&LteUePhy::SetTxMode7Gain ),
+ MakeDoubleChecker<double> ())
;
return tid;
}
@@ -328,6 +365,14 @@
LteUePhy::CreateDlCqiFeedbackMessage (const SpectrumValue& sinr)
{
NS_LOG_FUNCTION (this);
+
+ // apply transmission mode gain
+ NS_ASSERT (m_transmissionMode < m_txModeGain.size ());
+ SpectrumValue newSinr = sinr;
+ newSinr *= m_txModeGain.at (m_transmissionMode);
+// std::vector<int> cqi = m_amc->CreateCqiFeedbacks (newSinr);
+
+
// CREATE DlCqiIdealControlMessage
Ptr<DlCqiIdealControlMessage> msg = Create<DlCqiIdealControlMessage> ();
@@ -335,8 +380,9 @@
std::vector<int> cqi;
if (Simulator::Now () > m_p10CqiLast + m_p10CqiPeriocity)
{
- cqi = m_amc->CreateCqiFeedbacks (sinr, m_dlBandwidth);
-
+ cqi = m_amc->CreateCqiFeedbacks (newSinr, m_dlBandwidth);
+
+ int nLayer = TransmissionModesLayers::TxMode2LayerNum (m_transmissionMode);
int nbSubChannels = cqi.size ();
double cqiSum = 0.0;
int activeSubChannels = 0;
@@ -353,14 +399,19 @@
dlcqi.m_rnti = m_rnti;
dlcqi.m_ri = 1; // not yet used
dlcqi.m_cqiType = CqiListElement_s::P10; // Peridic CQI using PUCCH wideband
- if (activeSubChannels > 0)
+ NS_ASSERT_MSG (nLayer > 0, " nLayer negative");
+ NS_ASSERT_MSG (nLayer < 3, " nLayer limit is 2s");
+ for (int i = 0; i < nLayer; i++)
{
- dlcqi.m_wbCqi.push_back ((uint16_t) cqiSum / activeSubChannels);
- }
- else
- {
- // approximate with the worst case -> CQI = 1
- dlcqi.m_wbCqi.push_back (1);
+ if (activeSubChannels > 0)
+ {
+ dlcqi.m_wbCqi.push_back ((uint16_t) cqiSum / activeSubChannels);
+ }
+ else
+ {
+ // approximate with the worst case -> CQI = 1
+ dlcqi.m_wbCqi.push_back (1);
+ }
}
//NS_LOG_DEBUG (this << " Generate P10 CQI feedback " << (uint16_t) cqiSum / activeSubChannels);
dlcqi.m_wbPmi = 0; // not yet used
@@ -368,8 +419,9 @@
}
else if (Simulator::Now () > m_a30CqiLast + m_a30CqiPeriocity)
{
- cqi = m_amc->CreateCqiFeedbacks (sinr, GetRbgSize ());
- int nbSubChannels = m_dlBandwidth;
+ cqi = m_amc->CreateCqiFeedbacks (newSinr, GetRbgSize ());
+ int nLayer = TransmissionModesLayers::TxMode2LayerNum (m_transmissionMode);
+ int nbSubChannels = cqi.size ();
int rbgSize = GetRbgSize ();
double cqiSum = 0.0;
int cqiNum = 0;
@@ -389,7 +441,10 @@
//NS_LOG_DEBUG (this << " RBG CQI " << (uint16_t) cqiSum / rbgSize);
HigherLayerSelected_s hlCqi;
hlCqi.m_sbPmi = 0; // not yet used
- hlCqi.m_sbCqi.push_back ((uint16_t) cqiSum / rbgSize); // only CW0 (SISO mode)
+ for (int i = 0; i < nLayer; i++)
+ {
+ hlCqi.m_sbCqi.push_back ((uint16_t) cqiSum / rbgSize);
+ }
rbgMeas.m_higherLayerSelected.push_back (hlCqi);
cqiSum = 0.0;
cqiNum = 0;
@@ -455,8 +510,11 @@
}
// send TB info to LteSpectrumPhy
- NS_LOG_DEBUG (this << " UE " << m_rnti << " DCI " << dci.m_rnti << " bimap " << dci.m_rbBitmap);
- m_downlinkSpectrumPhy->AddExpectedTb (dci.m_rnti, dci.m_tbsSize.at (0), dci.m_mcs.at (0), dlRb); // SISO mode
+ NS_LOG_DEBUG (this << " UE " << m_rnti << " DCI " << dci.m_rnti << " bitmap " << dci.m_rbBitmap);
+ for (uint8_t i = 0; i < dci.m_tbsSize.size (); i++)
+ {
+ m_downlinkSpectrumPhy->AddExpectedTb (dci.m_rnti, dci.m_tbsSize.at (i), dci.m_mcs.at (i), dlRb, i);
+ }
SetSubChannelsForReception (dlRb);
@@ -541,5 +599,87 @@
}
+void
+LteUePhy::DoSetTransmissionMode (uint8_t txMode)
+{
+ NS_LOG_FUNCTION (this << (uint16_t)txMode);
+ m_transmissionMode = txMode;
+ m_downlinkSpectrumPhy->SetTransmissionMode (txMode);
+}
+
+
+void
+LteUePhy::SetTxMode1Gain (double gain)
+{
+ SetTxModeGain (1, gain);
+}
+
+void
+LteUePhy::SetTxMode2Gain (double gain)
+{
+ SetTxModeGain (2, gain);
+}
+
+void
+LteUePhy::SetTxMode3Gain (double gain)
+{
+ SetTxModeGain (3, gain);
+}
+
+void
+LteUePhy::SetTxMode4Gain (double gain)
+{
+ SetTxModeGain (4, gain);
+}
+
+void
+LteUePhy::SetTxMode5Gain (double gain)
+{
+ SetTxModeGain (5, gain);
+}
+
+void
+LteUePhy::SetTxMode6Gain (double gain)
+{
+ SetTxModeGain (6, gain);
+}
+
+void
+LteUePhy::SetTxMode7Gain (double gain)
+{
+ SetTxModeGain (7, gain);
+}
+
+
+void
+LteUePhy::SetTxModeGain (uint8_t txMode, double gain)
+{
+ NS_LOG_FUNCTION (this << gain);
+ // convert to linear
+ double gainLin = pow (10.0, (gain / 10.0));
+ if (m_txModeGain.size () < txMode)
+ {
+ m_txModeGain.resize (txMode);
+ }
+ std::vector <double> temp;
+ temp = m_txModeGain;
+ m_txModeGain.clear ();
+ for (uint8_t i = 0; i < temp.size (); i++)
+ {
+ if (i==txMode-1)
+ {
+ m_txModeGain.push_back (gainLin);
+ }
+ else
+ {
+ m_txModeGain.push_back (temp.at (i));
+ }
+ }
+ // forward the info to DL LteSpectrumPhy
+ m_downlinkSpectrumPhy->SetTxModeGain (txMode, gain);
+}
+
+
+
} // namespace ns3
--- a/src/lte/model/lte-ue-phy.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-ue-phy.h Mon Apr 23 13:16:03 2012 +0200
@@ -165,6 +165,10 @@
virtual void DoSendIdealControlMessage (Ptr<IdealControlMessage> msg);
virtual void ReceiveIdealControlMessage (Ptr<IdealControlMessage> msg);
+
+ virtual void DoSetTransmissionMode (uint8_t txMode);
+
+
@@ -195,9 +199,20 @@
* \param cellId the cell identifier of the eNB
*/
void SetEnbCellId (uint16_t cellId);
+
private:
+
+ void SetTxMode1Gain (double gain);
+ void SetTxMode2Gain (double gain);
+ void SetTxMode3Gain (double gain);
+ void SetTxMode4Gain (double gain);
+ void SetTxMode5Gain (double gain);
+ void SetTxMode6Gain (double gain);
+ void SetTxMode7Gain (double gain);
+ void SetTxModeGain (uint8_t txMode, double gain);
+
std::vector <int> m_subChannelsForTransmission;
std::vector <int> m_subChannelsForReception;
@@ -217,6 +232,9 @@
uint16_t m_rnti;
uint16_t m_enbCellId;
+
+ uint8_t m_transmissionMode;
+ std::vector <double> m_txModeGain;
};
--- a/src/lte/model/lte-ue-rrc.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-ue-rrc.cc Mon Apr 23 13:16:03 2012 +0200
@@ -298,6 +298,15 @@
return v;
}
+void
+LteUeRrc::DoRrcConfigurationUpdateInd (LteUeConfig_t params)
+{
+ NS_LOG_FUNCTION (this << " RNTI " << params.m_rnti << " txMode " << (uint16_t)params.m_transmissionMode);
+
+ // propagate the information to MAC layer
+ m_cmacSapProvider->RrcUpdateConfigurationReq (params);
+}
+
} // namespace ns3
--- a/src/lte/model/lte-ue-rrc.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/lte-ue-rrc.h Mon Apr 23 13:16:03 2012 +0200
@@ -162,6 +162,13 @@
*/
void SetForwardUpCallback (Callback <void, Ptr<Packet> > cb);
+ /**
+ * message from eNB-RRC for changing UE's configuration
+ * (up to now TxMode)
+ *
+ */
+ void DoRrcConfigurationUpdateInd (LteUeConfig_t params);
+
private:
void DoReceiveRrcPdu (LtePdcpSapUser::ReceiveRrcPduParameters params);
--- a/src/lte/model/pf-ff-mac-scheduler.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/pf-ff-mac-scheduler.cc Mon Apr 23 13:16:03 2012 +0200
@@ -212,7 +212,7 @@
m_schedSapUser (0),
m_timeWindow (99.0),
m_schedTtiDelay (2),
- // WILD ACK: based on a m_macChTtiDelay = 1
+ // WILD HACK: based on a m_macChTtiDelay = 1
m_nextRntiUl (0)
{
m_amc = CreateObject <LteAmc> ();
@@ -289,8 +289,17 @@
void
PfFfMacScheduler::DoCschedUeConfigReq (const struct FfMacCschedSapProvider::CschedUeConfigReqParameters& params)
{
- NS_LOG_FUNCTION (this);
- // Not used at this stage
+ NS_LOG_FUNCTION (this << " RNTI " << params.m_rnti << " txMode " << (uint16_t)params.m_transmissionMode);
+ std::map <uint16_t,uint8_t>::iterator it = m_uesTxMode.find (params.m_rnti);
+ if (it==m_uesTxMode.end ())
+ {
+ m_uesTxMode.insert (std::pair <uint16_t, double> (params.m_rnti, params.m_transmissionMode));
+ }
+ else
+ {
+ (*it).second = params.m_transmissionMode;
+ }
+ return;
return;
}
@@ -438,7 +447,6 @@
int rbgSize = GetRbgSize (m_cschedCellConfig.m_dlBandwidth);
int rbgNum = m_cschedCellConfig.m_dlBandwidth / rbgSize;
- //std::vector <LteFlowId_t> rbgAllocationMap;
std::map <uint16_t, std::vector <uint16_t> > allocationMap;
for (int i = 0; i < rbgNum; i++)
{
@@ -450,25 +458,56 @@
{
std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
itCqi = m_a30CqiRxed.find ((*it).first);
- uint8_t cqi = 0;
+ std::map <uint16_t,uint8_t>::iterator itTxMode;
+ itTxMode = m_uesTxMode.find ((*it).first);
+ if (itTxMode == m_uesTxMode.end())
+ {
+ NS_FATAL_ERROR ("No Transmission Mode info on user " << (*it).first);
+ }
+ int nLayer = TransmissionModesLayers::TxMode2LayerNum ((*itTxMode).second);
+ std::vector <uint8_t> sbCqi;
if (itCqi == m_a30CqiRxed.end ())
{
// NS_LOG_DEBUG (this << " No DL-CQI for this UE " << (*it).first);
- cqi = 1; // start with lowest value
+ for (uint8_t k = 0; k < nLayer; k++)
+ {
+ sbCqi.push_back (1); // start with lowest value
+ }
}
else
{
- cqi = (*itCqi).second.m_higherLayerSelected.at (i).m_sbCqi.at (0);
+ sbCqi = (*itCqi).second.m_higherLayerSelected.at (i).m_sbCqi;
// NS_LOG_INFO (this << " CQI " << (uint32_t)cqi);
}
- if (cqi > 0) // CQI == 0 means "out of range" (see table 7.2.3-1 of 36.213)
+ uint8_t cqi1 = sbCqi.at(0);
+ uint8_t cqi2 = 1;
+ if (sbCqi.size () > 1)
+ {
+ cqi2 = sbCqi.at(1);
+ }
+
+ if ((cqi1 > 0)||(cqi2 > 0)) // CQI == 0 means "out of range" (see table 7.2.3-1 of 36.213)
{
// NS_LOG_DEBUG (this << " LC active " << LcActivePerFlow ((*it).first));
if (LcActivePerFlow ((*it).first) > 0)
{
// this UE has data to transmit
- uint8_t mcs = m_amc->GetMcsFromCqi (cqi);
- double achievableRate = ((m_amc->GetTbSizeFromMcs (mcs, 1) / 8) / 0.001); // = TB size / TTI
+ double achievableRate = 0.0;
+ for (uint8_t k = 0; k < nLayer; k++)
+ {
+ uint8_t mcs = 0;
+ if (sbCqi.size () > k)
+ {
+ mcs = m_amc->GetMcsFromCqi (sbCqi.at (k));
+ }
+ else
+ {
+ // no info on this subband -> worst MCS
+ mcs = 0;
+ }
+ achievableRate += ((m_amc->GetTbSizeFromMcs (mcs, 1) / 8) / 0.001); // = TB size / TTI
+ }
+
double rcqi = achievableRate / (*it).second.lastAveragedThroughput;
// NS_LOG_DEBUG (this << " RNTI " << (*it).first << " MCS " << (uint32_t)mcs << " achievableRate " << achievableRate << " avgThr " << (*it).second.lastAveragedThroughput << " RCQI " << rcqi);
@@ -531,7 +570,14 @@
uint16_t RgbPerRnti = (*itMap).second.size ();
std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
itCqi = m_a30CqiRxed.find ((*itMap).first);
- uint8_t worstCqi = 15;
+ std::map <uint16_t,uint8_t>::iterator itTxMode;
+ itTxMode = m_uesTxMode.find ((*itMap).first);
+ if (itTxMode == m_uesTxMode.end())
+ {
+ NS_FATAL_ERROR ("No Transmission Mode info on user " << (*itMap).first);
+ }
+ int nLayer = TransmissionModesLayers::TxMode2LayerNum ((*itTxMode).second);
+ std::vector <uint8_t> worstCqi (2, 15);
if (itCqi != m_a30CqiRxed.end ())
{
for (uint16_t k = 0; k < (*itMap).second.size (); k++)
@@ -539,25 +585,48 @@
if ((*itCqi).second.m_higherLayerSelected.size () > (*itMap).second.at (k))
{
// NS_LOG_DEBUG (this << " RBG " << (*itMap).second.at (k) << " CQI " << (uint16_t)((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (0)) );
- if (((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (0)) < worstCqi)
+ for (uint8_t j = 0; j < nLayer; j++)
{
- worstCqi = ((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (0));
+ if ((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.size ()> j)
+ {
+ if (((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (j)) < worstCqi.at (j))
+ {
+ worstCqi.at (j) = ((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (j));
+ }
+ }
+ else
+ {
+ // no CQI for this layer of this suband -> worst one
+ worstCqi.at (j) = 1;
+ }
}
}
else
{
- worstCqi = 1; // try with lowest MCS in RBG with no info on channel
+ for (uint8_t j = 0; j < nLayer; j++)
+ {
+ worstCqi.at (j) = 1; // try with lowest MCS in RBG with no info on channel
+ }
}
}
}
else
{
- worstCqi = 1; // try with lowest MCS in RBG with no info on channel
+ for (uint8_t j = 0; j < nLayer; j++)
+ {
+ worstCqi.at (j) = 1; // try with lowest MCS in RBG with no info on channel
+ }
}
// NS_LOG_DEBUG (this << " CQI " << (uint16_t)worstCqi);
- newDci.m_mcs.push_back (m_amc->GetMcsFromCqi (worstCqi));
- int tbSize = (m_amc->GetTbSizeFromMcs (newDci.m_mcs.at (0), RgbPerRnti * rbgSize) / 8); // (size of TB in bytes according to table 7.1.7.2.1-1 of 36.213)
- newDci.m_tbsSize.push_back (tbSize);
+ uint32_t bytesTxed = 0;
+ for (uint8_t j = 0; j < nLayer; j++)
+ {
+ newDci.m_mcs.push_back (m_amc->GetMcsFromCqi (worstCqi.at (j)));
+ int tbSize = (m_amc->GetTbSizeFromMcs (newDci.m_mcs.at (j), RgbPerRnti * rbgSize) / 8); // (size of TB in bytes according to table 7.1.7.2.1-1 of 36.213)
+ newDci.m_tbsSize.push_back (tbSize);
+ NS_LOG_DEBUG (this << " MCS " << m_amc->GetMcsFromCqi (worstCqi.at (j)));
+ bytesTxed += tbSize;
+ }
newDci.m_resAlloc = 0; // only allocation type 0 at this stage
newDci.m_rbBitmap = 0; // TBD (32 bit bitmap see 7.1.6 of 36.213)
@@ -570,20 +639,23 @@
newDci.m_rbBitmap = rbgMask; // (32 bit bitmap see 7.1.6 of 36.213)
// create the rlc PDUs -> equally divide resources among actives LCs
- int rlcPduSize = tbSize / lcActives;
std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator itBufReq;
for (itBufReq = m_rlcBufferReq.begin (); itBufReq != m_rlcBufferReq.end (); itBufReq++)
{
- if (((*itBufReq).first.m_rnti == (*itMap).first) && (((*itBufReq).second.m_rlcTransmissionQueueSize > 0)
- || ((*itBufReq).second.m_rlcRetransmissionQueueSize > 0)
- || ((*itBufReq).second.m_rlcStatusPduSize > 0) ))
+ if (((*itBufReq).first.m_rnti == (*itMap).first) &&
+ (((*itBufReq).second.m_rlcTransmissionQueueSize > 0)
+ || ((*itBufReq).second.m_rlcRetransmissionQueueSize > 0)
+ || ((*itBufReq).second.m_rlcStatusPduSize > 0) ))
{
- RlcPduListElement_s newRlcEl;
- newRlcEl.m_logicalChannelIdentity = (*itBufReq).first.m_lcId;
-// NS_LOG_DEBUG (this << " LCID " << (uint32_t) newRlcEl.m_logicalChannelIdentity << " size " << rlcPduSize);
- newRlcEl.m_size = rlcPduSize;
- newRlcPduLe.push_back (newRlcEl);
- UpdateDlRlcBufferInfo (newDci.m_rnti, newRlcEl.m_logicalChannelIdentity, rlcPduSize);
+ for (uint8_t j = 0; j < nLayer; j++)
+ {
+ RlcPduListElement_s newRlcEl;
+ newRlcEl.m_logicalChannelIdentity = (*itBufReq).first.m_lcId;
+ newRlcEl.m_size = newDci.m_tbsSize.at (j) / lcActives;
+ NS_LOG_DEBUG (this << " LCID " << (uint32_t) newRlcEl.m_logicalChannelIdentity << " size " << newRlcEl.m_size << " layer " << (uint16_t)j);
+ newRlcPduLe.push_back (newRlcEl);
+ UpdateDlRlcBufferInfo (newDci.m_rnti, newRlcEl.m_logicalChannelIdentity, newRlcEl.m_size);
+ }
}
if ((*itBufReq).first.m_rnti > (*itMap).first)
{
@@ -604,7 +676,7 @@
it = m_flowStatsDl.find ((*itMap).first);
if (it != m_flowStatsDl.end ())
{
- (*it).second.lastTtiBytesTrasmitted = tbSize;
+ (*it).second.lastTtiBytesTrasmitted = bytesTxed;
// NS_LOG_DEBUG (this << " UE bytes txed " << (*it).second.lastTtiBytesTrasmitted);
@@ -1204,5 +1276,15 @@
}
+void
+PfFfMacScheduler::TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode)
+{
+ NS_LOG_FUNCTION (this << " RNTI " << rnti << " txMode " << (uint16_t)txMode);
+ FfMacCschedSapUser::CschedUeConfigUpdateIndParameters params;
+ params.m_rnti = rnti;
+ params.m_transmissionMode = txMode;
+ m_cschedSapUser->CschedUeConfigUpdateInd (params);
+}
+
}
--- a/src/lte/model/pf-ff-mac-scheduler.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/pf-ff-mac-scheduler.h Mon Apr 23 13:16:03 2012 +0200
@@ -85,6 +85,8 @@
friend class PfSchedulerMemberCschedSapProvider;
friend class PfSchedulerMemberSchedSapProvider;
+
+ void TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode);
private:
//
@@ -216,6 +218,7 @@
uint32_t m_cqiTimersThreshold; // # of TTIs for which a CQI canbe considered valid
+ std::map <uint16_t,uint8_t> m_uesTxMode; // txMode of the UEs
};
} // namespace ns3
--- a/src/lte/model/rr-ff-mac-scheduler.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/rr-ff-mac-scheduler.cc Mon Apr 23 13:16:03 2012 +0200
@@ -21,9 +21,10 @@
#include <ns3/log.h>
#include <ns3/pointer.h>
-#include "lte-amc.h"
-#include "rr-ff-mac-scheduler.h"
+#include <ns3/lte-amc.h>
+#include <ns3/rr-ff-mac-scheduler.h>
#include <ns3/simulator.h>
+#include <ns3/lte-common.h>
NS_LOG_COMPONENT_DEFINE ("RrFfMacScheduler");
@@ -290,8 +291,16 @@
void
RrFfMacScheduler::DoCschedUeConfigReq (const struct FfMacCschedSapProvider::CschedUeConfigReqParameters& params)
{
- NS_LOG_FUNCTION (this);
- // Not used at this stage
+ NS_LOG_FUNCTION (this << " RNTI " << params.m_rnti << " txMode " << (uint16_t)params.m_transmissionMode);
+ std::map <uint16_t,uint8_t>::iterator it = m_uesTxMode.find (params.m_rnti);
+ if (it==m_uesTxMode.end ())
+ {
+ m_uesTxMode.insert (std::pair <uint16_t, double> (params.m_rnti, params.m_transmissionMode));
+ }
+ else
+ {
+ (*it).second = params.m_transmissionMode;
+ }
return;
}
@@ -481,6 +490,7 @@
it = m_rlcBufferReq.begin ();
m_nextRntiDl = (*it).m_rnti;
}
+ std::map <uint16_t,uint8_t>::iterator itTxMode;
do
{
itLcRnti = lcActivesPerRnti.find ((*it).m_rnti);
@@ -495,6 +505,12 @@
}
continue;
}
+ itTxMode = m_uesTxMode.find ((*it).m_rnti);
+ if (itTxMode == m_uesTxMode.end())
+ {
+ NS_FATAL_ERROR ("No Transmission Mode info on user " << (*it).m_rnti);
+ }
+ int nLayer = TransmissionModesLayers::TxMode2LayerNum ((*itTxMode).second);
int lcNum = (*itLcRnti).second;
// create new BuildDataListElement_s for this RNTI
BuildDataListElement_s newEl;
@@ -505,29 +521,35 @@
newDci.m_resAlloc = 0;
newDci.m_rbBitmap = 0;
std::map <uint16_t,uint8_t>::iterator itCqi = m_p10CqiRxed.find (newEl.m_rnti);
- if (itCqi == m_p10CqiRxed.end ())
+ for (uint8_t i = 0; i < nLayer; i++)
{
- newDci.m_mcs.push_back (0); // no info on this user -> lowest MCS
- }
- else
- {
- newDci.m_mcs.push_back ( m_amc->GetMcsFromCqi ((*itCqi).second) );
+ if (itCqi == m_p10CqiRxed.end ())
+ {
+ newDci.m_mcs.push_back (0); // no info on this user -> lowest MCS
+ }
+ else
+ {
+ newDci.m_mcs.push_back ( m_amc->GetMcsFromCqi ((*itCqi).second) );
+ }
}
// group the LCs of this RNTI
std::vector <struct RlcPduListElement_s> newRlcPduLe;
// int totRbg = lcNum * rbgPerFlow;
// totRbg = rbgNum / nTbs;
-int tbSize = (m_amc->GetTbSizeFromMcs (newDci.m_mcs.at (0), rbgPerTb * rbgSize) / 8);
- NS_LOG_DEBUG (this << "Allocate user " << newEl.m_rnti << " LCs " << (uint16_t)(*itLcRnti).second << " bytes " << tbSize << " PRBs " << rbgPerTb * rbgSize << " mcs " << (uint16_t) newDci.m_mcs.at (0));
+ int tbSize = (m_amc->GetTbSizeFromMcs (newDci.m_mcs.at (0), rbgPerTb * rbgSize) / 8);
+ NS_LOG_DEBUG (this << "Allocate user " << newEl.m_rnti << " LCs " << (uint16_t)(*itLcRnti).second << " bytes " << tbSize << " PRBs " << rbgPerTb * rbgSize << " mcs " << (uint16_t) newDci.m_mcs.at (0) << " layers " << nLayer);
uint16_t rlcPduSize = tbSize / lcNum;
for (int i = 0; i < lcNum ; i++)
{
- RlcPduListElement_s newRlcEl;
- newRlcEl.m_logicalChannelIdentity = (*it).m_logicalChannelIdentity;
- NS_LOG_DEBUG (this << "LCID " << (uint32_t) newRlcEl.m_logicalChannelIdentity << " size " << rlcPduSize << " ID " << (*it).m_rnti);
- newRlcEl.m_size = rlcPduSize;
- UpdateDlRlcBufferInfo ((*it).m_rnti, newRlcEl.m_logicalChannelIdentity, rlcPduSize);
- newRlcPduLe.push_back (newRlcEl);
+ for (uint8_t j = 0; j < nLayer; j++)
+ {
+ RlcPduListElement_s newRlcEl;
+ newRlcEl.m_logicalChannelIdentity = (*it).m_logicalChannelIdentity;
+ NS_LOG_DEBUG (this << "LCID " << (uint32_t) newRlcEl.m_logicalChannelIdentity << " size " << rlcPduSize << " ID " << (*it).m_rnti << " layer " << (uint16_t)j);
+ newRlcEl.m_size = rlcPduSize;
+ UpdateDlRlcBufferInfo ((*it).m_rnti, newRlcEl.m_logicalChannelIdentity, rlcPduSize);
+ newRlcPduLe.push_back (newRlcEl);
+ }
it++;
if (it == m_rlcBufferReq.end ())
{
@@ -543,8 +565,7 @@
}
newDci.m_rbBitmap = rbgMask; // (32 bit bitmap see 7.1.6 of 36.213)
- int nbOfTbsInNewDci = 1; // SISO -> only one TB
- for (int i = 0; i < nbOfTbsInNewDci; i++)
+ for (int i = 0; i < nLayer; i++)
{
newDci.m_tbsSize.push_back (tbSize);
newDci.m_ndi.push_back (1); // TBD (new data indicator)
@@ -1034,4 +1055,17 @@
}
+
+void
+RrFfMacScheduler::TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode)
+{
+ NS_LOG_FUNCTION (this << " RNTI " << rnti << " txMode " << (uint16_t)txMode);
+ FfMacCschedSapUser::CschedUeConfigUpdateIndParameters params;
+ params.m_rnti = rnti;
+ params.m_transmissionMode = txMode;
+ m_cschedSapUser->CschedUeConfigUpdateInd (params);
}
+
+
+
+}
--- a/src/lte/model/rr-ff-mac-scheduler.h Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/model/rr-ff-mac-scheduler.h Mon Apr 23 13:16:03 2012 +0200
@@ -73,6 +73,8 @@
friend class RrSchedulerMemberCschedSapProvider;
friend class RrSchedulerMemberSchedSapProvider;
+
+ void TransmissionModeConfigurationUpdate (uint16_t rnti, uint8_t txMode);
private:
//
@@ -183,6 +185,7 @@
uint32_t m_cqiTimersThreshold; // # of TTIs for which a CQI canbe considered valid
+ std::map <uint16_t,uint8_t> m_uesTxMode; // txMode of the UEs
};
--- a/src/lte/test/lte-test-entities.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/test/lte-test-entities.cc Mon Apr 23 13:16:03 2012 +0200
@@ -450,14 +450,14 @@
LteTestMac::SendTxOpportunity (Time time, uint32_t bytes)
{
NS_LOG_FUNCTION (this << time << bytes);
- Simulator::Schedule (time, &LteMacSapUser::NotifyTxOpportunity, m_macSapUser, bytes);
+ Simulator::Schedule (time, &LteMacSapUser::NotifyTxOpportunity, m_macSapUser, bytes, 0);
if (m_txOpportunityMode == RANDOM_MODE)
+ {
+ if (m_txOppTime != Seconds (0))
{
- if (m_txOppTime != Seconds (0))
- {
- Simulator::Schedule (m_txOppTime, &LteTestMac::SendTxOpportunity, this, m_txOppTime, m_txOppSize);
- }
+ Simulator::Schedule (m_txOppTime, &LteTestMac::SendTxOpportunity, this, m_txOppTime, m_txOppSize);
}
+ }
}
void
@@ -572,17 +572,17 @@
if (params.statusPduSize)
{
Simulator::Schedule (Seconds (0.1), &LteMacSapUser::NotifyTxOpportunity,
- m_macSapUser, params.statusPduSize + 2);
+ m_macSapUser, params.statusPduSize + 2, 0);
}
else if (params.txQueueSize)
{
Simulator::Schedule (Seconds (0.1), &LteMacSapUser::NotifyTxOpportunity,
- m_macSapUser, params.txQueueSize + 2);
+ m_macSapUser, params.txQueueSize + 2, 0);
}
else if (params.retxQueueSize)
{
Simulator::Schedule (Seconds (0.1), &LteMacSapUser::NotifyTxOpportunity,
- m_macSapUser, params.retxQueueSize + 2);
+ m_macSapUser, params.retxQueueSize + 2, 0);
}
}
}
--- a/src/lte/test/lte-test-fading.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/test/lte-test-fading.cc Mon Apr 23 13:16:03 2012 +0200
@@ -64,13 +64,6 @@
*/
-// void
-// LteTestShadowingDlSchedCallback (LteShadowingSystemTestCase *testcase, std::string path, uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, uint8_t mcsTb1, uint16_t sizeTb1, uint8_t mcsTb2, uint16_t sizeTb2)
-// {
-// testcase->DlScheduling (frameNo, subframeNo, rnti, mcsTb1, sizeTb1, mcsTb2, sizeTb2);
-// }
-//
-
LteFadingTestSuite::LteFadingTestSuite ()
: TestSuite ("lte-fading-model", SYSTEM)
@@ -132,194 +125,7 @@
mm2->SetPosition (Vector (distance, 0.0, hm));
AddTestCase (new LteFadingTestCase (mm1, mm2, 137.93, "OH Urban Large city"));
-
-// AddTestCase (new LteFadingTestCase (mm1, mm2, 137.88, "OH Urban small city = ??"));
-//
-// AddTestCase (new LteFadingTestCase (mm1, mm2, 128.03, "loss OH SubUrban"));
-//
-// AddTestCase (new LteFadingTestCase (mm1, mm2, 110.21, "loss OH OpenAreas"));
-//
-// // Test #2 COST231 Model (1500 < freq < 2000~2170 MHz) (Macro<->UE)
-//
-// freq = 2.1140e9; // E_UTRA BAND #1 see table 5.5-1 of 36.101
-//
-// AddTestCase (new LteFadingTestCase (mm1, mm2, 148.55, "COST231 Urban Large city"));
-//
-// AddTestCase (new LteFadingTestCase (mm1, mm2, 150.64, "COST231 Urban small city and suburban"));
-//
-// // Test #3 2.6 GHz model (Macro<->UE)
-//
-// freq = 2.620e9; // E_UTRA BAND #7 see table 5.5-1 of 36.101
-//
-// AddTestCase (new LteFadingTestCase (mm1, mm2, 121.83, "2.6GHz model"));
-//
-// // Test #4 ITU1411 LOS model (Macro<->UE)
-//
-// freq = 2.1140e9; // E_UTRA BAND #1 see table 5.5-1 of 36.101
-// distance = 100;
-// Ptr<BuildingsMobilityModel> mm3 = ueNodes.Get (1)->GetObject<BuildingsMobilityModel> ();
-// mm3->SetPosition (Vector (distance, 0.0, hm));
-// AddTestCase (new LteFadingTestCase (mm1, mm3, 81.00, "ITU1411 LOS"));
-//
-// // Test #5 ITU1411 NLOS model (Macro<->UE)
-//
-// freq = 2.1140e9; // E_UTRA BAND #1 see table 5.5-1 of 36.101
-// distance = 900;
-//
-// Ptr<BuildingsMobilityModel> mm4 = ueNodes.Get (2)->GetObject<BuildingsMobilityModel> ();
-// mm4->SetPosition (Vector (distance, 0.0, hm));
-// AddTestCase (new LteFadingTestCase (mm1, mm4, 143.69, "ITU1411 NLOS"));
-//
-// // Test #6 ITUP1238 (HeNB <-> UE)
-//
-// distance = 30;
-// freq = 2.1140e9; // E_UTRA BAND #1 see table 5.5-1 of 36.101
-// double henbHeight = 10.0;
-// Ptr<BuildingsMobilityModel> mm5 = henbNodes.Get (0)->GetObject<BuildingsMobilityModel> ();
-// mm5->SetPosition (Vector (0.0, 0.0, henbHeight));
-// Ptr<Building> building1 = Create<Building> (0.0, 10.0, 0.0, 10.0, 0.0, 20.0/*, 1, 1, 1*/);
-// building1->SetBuildingType (Building::Residential);
-// building1->SetExtWallsType (Building::ConcreteWithWindows);
-// mm5->SetIndoor (building1);
-// Ptr<BuildingsMobilityModel> mm6 = hueNodes.Get (0)->GetObject<BuildingsMobilityModel> ();
-// mm6->SetPosition (Vector (distance, 0.0, hm));
-// mm6->SetIndoor (building1);
-// mm6->SetFloorNumber (2);
-// AddTestCase (new LteFadingTestCase (mm5, mm6, 88.3855, "ITUP1238"));
-//
-// // Test #7 Outdoor -> Indoor OkumuraHata (Macro<->UE)
-//
-// freq = 2.1140e9; // E_UTRA BAND #1 see table 5.5-1 of 36.101
-// distance = 2000;
-// // The loss is as in test #2 (large city) plus the building penetration loss
-// // which for ConcreteWithWindows is equal to 7 dB -> 148.55 + 7 = 155.55
-// Ptr<BuildingsMobilityModel> mm7 = ueNodes.Get (3)->GetObject<BuildingsMobilityModel> ();
-// mm7->SetPosition (Vector (distance, 0.0, hm));
-// mm7->SetIndoor (building1);
-// AddTestCase (new LteFadingTestCase (mm1, mm7, 155.55, "Okumura Hata Outdoor -> Indoor"));
-//
-// // Test #8 Outdoor -> Indoor ITU1411 (Macro<->UE)
-// freq = 2.1140e9; // E_UTRA BAND #1 see table 5.5-1 of 36.101
-// distance = 100;
-// Ptr<BuildingsMobilityModel> mm8 = ueNodes.Get (4)->GetObject<BuildingsMobilityModel> ();
-// mm8->SetPosition (Vector (distance, 0.0, hm));
-// mm8->SetIndoor (building1);
-// // The loss is as in test #4 plus the building penetration loss
-// // which for ConcreteWithWindows is equal to 7 dB -> 81.000 + 7 = 88.000
-// AddTestCase (new LteFadingTestCase (mm1, mm8, 88.000, "ITU1411 LOS Outdoor -> Indoor"));
-//
-// // Test #9 Indoor -> Outdoor LOS (HeNB <-> UE)
-//
-// distance = 100;
-// freq = 2.1140e9; // E_UTRA BAND #1 see table 5.5-1 of 36.101
-// Ptr<BuildingsMobilityModel> mm9 = henbNodes.Get (1)->GetObject<BuildingsMobilityModel> ();
-// mm9->SetPosition (Vector (0.0, 0.0, henbHeight));
-// mm9->SetIndoor (building1);
-// mm9->SetFloorNumber (2);
-// Ptr<BuildingsMobilityModel> mm10 = hueNodes.Get (1)->GetObject<BuildingsMobilityModel> ();
-// mm10->SetPosition (Vector (distance, 0.0, hm));
-// // The loss is similar of test #4 plus the building penetration loss
-// // which for ConcreteWithWindows is equal to 7 dB and the height gain
-// // (2 floors x 2 dB/floor = 4) -> 81.838 + 7 - 4 = 84.838
-// AddTestCase (new LteFadingTestCase (mm9, mm10, 84.838, "ITU1411 LOS Indoor -> Outdoor"));
-//
-// // Test #10 Indoor -> Outdoor NLOS (HeNB <-> UE)
-//
-// distance = 500;
-// freq = 2.1140e9; // E_UTRA BAND #1 see table 5.5-1 of 36.101
-// Ptr<BuildingsMobilityModel> mm11 = hueNodes.Get (2)->GetObject<BuildingsMobilityModel> ();
-// mm11->SetPosition (Vector (distance, 0.0, hm));
-// // The loss is similar as in test #4 plus the building penetration loss
-// // which for ConcreteWithWindows is equal to 7 dB and the height gain
-// // (2 floors x 2 dB/floor = 4) -> 180.90 + 7 - 4 = 183.90
-// AddTestCase (new LteFadingTestCase (mm9, mm11, 183.90, "ITU1411 NLOS Indoor -> Outdoor"));
-
-
- //------------------- SYSTEM TEST ------------------------------
-
-/* // LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL);
- //
- // LogComponentEnable ("LteHelper", logLevel);
- LogComponentEnable ("LteShadowingTest", LOG_LEVEL_ALL);
- // LogComponentEnable ("BuildingsPropagationLossModel", logLevel);
- // LogComponentEnable ("LteInterference", logLevel);
- // LogComponentEnable ("LteSpectrumValueHelper", logLevel);
-
-
- struct SnrEfficiencyMcs
- {
- double snrDb;
- double efficiency;
- int mcsIndex;
- };
-
-
- SnrEfficiencyMcs snrEfficiencyMcs[] = {
- { -5.00000, 0.08024, -1},
- { -4.00000, 0.10030, -1},
- { -3.00000, 0.12518, -1},
- { -2.00000, 0.15589, 0},
- { -1.00000, 0.19365, 0},
- { 0.00000, 0.23983, 2},
- { 1.00000, 0.29593, 2},
- { 2.00000, 0.36360, 2},
- { 3.00000, 0.44451, 4},
- { 4.00000, 0.54031, 4},
- { 5.00000, 0.65251, 6},
- { 6.00000, 0.78240, 6},
- { 7.00000, 0.93086, 8},
- { 8.00000, 1.09835, 8},
- { 9.00000, 1.28485, 10},
- { 10.00000, 1.48981, 12},
- { 11.00000, 1.71229, 12},
- { 12.00000, 1.95096, 14},
- { 13.00000, 2.20429, 14},
- { 14.00000, 2.47062, 16},
- { 15.00000, 2.74826, 18},
- { 16.00000, 3.03560, 18},
- { 17.00000, 3.33115, 20},
- { 18.00000, 3.63355, 20},
- { 19.00000, 3.94163, 22},
- { 20.00000, 4.25439, 22},
- { 21.00000, 4.57095, 24},
- { 22.00000, 4.89060, 24},
- { 23.00000, 5.21276, 26},
- { 24.00000, 5.53693, 26},
- { 25.00000, 5.86271, 28},
- { 26.00000, 6.18980, 28},
- { 27.00000, 6.51792, 28},
- { 28.00000, 6.84687, 28},
- { 29.00000, 7.17649, 28},
- { 30.00000, 7.50663, 28},
- };
-
-
- double txPowerDbm = 30; // default eNB TX power over whole bandwdith
- double txPowerLin = pow (10, (txPowerDbm - 30)/10);
- double ktDbm = -174; // reference LTE noise PSD
- double noisePowerDbm = ktDbm + 10 * log10 (25 * 180000); // corresponds to kT*bandwidth in linear units
- double receiverNoiseFigureDb = 9.0; // default UE noise figure
- double noiseLin = pow (10, (noisePowerDbm-30+receiverNoiseFigureDb)/10);
- double loss[] = {81.0000, 134.0125, 144.1489};
- double dist[] = {100.0, 500.0, 1500};
-
- int numOfTests = sizeof (loss) / sizeof (double);
- for ( int i = 0 ; i < numOfTests; i++ )
- {
- // double lossDb = txPowerDbm - snrEfficiencyMcs[i].snrDb - noisePowerDbm - receiverNoiseFigureDb;
- double sinrLin = (txPowerLin*(pow(10, loss[i]/10))) / noiseLin;
- // double sinrDb = txPowerDbm- noisePowerDbm - receiverNoiseFigureDb - loss[i];
- double sinrDb = 10*log10(sinrLin);
- NS_LOG_INFO (" Ptx " << txPowerDbm << " Pn " << noisePowerDbm << " Fn " << receiverNoiseFigureDb << " Pl " << loss[i] << " dist " << dist[i]);
- std::ostringstream name;
- name << " snr= " << sinrDb << " dB, "
- << " mcs= " << snrEfficiencyMcs[i].mcsIndex;
- AddTestCase (new LteShadowingSystemTestCase (name.str (), sinrDb, dist[i], snrEfficiencyMcs[i].mcsIndex));
- }
- */
-
-
-
+
}
@@ -456,6 +262,7 @@
// NS_TEST_ASSERT_MSG_EQ_TOL(loss, m_lossRef, 0.1, "Wrong loss !");
}
+
void
LteFadingTestCase::GetFadingSample ()
{
@@ -488,130 +295,3 @@
(*outPsd1)[1] = (10 * log10 (180000*(*outPsd1)[1])) - (10 * log10 (180000*(*inPsd1)[1]));
m_fadingSamples.push_back ((*outPsd1));
}
-
-
-//-------------------- SYSTEM TEST ---------------------------------
-
-/*
-LteShadowingSystemTestCase::LteShadowingSystemTestCase (std::string name, double snrDb, double dist, uint16_t mcsIndex)
-: TestCase (name),
-m_snrDb (snrDb),
-m_distance (dist),
-m_mcsIndex (mcsIndex)
-{
- std::ostringstream sstream1, sstream2;
- sstream1 << " snr=" << snrDb
- << " mcs=" << mcsIndex << " distance=" << dist;
-
- NS_LOG_INFO ("Creating LteShadowingSystemTestCase: " + sstream1.str ());
-}
-
-LteShadowingSystemTestCase::~LteShadowingSystemTestCase ()
-{
-}
-
-void
-LteShadowingSystemTestCase::DoRun (void)
-{
-
- // LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL);
- // LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
- // LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
- // LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
- // LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
- // LogComponentEnable ("SingleModelSpectrumChannel", LOG_LEVEL_ALL);
- // LogComponentEnable ("BuildingsPropagationLossModel", logLevel);
-
- LogComponentEnable ("BuildingsPropagationLossModel", LOG_LEVEL_ALL);
-
- Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
- lteHelper->EnableLogComponents ();
- lteHelper->EnableMacTraces ();
- lteHelper->EnableRlcTraces ();
- lteHelper->SetAttribute ("PropagationModel", StringValue ("ns3::BuildingsPropagationLossModel"));
-
- //Create Nodes: eNodeB and UE
- NodeContainer enbNodes;
- NodeContainer ueNodes;
- enbNodes.Create (1);
- ueNodes.Create (1);
- NodeContainer allNodes = NodeContainer ( enbNodes, ueNodes );
-
- // Install Mobility Model
- MobilityHelper mobility;
- mobility.SetMobilityModel ("ns3::BuildingsMobilityModel");
- mobility.Install (allNodes);
-
- // Create Devices and install them in the Nodes (eNB and UE)
- NetDeviceContainer enbDevs;
- NetDeviceContainer ueDevs;
- lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
- enbDevs = lteHelper->InstallEnbDevice (enbNodes);
- ueDevs = lteHelper->InstallUeDevice (ueNodes);
-
- Ptr<BuildingsMobilityModel> mm_enb = enbNodes.Get (0)->GetObject<BuildingsMobilityModel> ();
- mm_enb->SetPosition (Vector (0.0, 0.0, 30.0));
- Ptr<BuildingsMobilityModel> mm_ue = ueNodes.Get (0)->GetObject<BuildingsMobilityModel> ();
- mm_ue->SetPosition (Vector (m_distance, 0.0, 1.0));
-
- NS_LOG_INFO (" DISTANCE " << mm_ue->GetDistanceFrom (mm_enb));
-
- Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
- Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
- enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
- enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
-
- Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (0)->GetObject<LteUeNetDevice> ();
- Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
- uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
- uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
-
- // Attach a UE to a eNB
- lteHelper->Attach (ueDevs, enbDevs.Get (0));
-
- // Activate an EPS bearer
- enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
- EpsBearer bearer (q);
- lteHelper->ActivateEpsBearer (ueDevs, bearer);
-
- // Use testing chunk processor in the PHY layer
- // It will be used to test that the SNR is as intended
- // Ptr<LtePhy> uePhy = ueDevs.Get (0)->GetObject<LteUeNetDevice> ()->GetPhy ()->GetObject<LtePhy> ();
- Ptr<LteTestSinrChunkProcessor> testSinr = Create<LteTestSinrChunkProcessor> (uePhy);
- uePhy->GetDownlinkSpectrumPhy ()->AddSinrChunkProcessor (testSinr);
-
- // Config::Connect ("/NodeList/0/DeviceList/0/LteEnbMac/DlScheduling",
- // MakeBoundCallback (&LteTestShadowingDlSchedCallback, this));
-
- Simulator::Stop (Seconds (0.005));
- Simulator::Run ();
-
- double calculatedSinrDb = 10.0 * log10 (testSinr->GetSinr ()[0]);
- NS_LOG_INFO ("Distance " << m_distance << " Calculated SINR " << calculatedSinrDb << " ref " << m_snrDb);
- Simulator::Destroy ();
- NS_TEST_ASSERT_MSG_EQ_TOL (calculatedSinrDb, m_snrDb, 0.001, "Wrong SINR !");
-}
-
-
-void
-LteShadowingSystemTestCase::DlScheduling (uint32_t frameNo, uint32_t subframeNo, uint16_t rnti,
- uint8_t mcsTb1, uint16_t sizeTb1, uint8_t mcsTb2, uint16_t sizeTb2)
-{
- static bool firstTime = true;
-
- if ( firstTime )
- {
- firstTime = false;
- NS_LOG_INFO ("SNR\tRef_MCS\tCalc_MCS");
- }
-
-
- if ( (frameNo > 1) || (subframeNo > 4) )
- {
- NS_LOG_INFO (m_snrDb << "\t" << m_mcsIndex << "\t" << (uint16_t)mcsTb1);
-
- NS_TEST_ASSERT_MSG_EQ ((uint16_t)mcsTb1, m_mcsIndex, "Wrong MCS index");
- }
-
-}
-*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-test-mimo.cc Mon Apr 23 13:16:03 2012 +0200
@@ -0,0 +1,286 @@
+/* -*- 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: Marco Miozzo <marco.miozzo@cttc.es>
+ */
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include <ns3/object.h>
+#include <ns3/spectrum-interference.h>
+#include <ns3/spectrum-error-model.h>
+#include <ns3/log.h>
+#include <ns3/test.h>
+#include <ns3/simulator.h>
+#include <ns3/packet.h>
+#include <ns3/ptr.h>
+#include <iostream>
+#include "ns3/radio-bearer-stats-calculator.h"
+#include <ns3/buildings-mobility-model.h>
+#include <ns3/buildings-propagation-loss-model.h>
+#include "ns3/lte-test-mimo.h"
+#include <ns3/eps-bearer.h>
+#include <ns3/node-container.h>
+#include <ns3/mobility-helper.h>
+#include <ns3/net-device-container.h>
+#include <ns3/lte-ue-net-device.h>
+#include <ns3/lte-enb-net-device.h>
+#include <ns3/lte-ue-rrc.h>
+#include <ns3/lte-helper.h>
+#include "ns3/string.h"
+#include "ns3/double.h"
+#include <ns3/lte-enb-phy.h>
+#include <ns3/lte-ue-phy.h>
+#include <ns3/boolean.h>
+#include <ns3/rr-ff-mac-scheduler.h>
+#include <ns3/pf-ff-mac-scheduler.h>
+#include <ns3/pointer.h>
+#include <ns3/enum.h>
+
+
+NS_LOG_COMPONENT_DEFINE ("LenaTestMimo");
+
+using namespace ns3;
+
+
+LenaTestMimoSuite::LenaTestMimoSuite ()
+ : TestSuite ("lte-mimo", SYSTEM)
+{
+ NS_LOG_INFO ("creating LenaMimoTestCase");
+
+ // RR DOWNLINK- DISTANCE 300
+ // [0, 0.2] sec TxMode 0: MCS 20 -> TB size 1191
+ // [0.2, 0.3] sec TxMode 1: MCS 26 -> TB size 1836
+ // [0.3, 0.4] sec TxMode 2: MCS 18 -> TB size 967 (x2 layers)
+ // -->
+ std::vector<uint32_t> estThrDl;
+ estThrDl.push_back (119100); // TTI 1 estimated throughput for TxMode 1
+ estThrDl.push_back (183600); // TTI 2 estimated throughput for TxMode 2
+ estThrDl.push_back (193400); // TTI 3 estimated throughput for TxMode 3
+ AddTestCase (new LenaMimoTestCase(300, estThrDl, "ns3::RrFfMacScheduler"));
+ AddTestCase (new LenaMimoTestCase(300, estThrDl, "ns3::PfFfMacScheduler"));
+
+
+}
+
+static LenaTestMimoSuite lenaTestMimoSuite;
+
+std::string
+LenaMimoTestCase::BuildNameString (uint16_t dist)
+{
+ std::ostringstream oss;
+ oss << " UE distance " << dist << " m";
+ return oss.str ();
+}
+
+LenaMimoTestCase::LenaMimoTestCase (uint16_t dist, std::vector<uint32_t> estThrDl, std::string schedulerType)
+ : TestCase (BuildNameString (dist)),
+ m_dist (dist),
+ m_estThrDl (estThrDl),
+ m_schedulerType (schedulerType)
+{
+}
+
+LenaMimoTestCase::~LenaMimoTestCase ()
+{
+}
+
+void
+LenaMimoTestCase::DoRun (void)
+{
+// Config::SetDefault ("ns3::LteSpectrumPhy::PemEnabled", BooleanValue (false));
+ Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
+ LogComponentDisableAll (LOG_LEVEL_ALL);
+// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
+// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
+// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
+// LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
+// LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
+//
+// LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
+// LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
+// LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
+
+// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
+// LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
+// LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
+//
+// LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL);
+// LogComponentEnable ("LossModel", LOG_LEVEL_ALL);
+// LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL);
+// LogComponentEnable ("PenetrationLossModel", LOG_LEVEL_ALL);
+// LogComponentEnable ("MultipathLossModel", LOG_LEVEL_ALL);
+// LogComponentEnable ("PathLossModel", LOG_LEVEL_ALL);
+//
+// LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
+// LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
+// LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
+
+// LogComponentEnable ("LteMiErrorModel", LOG_LEVEL_ALL);
+// LogComponentEnable ("LteAmc", LOG_LEVEL_ALL);
+// LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
+
+ LogComponentEnable ("LenaTestMimo", LOG_LEVEL_ALL);
+// LogComponentEnable ("BuildingsPropagationLossModel", LOG_LEVEL_ALL);
+// LogComponentEnable ("RrFfMacScheduler", LOG_LEVEL_ALL);
+// LogComponentEnable ("PfFfMacScheduler", LOG_LEVEL_ALL);
+
+
+ /**
+ * Initialize Simulation Scenario: 1 eNB and m_nUser UEs
+ */
+
+
+ Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
+
+
+ lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::HybridBuildingsPropagationLossModel"));
+ lteHelper->SetPathlossModelAttribute ("ShadowSigmaOutdoor", DoubleValue (0.0));
+ lteHelper->SetPathlossModelAttribute ("ShadowSigmaIndoor", DoubleValue (0.0));
+ lteHelper->SetPathlossModelAttribute ("ShadowSigmaExtWalls", DoubleValue (0.0));
+
+// lteHelper->EnableLogComponents ();
+
+ // Create Nodes: eNodeB and UE
+ NodeContainer enbNodes;
+ NodeContainer ueNodes;
+ enbNodes.Create (1);
+ ueNodes.Create (1);
+
+ // Install Mobility Model
+ MobilityHelper mobility;
+ mobility.SetMobilityModel ("ns3::BuildingsMobilityModel");
+ mobility.Install (enbNodes);
+ mobility.SetMobilityModel ("ns3::BuildingsMobilityModel");
+ mobility.Install (ueNodes);
+
+ // Create Devices and install them in the Nodes (eNB and UE)
+ NetDeviceContainer enbDevs;
+ NetDeviceContainer ueDevs;
+ lteHelper->SetSchedulerType (m_schedulerType);
+ enbDevs = lteHelper->InstallEnbDevice (enbNodes);
+ ueDevs = lteHelper->InstallUeDevice (ueNodes);
+
+ // Attach a UE to a eNB
+ lteHelper->Attach (ueDevs, enbDevs.Get (0));
+
+ // Activate an EPS bearer
+ enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
+ EpsBearer bearer (q);
+ lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+
+
+ Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
+ Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
+ enbPhy->SetAttribute ("TxPower", DoubleValue (46.0));
+ enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
+ Ptr<BuildingsMobilityModel> mmenb = enbNodes.Get (0)->GetObject<BuildingsMobilityModel> ();
+ mmenb->SetPosition (Vector (0.0, 0.0, 30.0));
+
+ // Set UE's position and power
+ Ptr<BuildingsMobilityModel> mmue = ueNodes.Get (0)->GetObject<BuildingsMobilityModel> ();
+ mmue->SetPosition (Vector (m_dist, 0.0, 1.0));
+ Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (0)->GetObject<LteUeNetDevice> ();
+ Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
+ uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
+ uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
+
+
+ lteHelper->EnableRlcTraces ();
+ lteHelper->EnableMacTraces ();
+ double simulationTime = 0.401;
+ double tolerance = 0.1;
+
+ uint8_t rnti = ueDevs.Get (0)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetRnti ();
+ Ptr<LteEnbNetDevice> enbNetDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
+
+ PointerValue ptrval;
+ enbNetDev->GetAttribute ("FfMacScheduler", ptrval);
+ Ptr<PfFfMacScheduler> pfsched;
+ Ptr<RrFfMacScheduler> rrsched;
+ if (m_schedulerType.compare ("ns3::RrFfMacScheduler") == 0)
+ {
+ rrsched = ptrval.Get<RrFfMacScheduler> ();
+ if (rrsched == 0)
+ {
+ NS_FATAL_ERROR ("No RR Scheduler available");
+ }
+
+ Simulator::Schedule (Seconds (0.2), &RrFfMacScheduler::TransmissionModeConfigurationUpdate, rrsched, rnti, 1);
+ Simulator::Schedule (Seconds (0.3), &RrFfMacScheduler::TransmissionModeConfigurationUpdate, rrsched, rnti, 2);
+ }
+ else if (m_schedulerType.compare ("ns3::PfFfMacScheduler") == 0)
+ {
+ pfsched = ptrval.Get<PfFfMacScheduler> ();
+ if (pfsched == 0)
+ {
+ NS_FATAL_ERROR ("No Pf Scheduler available");
+ }
+
+ Simulator::Schedule (Seconds (0.2), &PfFfMacScheduler::TransmissionModeConfigurationUpdate, pfsched, rnti, 1);
+ Simulator::Schedule (Seconds (0.3), &PfFfMacScheduler::TransmissionModeConfigurationUpdate, pfsched, rnti, 2);
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Scheduler not supported by this test");
+ }
+
+
+ Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
+ rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (0.1)));
+
+
+ /**
+ * Check that the assignation is done in a RR fashion
+ */
+ NS_LOG_INFO (m_schedulerType << " MIMO test:");
+ double sampleTime = 0.2;
+ for (uint8_t j = 0; j < m_estThrDl.size (); j ++)
+ {
+ NS_LOG_INFO ("\t test with user at distance " << m_dist << " time " << sampleTime);
+ // get the imsi
+ uint64_t imsi = ueDevs.Get (0)->GetObject<LteUeNetDevice> ()->GetImsi ();
+ // get the lcId
+ uint8_t lcId = ueDevs.Get (0)->GetObject<LteUeNetDevice> ()->GetRrc ()->GetLcIdVector ().at (0);
+ Time t = Seconds (sampleTime);
+ Simulator::Schedule(t, &LenaMimoTestCase::GetRlcBufferSample, this, rlcStats, imsi, lcId);
+ sampleTime += 0.1;
+ }
+ Simulator::Stop (Seconds (simulationTime));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ NS_LOG_INFO ("Check consistency");
+ for (uint8_t i = 0; i < m_estThrDl.size (); i++)
+ {
+ NS_LOG_INFO ("\tTTI " << i + 1 << " bytes rxed " << (double)m_dlDataRxed.at (i) << " ref " << m_estThrDl.at (i));
+ NS_TEST_ASSERT_MSG_EQ_TOL ((double)m_dlDataRxed.at (i) , m_estThrDl.at (i), m_estThrDl.at (i) * tolerance, " Unfair Throughput!");
+ }
+
+}
+
+
+void
+LenaMimoTestCase::GetRlcBufferSample (Ptr<RadioBearerStatsCalculator> rlcStats, uint64_t imsi, uint8_t lcId)
+{
+ m_dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
+// NS_LOG_INFO ("\t get bytes " << m_dlDataRxed.at (m_dlDataRxed.size () - 1));
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-test-mimo.h Mon Apr 23 13:16:03 2012 +0200
@@ -0,0 +1,67 @@
+/* -*- 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: Marco Miozzo <marco.miozzo@cttc.es>
+ */
+
+#ifndef LENA_TEST_MIMO_H
+#define LENA_TEST_MIMO_H
+
+#include "ns3/simulator.h"
+#include "ns3/test.h"
+
+
+using namespace ns3;
+
+
+/**
+ * This system test program creates different test cases with a single eNB...
+ */
+class LenaMimoTestCase : public TestCase
+{
+public:
+ LenaMimoTestCase (uint16_t dist, std::vector<uint32_t> estThrDl, std::string schedulerType);
+ virtual ~LenaMimoTestCase ();
+
+private:
+ virtual void DoRun (void);
+
+ void GetRlcBufferSample (Ptr<RadioBearerStatsCalculator> rlcStats, uint64_t imsi, uint8_t rnti);
+
+ static std::string BuildNameString (uint16_t dist);
+ uint16_t m_nUser;
+ uint16_t m_nLc;
+ uint16_t m_dist;
+ std::vector<uint32_t> m_estThrDl;
+ std::string m_schedulerType;
+
+ std::vector <uint64_t> m_dlDataRxed;
+
+};
+
+
+
+class LenaTestMimoSuite : public TestSuite
+{
+public:
+ LenaTestMimoSuite ();
+};
+
+
+
+
+#endif /* LENA_TEST_MIMO_H */
--- a/src/lte/test/test-lte-epc-e2e-data.cc Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/test/test-lte-epc-e2e-data.cc Mon Apr 23 13:16:03 2012 +0200
@@ -109,7 +109,7 @@
void
LteEpcE2eDataTestCase::DoRun ()
{
-
+ Config::SetDefault ("ns3::LteSpectrumPhy::PemEnabled", BooleanValue (false));
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
Ptr<EpcHelper> epcHelper = CreateObject<EpcHelper> ();
lteHelper->SetEpcHelper (epcHelper);
--- a/src/lte/wscript Thu Apr 19 17:43:47 2012 +0200
+++ b/src/lte/wscript Mon Apr 23 13:16:03 2012 +0200
@@ -92,7 +92,8 @@
'test/epc-test-s1u-uplink.cc',
'test/test-lte-epc-e2e-data.cc',
'test/test-lte-antenna.cc',
- 'test/lte-test-phy-error-model.cc'
+ 'test/lte-test-phy-error-model.cc',
+ 'test/lte-test-mimo.cc'
]
headers = bld.new_task_gen(features=['ns3header'])
@@ -176,7 +177,8 @@
'test/lte-test-rlc-am-e2e.h',
'model/epc-tft.h',
'model/epc-tft-classifier.h',
- 'model/lte-mi-error-model.h'
+ 'model/lte-mi-error-model.h',
+ 'test/lte-test-mimo.h'
]
if (bld.env['ENABLE_EXAMPLES']):