From d762f84977ec84edd17c8589541c2b42b1282bb8 Mon Sep 17 00:00:00 2001 From: Nicola Baldo Date: Fri, 1 Aug 2014 14:30:42 +0200 Subject: [PATCH] refined fix for Bug 1762 --- RELEASE_NOTES | 2 + src/lte/doc/source/lte-testing.rst | 35 ++++-- src/lte/test/test-lte-rrc.cc | 191 +++++++++++++++++++++++------ 3 files changed, 182 insertions(+), 46 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 8371c9a9a..b096f82f1 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -27,6 +27,8 @@ New user-visible features Bugs fixed ---------- + +- Bug 1762 - UE stuck in IDLE_CONNECTING because RRC CONN REQ is not transmitted - Bug 1921 - Icmpv6L4Protocol::ForgeEchoRequest returns a malformed packet - Bug 1930 - Use of invalid reference in OLSR RemoveLinkTuple - Bug 1932 - NdiscCache entry is not failsafe on double neighbor probing. diff --git a/src/lte/doc/source/lte-testing.rst b/src/lte/doc/source/lte-testing.rst index 47cda5cb5..7be900e22 100644 --- a/src/lte/doc/source/lte-testing.rst +++ b/src/lte/doc/source/lte-testing.rst @@ -1038,8 +1038,8 @@ where: to allocate the UL grant because of lack of resources. The number of collisions depends on the number of UEs that try to access simultaneously; we estimated that for a :math:`0.99` RA success - probability, 5 attempts are sufficient for up to 20 UEs, 10 attempts for up - to 50 UEs, 20 attempts for up to 100 UEs, and 40 attempts for up to 200 UEs. + probability, 5 attempts are sufficient for up to 20 UEs, and 10 attempts for up + to 50 UEs. For the UL grant, considered the system bandwidth and the default MCS used for the UL grant (MCS 0), at most 4 UL grants can be assigned in a TTI; so for :math:`n` UEs trying to @@ -1063,8 +1063,11 @@ where: delay of 10ms plus :math:`\lceil 2n/4 \rceil`. delay of 20ms. -The conditions that are evaluated for a test case to pass are, for -each UE: + +The base version of the test ``LteRrcConnectionEstablishmentTestCase`` +tests for correct RRC connection establishment in absence of channel +errors. The conditions that are evaluated for this test case to pass +are, for each UE: - the RRC state at the UE is CONNECTED_NORMALLY - the UE is configured with the CellId, DlBandwidth, UlBandwidth, @@ -1075,12 +1078,24 @@ each UE: - for each Data Radio Bearer, the following identifiers match between the UE and the eNB: EPS bearer id, DRB id, LCID -Ideally, the UE context at the serving eNodeB would have an RRC state of -CONNECTED_NORMALLY at the end of the procedure. But in the rare case of error -while transmitting RRC CONNECTION SETUP COMPLETE message, the eNodeB would have -removed the context because of *connection setup timeout*. A better way to -handle this error is to make the UE fall back to Idle mode and retry the -connection, but this behaviour is not yet implemented at the moment. +The test variant ``LteRrcConnectionEstablishmentErrorTestCase`` is +similar except for the presence of errors in the transmission of a +particular RRC message of choice during the first connection +attempt. The error is obtained by temporarily moving the UE to a far +away location; the time of movement has been determined empyrically +for each instance of the test case based on the message that it was +desidred to be in error. the test case checks that at least one of the following +conditions is false at the time right before the UE is moved back to +the original location: + + - the RRC state at the UE is CONNECTED_NORMALLY + - the UE context at the eNB is present + - the RRC state of the UE Context at the eNB is CONNECTED_NORMALLY + +Additionally, all the conditions of the +``LteRrcConnectionEstablishmentTestCase`` are evaluated - they are +espected to be true because of the NAS behavior of immediately +re-attempting the connection establishment if it fails. Initial cell selection diff --git a/src/lte/test/test-lte-rrc.cc b/src/lte/test/test-lte-rrc.cc index 02e7dfa66..36fc437db 100644 --- a/src/lte/test/test-lte-rrc.cc +++ b/src/lte/test/test-lte-rrc.cc @@ -57,11 +57,10 @@ public: std::string description = ""); protected: + virtual void DoRun (void); - virtual void SetupNodes (NodeContainer &enbNodes, NodeContainer &ueNodes); uint32_t m_nUes; // number of UEs in the test -private: static std::string BuildNameString (uint32_t nUes, uint32_t nBearers, uint32_t tConnBase, @@ -72,6 +71,7 @@ private: std::string description = ""); void Connect (Ptr ueDevice, Ptr enbDevice); void CheckConnected (Ptr ueDevice, Ptr enbDevice); + void CheckNotConnected(Ptr ueDevice, Ptr enbDevice); void ConnectionEstablishedCallback (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti); void ConnectionTimeoutCallback (std::string context, uint64_t imsi, @@ -237,7 +237,15 @@ LteRrcConnectionEstablishmentTestCase::DoRun () NodeContainer enbNodes; NodeContainer ueNodes; - SetupNodes (enbNodes, ueNodes); + + enbNodes.Create (1); + ueNodes.Create (m_nUes); + + // the following positions all nodes at (0, 0, 0) + MobilityHelper mobility; + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.Install (enbNodes); + mobility.Install (ueNodes); int64_t stream = 1; NetDeviceContainer enbDevs; @@ -307,22 +315,6 @@ LteRrcConnectionEstablishmentTestCase::DoRun () } -void -LteRrcConnectionEstablishmentTestCase::SetupNodes (NodeContainer &enbNodes, - NodeContainer &ueNodes) -{ - NS_LOG_FUNCTION (this); - - enbNodes.Create (1); - ueNodes.Create (m_nUes); - - // the following positions all nodes at (0, 0, 0) - MobilityHelper mobility; - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - mobility.Install (enbNodes); - mobility.Install (ueNodes); -} - void LteRrcConnectionEstablishmentTestCase::Connect (Ptr ueDevice, Ptr enbDevice) { @@ -452,6 +444,37 @@ LteRrcConnectionEstablishmentTestCase::CheckConnected (Ptr ueDevice, } } +void +LteRrcConnectionEstablishmentTestCase::CheckNotConnected (Ptr ueDevice, Ptr enbDevice) +{ + Ptr ueLteDevice = ueDevice->GetObject (); + Ptr ueRrc = ueLteDevice->GetRrc (); + const uint64_t imsi = ueLteDevice->GetImsi (); + const uint16_t rnti = ueRrc->GetRnti (); + NS_LOG_FUNCTION (this << imsi << rnti); + NS_ASSERT_MSG (m_isConnectionEstablished.find (imsi) != m_isConnectionEstablished.end (), + "Invalid IMSI " << imsi); + + bool ueStateIsConnectedNormally = (LteUeRrc::CONNECTED_NORMALLY == ueRrc->GetState ()); + + Ptr enbLteDevice = enbDevice->GetObject (); + Ptr enbRrc = enbLteDevice->GetRrc (); + const bool hasContext = enbRrc->HasUeManager (rnti); + bool contextStateIsConnectedNormally = false; + if (hasContext) + { + Ptr ueManager = enbRrc->GetUeManager (rnti); + NS_ASSERT (ueManager != 0); + contextStateIsConnectedNormally = (UeManager::CONNECTED_NORMALLY == ueManager->GetState ()); + } + NS_TEST_ASSERT_MSG_EQ ((!m_isConnectionEstablished[imsi] + || !ueStateIsConnectedNormally + || !hasContext + || !contextStateIsConnectedNormally), + true, + "it should not happen that connection is completed both at the UE and at the eNB side"); +} + void LteRrcConnectionEstablishmentTestCase::ConnectionEstablishedCallback ( std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti) @@ -470,7 +493,7 @@ LteRrcConnectionEstablishmentTestCase::ConnectionTimeoutCallback ( -class LteRrcConnectionEstablishmentInterferenceTestCase +class LteRrcConnectionEstablishmentErrorTestCase : public LteRrcConnectionEstablishmentTestCase { public: @@ -481,10 +504,10 @@ public: * high-interference position and stay there for 100 ms * \param description additional description of the test case */ - LteRrcConnectionEstablishmentInterferenceTestCase (Time jumpAwayTime, + LteRrcConnectionEstablishmentErrorTestCase (Time jumpAwayTime, std::string description = ""); protected: - virtual void SetupNodes (NodeContainer &enbNodes, NodeContainer &ueNodes); + virtual void DoRun (void); private: void JumpAway (); @@ -495,7 +518,7 @@ private: }; -LteRrcConnectionEstablishmentInterferenceTestCase::LteRrcConnectionEstablishmentInterferenceTestCase ( +LteRrcConnectionEstablishmentErrorTestCase::LteRrcConnectionEstablishmentErrorTestCase ( Time jumpAwayTime, std::string description) : LteRrcConnectionEstablishmentTestCase (1, 1, 0, 0, 1, true, false, true, description), @@ -506,10 +529,35 @@ LteRrcConnectionEstablishmentInterferenceTestCase::LteRrcConnectionEstablishment void -LteRrcConnectionEstablishmentInterferenceTestCase::SetupNodes (NodeContainer &enbNodes, - NodeContainer &ueNodes) +LteRrcConnectionEstablishmentErrorTestCase::DoRun () { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION (this << GetName ()); + Config::Reset (); + + if (m_nUes < 25) + { + Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (40)); + } + else if (m_nUes < 60) + { + Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (80)); + } + else if (m_nUes < 120) + { + Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (160)); + } + else + { + Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (320)); + } + + // normal code + m_lteHelper = CreateObject (); + m_lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (m_useIdealRrc)); + + NodeContainer enbNodes; + NodeContainer ueNodes; + enbNodes.Create (4); ueNodes.Create (1); @@ -527,33 +575,104 @@ LteRrcConnectionEstablishmentInterferenceTestCase::SetupNodes (NodeContainer &en mobility.SetPositionAllocator (enbPosition); mobility.Install (enbNodes); + int64_t stream = 1; + NetDeviceContainer enbDevs; + enbDevs = m_lteHelper->InstallEnbDevice (enbNodes); + stream += m_lteHelper->AssignStreams (enbDevs, stream); + + NetDeviceContainer ueDevs; + ueDevs = m_lteHelper->InstallUeDevice (ueNodes); + stream += m_lteHelper->AssignStreams (ueDevs, stream); + + // custom code used for testing purposes + // instead of lteHelper->Attach () and lteHelper->ActivateXxx + + // Set AdmitConnectionRequest attribute + for (NetDeviceContainer::Iterator it = enbDevs.Begin (); + it != enbDevs.End (); + ++it) + { + Ptr enbRrc = (*it)->GetObject ()->GetRrc (); + enbRrc->SetAttribute ("AdmitRrcConnectionRequest", + BooleanValue (m_admitRrcConnectionRequest)); + } + + + uint32_t i = 0; + uint32_t tmax = 0; + for (NetDeviceContainer::Iterator it = ueDevs.Begin (); it != ueDevs.End (); ++it) + { + Ptr ueDevice = *it; + Ptr enbDevice = enbDevs.Get (0); + Ptr ueLteDevice = ueDevice->GetObject (); + + uint32_t tc = m_tConnBase + m_tConnIncrPerUe * i; // time connection start + uint32_t tcc = tc + m_delayConnEnd; // time check connection completed; + uint32_t td = tcc + m_delayDiscStart; // time disconnect start + uint32_t tcd = td + m_delayDiscEnd; // time check disconnection completed + tmax = std::max (tmax, tcd); + + // trick to resolve overloading + //void (LteHelper::* overloadedAttachFunctionPointer) (Ptr, Ptr) = &LteHelper::Attach; + //Simulator::Schedule (MilliSeconds (tc), overloadedAttachFunctionPointer, lteHelper, *it, enbDevice); + Simulator::Schedule (MilliSeconds (tc), &LteRrcConnectionEstablishmentErrorTestCase::Connect, this, ueDevice, enbDevice); + + Simulator::Schedule (MilliSeconds (tcc), &LteRrcConnectionEstablishmentErrorTestCase::CheckConnected, this, *it, enbDevice); + + // disconnection not supported yet + + uint64_t imsi = ueLteDevice->GetImsi (); + m_isConnectionEstablished[imsi] = false; + + ++i; + } + + // Connect to trace sources in UEs + Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/ConnectionEstablished", + MakeCallback (&LteRrcConnectionEstablishmentErrorTestCase::ConnectionEstablishedCallback, + this)); + Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/ConnectionTimeout", + MakeCallback (&LteRrcConnectionEstablishmentErrorTestCase::ConnectionTimeoutCallback, + this)); + + Simulator::Schedule (m_jumpAwayTime, - &LteRrcConnectionEstablishmentInterferenceTestCase::JumpAway, + &LteRrcConnectionEstablishmentErrorTestCase::JumpAway, this); + Simulator::Schedule (m_jumpAwayTime + MilliSeconds (99), + &LteRrcConnectionEstablishmentErrorTestCase::CheckNotConnected, + this, ueDevs.Get (0), enbDevs.Get (0)); Simulator::Schedule (m_jumpAwayTime + MilliSeconds (100), - &LteRrcConnectionEstablishmentInterferenceTestCase::JumpBack, + &LteRrcConnectionEstablishmentErrorTestCase::JumpBack, this); + + Simulator::Stop (MilliSeconds (tmax + 1)); + + Simulator::Run (); + + Simulator::Destroy (); + } void -LteRrcConnectionEstablishmentInterferenceTestCase::JumpAway () +LteRrcConnectionEstablishmentErrorTestCase::JumpAway () { NS_LOG_FUNCTION (this); - // Position with high interference from other eNodeBs. - m_ueMobility->SetPosition (Vector (100.0, 100.0, 0.0)); + // move to a really far away location so that transmission errors occur + m_ueMobility->SetPosition (Vector (10000.0, 0.0, 0.0)); } void -LteRrcConnectionEstablishmentInterferenceTestCase::JumpBack () +LteRrcConnectionEstablishmentErrorTestCase::JumpBack () { NS_LOG_FUNCTION (this); - // Position with low interference. m_ueMobility->SetPosition (Vector (0.0, 0.0, 0.0)); } + class LteRrcTestSuite : public TestSuite { public: @@ -609,15 +728,15 @@ LteRrcTestSuite::LteRrcTestSuite () } // Test cases with transmission error - AddTestCase (new LteRrcConnectionEstablishmentInterferenceTestCase ( + AddTestCase (new LteRrcConnectionEstablishmentErrorTestCase ( Seconds (0.020214), "failure at RRC Connection Request"), TestCase::QUICK); - AddTestCase (new LteRrcConnectionEstablishmentInterferenceTestCase ( + AddTestCase (new LteRrcConnectionEstablishmentErrorTestCase ( Seconds (0.025), "failure at RRC Connection Setup"), TestCase::QUICK); - AddTestCase (new LteRrcConnectionEstablishmentInterferenceTestCase ( + AddTestCase (new LteRrcConnectionEstablishmentErrorTestCase ( Seconds (0.030), "failure at RRC Connection Setup Complete"), TestCase::QUICK);