--- a/src/lte/model/ff-mac-common.h Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/model/ff-mac-common.h Mon Dec 03 18:18:12 2012 +0100
@@ -237,12 +237,29 @@
};
/**
+ * \brief Substitutive structure for specifying BuildRarListElement_s::m_grant field
+ */
+struct UlGrant_s
+{
+ uint16_t m_rnti;
+ uint8_t m_rbStart;
+ uint8_t m_rbLen;
+ uint16_t m_tbSize;
+ uint8_t m_mcs;
+ bool m_hopping;
+ int8_t m_tpc;
+ bool m_cqiRequest;
+ bool m_ulDelay;
+};
+
+/**
* \brief See section 4.3.10 buildRARListElement
*/
struct BuildRarListElement_s
{
uint16_t m_rnti;
- uint32_t m_grant;
+ //uint32_t m_grant; // Substituted with type UlGrant_s
+ UlGrant_s m_grant;
struct DlDciListElement_s m_dci;
};
--- a/src/lte/model/lte-enb-mac.cc Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/model/lte-enb-mac.cc Mon Dec 03 18:18:12 2012 +0100
@@ -323,7 +323,7 @@
MakeUintegerChecker<uint8_t> (4, 64))
.AddAttribute ("PreambleTransMax",
"Maximum number of random access preamble transmissions",
- UintegerValue (10),
+ UintegerValue (50),
MakeUintegerAccessor (&LteEnbMac::m_preambleTransMax),
MakeUintegerChecker<uint8_t> (3, 200))
.AddAttribute ("RaResponseWindowSize",
@@ -473,16 +473,10 @@
{
// process received RACH preambles and notify the scheduler
FfMacSchedSapProvider::SchedDlRachInfoReqParameters rachInfoReqParams;
- // TODO: we should wait for DL_SCHEDULE_INDICATION to build the RARs
- // from the RAR_List; this requires proper support from the scheduler.
- // For now, we take a shortcut and just build the RAR here
- // as an ideal message and without an UL grant.
- Ptr<RarLteControlMessage> rarMsg = Create<RarLteControlMessage> ();
NS_ASSERT (subframeNo > 0 && subframeNo <= 10); // subframe in 1..10
// see TS 36.321 5.1.4; preambles were sent two frames ago
// (plus 3GPP counts subframes from 0, not 1)
uint16_t raRnti = subframeNo - 3;
- rarMsg->SetRaRnti (raRnti);
for (std::map<uint8_t, uint32_t>::const_iterator it = m_receivedRachPreambleCount.begin ();
it != m_receivedRachPreambleCount.end ();
++it)
@@ -515,15 +509,10 @@
rachLe.m_rnti = rnti;
rachLe.m_estimatedSize = 144; // to be confirmed
rachInfoReqParams.m_rachList.push_back (rachLe);
- RarLteControlMessage::Rar rar;
- rar.rapId = it->first;
- rar.rarPayload.m_rnti = rnti;
- // no UL grant for now
- rarMsg->AddRar (rar);
+ m_rapIdRntiMap.insert (std::pair <uint16_t, uint32_t> (rnti, it->first));
}
}
m_schedSapProvider->SchedDlRachInfoReq (rachInfoReqParams);
- m_enbPhySapProvider->SendLteControlMessage (rarMsg);
m_receivedRachPreambleCount.clear ();
}
// Get downlink transmission opportunities
@@ -560,7 +549,7 @@
{
if (subframeNo>1)
{
- m_ulCqiReceived.at (i).m_sfnSf = ((0x3FF & frameNo) << 4) | (0xF & subframeNo);
+ m_ulCqiReceived.at (i).m_sfnSf = ((0x3FF & frameNo) << 4) | (0xF & (subframeNo - 1));
}
else
{
@@ -1007,6 +996,29 @@
NS_FATAL_ERROR ("Found element with more than two transport blocks");
}
}
+
+ // RACH
+ Ptr<RarLteControlMessage> rarMsg = Create<RarLteControlMessage> ();
+ uint16_t raRnti = m_subframeNo - 3;
+ rarMsg->SetRaRnti (raRnti);
+ for (unsigned int i = 0; i < ind.m_buildRarList.size (); i++)
+ {
+ std::map <uint16_t, uint32_t>::iterator itRapId = m_rapIdRntiMap.find (ind.m_buildRarList.at (i).m_rnti);
+ if (itRapId == m_rapIdRntiMap.end ())
+ {
+ NS_FATAL_ERROR ("Unable to find rapId of RNTI " << ind.m_buildRarList.at (i).m_rnti);
+ }
+ RarLteControlMessage::Rar rar;
+ rar.rapId = itRapId->second;
+ rar.rarPayload = ind.m_buildRarList.at (i);
+ rarMsg->AddRar (rar);
+ NS_LOG_INFO (this << " Send RAR message to RNTI " << ind.m_buildRarList.at (i).m_rnti << " rapId " << itRapId->second);
+ }
+ if (ind.m_buildRarList.size () > 0)
+ {
+ m_enbPhySapProvider->SendLteControlMessage (rarMsg);
+ }
+ m_rapIdRntiMap.clear ();
}
--- a/src/lte/model/lte-enb-mac.h Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/model/lte-enb-mac.h Mon Dec 03 18:18:12 2012 +0100
@@ -255,6 +255,8 @@
std::map<uint8_t, NcRaPreambleInfo> m_allocatedNcRaPreambleMap;
std::map<uint8_t, uint32_t> m_receivedRachPreambleCount;
+
+ std::map<uint16_t, uint32_t> m_rapIdRntiMap;
};
} // end namespace ns3
--- a/src/lte/model/lte-enb-phy.cc Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/model/lte-enb-phy.cc Mon Dec 03 18:18:12 2012 +0100
@@ -481,7 +481,6 @@
// update info on TB to be received
std::list<UlDciLteControlMessage> uldcilist = DequeueUlDci ();
std::list<UlDciLteControlMessage>::iterator dciIt = uldcilist.begin ();
- m_ulRntiRxed.clear ();
NS_LOG_DEBUG (this << " eNB Expected TBs " << uldcilist.size ());
for (dciIt = uldcilist.begin (); dciIt!=uldcilist.end (); dciIt++)
{
@@ -510,15 +509,11 @@
{
NS_LOG_DEBUG (this << " RNTI " << (*dciIt).GetDci ().m_rnti << " HARQ RETX");
}
- m_ulRntiRxed.push_back ((*dciIt).GetDci ().m_rnti);
}
}
// process the current burst of control messages
std::list<Ptr<LteControlMessage> > ctrlMsg = GetControlMessages ();
- std::list<DlDciListElement_s> dlDci;
- std::list<UlDciListElement_s> ulDci;
-// std::vector <int> dlRb;
m_dlDataRbMap.clear ();
if (ctrlMsg.size () > 0)
{
@@ -530,7 +525,6 @@
if (msg->GetMessageType () == LteControlMessage::DL_DCI)
{
Ptr<DlDciLteControlMessage> dci = DynamicCast<DlDciLteControlMessage> (msg);
- dlDci.push_back (dci->GetDci ());
// get the tx power spectral density according to DL-DCI(s)
// translate the DCI to Spectrum framework
uint32_t mask = 0x1;
@@ -551,7 +545,32 @@
{
Ptr<UlDciLteControlMessage> dci = DynamicCast<UlDciLteControlMessage> (msg);
QueueUlDci (*dci);
- ulDci.push_back (dci->GetDci ());
+ }
+ else if (msg->GetMessageType () == LteControlMessage::RAR)
+ {
+ Ptr<RarLteControlMessage> rarMsg = DynamicCast<RarLteControlMessage> (msg);
+ for (std::list<RarLteControlMessage::Rar>::const_iterator it = rarMsg->RarListBegin (); it != rarMsg->RarListEnd (); ++it)
+ {
+ if (it->rarPayload.m_grant.m_ulDelay == true)
+ {
+ NS_FATAL_ERROR (" RAR delay is not yet implemented");
+ }
+ UlGrant_s ulGrant = it->rarPayload.m_grant;
+ // translate the UL grant in a standard UL-DCI and queue it
+ UlDciListElement_s dci;
+ dci.m_rnti = ulGrant.m_rnti;
+ dci.m_rbStart = ulGrant.m_rbStart;
+ dci.m_rbLen = ulGrant.m_rbLen;
+ dci.m_tbSize = ulGrant.m_tbSize;
+ dci.m_mcs = ulGrant.m_mcs;
+ dci.m_hopping = ulGrant.m_hopping;
+ dci.m_tpc = ulGrant.m_tpc;
+ dci.m_cqiRequest = ulGrant.m_cqiRequest;
+ dci.m_ndi = 1;
+ UlDciLteControlMessage msg;
+ msg.SetDci (dci);
+ QueueUlDci (msg);
+ }
}
it++;
--- a/src/lte/model/lte-enb-phy.h Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/model/lte-enb-phy.h Mon Dec 03 18:18:12 2012 +0100
@@ -278,8 +278,6 @@
LteEnbCphySapProvider* m_enbCphySapProvider;
LteEnbCphySapUser* m_enbCphySapUser;
- std::vector <uint16_t> m_ulRntiRxed;
-
uint32_t m_nrFrames;
uint32_t m_nrSubFrames;
--- a/src/lte/model/lte-ue-mac.cc Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/model/lte-ue-mac.cc Mon Dec 03 18:18:12 2012 +0100
@@ -371,9 +371,9 @@
// bypass the m_ulConfigured flag. This is reasonable, since In fact
// the RACH preamble is sent on 6RB bandwidth so the uplink
// bandwidth does not need to be configured.
- m_uePhySapProvider->SendRachPreamble (m_raPreambleId);
NS_ASSERT (m_subframeNo > 0); // sanity check for subframe starting at 1
m_raRnti = m_subframeNo - 1;
+ m_uePhySapProvider->SendRachPreamble (m_raPreambleId, m_raRnti);
NS_LOG_INFO (this << " sent preamble id " << (uint32_t) m_raPreambleId << ", RA-RNTI " << (uint32_t) m_raRnti);
// 3GPP 36.321 5.1.4
Time raWindowBegin = MilliSeconds (3);
@@ -590,6 +590,9 @@
if (it->rapId == m_raPreambleId) // RAR is for me
{
RecvRaResponse (it->rarPayload);
+ // TODO:: RRC generates the RecvRaResponse messaged
+ // for avoiding holes in transmission at PHY layer
+ // (which produce erroneous UL CQI evaluation)
}
}
}
--- a/src/lte/model/lte-ue-phy-sap.h Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/model/lte-ue-phy-sap.h Mon Dec 03 18:18:12 2012 +0100
@@ -58,7 +58,7 @@
*
* \param prachId the ID of the preamble
*/
- virtual void SendRachPreamble (uint32_t prachId) = 0;
+ virtual void SendRachPreamble (uint32_t prachId, uint32_t raRnti) = 0;
};
--- a/src/lte/model/lte-ue-phy.cc Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/model/lte-ue-phy.cc Mon Dec 03 18:18:12 2012 +0100
@@ -71,7 +71,7 @@
// inherited from LtePhySapProvider
virtual void SendMacPdu (Ptr<Packet> p);
virtual void SendLteControlMessage (Ptr<LteControlMessage> msg);
- virtual void SendRachPreamble (uint32_t prachId);
+ virtual void SendRachPreamble (uint32_t prachId, uint32_t raRnti);
private:
LteUePhy* m_phy;
@@ -95,9 +95,9 @@
}
void
-UeMemberLteUePhySapProvider::SendRachPreamble (uint32_t prachId)
+UeMemberLteUePhySapProvider::SendRachPreamble (uint32_t prachId, uint32_t raRnti)
{
- m_phy->DoSendRachPreamble (prachId);
+ m_phy->DoSendRachPreamble (prachId, raRnti);
}
@@ -132,6 +132,8 @@
m_dlConfigured (false),
m_ulConfigured (false),
m_addedToDlChannel (false),
+ m_raPreambleId (255), // value out of range
+ m_raRnti (11), // value out of range
m_rsrpRsrqSampleCounter (0)
{
m_amc = CreateObject <LteAmc> ();
@@ -536,13 +538,15 @@
}
void
-LteUePhy::DoSendRachPreamble (uint32_t raPreambleId)
+LteUePhy::DoSendRachPreamble (uint32_t raPreambleId, uint32_t raRnti)
{
NS_LOG_FUNCTION (this << raPreambleId);
// unlike other control messages, RACH preamble is sent ASAP
Ptr<RachPreambleLteControlMessage> msg = Create<RachPreambleLteControlMessage> ();
msg->SetRapId (raPreambleId);
+ m_raPreambleId = raPreambleId;
+ m_raRnti = raRnti;
m_controlMessagesQueue.at (0).push_back (msg);
}
@@ -604,7 +608,6 @@
else if (msg->GetMessageType () == LteControlMessage::UL_DCI)
{
// set the uplink bandwidht according to the UL-CQI
- NS_LOG_DEBUG (this << " UL DCI");
Ptr<UlDciLteControlMessage> msg2 = DynamicCast<UlDciLteControlMessage> (msg);
UlDciListElement_s dci = msg2->GetDci ();
if (dci.m_rnti != m_rnti)
@@ -612,17 +615,49 @@
// DCI not for me
continue;
}
+ NS_LOG_INFO (this << " UL DCI");
std::vector <int> ulRb;
for (int i = 0; i < dci.m_rbLen; i++)
{
ulRb.push_back (i + dci.m_rbStart);
//NS_LOG_DEBUG (this << " UE RB " << i + dci.m_rbStart);
}
-
QueueSubChannelsForTransmission (ulRb);
// pass the info to the MAC
m_uePhySapUser->ReceiveLteControlMessage (msg);
}
+ else if (msg->GetMessageType () == LteControlMessage::RAR)
+ {
+ Ptr<RarLteControlMessage> rarMsg = DynamicCast<RarLteControlMessage> (msg);
+ if (rarMsg->GetRaRnti () == m_raRnti)
+ {
+ for (std::list<RarLteControlMessage::Rar>::const_iterator it = rarMsg->RarListBegin (); it != rarMsg->RarListEnd (); ++it)
+ {
+ if (it->rapId != m_raPreambleId)
+ {
+ // UL grant not for me
+ continue;
+ }
+ else
+ {
+ NS_LOG_INFO ("received RAR RNTI " << m_raRnti);
+ // set the uplink bandwidht according to the UL grant
+ std::vector <int> ulRb;
+ for (int i = 0; i < it->rarPayload.m_grant.m_rbLen; i++)
+ {
+ ulRb.push_back (i + it->rarPayload.m_grant.m_rbStart);
+ }
+
+ QueueSubChannelsForTransmission (ulRb);
+ // pass the info to the MAC
+ m_uePhySapUser->ReceiveLteControlMessage (msg);
+ // reset RACH variables with out of range values
+ m_raPreambleId = 255;
+ m_raRnti = 11;
+ }
+ }
+ }
+ }
else if (msg->GetMessageType () == LteControlMessage::MIB)
{
NS_LOG_INFO ("received MIB");
@@ -682,7 +717,7 @@
std::list<Ptr<LteControlMessage> > ctrlMsg = GetControlMessages ();
// send packets in queue
- NS_LOG_LOGIC (this << " UE - start TX PUSCH + PUCCH");
+ NS_LOG_LOGIC (this << " UE - start slot for PUSCH + PUCCH - RNTI " << m_rnti);
// send the current burts of packets
Ptr<PacketBurst> pb = GetPacketBurst ();
if (pb)
@@ -694,11 +729,15 @@
// send only PUCCH (ideal: fake null bandwidth signal)
if (ctrlMsg.size ()>0)
{
- NS_LOG_LOGIC (this << " UE - start TX PUCCH (NO PUSCH)");
+ NS_LOG_LOGIC (this << " UE - start TX PUCCH (NO PUSCH)");
std::vector <int> dlRb;
SetSubChannelsForTransmission (dlRb);
m_uplinkSpectrumPhy->StartTxDataFrame (pb, ctrlMsg, UL_DATA_DURATION);
}
+ else
+ {
+ NS_LOG_LOGIC (this << " UE - UL NOTHING TO SEND");
+ }
}
} // m_configured
--- a/src/lte/model/lte-ue-phy.h Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/model/lte-ue-phy.h Mon Dec 03 18:18:12 2012 +0100
@@ -226,7 +226,7 @@
// UE PHY SAP methods
virtual void DoSendMacPdu (Ptr<Packet> p);
virtual void DoSendLteControlMessage (Ptr<LteControlMessage> msg);
- virtual void DoSendRachPreamble (uint32_t prachId);
+ virtual void DoSendRachPreamble (uint32_t prachId, uint32_t raRnti);
std::vector <int> m_subChannelsForTransmission;
std::vector <int> m_subChannelsForReception;
@@ -267,6 +267,9 @@
Ptr<LteHarqPhy> m_harqPhyModule;
+ uint32_t m_raPreambleId;
+ uint32_t m_raRnti;
+
/**
* Trace information regarding RSRP and RSRQ (see TS 36.214)
* uint16_t rnti, uint16_t cellId, double rsrp, double rsrq
--- a/src/lte/model/pf-ff-mac-scheduler.cc Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/model/pf-ff-mac-scheduler.cc Mon Dec 03 18:18:12 2012 +0100
@@ -260,6 +260,11 @@
BooleanValue (true),
MakeBooleanAccessor (&PfFfMacScheduler::m_harqOn),
MakeBooleanChecker ())
+ .AddAttribute ("UlGrantMcs",
+ "The MCS of the UL grant, must be [0..15] (default 0)",
+ UintegerValue (0),
+ MakeUintegerAccessor (&PfFfMacScheduler::m_ulGrantMcs),
+ MakeUintegerChecker<uint8_t> ())
;
return tid;
}
@@ -296,6 +301,7 @@
NS_LOG_FUNCTION (this);
// Read the subset of parameters used
m_cschedCellConfig = params;
+ m_rachAllocationMap.resize (m_cschedCellConfig.m_ulBandwidth, 0);
FfMacCschedSapUser::CschedUeConfigCnfParameters cnf;
cnf.m_result = SUCCESS;
m_cschedSapUser->CschedUeConfigCnf (cnf);
@@ -563,6 +569,51 @@
rbgMap.resize (m_cschedCellConfig.m_dlBandwidth / rbgSize, false);
FfMacSchedSapUser::SchedDlConfigIndParameters ret;
+ // RACH Allocation
+ m_rachAllocationMap.resize (m_cschedCellConfig.m_ulBandwidth, 0);
+ uint16_t rbStart = 0;
+ std::vector <struct RachListElement_s>::iterator itRach;
+ for (itRach = m_rachList.begin (); itRach != m_rachList.end (); itRach++)
+ {
+ NS_ASSERT_MSG (m_amc->GetTbSizeFromMcs (m_ulGrantMcs, m_cschedCellConfig.m_ulBandwidth) > (*itRach).m_estimatedSize, " Default UL Grant MCS does not allow to send RACH messages");
+ BuildRarListElement_s newRar;
+ newRar.m_rnti = (*itRach).m_rnti;
+ // DL-RACH Allocation
+ // Ideal: no needs of configuring m_dci
+ // UL-RACH Allocation
+ newRar.m_grant.m_rnti = newRar.m_rnti;
+ newRar.m_grant.m_mcs = m_ulGrantMcs;
+ uint16_t rbLen = 1;
+ uint16_t tbSizeBits = 0;
+ // find lowest TB size that fits UL grant estimated size
+ while ((tbSizeBits < (*itRach).m_estimatedSize) && (rbStart + rbLen < m_cschedCellConfig.m_ulBandwidth))
+ {
+ rbLen++;
+ tbSizeBits = m_amc->GetTbSizeFromMcs (m_ulGrantMcs, rbLen);
+ }
+ if (tbSizeBits < (*itRach).m_estimatedSize)
+ {
+ // no more allocation space: finish allocation
+ break;
+ }
+ newRar.m_grant.m_rbStart = rbStart;
+ newRar.m_grant.m_rbLen = rbLen;
+ newRar.m_grant.m_tbSize = tbSizeBits / 8;
+ newRar.m_grant.m_hopping = false;
+ newRar.m_grant.m_tpc = 0;
+ newRar.m_grant.m_cqiRequest = false;
+ newRar.m_grant.m_ulDelay = false;
+ NS_LOG_INFO (this << " UL grant allocated to RNTI " << (*itRach).m_rnti << " rbStart " << rbStart << " rbLen " << rbLen << " MCS " << m_ulGrantMcs << " tbSize " << newRar.m_grant.m_tbSize);
+ for (uint16_t i = rbStart; i < rbStart + rbLen; i++)
+ {
+ m_rachAllocationMap.at (i) = (*itRach).m_rnti;
+ }
+ rbStart = rbStart + rbLen;
+
+ ret.m_buildRarList.push_back (newRar);
+ }
+ m_rachList.clear ();
+
// Process DL HARQ feedback
// retrieve past HARQ retx buffered
@@ -1113,7 +1164,9 @@
PfFfMacScheduler::DoSchedDlRachInfoReq (const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters& params)
{
NS_LOG_FUNCTION (this);
- // TODO: Implementation of the API
+
+ m_rachList = params.m_rachList;
+
return;
}
@@ -1222,9 +1275,22 @@
uint16_t rbAllocatedNum = 0;
std::set <uint16_t> rntiAllocated;
std::vector <uint16_t> rbgAllocationMap;
- rbgAllocationMap.resize (m_cschedCellConfig.m_ulBandwidth, 0);
+ // update with RACH allocation map
+ rbgAllocationMap = m_rachAllocationMap;
+ //rbgAllocationMap.resize (m_cschedCellConfig.m_ulBandwidth, 0);
+ m_rachAllocationMap.clear ();
+ m_rachAllocationMap.resize (m_cschedCellConfig.m_ulBandwidth, 0);
rbMap.resize (m_cschedCellConfig.m_ulBandwidth, false);
+ // remove RACH allocation
+ for (uint16_t i = 0; i < m_cschedCellConfig.m_ulBandwidth; i++)
+ {
+ if (rbgAllocationMap.at (i) != 0)
+ {
+ rbMap.at (i) = true;
+ NS_LOG_DEBUG (this << " Allocated for RACH " << i);
+ }
+ }
if (m_harqOn == true)
@@ -1288,7 +1354,8 @@
}
else
{
- NS_FATAL_ERROR ("Cannot allocare retx for UE " << rnti);
+ NS_LOG_INFO ("Cannot allocate retx due to RACH allocations for UE " << rnti);
+ continue;
}
dci.m_ndi = 0;
// Update HARQ buffers with new HarqId
@@ -1307,8 +1374,9 @@
for (it = m_ceBsrRxed.begin (); it != m_ceBsrRxed.end (); it++)
{
- // remove old entries of this UE-LC
- if ((*it).second > 0)
+ std::set <uint16_t>::iterator itRnti = rntiAllocated.find ((*it).first);
+ // select UEs with queues not empty and not yet allocated for HARQ
+ if (((*it).second > 0)&&(itRnti == rntiAllocated.end ()))
{
nflows++;
}
@@ -1316,6 +1384,11 @@
if (nflows == 0)
{
+ if (ret.m_dciList.size () > 0)
+ {
+ m_schedSapUser->SchedUlConfigInd (ret);
+ }
+
return; // no flows to be scheduled
}
@@ -1372,7 +1445,8 @@
uldci.m_rnti = (*it).first;
uldci.m_rbLen = rbPerFlow;
bool allocated = false;
- while ((!allocated)&&((rbAllocated + rbPerFlow - 1) < m_cschedCellConfig.m_ulBandwidth))
+ NS_LOG_INFO (this << " RB Allocated " << rbAllocated << " rbPerFlow " << rbPerFlow);
+ while ((!allocated)&&((rbAllocated + rbPerFlow - 1) < m_cschedCellConfig.m_ulBandwidth) && (rbPerFlow != 0))
{
// check availability
bool free = true;
@@ -1498,7 +1572,7 @@
(*itDci).second.at (harqId) = uldci;
}
- NS_LOG_INFO (this << " UE " << (*it).first << " startPRB " << (uint32_t)uldci.m_rbStart << " nPRB " << (uint32_t)uldci.m_rbLen << " CQI " << cqi << " MCS " << (uint32_t)uldci.m_mcs << " TBsize " << uldci.m_tbSize << " RbAlloc " << rbAllocated << " harqId " << (uint16_t)harqId);
+ NS_LOG_INFO (this << " UE Allocation RNTI " << (*it).first << " startPRB " << (uint32_t)uldci.m_rbStart << " nPRB " << (uint32_t)uldci.m_rbLen << " CQI " << cqi << " MCS " << (uint32_t)uldci.m_mcs << " TBsize " << uldci.m_tbSize << " RbAlloc " << rbAllocated << " harqId " << (uint16_t)harqId);
// update TTI UE stats
itStats = m_flowStatsUl.find ((*it).first);
@@ -1525,7 +1599,7 @@
break;
}
}
- while ((*it).first != m_nextRntiUl);
+ while (((*it).first != m_nextRntiUl)&&(rbPerFlow!=0));
// Update global UE stats
@@ -1541,6 +1615,7 @@
}
m_allocationMaps.insert (std::pair <uint16_t, std::vector <uint16_t> > (params.m_sfnSf, rbgAllocationMap));
m_schedSapUser->SchedUlConfigInd (ret);
+
return;
}
@@ -1640,6 +1715,7 @@
{
std::map <uint16_t, std::vector <uint16_t> >::iterator itMap;
std::map <uint16_t, std::vector <double> >::iterator itCqi;
+ NS_LOG_DEBUG (this << " Collect PUSCH CQIs of Frame no. " << (params.m_sfnSf >> 4) << " subframe no. " << (0xF & params.m_sfnSf));
itMap = m_allocationMaps.find (params.m_sfnSf);
if (itMap == m_allocationMaps.end ())
{
@@ -1675,6 +1751,7 @@
{
// update the value
(*itCqi).second.at (i) = sinr;
+ NS_LOG_DEBUG (this << " RNTI " << (*itMap).second.at (i) << " RB " << i << " SINR " << sinr);
// update correspondent timer
std::map <uint16_t, uint32_t>::iterator itTimers;
itTimers = m_ueCqiTimers.find ((*itMap).second.at (i));
@@ -1762,7 +1839,7 @@
// delete correspondent entries
std::map <uint16_t,uint8_t>::iterator itMap = m_p10CqiRxed.find ((*itP10).first);
NS_ASSERT_MSG (itMap != m_p10CqiRxed.end (), " Does not find CQI report for user " << (*itP10).first);
- NS_LOG_INFO (this << " P10-CQI exired for user " << (*itP10).first);
+ NS_LOG_INFO (this << " P10-CQI expired for user " << (*itP10).first);
m_p10CqiRxed.erase (itMap);
std::map <uint16_t,uint32_t>::iterator temp = itP10;
itP10++;
@@ -1785,7 +1862,7 @@
// delete correspondent entries
std::map <uint16_t,SbMeasResult_s>::iterator itMap = m_a30CqiRxed.find ((*itA30).first);
NS_ASSERT_MSG (itMap != m_a30CqiRxed.end (), " Does not find CQI report for user " << (*itA30).first);
- NS_LOG_INFO (this << " A30-CQI exired for user " << (*itA30).first);
+ NS_LOG_INFO (this << " A30-CQI expired for user " << (*itA30).first);
m_a30CqiRxed.erase (itMap);
std::map <uint16_t,uint32_t>::iterator temp = itA30;
itA30++;
--- a/src/lte/model/pf-ff-mac-scheduler.h Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/model/pf-ff-mac-scheduler.h Mon Dec 03 18:18:12 2012 +0100
@@ -269,6 +269,12 @@
std::map <uint16_t, UlHarqProcessesStatus_t> m_ulHarqProcessesStatus;
std::map <uint16_t, UlHarqProcessesDciBuffer_t> m_ulHarqProcessesDciBuffer;
+
+ // RACH attributes
+ std::vector <struct RachListElement_s> m_rachList;
+ std::vector <uint16_t> m_rachAllocationMap;
+ uint8_t m_ulGrantMcs; // MCS for UL grant (default 0)
+
};
} // namespace ns3
--- a/src/lte/model/rr-ff-mac-scheduler.cc Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/model/rr-ff-mac-scheduler.cc Mon Dec 03 18:18:12 2012 +0100
@@ -262,6 +262,11 @@
BooleanValue (true),
MakeBooleanAccessor (&RrFfMacScheduler::m_harqOn),
MakeBooleanChecker ())
+ .AddAttribute ("UlGrantMcs",
+ "The MCS of the UL grant, must be [0..15] (default 0)",
+ UintegerValue (0),
+ MakeUintegerAccessor (&RrFfMacScheduler::m_ulGrantMcs),
+ MakeUintegerChecker<uint8_t> ())
;
return tid;
}
@@ -298,6 +303,7 @@
NS_LOG_FUNCTION (this);
// Read the subset of parameters used
m_cschedCellConfig = params;
+ m_rachAllocationMap.resize (m_cschedCellConfig.m_ulBandwidth, 0);
FfMacCschedSapUser::CschedUeConfigCnfParameters cnf;
cnf.m_result = SUCCESS;
m_cschedSapUser->CschedUeConfigCnf (cnf);
@@ -387,6 +393,7 @@
}
// add the new parameters
m_rlcBufferReq.insert (it, params);
+ NS_LOG_INFO (this << " RNTI " << params.m_rnti << " LC " << (uint16_t)params.m_logicalChannelIdentity << " RLC tx size " << params.m_rlcTransmissionQueueHolDelay << " RLC retx size " << params.m_rlcRetransmissionQueueSize << " RLC stat size " << params.m_rlcStatusPduSize);
// initialize statistics of the flow in case of new flows
if (newLc == true)
{
@@ -526,6 +533,51 @@
std::set <uint16_t> rntiAllocated;
rbgMap.resize (m_cschedCellConfig.m_dlBandwidth / rbgSize, false);
+ // RACH Allocation
+ m_rachAllocationMap.resize (m_cschedCellConfig.m_ulBandwidth, 0);
+ uint16_t rbStart = 0;
+ std::vector <struct RachListElement_s>::iterator itRach;
+ for (itRach = m_rachList.begin (); itRach != m_rachList.end (); itRach++)
+ {
+ NS_ASSERT_MSG (m_amc->GetTbSizeFromMcs (m_ulGrantMcs, m_cschedCellConfig.m_ulBandwidth) > (*itRach).m_estimatedSize, " Default UL Grant MCS does not allow to send RACH messages");
+ BuildRarListElement_s newRar;
+ newRar.m_rnti = (*itRach).m_rnti;
+ // DL-RACH Allocation
+ // Ideal: no needs of configuring m_dci
+ // UL-RACH Allocation
+ newRar.m_grant.m_rnti = newRar.m_rnti;
+ newRar.m_grant.m_mcs = m_ulGrantMcs;
+ uint16_t rbLen = 1;
+ uint16_t tbSizeBits = 0;
+ // find lowest TB size that fits UL grant estimated size
+ while ((tbSizeBits < (*itRach).m_estimatedSize) && (rbStart + rbLen < m_cschedCellConfig.m_ulBandwidth))
+ {
+ rbLen++;
+ tbSizeBits = m_amc->GetTbSizeFromMcs (m_ulGrantMcs, rbLen);
+ }
+ if (tbSizeBits < (*itRach).m_estimatedSize)
+ {
+ // no more allocation space: finish allocation
+ break;
+ }
+ newRar.m_grant.m_rbStart = rbStart;
+ newRar.m_grant.m_rbLen = rbLen;
+ newRar.m_grant.m_tbSize = tbSizeBits / 8;
+ newRar.m_grant.m_hopping = false;
+ newRar.m_grant.m_tpc = 0;
+ newRar.m_grant.m_cqiRequest = false;
+ newRar.m_grant.m_ulDelay = false;
+ NS_LOG_INFO (this << " UL grant allocated to RNTI " << (*itRach).m_rnti << " rbStart " << rbStart << " rbLen " << rbLen << " MCS " << (uint16_t) m_ulGrantMcs << " tbSize " << newRar.m_grant.m_tbSize);
+ for (uint16_t i = rbStart; i < rbStart + rbLen; i++)
+ {
+ m_rachAllocationMap.at (i) = (*itRach).m_rnti;
+ }
+ rbStart = rbStart + rbLen;
+
+ ret.m_buildRarList.push_back (newRar);
+ }
+ m_rachList.clear ();
+
// Process DL HARQ feedback
// retrieve past HARQ retx buffered
if (m_dlInfoListBuffered.size () > 0)
@@ -826,7 +878,7 @@
if (nflows == 0)
{
- if (ret.m_buildDataList.size () > 0)
+ if ((ret.m_buildDataList.size () > 0) || (ret.m_buildRarList.size () > 0))
{
m_schedSapUser->SchedDlConfigInd (ret);
}
@@ -1002,7 +1054,7 @@
}
while ((*it).m_rnti != m_nextRntiDl);
- ret.m_nrOfPdcchOfdmSymbols = 1; // TODO: check correct value according the DCIs txed
+ ret.m_nrOfPdcchOfdmSymbols = 1; // TODO: check correct value according the DCIs txed
m_schedSapUser->SchedDlConfigInd (ret);
return;
@@ -1012,7 +1064,9 @@
RrFfMacScheduler::DoSchedDlRachInfoReq (const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters& params)
{
NS_LOG_FUNCTION (this);
- // TODO: Implementation of the API
+
+ m_rachList = params.m_rachList;
+
return;
}
@@ -1075,9 +1129,21 @@
uint16_t rbAllocatedNum = 0;
std::set <uint16_t> rntiAllocated;
std::vector <uint16_t> rbgAllocationMap;
- rbgAllocationMap.resize (m_cschedCellConfig.m_ulBandwidth, 0);
+ // update with RACH allocation map
+ rbgAllocationMap = m_rachAllocationMap;
+ //rbgAllocationMap.resize (m_cschedCellConfig.m_ulBandwidth, 0);
+ m_rachAllocationMap.clear ();
+ m_rachAllocationMap.resize (m_cschedCellConfig.m_ulBandwidth, 0);
rbMap.resize (m_cschedCellConfig.m_ulBandwidth, false);
+ // remove RACH allocation
+ for (uint16_t i = 0; i < m_cschedCellConfig.m_ulBandwidth; i++)
+ {
+ if (rbgAllocationMap.at (i) != 0)
+ {
+ rbMap.at (i) = true;
+ }
+ }
if (m_harqOn == true)
{
@@ -1140,7 +1206,8 @@
}
else
{
- NS_FATAL_ERROR ("Cannot allocare retx for UE " << rnti);
+ NS_LOG_INFO ("Cannot allocate retx due to RACH allocations for UE " << rnti);
+ continue;
}
dci.m_ndi = 0;
// Update HARQ buffers with new HarqId
@@ -1168,6 +1235,10 @@
if (nflows == 0)
{
+ if (ret.m_dciList.size () > 0)
+ {
+ m_schedSapUser->SchedUlConfigInd (ret);
+ }
return; // no flows to be scheduled
}
@@ -1199,7 +1270,7 @@
it = m_ceBsrRxed.begin ();
m_nextRntiUl = (*it).first;
}
- NS_LOG_INFO (this << " RB per Flow " << rbPerFlow);
+ NS_LOG_INFO (this << " NFlows " << nflows << " RB per Flow " << rbPerFlow);
do
{
std::set <uint16_t>::iterator itRnti = rntiAllocated.find ((*it).first);
@@ -1224,7 +1295,7 @@
uldci.m_rnti = (*it).first;
uldci.m_rbLen = rbPerFlow;
bool allocated = false;
- while ((!allocated)&&((rbAllocated + rbPerFlow - 1) < m_cschedCellConfig.m_ulBandwidth))
+ while ((!allocated)&&((rbAllocated + rbPerFlow - 1) < m_cschedCellConfig.m_ulBandwidth) && (rbPerFlow != 0))
{
// check availability
bool free = true;
@@ -1355,7 +1426,8 @@
break;
}
}
- while ((*it).first != m_nextRntiUl);
+ while (((*it).first != m_nextRntiUl)&&(rbPerFlow!=0));
+
m_allocationMaps.insert (std::pair <uint16_t, std::vector <uint16_t> > (params.m_sfnSf, rbgAllocationMap));
m_schedSapUser->SchedUlConfigInd (ret);
return;
--- a/src/lte/model/rr-ff-mac-scheduler.h Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/model/rr-ff-mac-scheduler.h Mon Dec 03 18:18:12 2012 +0100
@@ -211,6 +211,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
+
// HARQ attributes
@@ -233,6 +234,12 @@
// x>0: process Id equal to `x` trasmission count
std::map <uint16_t, UlHarqProcessesStatus_t> m_ulHarqProcessesStatus;
std::map <uint16_t, UlHarqProcessesDciBuffer_t> m_ulHarqProcessesDciBuffer;
+
+
+ // RACH attributes
+ std::vector <struct RachListElement_s> m_rachList;
+ std::vector <uint16_t> m_rachAllocationMap;
+ uint8_t m_ulGrantMcs; // MCS for UL grant (default 0)
};
} // namespace ns3
--- a/src/lte/test/lte-test-pf-ff-mac-scheduler.cc Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/test/lte-test-pf-ff-mac-scheduler.cc Mon Dec 03 18:18:12 2012 +0100
@@ -268,7 +268,7 @@
}
- double statsStartTime = 0.060; // need to allow for RRC connection establishment + SRS
+ double statsStartTime = 0.100; // need to allow for RRC connection establishment + SRS
double statsDuration = 0.6;
double tolerance = 0.1;
Simulator::Stop (Seconds (statsStartTime + statsDuration - 0.000001));
@@ -428,7 +428,7 @@
uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
}
- double statsStartTime = 0.050; // need to allow for RRC connection establishment + SRS
+ double statsStartTime = 0.100; // need to allow for RRC connection establishment + SRS
double statsDuration = 0.4;
double tolerance = 0.1;
Simulator::Stop (Seconds (statsStartTime + statsDuration + 0.000001));
--- a/src/lte/test/lte-test-rr-ff-mac-scheduler.cc Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/test/lte-test-rr-ff-mac-scheduler.cc Mon Dec 03 18:18:12 2012 +0100
@@ -254,7 +254,7 @@
}
- double statsStartTime = 0.050; // need to allow for RRC connection establishment + SRS
+ double statsStartTime = 0.100; // need to allow for RRC connection establishment + SRS
double statsDuration = 0.4;
double tolerance = 0.1;
Simulator::Stop (Seconds (statsStartTime + statsDuration - 0.0001));
--- a/src/lte/test/test-lte-rrc.cc Tue Nov 27 10:48:00 2012 +0100
+++ b/src/lte/test/test-lte-rrc.cc Mon Dec 03 18:18:12 2012 +0100
@@ -75,12 +75,12 @@
}
LteRrcConnectionEstablishmentTestCase::LteRrcConnectionEstablishmentTestCase (uint32_t nUes, uint32_t nBearers, uint32_t tConnBase, uint32_t tConnIncrPerUe, uint32_t delayDiscStart)
- : TestCase ("RRC connection establishment"),
+ : TestCase (BuildNameString (nUes, nBearers, tConnBase, tConnIncrPerUe, delayDiscStart)),
m_nUes (nUes),
m_nBearers (nBearers),
m_tConnBase (tConnBase),
m_tConnIncrPerUe (tConnIncrPerUe),
- m_delayConnEnd (150), // includes: time to receive system information, time for Random Access (RACH preamble, RAR response), time to send and receive RRC connection request+setup+completed. Value should be slightly higher than T300 in TS 36.331
+ m_delayConnEnd (140+nUes*8/4), // includes: time to receive system information, time for Random Access (RACH preamble, RAR response), time to send and receive RRC connection request+setup+completed. Value should be slightly higher than T300 in TS 36.331
m_delayDiscStart (delayDiscStart),
m_delayDiscEnd (10)
{
@@ -263,7 +263,7 @@
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 4, 0, 20, 0, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 4, 0, 20, 300, 1));
AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 20, 0, 10, 1, 1));
- AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 50, 0, 10, 0, 1));
+ AddTestCase (new LteRrcConnectionEstablishmentTestCase ( 50, 0, 0, 0, 1));
// // time consuming tests with a lot of UEs
// AddTestCase (new LteRrcConnectionEstablishmentTestCase (100, 0, 10, 0, 1));