merge
authorManuel Requena <manuel.requena@cttc.es>
Thu, 20 Dec 2012 18:09:40 +0100
changeset 9605 6da8fa4f016c
parent 9604 fc2e53d1f34d (current diff)
parent 9602 d3f5d483eb15 (diff)
child 9606 01c61ef3d568
merge
--- a/src/lte/model/lte-enb-rrc.cc	Thu Dec 20 18:09:04 2012 +0100
+++ b/src/lte/model/lte-enb-rrc.cc	Thu Dec 20 18:09:40 2012 +0100
@@ -873,6 +873,12 @@
   SwitchToState (CONNECTED_NORMALLY);
 }
 
+void 
+UeManager::RecvMeasurementReport (LteRrcSap::MeasurementReport msg)
+{
+  NS_LOG_FUNCTION (this);
+}
+
 
 // methods forwarded from CMAC SAP
 
@@ -1435,6 +1441,12 @@
   GetUeManager (rnti)->RecvRrcConnectionReestablishmentComplete (msg);
 }
 
+void 
+LteEnbRrc::DoRecvMeasurementReport (uint16_t rnti, LteRrcSap::MeasurementReport msg)
+{
+  NS_LOG_FUNCTION (this << rnti);
+  GetUeManager (rnti)->RecvMeasurementReport (msg);
+}
 
 void 
 LteEnbRrc::DoDataRadioBearerSetupRequest (EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters request)
--- a/src/lte/model/lte-enb-rrc.h	Thu Dec 20 18:09:04 2012 +0100
+++ b/src/lte/model/lte-enb-rrc.h	Thu Dec 20 18:09:40 2012 +0100
@@ -233,6 +233,7 @@
   void RecvRrcConnectionReconfigurationCompleted (LteRrcSap::RrcConnectionReconfigurationCompleted msg);
   void RecvRrcConnectionReestablishmentRequest (LteRrcSap::RrcConnectionReestablishmentRequest msg);
   void RecvRrcConnectionReestablishmentComplete (LteRrcSap::RrcConnectionReestablishmentComplete msg);
+  void RecvMeasurementReport (LteRrcSap::MeasurementReport msg);
 
 
   // methods forwarded from CMAC SAP
@@ -597,6 +598,7 @@
   void DoRecvRrcConnectionReconfigurationCompleted (uint16_t rnti, LteRrcSap::RrcConnectionReconfigurationCompleted msg);
   void DoRecvRrcConnectionReestablishmentRequest (uint16_t rnti, LteRrcSap::RrcConnectionReestablishmentRequest msg);
   void DoRecvRrcConnectionReestablishmentComplete (uint16_t rnti, LteRrcSap::RrcConnectionReestablishmentComplete msg);
+  void DoRecvMeasurementReport (uint16_t rnti, LteRrcSap::MeasurementReport msg);
 
 
   // S1 SAP methods
--- a/src/lte/model/lte-rrc-header.cc	Thu Dec 20 18:09:04 2012 +0100
+++ b/src/lte/model/lte-rrc-header.cc	Thu Dec 20 18:09:40 2012 +0100
@@ -389,23 +389,11 @@
 
   // Serialize plmn-IdentityList
   SerializeSequenceOf (1,6,1);
+
   // PLMN-IdentityInfo 
   SerializeSequence (std::bitset<0> (),false);
-  // plmn-Identity sequence, mcc is optional, no extension marker
-  SerializeSequence (std::bitset<1> (0), false);
-  // Serialize mnc
-  int x = systemInformationBlockType1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity;
-  int nDig = (x > 99) ? 3 : 2;
-
-  SerializeSequenceOf (nDig,3,2);
-  for (int i = nDig - 1; i >= 0; i--)
-    {
-      int n = floor (x / pow (10,i));
-      SerializeInteger (n,0,9);
-      x -= n * pow (10,i);
-    }
-  // cellReservedForOperatorUse 
-  SerializeEnum (2,0);
+
+  SerializePlmnIdentity (systemInformationBlockType1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity);
 
   // Serialize trackingAreaCode
   SerializeBitstring (std::bitset<16> (0));
@@ -534,6 +522,112 @@
   SerializeEnum (8,0);
 }
 
+void
+RrcAsn1Header::SerializeMeasResults (LteRrcSap::MeasResults measResults) const
+{
+  // Watchdog: if list has 0 elements, set boolean to false
+  if(measResults.measResultListEutra.empty())
+  {
+    measResults.haveMeasResultNeighCells = false;
+  }
+
+  // Serialize MeasResults sequence, 1 optional value, extension marker present
+  SerializeSequence(std::bitset<1>(measResults.haveMeasResultNeighCells),true);
+
+  // Serialize measId
+  SerializeInteger(measResults.measId,1,MAX_MEAS_ID);
+  
+  // Serialize measResultServCell sequence
+  SerializeSequence(std::bitset<0>(0),false);
+
+  // Serialize rsrpResult
+  SerializeInteger(measResults.rsrpResult,0,97);
+  
+  // Serialize rsrqResult
+  SerializeInteger(measResults.rsrqResult,0,34);
+  
+  if(measResults.haveMeasResultNeighCells)
+  {
+    // Serialize Choice = 0 (MeasResultListEUTRA)
+    SerializeChoice (4,0);
+    
+    // Serialize measResultNeighCells
+    SerializeSequenceOf(measResults.measResultListEutra.size(),MAX_CELL_REPORT,1);
+    
+    // serialize MeasResultEutra elements in the list
+    std::list<LteRrcSap::MeasResultEutra>::iterator it;
+    for (it = measResults.measResultListEutra.begin(); it != measResults.measResultListEutra.end(); it++)
+    {
+      SerializeSequence (std::bitset<1> (it->haveCgiInfo),false);
+      
+      // Serialize PhysCellId
+      SerializeInteger (it->physCellId, 0, 503);
+      
+      // Serialize CgiInfo
+      if(it->haveCgiInfo)
+      {
+        SerializeSequence (std::bitset<1>(it->cgiInfo.plmnIdentityList.size()),false);
+
+        // Serialize cellGlobalId
+        SerializeSequence (std::bitset<0>(0),false);
+        SerializePlmnIdentity(it->cgiInfo.plmnIdentity);
+        SerializeBitstring (std::bitset<28>(it->cgiInfo.cellIdentity));
+        
+        // Serialize trackingAreaCode
+        SerializeBitstring (std::bitset<16>(it->cgiInfo.trackingAreaCode));
+        
+        // Serialize plmn-IdentityList
+        if(!it->cgiInfo.plmnIdentityList.empty())
+        {
+          SerializeSequenceOf(it->cgiInfo.plmnIdentityList.size(),5,1);
+          std::list<uint32_t>::iterator it2;
+          for (it2 = it->cgiInfo.plmnIdentityList.begin(); it2 != it->cgiInfo.plmnIdentityList.end(); it2++)
+          {
+            SerializePlmnIdentity(*it2);
+          }
+        }
+      }
+      
+      // Serialize measResult
+      std::bitset<2> measResultFieldsPresent;
+      measResultFieldsPresent[1] = it->haveRsrpResult;
+      measResultFieldsPresent[0] = it->haveRsrqResult;
+      SerializeSequence(measResultFieldsPresent,true);
+      
+      if(it->haveRsrpResult)
+      {
+        SerializeInteger (it->rsrpResult,0,97);
+      }
+      
+      if(it->haveRsrqResult)
+      {
+        SerializeInteger (it->rsrqResult,0,34);
+      }
+    }
+  } 
+}
+
+void
+RrcAsn1Header::SerializePlmnIdentity (uint32_t plmnId) const
+{
+  // plmn-Identity sequence, mcc is optional, no extension marker
+  SerializeSequence (std::bitset<1> (0), false);
+  
+  // Serialize mnc
+  int nDig = (plmnId > 99) ? 3 : 2;
+
+  SerializeSequenceOf (nDig,3,2);
+  for (int i = nDig - 1; i >= 0; i--)
+    {
+      int n = floor (plmnId / pow (10,i));
+      SerializeInteger (n,0,9);
+      plmnId -= n * pow (10,i);
+    }
+    
+  // cellReservedForOperatorUse 
+  SerializeEnum (2,0);
+}
+
 Buffer::Iterator
 RrcAsn1Header::DeserializeRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated *radioResourceConfigDedicated, Buffer::Iterator bIterator)
 {
@@ -1053,27 +1147,7 @@
       bIterator = DeserializeSequence (&bitset0,false,bIterator);
 
       // plmn-Identity
-      std::bitset<1> isMccPresent;
-      bIterator = DeserializeSequence (&isMccPresent,false,bIterator);
-      if (isMccPresent[0])
-        {
-          // Deserialize mcc
-          // ...
-        }
-      // Deserialize mnc
-      int mncDigits;
-      int mnc = 0;
-      bIterator = DeserializeSequenceOf (&mncDigits,3,2,bIterator);
-
-      for (int j = mncDigits - 1; j >= 0; j--)
-        {
-          bIterator = DeserializeInteger (&n,0,9,bIterator);
-          mnc += n * pow (10,j);
-        }
-      systemInformationBlockType1->cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity = mnc;
-
-      // cellReservedForOperatorUse
-      bIterator = DeserializeEnum (2,&n,bIterator);
+      bIterator = DeserializePlmnIdentity(&systemInformationBlockType1->cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity,bIterator);
     }
 
   // Deserialize trackingAreaCode
@@ -1456,6 +1530,44 @@
   return bIterator;
 }
 
+Buffer::Iterator
+RrcAsn1Header::DeserializeMeasResults (LteRrcSap::MeasResults *measResults, Buffer::Iterator bIterator)
+{
+  // TODO
+  return bIterator;
+}
+
+Buffer::Iterator
+RrcAsn1Header::DeserializePlmnIdentity (uint32_t *plmnId, Buffer::Iterator bIterator)
+{
+  int n;
+  std::bitset<1> isMccPresent;
+  bIterator = DeserializeSequence (&isMccPresent,false,bIterator);
+  
+  if (isMccPresent[0])
+    {
+      // Deserialize mcc
+      // ...
+    }
+
+  // Deserialize mnc
+  int mncDigits;
+  int mnc = 0;
+  bIterator = DeserializeSequenceOf (&mncDigits,3,2,bIterator);
+
+  for (int j = mncDigits - 1; j >= 0; j--)
+    {
+      bIterator = DeserializeInteger (&n,0,9,bIterator);
+      mnc += n * pow (10,j);
+    }
+
+  *plmnId = mnc;
+
+  // cellReservedForOperatorUse
+  bIterator = DeserializeEnum (2,&n,bIterator);
+  return bIterator;
+}
+  
 //////////////////// RrcConnectionRequest class ////////////////////////
 
 // Constructor
@@ -1900,11 +2012,10 @@
 RrcConnectionReconfigurationCompleteHeader::Deserialize (Buffer::Iterator bIterator)
 {
   std::bitset<0> bitset0;
-  bIterator = DeserializeSequence (&bitset0,false,bIterator);
-
   int n;
 
   bIterator = DeserializeUlDcchMessage (bIterator);
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
 
   bIterator = DeserializeInteger (&n,0,3,bIterator);
   m_rrcTransactionIdentifier = n;
@@ -3486,6 +3597,111 @@
   return m_rrcConnectionReject;
 }
 
+//////////////////// MeasurementReportHeader class ////////////////////////
+
+MeasurementReportHeader::MeasurementReportHeader ()
+{
+}
+
+void
+MeasurementReportHeader::PreSerialize () const
+{
+  m_serializationResult = Buffer ();
+
+  // Serialize DCCH message
+  SerializeUlDcchMessage (1);
+
+  // Serialize MeasurementReport sequence:
+  // no default or optional fields. Extension marker not present.
+  SerializeSequence<0> (std::bitset<0> (),false);
+
+  // Serialize criticalExtensions choice:
+  // c1 chosen
+  SerializeChoice (2,0);
+  
+  // Serialize c1 choice
+  // measurementReport-r8 chosen
+  SerializeChoice (8,0);
+
+  // Serialize MeasurementReport-r8-IEs sequence:
+  // 1 optional fields, not present. Extension marker not present.
+  SerializeSequence<1> (std::bitset<1> (0),false);
+
+  // Serialize measResults
+  SerializeMeasResults (m_measurementReport.measResults);
+  
+  // Finish serialization
+  FinalizeSerialization ();
+}
+
+uint32_t
+MeasurementReportHeader::Deserialize (Buffer::Iterator bIterator)
+{
+  std::bitset<0> bitset0;
+
+  bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+  bIterator = DeserializeUlDcchMessage (bIterator);
+
+  int criticalExtensionsChoice;
+  bIterator = DeserializeChoice (2,&criticalExtensionsChoice,bIterator);
+
+  if (criticalExtensionsChoice == 1)
+    {
+      // Deserialize criticalExtensionsFuture
+      bIterator = DeserializeSequence (&bitset0,false,bIterator);
+    }
+  else if (criticalExtensionsChoice == 0)
+    {
+      // Deserialize c1
+      int c1Choice;
+      bIterator = DeserializeChoice (8,&c1Choice,bIterator);
+      
+      if(c1Choice>0)
+      {
+        bIterator = DeserializeNull(bIterator);
+      }
+      else
+      {
+        // Deserialize measurementReport-r8
+        std::bitset<1> isNonCriticalExtensionPresent;
+        bIterator = DeserializeSequence(&isNonCriticalExtensionPresent,false,bIterator);
+        
+        // Deserialize measResults
+        bIterator = DeserializeMeasResults (&m_measurementReport.measResults, bIterator);
+        
+        if(isNonCriticalExtensionPresent[0])
+        {
+          // Deserialize nonCriticalExtension MeasurementReport-v8a0-IEs
+          // ...
+        }
+
+      }
+    }
+
+  return GetSerializedSize ();
+}
+
+void
+MeasurementReportHeader::Print (std::ostream &os) const
+{
+  // TODO
+}
+
+void
+MeasurementReportHeader::SetMessage (MeasurementReport msg)
+{
+  m_measurementReport = msg;
+  m_isDataSerialized = false;
+}
+
+LteRrcSap::MeasurementReport
+MeasurementReportHeader::GetMessage () const
+{
+  MeasurementReport msg;
+  msg = m_measurementReport;
+  return msg;
+}
 
 ///////////////////  RrcUlDcchMessage //////////////////////////////////
 uint32_t
--- a/src/lte/model/lte-rrc-header.h	Thu Dec 20 18:09:04 2012 +0100
+++ b/src/lte/model/lte-rrc-header.h	Thu Dec 20 18:09:40 2012 +0100
@@ -51,6 +51,8 @@
   void SerializeSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 systemInformationBlockType1) const;
   void SerializeSystemInformationBlockType2 () const;
   void SerializeRadioResourceConfigCommonSIB () const;
+  void SerializeMeasResults (LteRrcSap::MeasResults measResults) const;
+  void SerializePlmnIdentity (uint32_t plmnId) const;
 
   // Deserialization functions
   Buffer::Iterator DeserializeDrbToAddModList (std::list<LteRrcSap::DrbToAddMod> *drbToAddModLis, Buffer::Iterator bIterator);
@@ -62,6 +64,8 @@
   Buffer::Iterator DeserializeSystemInformationBlockType2 (Buffer::Iterator bIterator);
   Buffer::Iterator DeserializeRadioResourceConfigCommon (Buffer::Iterator bIterator);
   Buffer::Iterator DeserializeRadioResourceConfigCommonSib (Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializeMeasResults (LteRrcSap::MeasResults *measResults, Buffer::Iterator bIterator);
+  Buffer::Iterator DeserializePlmnIdentity (uint32_t *plmnId, Buffer::Iterator bIterator);
 
   void Print (std::ostream &os, LteRrcSap::RadioResourceConfigDedicated radioResourceConfigDedicated) const;
 
@@ -395,6 +399,25 @@
   RrcConnectionReject m_rrcConnectionReject;
 };
 
+/**
+* This class manages the serialization/deserialization of MeasurementReport IE
+*/
+class MeasurementReportHeader : public RrcUlDcchMessage,
+                                                   LteRrcSap
+{
+public:
+  MeasurementReportHeader ();
+  void PreSerialize () const;
+  uint32_t Deserialize (Buffer::Iterator bIterator);
+  void Print (std::ostream &os) const;
+  void SetMessage (MeasurementReport msg);
+  MeasurementReport GetMessage () const;
+
+private:
+  MeasurementReport m_measurementReport;
+
+};
+
 } // namespace ns3
 
 #endif // EPC_ASN1_HEADER_H
--- a/src/lte/model/lte-rrc-protocol-ideal.cc	Thu Dec 20 18:09:04 2012 +0100
+++ b/src/lte/model/lte-rrc-protocol-ideal.cc	Thu Dec 20 18:09:40 2012 +0100
@@ -179,6 +179,15 @@
 msg);
 }
 
+void 
+LteUeRrcProtocolIdeal::DoSendMeasurementReport (LteRrcSap::MeasurementReport msg)
+{
+   Simulator::Schedule (RRC_IDEAL_MSG_DELAY, 
+                        &LteEnbRrcSapProvider::RecvMeasurementReport,
+                        m_enbRrcSapProvider,
+                        m_rnti, 
+                        msg);
+}
 
 void 
 LteUeRrcProtocolIdeal::SetEnbRrcSapProvider ()
--- a/src/lte/model/lte-rrc-protocol-ideal.h	Thu Dec 20 18:09:04 2012 +0100
+++ b/src/lte/model/lte-rrc-protocol-ideal.h	Thu Dec 20 18:09:40 2012 +0100
@@ -72,6 +72,7 @@
   void DoSendRrcConnectionReconfigurationCompleted (LteRrcSap::RrcConnectionReconfigurationCompleted msg);
   void DoSendRrcConnectionReestablishmentRequest (LteRrcSap::RrcConnectionReestablishmentRequest msg);
   void DoSendRrcConnectionReestablishmentComplete (LteRrcSap::RrcConnectionReestablishmentComplete msg);
+  void DoSendMeasurementReport (LteRrcSap::MeasurementReport msg);
 
   void SetEnbRrcSapProvider ();
 
--- a/src/lte/model/lte-rrc-protocol-real.cc	Thu Dec 20 18:09:04 2012 +0100
+++ b/src/lte/model/lte-rrc-protocol-real.cc	Thu Dec 20 18:09:40 2012 +0100
@@ -201,6 +201,29 @@
 }
 
 void 
+LteUeRrcProtocolReal::DoSendMeasurementReport (LteRrcSap::MeasurementReport msg)
+{
+  // re-initialize the RNTI and get the EnbLteRrcSapProvider for the
+  // eNB we are currently attached to
+  m_rnti = m_rrc->GetRnti ();
+  SetEnbRrcSapProvider ();
+
+  Ptr<Packet> packet = Create<Packet> ();
+
+  MeasurementReportHeader measurementReportHeader;
+  measurementReportHeader.SetMessage (msg);
+
+  packet->AddHeader (measurementReportHeader);
+
+  LtePdcpSapProvider::TransmitPdcpSduParameters transmitPdcpSduParameters;
+  transmitPdcpSduParameters.pdcpSdu = packet;
+  transmitPdcpSduParameters.rnti = m_rnti;
+  transmitPdcpSduParameters.lcid = 1;
+
+  m_setupParameters.srb1SapProvider->TransmitPdcpSdu (transmitPdcpSduParameters);
+}
+
+void 
 LteUeRrcProtocolReal::DoSendRrcConnectionReestablishmentRequest (LteRrcSap::RrcConnectionReestablishmentRequest msg)
 {
   Ptr<Packet> packet = Create<Packet> ();
@@ -714,28 +737,37 @@
   params.pdcpSdu->PeekHeader (rrcUlDcchMessage);
 
   // Declare possible headers to receive
+  MeasurementReportHeader measurementReportHeader;
   RrcConnectionReconfigurationCompleteHeader rrcConnectionReconfigurationCompleteHeader;
   RrcConnectionReestablishmentCompleteHeader rrcConnectionReestablishmentCompleteHeader;
   RrcConnectionSetupCompleteHeader rrcConnectionSetupCompleteHeader;
 
+  // Declare possible messages to receive
+  LteRrcSap::MeasurementReport measurementReportMsg;
+  LteRrcSap::RrcConnectionReconfigurationCompleted rrcConnectionReconfigurationCompleteMsg;
+  LteRrcSap::RrcConnectionReestablishmentComplete rrcConnectionReestablishmentCompleteMsg;
+  LteRrcSap::RrcConnectionSetupCompleted rrcConnectionSetupCompletedMsg;
+
   // Deserialize packet and call member recv function with appropiate structure
   switch ( rrcUlDcchMessage.GetMessageType () )
     {
+    case 1:
+      params.pdcpSdu->RemoveHeader (measurementReportHeader);
+      measurementReportMsg = measurementReportHeader.GetMessage ();
+      m_enbRrcSapProvider->RecvMeasurementReport (params.rnti,measurementReportMsg);
+      break;
     case 2:
       params.pdcpSdu->RemoveHeader (rrcConnectionReconfigurationCompleteHeader);
-      LteRrcSap::RrcConnectionReconfigurationCompleted rrcConnectionReconfigurationCompleteMsg;
       rrcConnectionReconfigurationCompleteMsg = rrcConnectionReconfigurationCompleteHeader.GetMessage ();
       m_enbRrcSapProvider->RecvRrcConnectionReconfigurationCompleted (params.rnti,rrcConnectionReconfigurationCompleteMsg);
       break;
     case 3:
       params.pdcpSdu->RemoveHeader (rrcConnectionReestablishmentCompleteHeader);
-      LteRrcSap::RrcConnectionReestablishmentComplete rrcConnectionReestablishmentCompleteMsg;
       rrcConnectionReestablishmentCompleteMsg = rrcConnectionReestablishmentCompleteHeader.GetMessage ();
       m_enbRrcSapProvider->RecvRrcConnectionReestablishmentComplete (params.rnti,rrcConnectionReestablishmentCompleteMsg);
       break;
     case 4:
       params.pdcpSdu->RemoveHeader (rrcConnectionSetupCompleteHeader);
-      LteRrcSap::RrcConnectionSetupCompleted rrcConnectionSetupCompletedMsg;
       rrcConnectionSetupCompletedMsg = rrcConnectionSetupCompleteHeader.GetMessage ();
       m_enbRrcSapProvider->RecvRrcConnectionSetupCompleted (params.rnti, rrcConnectionSetupCompletedMsg);
       break;
--- a/src/lte/model/lte-rrc-protocol-real.h	Thu Dec 20 18:09:04 2012 +0100
+++ b/src/lte/model/lte-rrc-protocol-real.h	Thu Dec 20 18:09:40 2012 +0100
@@ -76,6 +76,7 @@
   void DoSendRrcConnectionReconfigurationCompleted (LteRrcSap::RrcConnectionReconfigurationCompleted msg);
   void DoSendRrcConnectionReestablishmentRequest (LteRrcSap::RrcConnectionReestablishmentRequest msg);
   void DoSendRrcConnectionReestablishmentComplete (LteRrcSap::RrcConnectionReestablishmentComplete msg);
+  void DoSendMeasurementReport (LteRrcSap::MeasurementReport msg);
 
   void SetEnbRrcSapProvider ();
   void DoReceivePdcpPdu (Ptr<Packet> p);
--- a/src/lte/model/lte-rrc-sap.h	Thu Dec 20 18:09:04 2012 +0100
+++ b/src/lte/model/lte-rrc-sap.h	Thu Dec 20 18:09:40 2012 +0100
@@ -383,19 +383,22 @@
     uint16_t sourceDlCarrierFreq;
   };
 
-  struct CellGlobalIdEutra
+  struct CgiInfo
   {
     uint32_t plmnIdentity;
     uint32_t cellIdentity;
+    uint16_t trackingAreaCode;
+    std::list<uint32_t> plmnIdentityList;
   };
 
   struct MeasResultEutra
   {
     uint16_t physCellId;
-    CellGlobalIdEutra cellGlobalId;
-    uint16_t trackingAreaCode;
-    std::list<uint32_t> plmnIdentityList;
+    bool haveCgiInfo;
+    CgiInfo cgiInfo;
+    bool haveRsrpResult;
     uint8_t rsrpResult;
+    bool haveRsrqResult;
     uint8_t rsrqResult;
   };
 
@@ -404,7 +407,8 @@
     uint8_t measId;
     uint8_t rsrpResult;
     uint8_t rsrqResult;
-    std::list<MeasResultEutra> MeasResultListEutra;
+    bool haveMeasResultNeighCells;
+    std::list<MeasResultEutra> measResultListEutra;
 
   };
 
@@ -601,6 +605,7 @@
   virtual void RecvRrcConnectionReconfigurationCompleted (uint16_t rnti, RrcConnectionReconfigurationCompleted msg) = 0;
   virtual void RecvRrcConnectionReestablishmentRequest (uint16_t rnti, RrcConnectionReestablishmentRequest msg) = 0;
   virtual void RecvRrcConnectionReestablishmentComplete (uint16_t rnti, RrcConnectionReestablishmentComplete msg) = 0;
+  virtual void RecvMeasurementReport (uint16_t rnti, MeasurementReport msg) = 0;
 
 };
 
@@ -979,6 +984,7 @@
   virtual void RecvRrcConnectionReconfigurationCompleted (uint16_t rnti, RrcConnectionReconfigurationCompleted msg);
   virtual void RecvRrcConnectionReestablishmentRequest (uint16_t rnti, RrcConnectionReestablishmentRequest msg);
   virtual void RecvRrcConnectionReestablishmentComplete (uint16_t rnti, RrcConnectionReestablishmentComplete msg);
+  virtual void RecvMeasurementReport (uint16_t rnti, MeasurementReport msg);
 
 private:
   MemberLteEnbRrcSapProvider ();
@@ -1038,6 +1044,12 @@
   Simulator::ScheduleNow (&C::DoRecvRrcConnectionReestablishmentComplete, m_owner, rnti, msg);
 }
 
+template <class C>
+void 
+MemberLteEnbRrcSapProvider<C>::RecvMeasurementReport (uint16_t rnti, MeasurementReport msg)
+{
+  Simulator::ScheduleNow (&C::DoRecvMeasurementReport, m_owner, rnti, msg);
+}
 
 
 
--- a/src/lte/model/pf-ff-mac-scheduler.cc	Thu Dec 20 18:09:04 2012 +0100
+++ b/src/lte/model/pf-ff-mac-scheduler.cc	Thu Dec 20 18:09:40 2012 +0100
@@ -1508,9 +1508,9 @@
 
   // Divide the remaining resources equally among the active users starting from the subsequent one served last scheduling trigger
   uint16_t rbPerFlow = (m_cschedCellConfig.m_ulBandwidth) / (nflows + rntiAllocated.size ());
-  if (rbPerFlow == 0)
+  if (rbPerFlow < 3)
     {
-      rbPerFlow = 1;  // at least 1 rbg per flow (till available resource)
+      rbPerFlow = 3;  // at least 3 rbg per flow (till available resource) to ensure TxOpportunity >= 7 bytes
     }
   int rbAllocated = 0;
 
@@ -1552,6 +1552,12 @@
         {
           // limit to physical resources last resource assignment
           rbPerFlow = m_cschedCellConfig.m_ulBandwidth - rbAllocated;
+          // at least 3 rbg per flow to ensure TxOpportunity >= 7 bytes
+          if (rbPerFlow < 3)
+            {
+              // terminate allocation
+              rbPerFlow = 0;      
+            }
         }
 
       UlDciListElement_s uldci;
@@ -1590,11 +1596,18 @@
             {
               // limit to physical resources last resource assignment
               rbPerFlow = m_cschedCellConfig.m_ulBandwidth - rbAllocated;
+              // at least 3 rbg per flow to ensure TxOpportunity >= 7 bytes
+              if (rbPerFlow < 3)
+                {
+                  // terminate allocation
+                  rbPerFlow = 0;                 
+                }
             }
         }
       if (!allocated)
         {
           // unable to allocate new resource: finish scheduling
+          m_nextRntiUl = (*it).first;
           if (ret.m_dciList.size () > 0)
             {
               m_schedSapUser->SchedUlConfigInd (ret);
@@ -1705,7 +1718,7 @@
           // restart from the first
           it = m_ceBsrRxed.begin ();
         }
-      if (rbAllocated == m_cschedCellConfig.m_ulBandwidth)
+      if ((rbAllocated == m_cschedCellConfig.m_ulBandwidth) || (rbPerFlow == 0))
         {
           // Stop allocation: no more PRBs
           m_nextRntiUl = (*it).first;
--- a/src/lte/test/lte-test-pf-ff-mac-scheduler.cc	Thu Dec 20 18:09:04 2012 +0100
+++ b/src/lte/test/lte-test-pf-ff-mac-scheduler.cc	Thu Dec 20 18:09:40 2012 +0100
@@ -71,13 +71,22 @@
   // 1 user -> 25 PRB at Itbs 26 -> 2292 -> 2292000 bytes/sec
   // 3 users -> 8 PRB at Itbs 26 -> 749 -> 749000 bytes/sec
   // 6 users -> 4 PRB at Itbs 26 -> 373 -> 373000 bytes/sec
+  // before the patch enforcing min 3 PRBs per UE:
   // 12 users -> 2 PRB at Itbs 26 -> 185 -> 185000 bytes/sec
   // 15 users -> 1 PRB at Itbs 26 -> 89 -> 89000 bytes/sec
+  // after the patch enforcing min 3 PRBs per UE:
+  // 12 users -> 3 PRB at Itbs 26 -> 277 bytes * 8/12 UE/TTI -> 184670 bytes/sec
+  // 15 users -> 3 PRB at Itbs 26 -> 277 bytes * 8/15 UE/TTI -> 147730 bytes/sec
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (1,0,0,2196000,2292000));
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (3,0,0,732000,749000));
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (6,0,0,366000,373000));
-  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,0,183000,185000));
-  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,0,146400,89000));
+  // before the patch enforcing min 3 PRBs per UE:
+  //AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,0,183000,185000));
+  //AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,0,146400,89000));
+  // after the patch enforcing min 3 PRBs per UE:
+  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,0,183000,184670));
+  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,0,146400,147730));
+  
  
   // DOWNLINK - DISTANCE 3000 -> MCS 24 -> Itbs 30 (from table 7.1.7.2.1-1 of 36.213)
   // 1 user -> 24 PRB at Itbs 20 -> 1383 -> 1383000 bytes/sec
@@ -89,14 +98,22 @@
   // 1 user -> 25 PRB at Itbs 18 -> 1239 -> 1239000 bytes/sec
   // 3 users -> 8 PRB at Itbs 18 -> 389 -> 389000 bytes/sec
   // 6 users -> 4 PRB at Itbs 18 -> 193 -> 193000 bytes/sec
+  // before the patch enforcing min 3 PRBs per UE:
   // 12 users -> 2 PRB at Itbs 18 -> 97 -> 97000 bytes/sec
   // 15 users -> 1 PRB at Itbs 18 -> 47 -> 47000 bytes/sec 
+  // after the patch enforcing min 3 PRBs per UE:
+  // 12 users -> 3 PRB at Itbs 18 -> 145  bytes * 8/12 UE/TTI  -> 96667 bytes/sec
+  // 15 users -> 3 PRB at Itbs 18 -> 145  bytes * 8/15 UE/TTI  -> 77333 bytes/sec
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (1,0,3000,1383000,1239000));
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (3,0,3000,461000,389000));
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (6,0,3000,230500,193000));
-  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,3000,115250,97000));
-  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,3000,92200,47000));
- 
+  // before the patch enforcing min 3 PRBs per UE:
+  //AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,3000,115250,97000));
+  //AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,3000,92200,47000));
+  // after the patch enforcing min 3 PRBs per UE:
+  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,3000,115250,96667));
+  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,3000,92200,77333));
+  
   // DOWNLINK - DISTANCE 6000 -> MCS 16 -> Itbs 15 (from table 7.1.7.2.1-1 of 36.213)
   // 1 user -> 24 PRB at Itbs 15 -> 903 -> 903000 bytes/sec
   // 3 users -> 903000 among 3 users -> 301000 bytes/sec
@@ -107,14 +124,22 @@
   // 1 user -> 25 PRB at Itbs 11 -> 621 -> 621000 bytes/sec
   // 3 users -> 8 PRB at Itbs 11 -> 201 -> 201000 bytes/sec
   // 6 users -> 4 PRB at Itbs 11 -> 97 -> 97000 bytes/sec
+  // before the patch enforcing min 3 PRBs per UE:
   // 12 users -> 2 PRB at Itbs 11 -> 47 -> 47000 bytes/sec
   // 15 users -> 1 PRB at Itbs 11 -> 22 -> 22000 bytes/sec
+  // after the patch enforcing min 3 PRBs per UE:
+  // 12 users -> 3 PRB at Itbs 11 -> 73 bytes * 8/12 UE/TTI -> 48667 bytes/sec
+  // 15 users -> 3 PRB at Itbs 11 -> 73 bytes * 8/15 UE/TTI -> 38993 bytes/sec
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (1,0,6000,903000,621000));
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (3,0,6000,301000,201000));
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (6,0,6000,150500,97000));
-  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,6000,75250,47000));
-  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,6000,60200,22000));
- 
+  // before the patch enforcing min 3 PRBs per UE:
+  //AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,6000,75250,47000));
+  //AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,6000,60200,22000));
+  // after the patch enforcing min 3 PRBs per UE:
+  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,6000,75250,48667));
+  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,6000,60200,38993));
+
   // DOWNLINK - DISTANCE 9000 -> MCS 12 -> Itbs 11 (from table 7.1.7.2.1-1 of 36.213)
   // 1 user -> 24 PRB at Itbs 11 -> 597 -> 597000 bytes/sec
   // 3 users -> 597000 among 3 users -> 199000 bytes/sec
@@ -125,13 +150,21 @@
   // 1 user -> 24 PRB at Itbs 8 -> 437 -> 437000 bytes/sec
   // 3 users -> 8 PRB at Itbs 8 -> 137 -> 137000 bytes/sec
   // 6 users -> 4 PRB at Itbs 8 -> 67 -> 67000 bytes/sec
+  // before the patch enforcing min 3 PRBs per UE:
   // 12 users -> 2 PRB at Itbs 8 -> 32 -> 32000 bytes/sec
   // 15 users -> 1 PRB at Itbs 8 -> 15 -> 15000 bytes/sec 
+  // after the patch enforcing min 3 PRBs per UE:
+  // 12 users -> 3 PRB at Itbs 8 -> 49 bytes * 8/12 UE/TTI -> 32667 bytes/sec
+  // 15 users -> 3 PRB at Itbs 8 -> 49 bytes * 8/15 UE/TTI -> 26133 bytes/sec
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (1,0,9000,597000,437000));
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (3,0,9000,199000,137000));
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (6,0,9000,99500,67000));
-  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,9000,49750,32000));
-  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,9000,39800,15000));
+  // before the patch enforcing min 3 PRBs per UE:
+  //AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,9000,49750,32000));
+  //AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,9000,39800,15000));
+  // after the patch enforcing min 3 PRBs per UE:
+  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,9000,49750,32667));
+  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,9000,39800,26133));
  
   // DONWLINK - DISTANCE 15000 -> MCS 6 -> Itbs 6 (from table 7.1.7.2.1-1 of 36.213)
   // 1 user -> 24 PRB at Itbs 6 -> 309 -> 309000 bytes/sec
@@ -143,13 +176,23 @@
   // 1 user -> 25 PRB at Itbs 6 -> 233 -> 233000 bytes/sec
   // 3 users -> 8 PRB at Itbs 6 -> 69 -> 69000 bytes/sec
   // 6 users -> 4 PRB at Itbs 6 -> 32 -> 32000 bytes/sec
+  // before the patch enforcing min 3 PRBs per UE:
   // 12 users -> 2 PRB at Itbs 6 -> 15 -> 15000 bytes/sec
   // 15 users -> 1 PRB at Itbs 6 -> 7 -> 7000 bytes/sec
+  // after the patch enforcing min 3 PRBs per UE:
+  // NOTE: MCS 4 was actually found to be used
+  // 12 users -> 3 PRB at Itbs 4 -> 26 bytes * 8/12 UE/TTI -> 17333 bytes/sec
+  // 15 users -> 3 PRB at Itbs 4 -> 26 bytes * 8/15 UE/TTI -> 13867 bytes/sec
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (1,0,15000,309000,233000));
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (3,0,15000,103000,69000));
   AddTestCase (new LenaPfFfMacSchedulerTestCase1 (6,0,15000,51500,32000));
-  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,15000,25750,15000));
-  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,15000,20600,7000));
+  // before the patch enforcing min 3 PRBs per UE:
+  //AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,15000,25750,15000));
+  //AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,15000,20600,7000));
+  // after the patch enforcing min 3 PRBs per UE:
+  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (12,0,15000,25750,17333));
+  AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,15000,20600,13867));
+
 
   // Test Case 2: fairness check
 
@@ -212,7 +255,7 @@
   Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));  
   Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
   Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
-  Config::SetDefault ("ns3::LteHelper::UseIdealRrc", BooleanValue (false));
+  Config::SetDefault ("ns3::LteHelper::UseIdealRrc", BooleanValue (true));
 
   /**
    * Initialize Simulation Scenario: 1 eNB and m_nUser UEs