diff --git a/src/lte/helper/lte-helper.cc b/src/lte/helper/lte-helper.cc index cb8a94035..0807015d1 100644 --- a/src/lte/helper/lte-helper.cc +++ b/src/lte/helper/lte-helper.cc @@ -475,6 +475,7 @@ LteHelper::Attach (Ptr ueDevice, Ptr enbDevice) uint16_t rnti = enbRrc->AddUe (ueDevice->GetObject ()->GetImsi ()); Ptr ueRrc = ueDevice->GetObject ()->GetRrc (); ueRrc->ConfigureUe (rnti, enbDevice->GetObject ()->GetCellId () ); + //enbRrc->SetCellId (enbDevice->GetObject ()->GetCellId ()); // attach UE to eNB ueDevice->GetObject ()->SetTargetEnb (enbDevice->GetObject ()); @@ -498,12 +499,13 @@ LteHelper::Attach (Ptr ueDevice, Ptr enbDevice) } // WILD HACK - should be done through PHY SAP, probably passing by RRC + NS_LOG_DEBUG ("!Attach eNB " << enbDevice->GetObject ()->GetCellId () << " with UE " << rnti); uePhy->SetRnti (rnti); uePhy->DoSetBandwidth (enbDevice->GetObject ()->GetUlBandwidth (), enbDevice->GetObject ()->GetDlBandwidth ()); uePhy->DoSetEarfcn (enbDevice->GetObject ()->GetDlEarfcn (), enbDevice->GetObject ()->GetUlEarfcn ()); - + enbRrc->ConfigureNewUe (rnti); ueDevice->Start (); m_downlinkChannel->AddRx (uePhy->GetDownlinkSpectrumPhy ()); diff --git a/src/lte/model/lte-common.h b/src/lte/model/lte-common.h index 279fb8d50..1f0de62f9 100644 --- a/src/lte/model/lte-common.h +++ b/src/lte/model/lte-common.h @@ -59,7 +59,9 @@ public: struct LteUeConfig_t { uint16_t m_rnti; + bool m_reconfigureFlag; uint8_t m_transmissionMode; + uint16_t m_srsConfigurationIndex; public: LteUeConfig_t (); diff --git a/src/lte/model/lte-enb-cmac-sap.h b/src/lte/model/lte-enb-cmac-sap.h index e6acc9c17..4f9caf906 100644 --- a/src/lte/model/lte-enb-cmac-sap.h +++ b/src/lte/model/lte-enb-cmac-sap.h @@ -26,7 +26,7 @@ #include #include #include -#include +//#include namespace ns3 { @@ -98,7 +98,7 @@ public: */ virtual void ReleaseLc (uint16_t rnti, uint8_t lcid) = 0; - virtual void RrcUpdateConfigurationReq (FfMacCschedSapProvider::CschedUeConfigReqParameters params) = 0; + virtual void UeUpdateConfigurationReq (LteUeConfig_t params) = 0; }; diff --git a/src/lte/model/lte-enb-mac.cc b/src/lte/model/lte-enb-mac.cc index 577c263b0..bdff14fa6 100644 --- a/src/lte/model/lte-enb-mac.cc +++ b/src/lte/model/lte-enb-mac.cc @@ -62,7 +62,7 @@ public: 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); + virtual void UeUpdateConfigurationReq (LteUeConfig_t params); private: LteEnbMac* m_mac; @@ -105,9 +105,9 @@ EnbMacMemberLteEnbCmacSapProvider::ReleaseLc (uint16_t rnti, uint8_t lcid) } void -EnbMacMemberLteEnbCmacSapProvider::RrcUpdateConfigurationReq (FfMacCschedSapProvider::CschedUeConfigReqParameters params) +EnbMacMemberLteEnbCmacSapProvider::UeUpdateConfigurationReq (LteUeConfig_t params) { - m_mac->DoRrcUpdateConfigurationReq (params); + m_mac->DoUeUpdateConfigurationReq (params); } @@ -870,11 +870,12 @@ LteEnbMac::DoCschedUeConfigUpdateInd (FfMacCschedSapUser::CschedUeConfigUpdateIn } void -LteEnbMac::DoRrcUpdateConfigurationReq (FfMacCschedSapProvider::CschedUeConfigReqParameters params) +LteEnbMac::DoUeUpdateConfigurationReq (LteUeConfig_t params) { NS_LOG_FUNCTION (this); // propagates to PHY layer m_enbPhySapProvider->SetTransmissionMode (params.m_rnti, params.m_transmissionMode); + m_enbPhySapProvider->SetSrsConfigurationIndex (params.m_rnti, params.m_srsConfigurationIndex); // propagates to scheduler FfMacCschedSapProvider::CschedUeConfigReqParameters req; req.m_rnti = params.m_rnti; diff --git a/src/lte/model/lte-enb-mac.h b/src/lte/model/lte-enb-mac.h index 89aa00529..31ec14cba 100644 --- a/src/lte/model/lte-enb-mac.h +++ b/src/lte/model/lte-enb-mac.h @@ -163,7 +163,7 @@ private: void DoSchedDlConfigInd (FfMacSchedSapUser::SchedDlConfigIndParameters ind); void DoSchedUlConfigInd (FfMacSchedSapUser::SchedUlConfigIndParameters params); - void DoRrcUpdateConfigurationReq (FfMacCschedSapProvider::CschedUeConfigReqParameters params); + void DoUeUpdateConfigurationReq (LteUeConfig_t params); /** * \brief Forwarded from LteEnbPhySapUser: trigger the start from a new frame diff --git a/src/lte/model/lte-enb-net-device.cc b/src/lte/model/lte-enb-net-device.cc index b2f9ac551..10afe24ee 100644 --- a/src/lte/model/lte-enb-net-device.cc +++ b/src/lte/model/lte-enb-net-device.cc @@ -277,6 +277,7 @@ LteEnbNetDevice::UpdateConfig (void) NS_LOG_FUNCTION (this); m_rrc->ConfigureCell (m_ulBandwidth, m_dlBandwidth); + m_rrc->SetCellId (m_cellId); // Configuring directly for now, but ideally we should use the PHY // SAP instead. Probably should handle this through the RRC. diff --git a/src/lte/model/lte-enb-phy-sap.h b/src/lte/model/lte-enb-phy-sap.h index 70110fa99..217c3838f 100644 --- a/src/lte/model/lte-enb-phy-sap.h +++ b/src/lte/model/lte-enb-phy-sap.h @@ -59,6 +59,12 @@ public: * \param txMode the transmissionMode of the user */ virtual void SetTransmissionMode (uint16_t rnti, uint8_t txMode) = 0; + + /** + * \param rnti the RNTI of the user + * \param txMode the SRS Configuration Index of the user + */ + virtual void SetSrsConfigurationIndex (uint16_t rnti, uint16_t srsCI) = 0; /** * diff --git a/src/lte/model/lte-enb-phy.cc b/src/lte/model/lte-enb-phy.cc index 80970606d..26bcdc148 100644 --- a/src/lte/model/lte-enb-phy.cc +++ b/src/lte/model/lte-enb-phy.cc @@ -58,6 +58,7 @@ public: virtual void SendLteControlMessage (Ptr msg); virtual uint8_t GetMacChTtiDelay (); virtual void SetTransmissionMode (uint16_t rnti, uint8_t txMode); + virtual void SetSrsConfigurationIndex (uint16_t rnti, uint16_t srsCI); private: @@ -106,6 +107,12 @@ EnbMemberLteEnbPhySapProvider::SetTransmissionMode (uint16_t rnti, uint8_t txMo m_phy->DoSetTransmissionMode (rnti, txMode); } +void +EnbMemberLteEnbPhySapProvider::SetSrsConfigurationIndex (uint16_t rnti, uint16_t srsCI) +{ + m_phy->DoSetSrsConfigurationIndex (rnti, srsCI); +} + //////////////////////////////////////// // generic LteEnbPhy methods @@ -125,7 +132,8 @@ LteEnbPhy::LteEnbPhy () LteEnbPhy::LteEnbPhy (Ptr dlPhy, Ptr ulPhy) : LtePhy (dlPhy, ulPhy), m_nrFrames (0), - m_nrSubFrames (0) + m_nrSubFrames (0), + m_srsPeriodicity (0) { m_enbPhySapProvider = new EnbMemberLteEnbPhySapProvider (this); Simulator::ScheduleNow (&LteEnbPhy::StartFrame, this); @@ -547,16 +555,25 @@ LteEnbPhy::EndFrame (void) void -LteEnbPhy::GenerateCqiReport (const SpectrumValue& sinr) +LteEnbPhy::GenerateCtrlCqiReport (const SpectrumValue& sinr) { NS_LOG_FUNCTION (this << sinr); - UlCqi_s ulcqi = CreateUlCqiReport (sinr); + UlCqi_s ulcqi = CreateSrsCqiReport (sinr); + m_enbPhySapUser->UlCqiReport (ulcqi); +} + +void +LteEnbPhy::GenerateDataCqiReport (const SpectrumValue& sinr) +{ + NS_LOG_FUNCTION (this << sinr); + UlCqi_s ulcqi = CreatePuschCqiReport (sinr); m_enbPhySapUser->UlCqiReport (ulcqi); } + UlCqi_s -LteEnbPhy::CreateUlCqiReport (const SpectrumValue& sinr) +LteEnbPhy::CreatePuschCqiReport (const SpectrumValue& sinr) { NS_LOG_FUNCTION (this << sinr); Values::const_iterator it; @@ -576,6 +593,28 @@ LteEnbPhy::CreateUlCqiReport (const SpectrumValue& sinr) } + +UlCqi_s +LteEnbPhy::CreateSrsCqiReport (const SpectrumValue& sinr) +{ + NS_LOG_FUNCTION (this << sinr); + Values::const_iterator it; + UlCqi_s ulcqi; + ulcqi.m_type = UlCqi_s::PUSCH; + int i = 0; + for (it = sinr.ConstValuesBegin (); it != sinr.ConstValuesEnd (); it++) + { + double sinrdb = 10 * log10 ((*it)); + // NS_LOG_DEBUG ("ULCQI RB " << i << " value " << sinrdb); + // convert from double to fixed point notation Sxxxxxxxxxxx.xxx + int16_t sinrFp = LteFfConverter::double2fpS11dot3 (sinrdb); + ulcqi.m_sinr.push_back (sinrFp); + i++; + } + return (ulcqi); + +} + void LteEnbPhy::DoSetTransmissionMode (uint16_t rnti, uint8_t txMode) { @@ -612,5 +651,22 @@ LteEnbPhy::DequeueUlDci (void) } } +void +LteEnbPhy::DoSetSrsConfigurationIndex (uint16_t rnti, uint16_t srsCI) +{ + NS_LOG_FUNCTION (this); + m_srsPeriodicity = GetSrsPeriodicity (srsCI); + NS_LOG_DEBUG (this << " ENB SRS P " << m_srsPeriodicity << " RNTI " << rnti << " offset " << GetSrsSubframeOffset (srsCI) << " CI " << srsCI); + std::map ::iterator it = m_srsCounter.find (rnti); + if (it != m_srsCounter.end ()) + { + (*it).second = GetSrsSubframeOffset (srsCI) + 1; + } + else + { + m_srsCounter.insert (std::pair (rnti, GetSrsSubframeOffset (srsCI) + 1)); + } +} + }; diff --git a/src/lte/model/lte-enb-phy.h b/src/lte/model/lte-enb-phy.h index a8a4ed858..d999b93aa 100644 --- a/src/lte/model/lte-enb-phy.h +++ b/src/lte/model/lte-enb-phy.h @@ -112,6 +112,10 @@ public: */ virtual void DoSendMacPdu (Ptr p); + virtual void DoSetTransmissionMode (uint16_t rnti, uint8_t txMode); + + virtual void DoSetSrsConfigurationIndex (uint16_t rnti, uint16_t srsCI); + virtual uint8_t DoGetMacChTtiDelay (); @@ -142,10 +146,17 @@ public: /** * \brief Create the UL CQI feedback from SINR values perceived at - * the physical layer with the signal received from eNB + * the physical layer with the PUSCH signal received from eNB * \param sinr SINR values vector */ - UlCqi_s CreateUlCqiReport (const SpectrumValue& sinr); + UlCqi_s CreatePuschCqiReport (const SpectrumValue& sinr); + + /** + * \brief Create the UL CQI feedback from SINR values perceived at + * the physical layer with the SRS signal received from eNB + * \param sinr SINR values vector + */ + UlCqi_s CreateSrsCqiReport (const SpectrumValue& sinr); void DoSendLteControlMessage (Ptr msg); @@ -153,9 +164,7 @@ public: bool AddUePhy (uint16_t rnti, Ptr phy); bool DeleteUePhy (uint16_t rnti); - - virtual void DoSetTransmissionMode (uint16_t rnti, uint8_t txMode); - + void SendControlChannels (std::list > ctrlMsgList); void SendDataChannels (Ptr pb); @@ -198,7 +207,8 @@ public: virtual void ReceiveLteControlMessageList (std::list >); // inherited from LtePhy - virtual void GenerateCqiReport (const SpectrumValue& sinr); + virtual void GenerateCtrlCqiReport (const SpectrumValue& sinr); + virtual void GenerateDataCqiReport (const SpectrumValue& sinr); private: @@ -216,6 +226,9 @@ private: uint32_t m_nrFrames; uint32_t m_nrSubFrames; + uint16_t m_srsPeriodicity; + std::map m_srsCounter; + }; diff --git a/src/lte/model/lte-enb-rrc.cc b/src/lte/model/lte-enb-rrc.cc index 9252cd434..0f231b5ce 100644 --- a/src/lte/model/lte-enb-rrc.cc +++ b/src/lte/model/lte-enb-rrc.cc @@ -16,7 +16,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Nicola Baldo - * Marco Miozzo + * Modified by: Marco Miozzo + * add transmission Mode and SRS related functionalities */ #include @@ -35,6 +36,8 @@ #include "ns3/object-map.h" #include +#include + // WILD HACK for UE-RRC direct communications #include #include @@ -42,6 +45,7 @@ #include + NS_LOG_COMPONENT_DEFINE ("LteEnbRrc"); namespace ns3 { @@ -124,12 +128,31 @@ UeInfo::UeInfo (void) : m_lastAllocatedId (0) { m_imsi = 0; + m_srsConfigurationIndex = 0; + m_transmissionMode = 0; } UeInfo::UeInfo (uint64_t imsi) : m_lastAllocatedId (0) { m_imsi = imsi; + m_srsConfigurationIndex = 0; + m_transmissionMode = 0; +} + +UeInfo::UeInfo (uint64_t imsi, uint16_t srsConfIndex) +: m_lastAllocatedId (0) +{ + m_imsi = imsi; + m_srsConfigurationIndex = srsConfIndex; + m_transmissionMode = 0; +} + +UeInfo::UeInfo (uint64_t imsi, uint16_t srsConfIndex, uint8_t txMode) +{ + m_imsi = imsi; + m_srsConfigurationIndex = srsConfIndex; + m_transmissionMode = txMode; } @@ -158,6 +181,30 @@ UeInfo::GetImsi (void) return m_imsi; } +uint16_t +UeInfo::GetSrsConfigurationIndex (void) +{ + return m_srsConfigurationIndex; +} + +uint8_t +UeInfo::GetTransmissionMode (void) +{ + return m_transmissionMode; +} + +void +UeInfo::SetSrsConfigurationIndex (uint16_t srsConfIndex) +{ + m_srsConfigurationIndex = srsConfIndex; +} + +void +UeInfo::SetTransmissionMode (uint8_t txMode) +{ + m_transmissionMode = txMode; +} + uint8_t UeInfo::AddRadioBearer (Ptr rbi) { @@ -213,7 +260,10 @@ LteEnbRrc::LteEnbRrc () m_ffMacSchedSapProvider (0), m_macSapProvider (0), m_configured (false), - m_lastAllocatedRnti (0) + m_lastAllocatedRnti (0), + m_srsCurrentPeriodicityId (0), + m_lastAllocatedConfigurationIndex (0), + m_reconfigureUes (false) { NS_LOG_FUNCTION (this); m_cmacSapUser = new EnbRrcMemberLteEnbCmacSapUser (this); @@ -388,12 +438,6 @@ LteEnbRrc::SetupRadioBearer (uint16_t rnti, EpsBearer bearer, TypeId rlcTypeId) 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; } @@ -461,6 +505,16 @@ LteEnbRrc::DoNotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success) // management of multiple UE info instances // ///////////////////////////////////////// +// from 3GPP TS 36.213 table 8.2-1 UE Specific SRS Periodicity +uint16_t SrsPeriodicity[9] = {0, 2, 5, 10, 20, 40, 80, 160, 320}; +uint16_t SrsCiLow[9] = {0, 0, 2, 7, 17, 37, 77, 157, 317}; +uint16_t SrsCiHigh[9] = {0, 1, 6, 16, 36, 76, 156, 316, 636}; + +void +LteEnbRrc::SetCellId (uint16_t cellId) +{ + m_cellId = cellId; +} uint16_t LteEnbRrc::CreateUeInfo (uint64_t imsi) @@ -473,14 +527,135 @@ LteEnbRrc::CreateUeInfo (uint64_t imsi) if (m_ueMap.find (rnti) == m_ueMap.end ()) { m_lastAllocatedRnti = rnti; - m_ueMap.insert (std::pair > (rnti, CreateObject (imsi))); + Ptr ueInfo = CreateObject (imsi, GetNewSrsConfigurationIndex ()); + m_ueMap.insert (std::pair > (rnti, ueInfo)); + NS_LOG_DEBUG (this << " New UE RNTI " << rnti << " cellId " << m_cellId << " srs CI " << ueInfo->GetSrsConfigurationIndex ()); return rnti; } } } + return 0; } +uint16_t +LteEnbRrc::GetNewSrsConfigurationIndex () +{ + NS_LOG_FUNCTION (this << m_ueSrsConfigurationIndexSet.size ()); + // SRS + if (m_srsCurrentPeriodicityId==0) + { + // no UEs -> init + m_ueSrsConfigurationIndexSet.insert (0); + m_lastAllocatedConfigurationIndex = 0; + m_srsCurrentPeriodicityId++; + + return 0; + } + NS_LOG_DEBUG (this << " SRS p " << SrsPeriodicity[m_srsCurrentPeriodicityId] << " set " << m_ueSrsConfigurationIndexSet.size ()); + if (m_ueSrsConfigurationIndexSet.size () == SrsPeriodicity[m_srsCurrentPeriodicityId]) + { + NS_LOG_DEBUG (this << " SRS reconfigure CIs " << SrsPeriodicity[m_srsCurrentPeriodicityId] << " to " << SrsPeriodicity[m_srsCurrentPeriodicityId+1] << " at " << Simulator::Now ()); + // increase the current periocity for having enough CIs + m_ueSrsConfigurationIndexSet.clear (); + m_srsCurrentPeriodicityId++; + // update all the UE's CI + uint16_t srsCI = SrsCiLow[m_srsCurrentPeriodicityId]; + std::map >::iterator it; + for (it = m_ueMap.begin (); it != m_ueMap.end (); it++) + { + (*it).second->SetSrsConfigurationIndex (srsCI); + m_ueSrsConfigurationIndexSet.insert (srsCI); + m_lastAllocatedConfigurationIndex = srsCI; + srsCI++; + // send update to peer RRC + LteUeConfig_t ueConfig; + ueConfig.m_rnti = (*it).first; + ueConfig.m_transmissionMode = (*it).second->GetTransmissionMode (); + ueConfig.m_srsConfigurationIndex = (*it).second->GetSrsConfigurationIndex (); + ueConfig.m_reconfigureFlag = false; + NS_LOG_DEBUG (this << "\t rnti "<::reverse_iterator rit = m_ueSrsConfigurationIndexSet.rbegin (); + NS_LOG_DEBUG (this << " lower bound " << (*rit) << " of " << SrsCiHigh[m_srsCurrentPeriodicityId]); + if ((*rit) <= SrsCiHigh[m_srsCurrentPeriodicityId]) + { + // got it from the upper bound + m_lastAllocatedConfigurationIndex = (*rit) + 1; + m_ueSrsConfigurationIndexSet.insert (m_lastAllocatedConfigurationIndex); + } + else + { + // look for released ones + for (uint16_t srsCI = SrsCiLow[m_srsCurrentPeriodicityId]; srsCI < SrsCiHigh[m_srsCurrentPeriodicityId]; srsCI++) + { + std::set::iterator it = m_ueSrsConfigurationIndexSet.find (srsCI); + if (it==m_ueSrsConfigurationIndexSet.end ()) + { + m_lastAllocatedConfigurationIndex = srsCI; + m_ueSrsConfigurationIndexSet.insert (srsCI); + break; + } + } + } + } + return m_lastAllocatedConfigurationIndex; + +} + + +void +LteEnbRrc::RemoveSrsConfigurationIndex (uint16_t srsCI) +{ + NS_LOG_FUNCTION (this << srsCI); + std::set::iterator it = m_ueSrsConfigurationIndexSet.find (srsCI); + NS_ASSERT_MSG (it != m_ueSrsConfigurationIndexSet.end (), "request to remove unkwown SRS CI " << srsCI); + m_ueSrsConfigurationIndexSet.erase (it); + if (m_ueSrsConfigurationIndexSet.size () < SrsPeriodicity[m_srsCurrentPeriodicityId - 1]) + { + // reduce the periodicity + m_ueSrsConfigurationIndexSet.clear (); + m_srsCurrentPeriodicityId--; + if (m_srsCurrentPeriodicityId==0) + { + // no active users : renitialize structures + m_lastAllocatedConfigurationIndex = 0; + } + else + { + // update all the UE's CI + uint16_t srsCI = SrsCiLow[m_srsCurrentPeriodicityId]; + std::map >::iterator it; + for (it = m_ueMap.begin (); it != m_ueMap.end (); it++) + { + (*it).second->SetSrsConfigurationIndex (srsCI); + m_ueSrsConfigurationIndexSet.insert (srsCI); + m_lastAllocatedConfigurationIndex = srsCI; + srsCI++; + // send update to peer RRC + LteUeConfig_t ueConfig; + ueConfig.m_rnti = (*it).first; + ueConfig.m_transmissionMode = (*it).second->GetTransmissionMode (); + ueConfig.m_srsConfigurationIndex = (*it).second->GetSrsConfigurationIndex (); + ueConfig.m_reconfigureFlag = false; + NS_LOG_DEBUG (this << "\t rnti "< LteEnbRrc::GetUeInfo (uint16_t rnti) { @@ -497,7 +672,9 @@ LteEnbRrc::RemoveUeInfo (uint16_t rnti) NS_LOG_FUNCTION (this << (uint32_t) rnti); std::map >::iterator it = m_ueMap.find (rnti); NS_ASSERT_MSG (it != m_ueMap.end (), "request to remove UE info with unknown rnti " << rnti); + RemoveSrsConfigurationIndex ((*it).second->GetSrsConfigurationIndex ()); m_ueMap.erase (it); + // remove SRS configuration index } @@ -505,10 +682,46 @@ 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 + // at this stage used only by the scheduler for updating txMode + // retrieve UE info + std::map >::iterator it; + it = m_ueMap.find (params.m_rnti); + NS_ASSERT_MSG (it!=m_ueMap.end (), "Unable to find UeInfo"); + params.m_srsConfigurationIndex = (*it).second->GetSrsConfigurationIndex (); + // update Tx Mode info + (*it).second->SetTransmissionMode (params.m_transmissionMode); + params.m_reconfigureFlag = true; + // answer to MAC (and scheduler) and forward info to UEs + SendUeConfigurationUpdate (params); +} + +void +LteEnbRrc::ConfigureNewUe (uint16_t rnti) +{ + NS_LOG_FUNCTION (this); + // at this stage used only by the scheduler for updating txMode + // retrieve UE info + std::map >::iterator it; + it = m_ueMap.find (rnti); + NS_ASSERT_MSG (it!=m_ueMap.end (), "Unable to find UeInfo"); + LteUeConfig_t params; + params.m_rnti = rnti; + params.m_srsConfigurationIndex = (*it).second->GetSrsConfigurationIndex (); + params.m_transmissionMode = (*it).second->GetTransmissionMode (); + params.m_reconfigureFlag = false; + // answer to MAC (and scheduler) and forward info to UEs + SendUeConfigurationUpdate (params); +} + +void +LteEnbRrc::SendUeConfigurationUpdate (LteUeConfig_t params) +{ + NS_LOG_FUNCTION (this); + // send LteUeConfig_t to MAC layer and peer RRCs + m_cmacSapProvider->UeUpdateConfigurationReq (params); NodeList::Iterator listEnd = NodeList::End (); bool done = false; + params.m_reconfigureFlag = false; for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++) { Ptr node = *i; @@ -523,7 +736,7 @@ LteEnbRrc::DoRrcConfigurationUpdateInd (LteUeConfig_t params) else { Ptr ueRrc = uedev->GetRrc (); - if (ueRrc->GetRnti () == params.m_rnti) + if ((ueRrc->GetRnti () == params.m_rnti)&&(ueRrc->GetCellId () == m_cellId)) { ueRrc->DoRrcConfigurationUpdateInd (params); done = true; @@ -536,12 +749,6 @@ LteEnbRrc::DoRrcConfigurationUpdateInd (LteUeConfig_t params) } } 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); - } diff --git a/src/lte/model/lte-enb-rrc.h b/src/lte/model/lte-enb-rrc.h index 39bce0380..baf2bc1d8 100644 --- a/src/lte/model/lte-enb-rrc.h +++ b/src/lte/model/lte-enb-rrc.h @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Nicola Baldo + * Modified by: Marco Miozzo + * add transmission Mode and SRS related functionalities */ #ifndef LTE_ENB_RRC_H @@ -28,6 +30,7 @@ #include #include +#include namespace ns3 { @@ -74,16 +77,24 @@ public: UeInfo (void); UeInfo (uint64_t imsi); + UeInfo (uint64_t imsi, uint16_t srsConfIndex); + UeInfo (uint64_t imsi, uint16_t srsConfIndex, uint8_t txMode); virtual ~UeInfo (void); static TypeId GetTypeId (void); uint64_t GetImsi (void); + uint16_t GetSrsConfigurationIndex (void); + uint8_t GetTransmissionMode (void); + void SetSrsConfigurationIndex (uint16_t srsConfIndex); + void SetTransmissionMode (uint8_t txMode); private: std::map > m_rbMap; uint8_t m_lastAllocatedId; uint64_t m_imsi; + uint16_t m_srsConfigurationIndex; + uint8_t m_transmissionMode; }; @@ -166,6 +177,8 @@ public: * \return the C-RNTI of the newly added UE */ uint16_t AddUe (uint64_t imsi); + + void SetCellId (uint16_t m_cellId); /** * remove a UE from the cell @@ -218,11 +231,16 @@ public: */ void SetForwardUpCallback (Callback > cb); +// void DoStart (); + + void ConfigureNewUe (uint16_t rnti); + private: void DoReceiveRrcPdu (LtePdcpSapUser::ReceiveRrcPduParameters params); void DoRrcConfigurationUpdateInd (LteUeConfig_t params); + void SendUeConfigurationUpdate (LteUeConfig_t params); void DoNotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success); LtePdcpSapProvider* GetLtePdcpSapProvider (uint16_t rnti, uint8_t lcid); @@ -231,6 +249,8 @@ private: uint16_t CreateUeInfo (uint64_t imsi); Ptr GetUeInfo (uint16_t rnti); void RemoveUeInfo (uint16_t rnti); + uint16_t GetNewSrsConfigurationIndex (void); + void RemoveSrsConfigurationIndex (uint16_t srsCI); Callback > m_forwardUpCallback; @@ -244,9 +264,17 @@ private: bool m_configured; uint16_t m_lastAllocatedRnti; - std::map > m_ueMap; + std::map > m_ueMap; uint8_t m_defaultTransmissionMode; + + uint16_t m_cellId; + + // SRS related attributes + uint16_t m_srsCurrentPeriodicityId; + std::set m_ueSrsConfigurationIndexSet; + uint16_t m_lastAllocatedConfigurationIndex; + bool m_reconfigureUes; }; diff --git a/src/lte/model/lte-phy.cc b/src/lte/model/lte-phy.cc index bce217a91..053b1bf69 100644 --- a/src/lte/model/lte-phy.cc +++ b/src/lte/model/lte-phy.cc @@ -35,6 +35,7 @@ namespace ns3 { NS_OBJECT_ENSURE_REGISTERED (LtePhy); + LtePhy::LtePhy () { NS_LOG_FUNCTION (this); @@ -48,7 +49,8 @@ LtePhy::LtePhy (Ptr dlPhy, Ptr ulPhy) m_ulBandwidth (0), m_dlBandwidth (0), m_rbgSize (0), - m_macChTtiDelay (0) + m_macChTtiDelay (0), + m_cellId (0) { NS_LOG_FUNCTION (this); } @@ -209,6 +211,43 @@ LtePhy::DoSetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth) } } + +uint16_t +LtePhy::GetSrsPeriodicity (uint16_t srsCI) const +{ + // from 3GPP TS 36.213 table 8.2-1 UE Specific SRS Periodicity + uint16_t SrsPeriodicity[9] = {0, 2, 5, 10, 20, 40, 80, 160, 320}; + uint16_t SrsCiLow[9] = {0, 0, 2, 7, 17, 37, 77, 157, 317}; + uint16_t SrsCiHigh[9] = {0, 1, 6, 16, 36, 76, 156, 316, 636}; + uint8_t i; + for (i = 8; i > 0; i --) + { + if ((srsCI>=SrsCiLow[i])&&(srsCI<=SrsCiHigh[i])) + { + break; + } + } + return SrsPeriodicity[i]; +} + +uint16_t +LtePhy::GetSrsSubframeOffset (uint16_t srsCI) const +{ + // from 3GPP TS 36.213 table 8.2-1 UE Specific SRS Periodicity + uint16_t SrsSubframeOffset[9] = {0, 0, 2, 7, 17, 37, 77, 157, 317}; + uint16_t SrsCiLow[9] = {0, 0, 2, 7, 17, 37, 77, 157, 317}; + uint16_t SrsCiHigh[9] = {0, 1, 6, 16, 36, 76, 156, 316, 636}; + uint8_t i; + for (i = 8; i > 0; i --) + { + if ((srsCI>=SrsCiLow[i])&&(srsCI<=SrsCiHigh[i])) + { + break; + } + } + return (srsCI - SrsSubframeOffset[i]); +} + void LtePhy::DoSetEarfcn (uint16_t dlEarfcn, uint16_t ulEarfcn) { diff --git a/src/lte/model/lte-phy.h b/src/lte/model/lte-phy.h index 4785623cf..668b610ce 100644 --- a/src/lte/model/lte-phy.h +++ b/src/lte/model/lte-phy.h @@ -195,6 +195,19 @@ public: * \returns the RB gruop size according to the bandwidth */ uint8_t GetRbgSize (void) const; + + + /** + * \returns the SRS periodicity (see Table 8.2-1 of 36.213) + * \param srsCI the SRS Configuration Index + */ + uint16_t GetSrsPeriodicity (uint16_t srsCI) const; + + /** + * \returns the SRS Subframe offset (see Table 8.2-1 of 36.213) + * \param srsCI the SRS Configuration Index + */ + uint16_t GetSrsSubframeOffset (uint16_t srsCI) const; /** @@ -219,23 +232,19 @@ public: /** - * generate a CQI report based on the given SINR + * generate a CQI report based on the given SINR of Ctrl frame * * \param sinr the SINR vs frequency measured by the device */ - virtual void GenerateCqiReport (const SpectrumValue& sinr) = 0; + virtual void GenerateCtrlCqiReport (const SpectrumValue& sinr) = 0; /** - * Send the control channels (PCFICH and PDCCH in downlink and SRS in uplink) - * - */ -// virtual void SendControlChannels (void) = 0; - - /** - * Send the PDSCH/PUSCH TBs + * generate a CQI report based on the given SINR of Data frame + * (used for PUSCH CQIs) * + * \param sinr the SINR vs frequency measured by the device */ -// virtual void SendDataChannels (void) = 0; + virtual void GenerateDataCqiReport (const SpectrumValue& sinr) = 0; diff --git a/src/lte/model/lte-sinr-chunk-processor.cc b/src/lte/model/lte-sinr-chunk-processor.cc index aaef75529..8f6acea10 100644 --- a/src/lte/model/lte-sinr-chunk-processor.cc +++ b/src/lte/model/lte-sinr-chunk-processor.cc @@ -76,7 +76,7 @@ LteCtrlSinrChunkProcessor::End () NS_LOG_FUNCTION (this); if (m_totDuration.GetSeconds () > 0) { - m_phy->GenerateCqiReport ((*m_sumSinr) / m_totDuration.GetSeconds ()); + m_phy->GenerateCtrlCqiReport ((*m_sumSinr) / m_totDuration.GetSeconds ()); } else { @@ -143,7 +143,7 @@ LteDataSinrChunkProcessor::End () m_spectrumPhy->UpdateSinrPerceived ((*m_sumSinr) / m_totDuration.GetSeconds ()); if (m_phy) { - m_phy->GenerateCqiReport ((*m_sumSinr) / m_totDuration.GetSeconds ()); + m_phy->GenerateDataCqiReport ((*m_sumSinr) / m_totDuration.GetSeconds ()); } } else diff --git a/src/lte/model/lte-spectrum-phy.cc b/src/lte/model/lte-spectrum-phy.cc index 7ad4c484c..364de70cc 100644 --- a/src/lte/model/lte-spectrum-phy.cc +++ b/src/lte/model/lte-spectrum-phy.cc @@ -497,7 +497,7 @@ LteSpectrumPhy::StartTxUlSrsFrame () ChangeState (TX); NS_ASSERT (m_channel); double ulCtrlFrame = 0.000071429; // 0.001 / 14 * 1 (fixed to 1 symbols) - Ptr txParams = Create (); + Ptr txParams = Create (); txParams->duration = Seconds (ulCtrlFrame); txParams->txPhy = GetObject (); txParams->txAntenna = m_antenna; @@ -892,9 +892,9 @@ LteSpectrumPhy::EndRxDlCtrl () void LteSpectrumPhy::EndRxUlSrs () { + ChangeState (IDLE); m_interferenceCtrl->EndRx (); // nothing to do (used only for SRS at this stage) - ChangeState (IDLE); } void diff --git a/src/lte/model/lte-ue-mac.cc b/src/lte/model/lte-ue-mac.cc index a29a97de3..fff134fb4 100644 --- a/src/lte/model/lte-ue-mac.cc +++ b/src/lte/model/lte-ue-mac.cc @@ -339,6 +339,7 @@ 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); + m_uePhySapProvider->SetSrsConfigurationIndex (params.m_srsConfigurationIndex); } diff --git a/src/lte/model/lte-ue-phy-sap.h b/src/lte/model/lte-ue-phy-sap.h index 1af606d0c..bececbdfa 100644 --- a/src/lte/model/lte-ue-phy-sap.h +++ b/src/lte/model/lte-ue-phy-sap.h @@ -57,6 +57,11 @@ public: * \param txMode the transmissionMode of the user */ virtual void SetTransmissionMode (uint8_t txMode) = 0; + + /** + * \param txMode the transmissionMode of the user + */ + virtual void SetSrsConfigurationIndex (uint16_t srsCI) = 0; /** * \brief Send SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel diff --git a/src/lte/model/lte-ue-phy.cc b/src/lte/model/lte-ue-phy.cc index 39dd28012..3c15c96c5 100644 --- a/src/lte/model/lte-ue-phy.cc +++ b/src/lte/model/lte-ue-phy.cc @@ -57,6 +57,7 @@ public: virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth); virtual void SendLteControlMessage (Ptr msg); virtual void SetTransmissionMode (uint8_t txMode); + virtual void SetSrsConfigurationIndex (uint16_t srsCI); private: LteUePhy* m_phy; @@ -92,7 +93,11 @@ UeMemberLteUePhySapProvider::SetTransmissionMode (uint8_t txMode) m_phy->DoSetTransmissionMode (txMode); } - +void +UeMemberLteUePhySapProvider::SetSrsConfigurationIndex (uint16_t srsCI) +{ + m_phy->DoSetSrsConfigurationIndex (srsCI); +} //////////////////////////////////////// // generic LteUePhy methods @@ -115,7 +120,9 @@ LteUePhy::LteUePhy (Ptr dlPhy, Ptr ulPhy) m_p10CqiLast (MilliSeconds (0)), m_a30CqiPeriocity (MilliSeconds (1)), // ideal behavior - m_a30CqiLast (MilliSeconds (0)) + m_a30CqiLast (MilliSeconds (0)), + m_rnti (0), + m_srsPeriodicity (0) { m_amc = CreateObject (); m_uePhySapProvider = new UeMemberLteUePhySapProvider (this); @@ -343,7 +350,7 @@ LteUePhy::CreateTxPowerSpectralDensity () } void -LteUePhy::GenerateCqiReport (const SpectrumValue& sinr) +LteUePhy::GenerateCtrlCqiReport (const SpectrumValue& sinr) { NS_LOG_FUNCTION (this); // check periodic wideband CQI @@ -364,6 +371,12 @@ LteUePhy::GenerateCqiReport (const SpectrumValue& sinr) } } +void +LteUePhy::GenerateDataCqiReport (const SpectrumValue& sinr) +{ + // Not used by UE, CQI are based only on RS +} + Ptr @@ -588,13 +601,22 @@ LteUePhy::SubframeIndication (uint32_t frameNo, uint32_t subframeNo) } m_subChannelsForTransmissionQueue.at (m_macChTtiDelay-1).clear (); - - bool srs = false; // TODO: implement periodicity - double dataFrame = 0.001; + bool srs = false; + // check SRS periodicity + if (m_srsCounter==1) + { + srs = true; + m_srsCounter = m_srsPeriodicity; + } + else + { + m_srsCounter--; + } + double dataFrame = 0.001 - 0.000071429; // 0.001 - 1 symbol for SRS if (srs) { - dataFrame -= 0.000071429; // subtract 1 symbol reserved for SRS - SendSrsChannel (); + Simulator::Schedule (Seconds (0.000928572), // (0.001/14) * 13 + &LteUePhy::SendSrsChannel, this); } @@ -631,7 +653,7 @@ LteUePhy::SubframeIndication (uint32_t frameNo, uint32_t subframeNo) void LteUePhy::SendSrsChannel () { - NS_LOG_FUNCTION (this << " UE " << m_rnti << " start tx SRS"); + NS_LOG_FUNCTION (this << " UE " << m_rnti << " start tx SRS, cell Id " << m_cellId); // set the current tx power spectral density (full bandwidth) std::vector dlRb; for (uint8_t i = 0; i < m_ulBandwidth; i++) @@ -670,6 +692,15 @@ LteUePhy::DoSetTransmissionMode (uint8_t txMode) m_downlinkSpectrumPhy->SetTransmissionMode (txMode); } +void +LteUePhy::DoSetSrsConfigurationIndex (uint16_t srsCI) +{ + NS_LOG_FUNCTION (this << srsCI); + m_srsPeriodicity = GetSrsPeriodicity (srsCI); + m_srsCounter = GetSrsSubframeOffset (srsCI) + 1; + NS_LOG_DEBUG (this << " UE SRS P " << m_srsPeriodicity << " RNTI " << m_rnti << " offset " << GetSrsSubframeOffset (srsCI) << " cellId " << m_cellId << " CI " << srsCI); +} + void LteUePhy::SetTxMode1Gain (double gain) diff --git a/src/lte/model/lte-ue-phy.h b/src/lte/model/lte-ue-phy.h index 081531d46..a458b41f1 100644 --- a/src/lte/model/lte-ue-phy.h +++ b/src/lte/model/lte-ue-phy.h @@ -156,12 +156,14 @@ public: // inherited from LtePhy - virtual void GenerateCqiReport (const SpectrumValue& sinr); + virtual void GenerateCtrlCqiReport (const SpectrumValue& sinr); + virtual void GenerateDataCqiReport (const SpectrumValue& sinr); virtual void DoSendLteControlMessage (Ptr msg); virtual void ReceiveLteControlMessageList (std::list >); virtual void DoSetTransmissionMode (uint8_t txMode); + virtual void DoSetSrsConfigurationIndex (uint16_t srsCI); @@ -238,6 +240,9 @@ private: uint8_t m_transmissionMode; std::vector m_txModeGain; + + uint16_t m_srsPeriodicity; + uint16_t m_srsCounter; }; diff --git a/src/lte/model/lte-ue-rrc.cc b/src/lte/model/lte-ue-rrc.cc index fac51e84b..a94073d5e 100644 --- a/src/lte/model/lte-ue-rrc.cc +++ b/src/lte/model/lte-ue-rrc.cc @@ -99,6 +99,7 @@ NS_OBJECT_ENSURE_REGISTERED (LteUeRrc); LteUeRrc::LteUeRrc () : m_cmacSapProvider (0), m_macSapProvider (0), + m_rnti (0), m_cellId (0) { NS_LOG_FUNCTION (this); @@ -138,7 +139,7 @@ LteUeRrc::GetTypeId (void) MakeUintegerChecker ()) .AddAttribute ("C-RNTI", "Cell Radio Network Temporary Identifier", - UintegerValue (1), + UintegerValue (0), MakeUintegerAccessor (&LteUeRrc::m_rnti), MakeUintegerChecker ()) ; diff --git a/src/lte/test/lte-test-phy-error-model.cc b/src/lte/test/lte-test-phy-error-model.cc index e0a557fdf..759b1a112 100644 --- a/src/lte/test/lte-test-phy-error-model.cc +++ b/src/lte/test/lte-test-phy-error-model.cc @@ -60,7 +60,7 @@ LenaTestPhyErrorModelrSuite::LenaTestPhyErrorModelrSuite () NS_LOG_INFO ("creating LenaTestPhyErrorModelTestCase"); // MCS 2 TB size of 256 bits BER 0.33 SINR -5.51 - AddTestCase (new LenaPhyErrorModelTestCase (4, 1800, 32, 0.33, 29)); + AddTestCase (new LenaPhyErrorModelTestCase (4, 1800, 32, 0.35, 29)); // MCS 2 TB size of 528 bits BER 0.11 SINR -5.51 AddTestCase (new LenaPhyErrorModelTestCase (2, 1800, 66, 0.11, 20)); // MCS 2 TB size of 1088 bits BER 0.02 SINR -5.51 @@ -151,7 +151,7 @@ LenaPhyErrorModelTestCase::DoRun (void) // LogComponentEnable ("LteAmc", LOG_LEVEL_ALL); // LogComponentDisableAll (LOG_LEVEL_ALL); - + LogComponentEnable ("LenaTestPhyErrorModel", LOG_LEVEL_ALL); diff --git a/src/lte/test/lte-test-ue-phy.cc b/src/lte/test/lte-test-ue-phy.cc index 375c13fa8..c56492e44 100644 --- a/src/lte/test/lte-test-ue-phy.cc +++ b/src/lte/test/lte-test-ue-phy.cc @@ -78,7 +78,7 @@ LteTestUePhy::CreateTxPowerSpectralDensity () } void -LteTestUePhy::GenerateCqiReport (const SpectrumValue& sinr) +LteTestUePhy::GenerateCtrlCqiReport (const SpectrumValue& sinr) { NS_LOG_FUNCTION (this); @@ -86,6 +86,15 @@ LteTestUePhy::GenerateCqiReport (const SpectrumValue& sinr) m_sinr = sinr; } +void +LteTestUePhy::GenerateDataCqiReport (const SpectrumValue& sinr) +{ + NS_LOG_FUNCTION (this); + + // Store calculated SINR, it will be retrieved at the end of the test + m_sinr = sinr; +} + void LteTestUePhy::ReceiveLteControlMessage (Ptr msg) { diff --git a/src/lte/test/lte-test-ue-phy.h b/src/lte/test/lte-test-ue-phy.h index 2110120a7..7f5aca848 100644 --- a/src/lte/test/lte-test-ue-phy.h +++ b/src/lte/test/lte-test-ue-phy.h @@ -58,7 +58,9 @@ public: */ virtual Ptr CreateTxPowerSpectralDensity (); - virtual void GenerateCqiReport (const SpectrumValue& sinr); + virtual void GenerateCtrlCqiReport (const SpectrumValue& sinr); + + virtual void GenerateDataCqiReport (const SpectrumValue& sinr); virtual void ReceiveLteControlMessage (Ptr msg);