--- a/AUTHORS Sun Jun 15 08:54:48 2014 -0700
+++ b/AUTHORS Thu Nov 27 16:01:05 2014 +0100
@@ -156,3 +156,4 @@
He Wu (mdzz@u.washington.edu)
Yoshihiko Yazawa (yoshiyaz@gmail.com)
Dizhi Zhou (dizhi.zhou@gmail.com)
+Gaurav Sathe (gaurav.sathe@tcs.com)
--- a/RELEASE_NOTES Sun Jun 15 08:54:48 2014 -0700
+++ b/RELEASE_NOTES Thu Nov 27 16:01:05 2014 +0100
@@ -48,6 +48,11 @@
- Fixes to support Python >= 3.3 in ns3 Python bindings
- Enable selection of high precision int64x64_t implementation
at configure time, for debugging purposes.
+- In LENA NS3.20, bearer release functionality is partially present.
+ As an enhancement, complete release bearer functionality is provided on access and core side(3GPP compliant).
+ A new procedure 'DeActivateDedicatedEpsBearer' is defined in LTEHelper for the same.
+ Related output can be seen through the stats collected at different layers like PDCP, RLC, MAC, PHY.
+ To support the implementation, example and test suite is added under examples and tests folder.
Bugs fixed
----------
--- a/src/lte/bindings/modulegen__gcc_ILP32.py Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/bindings/modulegen__gcc_ILP32.py Thu Nov 27 16:01:05 2014 +0100
@@ -2878,6 +2878,11 @@
'void',
[param('uint16_t', 'rnti')],
is_pure_virtual=True, is_virtual=True)
+ ## epc-enb-s1-sap.h (module 'lte'): void ns3::EpcEnbS1SapProvider::DoSendReleaseIndication(uint64_t imsi, uint16_t rnti, uint8_t bearerId) [member function]
+ cls.add_method('DoSendReleaseIndication',
+ 'void',
+ [param('uint64_t', 'imsi'), param('uint16_t', 'rnti'), param('uint8_t', 'bearerId')],
+ is_pure_virtual=True, is_virtual=True)
return
def register_Ns3EpcEnbS1SapProviderBearerToBeSwitched_methods(root_module, cls):
@@ -3000,6 +3005,11 @@
'void',
[param('ns3::EpcS11SapMme::ModifyBearerResponseMessage', 'msg')],
is_pure_virtual=True, is_virtual=True)
+ ## epc-s11-sap.h (module 'lte'): void ns3::EpcS11SapMme::DeleteBearerRequest(ns3::EpcS11SapMme::DeleteBearerRequestMessage msg) [member function]
+ cls.add_method('DeleteBearerRequest',
+ 'void',
+ [param('ns3::EpcS11SapMme::DeleteBearerRequestMessage', 'msg')],
+ is_pure_virtual=True, is_virtual=True)
return
def register_Ns3EpcS11SapMmeBearerContextCreated_methods(root_module, cls):
@@ -3050,6 +3060,16 @@
'void',
[param('ns3::EpcS11SapSgw::ModifyBearerRequestMessage', 'msg')],
is_pure_virtual=True, is_virtual=True)
+ ## epc-s11-sap.h (module 'lte'): void ns3::EpcS11SapSgw::DeleteBearerCommand(ns3::EpcS11SapSgw::DeleteBearerCommandMessage msg) [member function]
+ cls.add_method('DeleteBearerCommand',
+ 'void',
+ [param('ns3::EpcS11SapSgw::DeleteBearerCommandMessage', 'msg')],
+ is_pure_virtual=True, is_virtual=True)
+ ## epc-s11-sap.h (module 'lte'): void ns3::EpcS11SapSgw::DeleteBearerResponse(ns3::EpcS11SapSgw::DeleteBearerResponseMessage msg) [member function]
+ cls.add_method('DeleteBearerResponse',
+ 'void',
+ [param('ns3::EpcS11SapSgw::DeleteBearerResponseMessage', 'msg')],
+ is_pure_virtual=True, is_virtual=True)
return
def register_Ns3EpcS11SapSgwBearerContextToBeCreated_methods(root_module, cls):
@@ -3161,6 +3181,11 @@
'void',
[param('uint64_t', 'enbUeS1Id'), param('uint64_t', 'mmeUeS1Id'), param('uint16_t', 'gci'), param('std::list< ns3::EpcS1apSapMme::ErabSwitchedInDownlinkItem >', 'erabToBeSwitchedInDownlinkList')],
is_pure_virtual=True, is_virtual=True)
+ ## epc-s1ap-sap.h (module 'lte'): void ns3::EpcS1apSapMme::ErabReleaseIndication(uint64_t enbUeS1Id, uint64_t mmeUeS1Id, std::list<ErabToBeReleasedIndication> erabToBeReleaseIndication) [member function]
+ cls.add_method('ErabReleaseIndication',
+ 'void',
+ [param('uint64_t', 'mmeUeS1Id'), param('uint16_t', 'enbUeS1Id'), param('std::list<ns3::EpcS1apSapMme::ErabToBeReleasedIndication>', 'erabToBeReleaseIndication')],
+ is_pure_virtual=True, is_virtual=True)
return
def register_Ns3EpcS1apSapMmeErabSetupItem_methods(root_module, cls):
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/examples/lena-deactivate-bearer.cc Thu Nov 27 16:01:05 2014 +0100
@@ -0,0 +1,234 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Gaurav Sathe <gaurav.sathe@tcs.com>
+ */
+
+#include "ns3/lte-helper.h"
+#include "ns3/epc-helper.h"
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/internet-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/lte-module.h"
+#include "ns3/applications-module.h"
+#include "ns3/point-to-point-helper.h"
+#include "ns3/config-store.h"
+//#include "ns3/gtk-config-store.h"
+
+using namespace ns3;
+
+/**
+ * Sample simulation script for LTE+EPC. It instantiates one eNodeB,
+ * attaches three UE to eNodeB starts a flow for each UE to and from a remote host.
+ * It also instantiates one dedicated bearer per UE
+ */
+NS_LOG_COMPONENT_DEFINE ("BearerDeactivateExample");
+int
+main (int argc, char *argv[])
+{
+
+ uint16_t numberOfNodes = 1;
+ uint16_t numberOfUeNodes = 3;
+ double simTime = 1.1;
+ double distance = 60.0;
+ double interPacketInterval = 100;
+
+ // Command line arguments
+ CommandLine cmd;
+ cmd.AddValue ("numberOfNodes", "Number of eNodeBs + UE pairs", numberOfNodes);
+ cmd.AddValue ("simTime", "Total duration of the simulation [s])", simTime);
+ cmd.AddValue ("distance", "Distance between eNBs [m]", distance);
+ cmd.AddValue ("interPacketInterval", "Inter packet interval [ms])", interPacketInterval);
+ cmd.Parse (argc, argv);
+
+ Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
+ Ptr<PointToPointEpcHelper> epcHelper = CreateObject<PointToPointEpcHelper> ();
+ lteHelper->SetEpcHelper (epcHelper);
+
+ ConfigStore inputConfig;
+ inputConfig.ConfigureDefaults ();
+
+ // parse again so you can override default values from the command line
+ cmd.Parse (argc, argv);
+
+ Ptr<Node> pgw = epcHelper->GetPgwNode ();
+
+ // Enable Logging
+ LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL);
+
+ LogComponentEnable ("BearerDeactivateExample", LOG_LEVEL_ALL);
+ LogComponentEnable ("LteHelper", logLevel);
+ LogComponentEnable ("EpcHelper", logLevel);
+ LogComponentEnable ("EpcEnbApplication", logLevel);
+ LogComponentEnable ("EpcSgwPgwApplication", logLevel);
+ LogComponentEnable ("EpcMme", logLevel);
+ LogComponentEnable ("LteEnbRrc", logLevel);
+
+
+ // Create a single RemoteHost
+ NodeContainer remoteHostContainer;
+ remoteHostContainer.Create (1);
+ Ptr<Node> remoteHost = remoteHostContainer.Get (0);
+ InternetStackHelper internet;
+ internet.Install (remoteHostContainer);
+
+ // Create the Internet
+ PointToPointHelper p2ph;
+ p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
+ p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
+ p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.010)));
+ NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
+ Ipv4AddressHelper ipv4h;
+ ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
+ Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
+ // interface 0 is localhost, 1 is the p2p device
+ Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1);
+
+ Ipv4StaticRoutingHelper ipv4RoutingHelper;
+ Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
+ remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
+
+ NodeContainer ueNodes;
+ NodeContainer enbNodes;
+ enbNodes.Create (numberOfNodes);
+ ueNodes.Create (numberOfUeNodes);
+
+ // Install Mobility Model
+ Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+ for (uint16_t i = 0; i < numberOfNodes; i++)
+ {
+ positionAlloc->Add (Vector (distance * i, 0, 0));
+ }
+ MobilityHelper mobility;
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+ mobility.SetPositionAllocator (positionAlloc);
+ mobility.Install (enbNodes);
+ mobility.Install (ueNodes);
+
+ // Install LTE Devices to the nodes
+ NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice (enbNodes);
+ NetDeviceContainer ueLteDevs = lteHelper->InstallUeDevice (ueNodes);
+
+ // Install the IP stack on the UEs
+ internet.Install (ueNodes);
+ Ipv4InterfaceContainer ueIpIface;
+ ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueLteDevs));
+ // Assign IP address to UEs, and install applications
+ for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
+ {
+ Ptr<Node> ueNode = ueNodes.Get (u);
+ // Set the default gateway for the UE
+ Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
+ ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
+ }
+
+ // Attach a UE to a eNB
+ lteHelper->Attach (ueLteDevs, enbLteDevs.Get (0));
+
+ // Activate an EPS bearer on all UEs
+
+ for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
+ {
+ Ptr<NetDevice> ueDevice = ueLteDevs.Get (u);
+ GbrQosInformation qos;
+ qos.gbrDl = 132; // bit/s, considering IP, UDP, RLC, PDCP header size
+ qos.gbrUl = 132;
+ qos.mbrDl = qos.gbrDl;
+ qos.mbrUl = qos.gbrUl;
+
+ enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
+ EpsBearer bearer (q, qos);
+ bearer.arp.priorityLevel = 15 - (u + 1);
+ bearer.arp.preemptionCapability = true;
+ bearer.arp.preemptionVulnerability = true;
+ lteHelper->ActivateDedicatedEpsBearer (ueDevice, bearer, EpcTft::Default ());
+ }
+
+
+ // Install and start applications on UEs and remote host
+ uint16_t dlPort = 1234;
+ uint16_t ulPort = 2000;
+ uint16_t otherPort = 3000;
+ ApplicationContainer clientApps;
+ ApplicationContainer serverApps;
+ for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
+ {
+ ++ulPort;
+ ++otherPort;
+ PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), dlPort));
+ PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), ulPort));
+ PacketSinkHelper packetSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), otherPort));
+ serverApps.Add (dlPacketSinkHelper.Install (ueNodes.Get (u)));
+ serverApps.Add (ulPacketSinkHelper.Install (remoteHost));
+ serverApps.Add (packetSinkHelper.Install (ueNodes.Get (u)));
+
+ UdpClientHelper dlClient (ueIpIface.GetAddress (u), dlPort);
+ dlClient.SetAttribute ("Interval", TimeValue (MilliSeconds (interPacketInterval)));
+ dlClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
+
+ UdpClientHelper ulClient (remoteHostAddr, ulPort);
+ ulClient.SetAttribute ("Interval", TimeValue (MilliSeconds (interPacketInterval)));
+ ulClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
+
+ UdpClientHelper client (ueIpIface.GetAddress (u), otherPort);
+ client.SetAttribute ("Interval", TimeValue (MilliSeconds (interPacketInterval)));
+ client.SetAttribute ("MaxPackets", UintegerValue (1000000));
+
+ clientApps.Add (dlClient.Install (remoteHost));
+ clientApps.Add (ulClient.Install (ueNodes.Get (u)));
+ if (u + 1 < ueNodes.GetN ())
+ {
+ clientApps.Add (client.Install (ueNodes.Get (u + 1)));
+ }
+ else
+ {
+ clientApps.Add (client.Install (ueNodes.Get (0)));
+ }
+ }
+
+ serverApps.Start (Seconds (0.030));
+ clientApps.Start (Seconds (0.030));
+
+ double statsStartTime = 0.04; // need to allow for RRC connection establishment + SRS
+ double statsDuration = 1.0;
+
+ lteHelper->EnableRlcTraces ();
+ Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
+ rlcStats->SetAttribute ("StartTime", TimeValue (Seconds (statsStartTime)));
+ rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (statsDuration)));
+
+ /*
+ * Schedule dedicated bearer de-activation at 'deActivateTime'
+ * Instantiate De-activation in sequence (Time deActivateTime, Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice, uint8_t bearerId)
+ */
+ Time deActivateTime (Seconds (1.5));
+ lteHelper->DeActivateDedicatedEpsBearer (deActivateTime,ueLteDevs.Get (0),enbLteDevs.Get (0), 2);
+
+ //stop simulation after 3 seconds
+ Simulator::Stop (Seconds (3.0));
+
+ Simulator::Run ();
+ /*GtkConfigStore config;
+ config.ConfigureAttributes();*/
+
+ Simulator::Destroy ();
+ return 0;
+
+}
+
--- a/src/lte/examples/wscript Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/examples/wscript Thu Nov 27 16:01:05 2014 +0100
@@ -34,6 +34,9 @@
obj = bld.create_ns3_program('lena-simple-epc',
['lte'])
obj.source = 'lena-simple-epc.cc'
+ obj = bld.create_ns3_program('lena-deactivate-bearer',
+ ['lte'])
+ obj.source = 'lena-deactivate-bearer.cc'
obj = bld.create_ns3_program('lena-x2-handover',
['lte'])
obj.source = 'lena-x2-handover.cc'
--- a/src/lte/helper/lte-helper.cc Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/helper/lte-helper.cc Thu Nov 27 16:01:05 2014 +0100
@@ -813,8 +813,8 @@
Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetObject<LteEnbNetDevice> ()->GetRrc ();
NS_ASSERT (ueRrc->GetCellId () == enbLteDevice->GetCellId ());
Ptr<UeManager> ueManager = enbRrc->GetUeManager (rnti);
- NS_ASSERT (ueManager->GetState () == UeManager::CONNECTED_NORMALLY ||
- ueManager->GetState () == UeManager::CONNECTION_RECONFIGURATION);
+ NS_ASSERT (ueManager->GetState () == UeManager::CONNECTED_NORMALLY
+ || ueManager->GetState () == UeManager::CONNECTION_RECONFIGURATION);
EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params;
params.rnti = rnti;
params.bearer = m_bearer;
@@ -892,8 +892,30 @@
sourceRrc->SendHandoverRequest (rnti, targetCellId);
}
+void
+LteHelper::DeActivateDedicatedEpsBearer (Time deActivateTime, Ptr<NetDevice> ueDevice,Ptr<NetDevice> enbDevice, uint8_t bearerId)
+{
+ NS_LOG_FUNCTION (this << ueDevice << bearerId);
+ NS_ASSERT_MSG (m_epcHelper != 0, "Dedicated EPS bearers cannot be de-activated when the EPC is not used");
+ NS_ASSERT_MSG (bearerId != 1, "Default bearer cannot be de-activated until and unless and UE is released");
+
+ Simulator::Schedule (deActivateTime, &LteHelper::DoDeActivateDedicatedEpsBearer, this, ueDevice, enbDevice, bearerId);
+}
+
+void
+LteHelper::DoDeActivateDedicatedEpsBearer (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice, uint8_t bearerId)
+{
+ NS_LOG_FUNCTION (this << ueDevice << bearerId);
+
+ //Extract IMSI and rnti
+ uint64_t imsi = ueDevice->GetObject<LteUeNetDevice> ()->GetImsi ();
+ uint16_t rnti = ueDevice->GetObject<LteUeNetDevice> ()->GetRrc ()->GetRnti ();
+ Ptr<LteEnbRrc> enbRrc = enbDevice->GetObject<LteEnbNetDevice> ()->GetRrc ();
+
+ enbRrc->DoSendReleaseDataRadioBearer (imsi,rnti,bearerId);
+}
void
--- a/src/lte/helper/lte-helper.h Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/helper/lte-helper.h Thu Nov 27 16:01:05 2014 +0100
@@ -325,6 +325,17 @@
*/
void ActivateDedicatedEpsBearer (Ptr<NetDevice> ueDevice, EpsBearer bearer, Ptr<EpcTft> tft);
+ /**
+ * \brief Manually trigger dedicated bearer de-activation at specific simulation time
+ * \param deActivateTime when the dedicated bearer de-activation to be initiated
+ * \param ueDevice the UE on which dedicated bearer to be de-activated must be of the type LteUeNetDevice
+ * \param enbDevice eNB, must be of the type LteEnbNetDevice
+ * \param bearerId Bearer Identity which is to be de-activated
+ *
+ * \warning Requires the use of EPC mode. See SetEpcHelper() method.
+ */
+
+ void DeActivateDedicatedEpsBearer (Time deActivateTime, Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice, uint8_t bearerId);
/**
* Create an X2 interface between all the eNBs in a given set
@@ -479,10 +490,13 @@
*/
Ptr<RadioBearerStatsCalculator> GetPdcpStats (void);
- enum LteEpsBearerToRlcMapping_t {RLC_SM_ALWAYS = 1,
+ enum LteEpsBearerToRlcMapping_t
+ {
+ RLC_SM_ALWAYS = 1,
RLC_UM_ALWAYS = 2,
RLC_AM_ALWAYS = 3,
- PER_BASED = 4};
+ PER_BASED = 4
+ };
/**
* Assign a fixed random variable stream number to the random variables
@@ -531,6 +545,19 @@
Ptr<NetDevice> sourceEnbDev,
Ptr<NetDevice> targetEnbDev);
+
+ /**
+ * \brief The actual function to trigger a manual bearer de-activation
+ * \param ueDevice the UE on which bearer to be de-activated must be of the type LteUeNetDevice
+ * \param enbDevice eNB, must be of the type LteEnbNetDevice
+ * \param bearerId Bearer Identity which is to be de-activated
+ *
+ * This method is normally scheduled by DeActivateDedicatedEpsBearer() to run at a specific
+ * time when a manual bearer de-activation is desired by the simulation user.
+ */
+ void DoDeActivateDedicatedEpsBearer (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice, uint8_t bearerId);
+
+
Ptr<SpectrumChannel> m_downlinkChannel;
Ptr<SpectrumChannel> m_uplinkChannel;
--- a/src/lte/helper/radio-bearer-stats-calculator.cc Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/helper/radio-bearer-stats-calculator.cc Thu Nov 27 16:01:05 2014 +0100
@@ -26,8 +26,7 @@
#include <vector>
#include <algorithm>
-namespace ns3
-{
+namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("RadioBearerStatsCalculator");
--- a/src/lte/model/epc-enb-application.cc Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/model/epc-enb-application.cc Thu Nov 27 16:01:05 2014 +0100
@@ -310,8 +310,18 @@
gtpu.SetLength (packet->GetSize () + gtpu.GetSerializedSize () - 8);
packet->AddHeader (gtpu);
uint32_t flags = 0;
- m_s1uSocket->SendTo (packet, flags, InetSocketAddress(m_sgwS1uAddress, m_gtpuUdpPort));
+ m_s1uSocket->SendTo (packet, flags, InetSocketAddress (m_sgwS1uAddress, m_gtpuUdpPort));
}
-
-}; // namespace ns3
+void
+EpcEnbApplication::DoReleaseIndication (uint64_t imsi, uint16_t rnti, uint8_t bearerId)
+{
+ NS_LOG_FUNCTION (this << bearerId );
+ std::list<EpcS1apSapMme::ErabToBeReleasedIndication> erabToBeReleaseIndication;
+ EpcS1apSapMme::ErabToBeReleasedIndication erab;
+ erab.erabId = bearerId;
+ erabToBeReleaseIndication.push_back (erab);
+ //From 3GPP TS 23401-950 Section 5.4.4.2, enB sends EPS bearer Identity in Bearer Release Indication message to MME
+ m_s1apSapMme->ErabReleaseIndication (imsi, rnti, erabToBeReleaseIndication);
+}
+} // namespace ns3
--- a/src/lte/model/epc-enb-application.h Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/model/epc-enb-application.h Thu Nov 27 16:01:05 2014 +0100
@@ -150,6 +150,15 @@
void DoPathSwitchRequestAcknowledge (uint64_t enbUeS1Id, uint64_t mmeUeS1Id, uint16_t cgi, std::list<EpcS1apSapEnb::ErabSwitchedInUplinkItem> erabToBeSwitchedInUplinkList);
/**
+ * \brief This function accepts bearer id corresponding to a particular UE and schedules indication of bearer release towards MME
+ * \param imsi maps to mmeUeS1Id
+ * \param rnti maps to enbUeS1Id
+ * \param bearerId Bearer Identity which is to be de-activated
+ */
+ void DoReleaseIndication (uint64_t imsi, uint16_t rnti, uint8_t bearerId);
+
+
+ /**
* Send a packet to the UE via the LTE radio interface of the eNB
*
* \param packet t
--- a/src/lte/model/epc-enb-s1-sap.h Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/model/epc-enb-s1-sap.h Thu Nov 27 16:01:05 2014 +0100
@@ -49,6 +49,13 @@
*/
virtual void InitialUeMessage (uint64_t imsi, uint16_t rnti) = 0;
+ /**
+ * \brief Triggers epc-enb-application to send ERAB Release Indication message towards MME
+ * \param imsi the UE IMSI
+ * \param rnti the UE RNTI
+ * \param bearerId Bearer Identity which is to be de-activated
+ */
+ virtual void DoSendReleaseIndication (uint64_t imsi, uint16_t rnti, uint8_t bearerId) = 0;
struct BearerToBeSwitched
{
@@ -139,6 +146,8 @@
// inherited from EpcEnbS1SapProvider
virtual void InitialUeMessage (uint64_t imsi, uint16_t rnti);
+ virtual void DoSendReleaseIndication (uint64_t imsi, uint16_t rnti, uint8_t bearerId);
+
virtual void PathSwitchRequest (PathSwitchRequestParameters params);
virtual void UeContextRelease (uint16_t rnti);
@@ -165,6 +174,11 @@
m_owner->DoInitialUeMessage (imsi, rnti);
}
+template <class C>
+void MemberEpcEnbS1SapProvider<C>::DoSendReleaseIndication (uint64_t imsi, uint16_t rnti, uint8_t bearerId)
+{
+ m_owner->DoReleaseIndication (imsi, rnti, bearerId);
+}
template <class C>
void MemberEpcEnbS1SapProvider<C>::PathSwitchRequest (PathSwitchRequestParameters params)
--- a/src/lte/model/epc-mme.cc Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/model/epc-mme.cc Thu Nov 27 16:01:05 2014 +0100
@@ -221,4 +221,66 @@
jt->second->s1apSapEnb->PathSwitchRequestAcknowledge (enbUeS1Id, mmeUeS1Id, cgi, erabToBeSwitchedInUplinkList);
}
+void
+EpcMme::DoErabReleaseIndication (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, std::list<EpcS1apSapMme::ErabToBeReleasedIndication> erabToBeReleaseIndication)
+{
+ NS_LOG_FUNCTION (this << mmeUeS1Id << enbUeS1Id);
+ uint64_t imsi = mmeUeS1Id;
+ std::map<uint64_t, Ptr<UeInfo> >::iterator it = m_ueInfoMap.find (imsi);
+ NS_ASSERT_MSG (it != m_ueInfoMap.end (), "could not find any UE with IMSI " << imsi);
+
+ EpcS11SapSgw::DeleteBearerCommandMessage msg;
+ // trick to avoid the need for allocating TEIDs on the S11 interface
+ msg.teid = imsi;
+
+ for (std::list<EpcS1apSapMme::ErabToBeReleasedIndication>::iterator bit = erabToBeReleaseIndication.begin (); bit != erabToBeReleaseIndication.end (); ++bit)
+ {
+ EpcS11SapSgw::BearerContextToBeRemoved bearerContext;
+ bearerContext.epsBearerId = bit->erabId;
+ msg.bearerContextsToBeRemoved.push_back (bearerContext);
+ }
+ //Delete Bearer command towards epc-sgw-pgw-application
+ m_s11SapSgw->DeleteBearerCommand (msg);
+}
+
+void
+EpcMme::DoDeleteBearerRequest (EpcS11SapMme::DeleteBearerRequestMessage msg)
+{
+ NS_LOG_FUNCTION (this);
+ uint64_t imsi = msg.teid;
+ std::map<uint64_t, Ptr<UeInfo> >::iterator it = m_ueInfoMap.find (imsi);
+ NS_ASSERT_MSG (it != m_ueInfoMap.end (), "could not find any UE with IMSI " << imsi);
+ EpcS11SapSgw::DeleteBearerResponseMessage res;
+
+ res.teid = imsi;
+
+ for (std::list<EpcS11SapMme::BearerContextRemoved>::iterator bit = msg.bearerContextsRemoved.begin ();
+ bit != msg.bearerContextsRemoved.end ();
+ ++bit)
+ {
+ EpcS11SapSgw::BearerContextRemovedSgwPgw bearerContext;
+ bearerContext.epsBearerId = bit->epsBearerId;
+ res.bearerContextsRemoved.push_back (bearerContext);
+
+ RemoveBearer (it->second, bearerContext.epsBearerId); //schedules function to erase, context of de-activated bearer
+ }
+ //schedules Delete Bearer Response towards epc-sgw-pgw-application
+ m_s11SapSgw->DeleteBearerResponse (res);
+}
+
+void EpcMme::RemoveBearer (Ptr<UeInfo> ueInfo, uint8_t epsBearerId)
+{
+ NS_LOG_FUNCTION (this << epsBearerId);
+ for (std::list<BearerInfo>::iterator bit = ueInfo->bearersToBeActivated.begin ();
+ bit != ueInfo->bearersToBeActivated.end ();
+ ++bit)
+ {
+ if (bit->bearerId == epsBearerId)
+ {
+ ueInfo->bearersToBeActivated.erase (bit);
+ break;
+ }
+ }
+}
+
} // namespace ns3
--- a/src/lte/model/epc-mme.h Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/model/epc-mme.h Thu Nov 27 16:01:05 2014 +0100
@@ -115,11 +115,13 @@
void DoInitialUeMessage (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, uint64_t imsi, uint16_t ecgi);
void DoInitialContextSetupResponse (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, std::list<EpcS1apSapMme::ErabSetupItem> erabSetupList);
void DoPathSwitchRequest (uint64_t enbUeS1Id, uint64_t mmeUeS1Id, uint16_t cgi, std::list<EpcS1apSapMme::ErabSwitchedInDownlinkItem> erabToBeSwitchedInDownlinkList);
-
+ void DoErabReleaseIndication (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, std::list<EpcS1apSapMme::ErabToBeReleasedIndication> erabToBeReleaseIndication);
// S11 SAP MME forwarded methods
void DoCreateSessionResponse (EpcS11SapMme::CreateSessionResponseMessage msg);
void DoModifyBearerResponse (EpcS11SapMme::ModifyBearerResponseMessage msg);
+ void DoDeleteBearerRequest (EpcS11SapMme::DeleteBearerRequestMessage msg);
+
/**
* Hold info on an EPS bearer to be activated
@@ -153,6 +155,13 @@
std::map<uint64_t, Ptr<UeInfo> > m_ueInfoMap;
/**
+ * \brief This Function erases all contexts of bearer from MME side
+ * \param ueInfo UE information pointer
+ * \param epsBearerId Bearer Id which need to be removed corresponding to UE
+ */
+ void RemoveBearer (Ptr<UeInfo> ueInfo, uint8_t epsBearerId);
+
+ /**
* Hold info on a ENB
*
*/
--- a/src/lte/model/epc-s11-sap.h Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/model/epc-s11-sap.h Thu Nov 27 16:01:05 2014 +0100
@@ -103,6 +103,27 @@
*/
virtual void CreateSessionResponse (CreateSessionResponseMessage msg) = 0;
+ struct BearerContextRemoved
+ {
+ uint8_t epsBearerId;
+ };
+
+ /**
+ * Delete Bearer Request message, see 3GPP TS 29.274 Release 9 V9.3.0 section 7.2.9.2
+ */
+ struct DeleteBearerRequestMessage : public GtpcMessage
+ {
+ std::list<BearerContextRemoved> bearerContextsRemoved;
+ };
+
+ /**
+ * \brief As per 3GPP TS 29.274 Release 9 V9.3.0, a Delete Bearer Request message shall be sent on the S11 interface by PGW to SGW and from SGW to MME
+ * \param msg the message
+ */
+ virtual void DeleteBearerRequest (DeleteBearerRequestMessage msg) = 0;
+
+
+
/**
* Modify Bearer Response message, see 3GPP TS 29.274 7.2.7
@@ -162,6 +183,43 @@
*/
virtual void CreateSessionRequest (CreateSessionRequestMessage msg) = 0;
+ struct BearerContextToBeRemoved
+ {
+ uint8_t epsBearerId;
+ };
+
+ /**
+ * Delete Bearer Command message, see 3GPP TS 29.274 Release 9 V9.3.0 section 7.2.17.1
+ */
+ struct DeleteBearerCommandMessage : public GtpcMessage
+ {
+ std::list<BearerContextToBeRemoved> bearerContextsToBeRemoved;
+ };
+
+ /**
+ * \brief As per 3GPP TS 29.274 Release 9 V9.3.0, a Delete Bearer Command message shall be sent on the S11 interface by the MME to the SGW
+ */
+ virtual void DeleteBearerCommand (DeleteBearerCommandMessage msg) = 0;
+
+
+ struct BearerContextRemovedSgwPgw
+ {
+ uint8_t epsBearerId;
+ };
+
+ /**
+ * Delete Bearer Response message, see 3GPP TS 29.274 Release 9 V9.3.0 section 7.2.10.2
+ */
+ struct DeleteBearerResponseMessage : public GtpcMessage
+ {
+ std::list<BearerContextRemovedSgwPgw> bearerContextsRemoved;
+ };
+
+ /**
+ * \brief As per 3GPP TS 29.274 Release 9 V9.3.0, a Delete Bearer Command message shall be sent on the S11 interface by the MME to the SGW
+ * \param msg the message
+ */
+ virtual void DeleteBearerResponse (DeleteBearerResponseMessage msg) = 0;
/**
* Modify Bearer Request message, see 3GPP TS 29.274 7.2.7
@@ -200,6 +258,7 @@
// inherited from EpcS11SapMme
virtual void CreateSessionResponse (CreateSessionResponseMessage msg);
virtual void ModifyBearerResponse (ModifyBearerResponseMessage msg);
+ virtual void DeleteBearerRequest (DeleteBearerRequestMessage msg);
private:
MemberEpcS11SapMme ();
@@ -224,6 +283,12 @@
}
template <class C>
+void MemberEpcS11SapMme<C>::DeleteBearerRequest (DeleteBearerRequestMessage msg)
+{
+ m_owner->DoDeleteBearerRequest (msg);
+}
+
+template <class C>
void MemberEpcS11SapMme<C>::ModifyBearerResponse (ModifyBearerResponseMessage msg)
{
m_owner->DoModifyBearerResponse (msg);
@@ -247,6 +312,8 @@
// inherited from EpcS11SapSgw
virtual void CreateSessionRequest (CreateSessionRequestMessage msg);
virtual void ModifyBearerRequest (ModifyBearerRequestMessage msg);
+ virtual void DeleteBearerCommand (DeleteBearerCommandMessage msg);
+ virtual void DeleteBearerResponse (DeleteBearerResponseMessage msg);
private:
MemberEpcS11SapSgw ();
@@ -276,10 +343,17 @@
m_owner->DoModifyBearerRequest (msg);
}
-
+template <class C>
+void MemberEpcS11SapSgw<C>::DeleteBearerCommand (DeleteBearerCommandMessage msg)
+{
+ m_owner->DoDeleteBearerCommand (msg);
+}
-
-
+template <class C>
+void MemberEpcS11SapSgw<C>::DeleteBearerResponse (DeleteBearerResponseMessage msg)
+{
+ m_owner->DoDeleteBearerResponse (msg);
+}
--- a/src/lte/model/epc-s1ap-sap.h Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/model/epc-s1ap-sap.h Thu Nov 27 16:01:05 2014 +0100
@@ -61,6 +61,24 @@
/**
+ * E-RAB Release Indication Item IEs, 3GPP TS 36.413 version 9.8.0 section 9.1.3.7
+ *
+ */
+ struct ErabToBeReleasedIndication
+ {
+ uint8_t erabId;
+ };
+
+ /**
+ * \brief As per 3GPP TS 23.401 Release 9 V9.5.0 Figure 5.4.4.2-1 eNB sends indication of Bearer Release to MME
+ * \param mmeUeS1Id in practice, we use the IMSI
+ * \param enbUeS1Id in practice, we use the RNTI
+ * \param erabToBeReleaseIndication, List of bearers to be deactivated
+ *
+ */
+ virtual void ErabReleaseIndication (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, std::list<ErabToBeReleasedIndication> erabToBeReleaseIndication ) = 0;
+
+ /**
* E-RAB Setup Item IEs, see 3GPP TS 36.413 9.1.4.2
*
*/
@@ -174,6 +192,8 @@
// inherited from EpcS1apSapMme
virtual void InitialUeMessage (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, uint64_t imsi, uint16_t ecgi);
+ virtual void ErabReleaseIndication (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, std::list<ErabToBeReleasedIndication> erabToBeReleaseIndication );
+
virtual void InitialContextSetupResponse (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, std::list<ErabSetupItem> erabSetupList);
virtual void PathSwitchRequest (uint64_t enbUeS1Id, uint64_t mmeUeS1Id, uint16_t cgi, std::list<ErabSwitchedInDownlinkItem> erabToBeSwitchedInDownlinkList);
@@ -200,6 +220,12 @@
}
template <class C>
+void MemberEpcS1apSapMme<C>::ErabReleaseIndication (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, std::list<ErabToBeReleasedIndication> erabToBeReleaseIndication)
+{
+ m_owner->DoErabReleaseIndication (mmeUeS1Id, enbUeS1Id, erabToBeReleaseIndication);
+}
+
+template <class C>
void MemberEpcS1apSapMme<C>::InitialContextSetupResponse (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, std::list<ErabSetupItem> erabSetupList)
{
m_owner->DoInitialContextSetupResponse (mmeUeS1Id, enbUeS1Id, erabSetupList);
--- a/src/lte/model/epc-sgw-pgw-application.cc Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/model/epc-sgw-pgw-application.cc Thu Nov 27 16:01:05 2014 +0100
@@ -51,6 +51,13 @@
return m_tftClassifier.Add (tft, teid);
}
+void
+EpcSgwPgwApplication::UeInfo::RemoveBearer (uint8_t bearerId)
+{
+ NS_LOG_FUNCTION (this << bearerId);
+ m_teidByBearerIdMap.erase (bearerId);
+}
+
uint32_t
EpcSgwPgwApplication::UeInfo::Classify (Ptr<Packet> p)
{
@@ -144,7 +151,7 @@
std::map<Ipv4Address, Ptr<UeInfo> >::iterator it = m_ueInfoByAddrMap.find (ueAddr);
if (it == m_ueInfoByAddrMap.end ())
{
- NS_LOG_WARN ("unknown UE address " << ueAddr) ;
+ NS_LOG_WARN ("unknown UE address " << ueAddr);
}
else
{
@@ -204,7 +211,7 @@
gtpu.SetLength (packet->GetSize () + gtpu.GetSerializedSize () - 8);
packet->AddHeader (gtpu);
uint32_t flags = 0;
- m_s1uSocket->SendTo (packet, flags, InetSocketAddress(enbAddr, m_gtpuUdpPort));
+ m_s1uSocket->SendTo (packet, flags, InetSocketAddress (enbAddr, m_gtpuUdpPort));
}
@@ -305,4 +312,44 @@
m_s11SapMme->ModifyBearerResponse (res);
}
-}; // namespace ns3
+void
+EpcSgwPgwApplication::DoDeleteBearerCommand (EpcS11SapSgw::DeleteBearerCommandMessage req)
+{
+ NS_LOG_FUNCTION (this << req.teid);
+ uint64_t imsi = req.teid; // trick to avoid the need for allocating TEIDs on the S11 interface
+ std::map<uint64_t, Ptr<UeInfo> >::iterator ueit = m_ueInfoByImsiMap.find (imsi);
+ NS_ASSERT_MSG (ueit != m_ueInfoByImsiMap.end (), "unknown IMSI " << imsi);
+
+ EpcS11SapMme::DeleteBearerRequestMessage res;
+ res.teid = imsi;
+
+ for (std::list<EpcS11SapSgw::BearerContextToBeRemoved>::iterator bit = req.bearerContextsToBeRemoved.begin ();
+ bit != req.bearerContextsToBeRemoved.end ();
+ ++bit)
+ {
+ EpcS11SapMme::BearerContextRemoved bearerContext;
+ bearerContext.epsBearerId = bit->epsBearerId;
+ res.bearerContextsRemoved.push_back (bearerContext);
+ }
+ //schedules Delete Bearer Request towards MME
+ m_s11SapMme->DeleteBearerRequest (res);
+}
+
+void
+EpcSgwPgwApplication::DoDeleteBearerResponse (EpcS11SapSgw::DeleteBearerResponseMessage req)
+{
+ NS_LOG_FUNCTION (this << req.teid);
+ uint64_t imsi = req.teid; // trick to avoid the need for allocating TEIDs on the S11 interface
+ std::map<uint64_t, Ptr<UeInfo> >::iterator ueit = m_ueInfoByImsiMap.find (imsi);
+ NS_ASSERT_MSG (ueit != m_ueInfoByImsiMap.end (), "unknown IMSI " << imsi);
+
+ for (std::list<EpcS11SapSgw::BearerContextRemovedSgwPgw>::iterator bit = req.bearerContextsRemoved.begin ();
+ bit != req.bearerContextsRemoved.end ();
+ ++bit)
+ {
+ //Function to remove de-activated bearer contexts from S-Gw and P-Gw side
+ ueit->second->RemoveBearer (bit->epsBearerId);
+ }
+}
+
+} // namespace ns3
--- a/src/lte/model/epc-sgw-pgw-application.h Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/model/epc-sgw-pgw-application.h Thu Nov 27 16:01:05 2014 +0100
@@ -156,12 +156,16 @@
void DoCreateSessionRequest (EpcS11SapSgw::CreateSessionRequestMessage msg);
void DoModifyBearerRequest (EpcS11SapSgw::ModifyBearerRequestMessage msg);
+ void DoDeleteBearerCommand (EpcS11SapSgw::DeleteBearerCommandMessage req);
+ void DoDeleteBearerResponse (EpcS11SapSgw::DeleteBearerResponseMessage req);
+
+
/**
* store info for each UE connected to this SGW
*/
class UeInfo : public SimpleRefCount<UeInfo>
{
- public:
+public:
UeInfo ();
/**
@@ -173,6 +177,12 @@
void AddBearer (Ptr<EpcTft> tft, uint8_t epsBearerId, uint32_t teid);
/**
+ * \brief Function, deletes contexts of bearer on SGW and PGW side
+ * \param bearerId, the Bearer Id whose contexts to be removed
+ */
+ void RemoveBearer (uint8_t bearerId);
+
+ /**
*
*
* \param p the IP packet from the internet to be classified
--- a/src/lte/model/lte-enb-mac.cc Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/model/lte-enb-mac.cc Thu Nov 27 16:01:05 2014 +0100
@@ -544,13 +544,13 @@
std::vector <FfMacSchedSapProvider::SchedUlCqiInfoReqParameters>::iterator itCqi;
for (uint16_t i = 0; i < m_ulCqiReceived.size (); i++)
{
- if (subframeNo>1)
+ if (subframeNo > 1)
{
m_ulCqiReceived.at (i).m_sfnSf = ((0x3FF & frameNo) << 4) | (0xF & (subframeNo - 1));
}
else
{
- m_ulCqiReceived.at (i).m_sfnSf = ((0x3FF & (frameNo-1)) << 4) | (0xF & 10);
+ m_ulCqiReceived.at (i).m_sfnSf = ((0x3FF & (frameNo - 1)) << 4) | (0xF & 10);
}
m_schedSapProvider->SchedUlCqiInfoReq (m_ulCqiReceived.at (i));
}
@@ -571,14 +571,14 @@
uint32_t ulSchedFrameNo = m_frameNo;
uint32_t ulSchedSubframeNo = m_subframeNo;
// NS_LOG_DEBUG (this << " sfn " << frameNo << " sbfn " << subframeNo);
- if (ulSchedSubframeNo + (m_macChTtiDelay+UL_PUSCH_TTIS_DELAY) > 10)
+ if (ulSchedSubframeNo + (m_macChTtiDelay + UL_PUSCH_TTIS_DELAY) > 10)
{
ulSchedFrameNo++;
- ulSchedSubframeNo = (ulSchedSubframeNo + (m_macChTtiDelay+UL_PUSCH_TTIS_DELAY)) % 10;
+ ulSchedSubframeNo = (ulSchedSubframeNo + (m_macChTtiDelay + UL_PUSCH_TTIS_DELAY)) % 10;
}
else
{
- ulSchedSubframeNo = ulSchedSubframeNo + (m_macChTtiDelay+UL_PUSCH_TTIS_DELAY);
+ ulSchedSubframeNo = ulSchedSubframeNo + (m_macChTtiDelay + UL_PUSCH_TTIS_DELAY);
}
FfMacSchedSapProvider::SchedUlTriggerReqParameters ulparams;
ulparams.m_sfnSf = ((0x3FF & ulSchedFrameNo) << 4) | (0xF & ulSchedSubframeNo);
@@ -711,9 +711,13 @@
std::map <uint16_t, std::map<uint8_t, LteMacSapUser*> >::iterator rntiIt = m_rlcAttached.find (rnti);
NS_ASSERT_MSG (rntiIt != m_rlcAttached.end (), "could not find RNTI" << rnti);
std::map<uint8_t, LteMacSapUser*>::iterator lcidIt = rntiIt->second.find (lcid);
- NS_ASSERT_MSG (lcidIt != rntiIt->second.end (), "could not find LCID" << lcid);
- (*lcidIt).second->ReceivePdu (p);
+ //NS_ASSERT_MSG (lcidIt != rntiIt->second.end (), "could not find LCID" << lcid);
+ //Receive PDU only if LCID is found
+ if (lcidIt != rntiIt->second.end ())
+ {
+ (*lcidIt).second->ReceivePdu (p);
+ }
}
@@ -840,7 +844,16 @@
void
LteEnbMac::DoReleaseLc (uint16_t rnti, uint8_t lcid)
{
- NS_FATAL_ERROR ("not implemented");
+ NS_LOG_FUNCTION (this);
+
+ //Find user based on rnti and then erase lcid stored against the same
+ std::map <uint16_t, std::map<uint8_t, LteMacSapUser*> >::iterator rntiIt = m_rlcAttached.find (rnti);
+ rntiIt->second.erase (lcid);
+
+ struct FfMacCschedSapProvider::CschedLcReleaseReqParameters params;
+ params.m_rnti = rnti;
+ params.m_logicalChannelIdentity.push_back (lcid);
+ m_cschedSapProvider->CschedLcReleaseReq (params);
}
void
@@ -919,8 +932,8 @@
params.pdu->AddPacketTag (tag);
// Store pkt in HARQ buffer
std::map <uint16_t, DlHarqProcessesBuffer_t>::iterator it = m_miDlHarqProcessesPackets.find (params.rnti);
- NS_ASSERT (it!=m_miDlHarqProcessesPackets.end ());
- NS_LOG_DEBUG (this << " LAYER " <<(uint16_t)tag.GetLayer () << " HARQ ID " << (uint16_t)params.harqProcessId);
+ NS_ASSERT (it != m_miDlHarqProcessesPackets.end ());
+ NS_LOG_DEBUG (this << " LAYER " << (uint16_t)tag.GetLayer () << " HARQ ID " << (uint16_t)params.harqProcessId);
//(*it).second.at (params.layer).at (params.harqProcessId) = params.pdu;//->Copy ();
(*it).second.at (params.layer).at (params.harqProcessId)->AddPacket (params.pdu);
@@ -966,8 +979,8 @@
{
// new data -> force emptying correspondent harq pkt buffer
std::map <uint16_t, DlHarqProcessesBuffer_t>::iterator it = m_miDlHarqProcessesPackets.find (ind.m_buildDataList.at (i).m_rnti);
- NS_ASSERT(it!=m_miDlHarqProcessesPackets.end());
- for (uint16_t lcId = 0; lcId < (*it).second.size (); lcId ++)
+ NS_ASSERT (it != m_miDlHarqProcessesPackets.end ());
+ for (uint16_t lcId = 0; lcId < (*it).second.size (); lcId++)
{
Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
(*it).second.at (lcId).at (ind.m_buildDataList.at (i).m_dci.m_harqProcess) = pb;
@@ -992,11 +1005,11 @@
}
else
{
- if (ind.m_buildDataList.at (i).m_dci.m_tbsSize.at (k)>0)
+ if (ind.m_buildDataList.at (i).m_dci.m_tbsSize.at (k) > 0)
{
// HARQ retransmission -> retrieve TB from HARQ buffer
std::map <uint16_t, DlHarqProcessesBuffer_t>::iterator it = m_miDlHarqProcessesPackets.find (ind.m_buildDataList.at (i).m_rnti);
- NS_ASSERT(it!=m_miDlHarqProcessesPackets.end());
+ NS_ASSERT (it != m_miDlHarqProcessesPackets.end ());
Ptr<PacketBurst> pb = (*it).second.at (k).at ( ind.m_buildDataList.at (i).m_dci.m_harqProcess);
for (std::list<Ptr<Packet> >::const_iterator j = pb->Begin (); j != pb->End (); ++j)
{
@@ -1171,17 +1184,17 @@
NS_LOG_FUNCTION (this);
// Update HARQ buffer
std::map <uint16_t, DlHarqProcessesBuffer_t>::iterator it = m_miDlHarqProcessesPackets.find (params.m_rnti);
- NS_ASSERT (it!=m_miDlHarqProcessesPackets.end ());
+ NS_ASSERT (it != m_miDlHarqProcessesPackets.end ());
for (uint8_t layer = 0; layer < params.m_harqStatus.size (); layer++)
{
- if (params.m_harqStatus.at (layer)==DlInfoListElement_s::ACK)
+ if (params.m_harqStatus.at (layer) == DlInfoListElement_s::ACK)
{
// discard buffer
Ptr<PacketBurst> emptyBuf = CreateObject <PacketBurst> ();
(*it).second.at (layer).at (params.m_harqProcessId) = emptyBuf;
NS_LOG_DEBUG (this << " HARQ-ACK UE " << params.m_rnti << " harqId " << (uint16_t)params.m_harqProcessId << " layer " << (uint16_t)layer);
}
- else if (params.m_harqStatus.at (layer)==DlInfoListElement_s::NACK)
+ else if (params.m_harqStatus.at (layer) == DlInfoListElement_s::NACK)
{
NS_LOG_DEBUG (this << " HARQ-NACK UE " << params.m_rnti << " harqId " << (uint16_t)params.m_harqProcessId << " layer " << (uint16_t)layer);
}
--- a/src/lte/model/lte-enb-rrc.cc Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/model/lte-enb-rrc.cc Thu Nov 27 16:01:05 2014 +0100
@@ -458,14 +458,29 @@
LteRrcSap::RadioResourceConfigDedicated rrcd;
rrcd.havePhysicalConfigDedicated = false;
rrcd.drbToReleaseList.push_back (drbid);
+ //populating RadioResourceConfigDedicated information element as per 3GPP TS 36.331 version 9.2.0
+ rrcd.havePhysicalConfigDedicated = true;
+ rrcd.physicalConfigDedicated = m_physicalConfigDedicated;
+ //populating RRCConnectionReconfiguration message as per 3GPP TS 36.331 version 9.2.0 Release 9
LteRrcSap::RrcConnectionReconfiguration msg;
msg.haveMeasConfig = false;
msg.haveMobilityControlInfo = false;
-
+ msg.radioResourceConfigDedicated = rrcd;
+ msg.haveRadioResourceConfigDedicated = true;
+ //RRC Connection Reconfiguration towards UE
m_rrc->m_rrcSapUser->SendRrcConnectionReconfiguration (m_rnti, msg);
}
+void
+LteEnbRrc::DoSendReleaseDataRadioBearer (uint64_t imsi, uint16_t rnti, uint8_t bearerId)
+{
+ Ptr<UeManager> ueManager = GetUeManager (rnti);
+ // Bearer de-activation towards UE
+ ueManager->ReleaseDataRadioBearer (bearerId);
+ // Bearer de-activation indication towards epc-enb application
+ m_s1SapProvider->DoSendReleaseIndication (imsi,rnti,bearerId);
+}
void
UeManager::ScheduleRrcConnectionReconfiguration ()
@@ -642,9 +657,18 @@
params.rnti = m_rnti;
params.lcid = Bid2Lcid (bid);
uint8_t drbid = Bid2Drbid (bid);
- LtePdcpSapProvider* pdcpSapProvider = GetDataRadioBearerInfo (drbid)->m_pdcp->GetLtePdcpSapProvider ();
+ //Transmit PDCP sdu only if DRB ID found in drbMap
+ std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
+ if (it != m_drbMap.end ())
+ {
+ Ptr<LteDataRadioBearerInfo> bearerInfo = GetDataRadioBearerInfo (drbid);
+ if (bearerInfo != NULL)
+ {
+ LtePdcpSapProvider* pdcpSapProvider = bearerInfo->m_pdcp->GetLtePdcpSapProvider ();
pdcpSapProvider->TransmitPdcpSdu (params);
}
+ }
+ }
break;
case HANDOVER_LEAVING:
@@ -852,6 +876,11 @@
m_rrc->m_connectionReconfigurationTrace (m_imsi, m_rrc->m_cellId, m_rnti);
break;
+ // This case is added to NS-3 in order to handle bearer de-activation scenario for CONNECTED state UE
+ case CONNECTED_NORMALLY:
+ NS_LOG_INFO ("ignoring RecvRrcConnectionReconfigurationCompleted in state " << ToString (m_state));
+ break;
+
case HANDOVER_LEAVING:
NS_LOG_INFO ("ignoring RecvRrcConnectionReconfigurationCompleted in state " << ToString (m_state));
break;
@@ -1823,8 +1852,8 @@
NS_LOG_INFO ("rejecting handover request from cellId " << req.sourceCellId);
EpcX2Sap::HandoverPreparationFailureParams res;
res.oldEnbUeX2apId = req.oldEnbUeX2apId;
- res.sourceCellId = req.sourceCellId ;
- res.targetCellId = req.targetCellId ;
+ res.sourceCellId = req.sourceCellId;
+ res.targetCellId = req.targetCellId;
res.cause = 0;
res.criticalityDiagnostics = 0;
m_x2SapProvider->SendHandoverPreparationFailure (res);
@@ -2271,7 +2300,7 @@
for (uint16_t srcCi = g_srsCiLow[m_srsCurrentPeriodicityId]; srcCi < g_srsCiHigh[m_srsCurrentPeriodicityId]; srcCi++)
{
std::set<uint16_t>::iterator it = m_ueSrsConfigurationIndexSet.find (srcCi);
- if (it==m_ueSrsConfigurationIndexSet.end ())
+ if (it == m_ueSrsConfigurationIndexSet.end ())
{
m_lastAllocatedConfigurationIndex = srcCi;
m_ueSrsConfigurationIndexSet.insert (srcCi);
--- a/src/lte/model/lte-enb-rrc.h Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/model/lte-enb-rrc.h Thu Nov 27 16:01:05 2014 +0100
@@ -687,6 +687,14 @@
void SendHandoverRequest (uint16_t rnti, uint16_t cellId);
/**
+ * \brief This function acts as an interface to trigger Release indication messages towards eNB and EPC
+ * \param imsi the IMSI
+ * \param rnti the RNTI
+ * \param bearerId Bearer Identity which is to be de-activated
+ */
+ void DoSendReleaseDataRadioBearer (uint64_t imsi, uint16_t rnti, uint8_t bearerId);
+
+ /**
* Identifies how EPS Bearer parameters are mapped to different RLC types
*
*/
--- a/src/lte/model/lte-ue-mac.cc Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/model/lte-ue-mac.cc Thu Nov 27 16:01:05 2014 +0100
@@ -297,7 +297,7 @@
it = m_ulBsrReceived.find (params.lcid);
- if (it!=m_ulBsrReceived.end ())
+ if (it != m_ulBsrReceived.end ())
{
// update entry
(*it).second = params;
@@ -555,7 +555,7 @@
{
Ptr<UlDciLteControlMessage> msg2 = DynamicCast<UlDciLteControlMessage> (msg);
UlDciListElement_s dci = msg2->GetDci ();
- if (dci.m_ndi==1)
+ if (dci.m_ndi == 1)
{
// New transmission -> emtpy pkt buffer queue (for deleting eventual pkts not acked )
Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
@@ -569,11 +569,11 @@
if (((*itBsr).second.statusPduSize > 0) || ((*itBsr).second.retxQueueSize > 0) || ((*itBsr).second.txQueueSize > 0))
{
activeLcs++;
- if (((*itBsr).second.statusPduSize!=0)&&((*itBsr).second.statusPduSize < statusPduMinSize))
+ if (((*itBsr).second.statusPduSize != 0)&&((*itBsr).second.statusPduSize < statusPduMinSize))
{
statusPduMinSize = (*itBsr).second.statusPduSize;
}
- if (((*itBsr).second.statusPduSize!=0)&&(statusPduMinSize == 0))
+ if (((*itBsr).second.statusPduSize != 0)&&(statusPduMinSize == 0))
{
statusPduMinSize = (*itBsr).second.statusPduSize;
}
@@ -598,14 +598,14 @@
}
}
NS_LOG_LOGIC (this << " UE " << m_rnti << ": UL-CQI notified TxOpportunity of " << dci.m_tbSize << " => " << bytesPerActiveLc << " bytes per active LC" << " statusPduMinSize " << statusPduMinSize);
- for (it = m_lcInfoMap.begin (); it!=m_lcInfoMap.end (); it++)
+ for (it = m_lcInfoMap.begin (); it != m_lcInfoMap.end (); it++)
{
itBsr = m_ulBsrReceived.find ((*it).first);
NS_LOG_DEBUG (this << " Processing LC " << (uint32_t)(*it).first << " bytesPerActiveLc " << bytesPerActiveLc);
- if ( (itBsr!=m_ulBsrReceived.end ()) &&
- ( ((*itBsr).second.statusPduSize > 0) ||
- ((*itBsr).second.retxQueueSize > 0) ||
- ((*itBsr).second.txQueueSize > 0)) )
+ if ( (itBsr != m_ulBsrReceived.end ())
+ && ( ((*itBsr).second.statusPduSize > 0)
+ || ((*itBsr).second.retxQueueSize > 0)
+ || ((*itBsr).second.txQueueSize > 0)) )
{
if ((statusPduPriority) && ((*itBsr).second.statusPduSize == statusPduMinSize))
{
@@ -627,15 +627,15 @@
}
else
{
- if ((*itBsr).second.statusPduSize>bytesForThisLc)
+ if ((*itBsr).second.statusPduSize > bytesForThisLc)
{
NS_FATAL_ERROR ("Insufficient Tx Opportunity for sending a status message");
}
}
- if ((bytesForThisLc > 7) && // 7 is the min TxOpportunity useful for Rlc
- (((*itBsr).second.retxQueueSize > 0) ||
- ((*itBsr).second.txQueueSize > 0)))
+ if ((bytesForThisLc > 7) // 7 is the min TxOpportunity useful for Rlc
+ && (((*itBsr).second.retxQueueSize > 0)
+ || ((*itBsr).second.txQueueSize > 0)))
{
if ((*itBsr).second.retxQueueSize > 0)
{
@@ -769,7 +769,7 @@
m_frameNo = frameNo;
m_subframeNo = subframeNo;
RefreshHarqProcessesPacketBuffer ();
- if ((Simulator::Now () >= m_bsrLast + m_bsrPeriodicity) && (m_freshUlBsr==true))
+ if ((Simulator::Now () >= m_bsrLast + m_bsrPeriodicity) && (m_freshUlBsr == true))
{
SendReportBufferStatus ();
m_bsrLast = Simulator::Now ();
--- a/src/lte/model/lte-ue-rrc.cc Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/model/lte-ue-rrc.cc Thu Nov 27 16:01:05 2014 +0100
@@ -404,6 +404,8 @@
uint8_t drbid = Bid2Drbid (bid);
+ if (drbid != 0)
+ {
std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with drbid == " << drbid);
@@ -417,6 +419,7 @@
<< " (LCID " << (uint32_t) params.lcid << ")"
<< " (" << packet->GetSize () << " bytes)");
it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitPdcpSdu (params);
+ }
}
@@ -1250,6 +1253,8 @@
NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with given lcid");
m_drbMap.erase (it);
m_bid2DrbidMap.erase (drbid);
+ //Remove LCID
+ m_cmacSapProvider->RemoveLc (drbid + 2);
}
}
@@ -1398,8 +1403,8 @@
NS_LOG_LOGIC (this << " setting quantityConfig");
m_varMeasConfig.quantityConfig = mc.quantityConfig;
// we calculate here the coefficient a used for Layer 3 filtering, see 3GPP TS 36.331 section 5.5.3.2
- m_varMeasConfig.aRsrp = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRP/4.0);
- m_varMeasConfig.aRsrq = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRQ/4.0);
+ m_varMeasConfig.aRsrp = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRP / 4.0);
+ m_varMeasConfig.aRsrq = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRQ / 4.0);
NS_LOG_LOGIC (this << " new filter coefficients: aRsrp=" << m_varMeasConfig.aRsrp << ", aRsrq=" << m_varMeasConfig.aRsrq);
for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
@@ -1477,7 +1482,7 @@
{
NS_LOG_FUNCTION (this << cellId << rsrp << rsrq << useLayer3Filtering);
- std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);;
+ std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);
if (storedMeasIt != m_storedMeasValues.end ())
{
@@ -2738,11 +2743,17 @@
LteUeRrc::Bid2Drbid (uint8_t bid)
{
std::map<uint8_t, uint8_t>::iterator it = m_bid2DrbidMap.find (bid);
- NS_ASSERT_MSG (it != m_bid2DrbidMap.end (), "could not find BID " << bid);
+ //NS_ASSERT_MSG (it != m_bid2DrbidMap.end (), "could not find BID " << bid);
+ if (it == m_bid2DrbidMap.end ())
+ {
+ return 0;
+ }
+ else
+ {
return it->second;
+ }
}
-
void
LteUeRrc::SwitchToState (State newState)
{
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-test-deactivate-bearer.cc Thu Nov 27 16:01:05 2014 +0100
@@ -0,0 +1,347 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011, 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author:Gaurav Sathe <gaurav.sathe@tcs.com>
+ */
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include <ns3/object.h>
+#include <ns3/spectrum-interference.h>
+#include <ns3/spectrum-error-model.h>
+#include <ns3/log.h>
+#include <ns3/test.h>
+#include <ns3/simulator.h>
+#include <ns3/packet.h>
+#include <ns3/ptr.h>
+#include "ns3/radio-bearer-stats-calculator.h"
+#include <ns3/constant-position-mobility-model.h>
+#include <ns3/eps-bearer.h>
+#include <ns3/node-container.h>
+#include <ns3/mobility-helper.h>
+#include <ns3/net-device-container.h>
+#include <ns3/lte-ue-net-device.h>
+#include <ns3/lte-enb-net-device.h>
+#include <ns3/lte-ue-rrc.h>
+#include <ns3/lte-helper.h>
+#include "ns3/string.h"
+#include "ns3/double.h"
+#include <ns3/lte-enb-phy.h>
+#include <ns3/lte-ue-phy.h>
+#include <ns3/boolean.h>
+#include <ns3/enum.h>
+
+#include "ns3/point-to-point-epc-helper.h"
+#include "ns3/network-module.h"
+#include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/internet-module.h"
+#include "ns3/applications-module.h"
+#include "ns3/point-to-point-helper.h"
+
+#include "lte-test-deactivate-bearer.h"
+
+NS_LOG_COMPONENT_DEFINE ("LenaTestDeactivateBearer");
+
+namespace ns3 {
+
+LenaTestBearerDeactivateSuite::LenaTestBearerDeactivateSuite ()
+ : TestSuite ("lte-test-deactivate-bearer", SYSTEM)
+{
+ NS_LOG_INFO ("creating LenaTestPssFfMacSchedulerSuite");
+
+ bool errorModel = false;
+
+ // Test Case: homogeneous flow test in PSS (different distance)
+ // Traffic1 info
+ // UDP traffic: payload size = 100 bytes, interval = 1 ms
+ // UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 132000 byte/rate
+ // Maximum throughput = 3 / ( 1/2196000 + 1/1191000 + 1/1383000) = 1486569 byte/s
+ // 132000 * 3 = 396000 < 1209046 -> estimated throughput in downlink = 132000 byte/sec
+ std::vector<uint16_t> dist_1;
+
+ dist_1.push_back (0); // User 0 distance --> MCS 28
+ dist_1.push_back (0); // User 1 distance --> MCS 22
+ dist_1.push_back (0); // User 2 distance --> MCS 20
+
+ std::vector<uint16_t> packetSize_1;
+
+ packetSize_1.push_back (100); //1
+ packetSize_1.push_back (100); //2
+ packetSize_1.push_back (100); //3
+
+ std::vector<uint32_t> estThrPssDl_1;
+
+ estThrPssDl_1.push_back (132000); // User 0 estimated TTI throughput from PSS
+ estThrPssDl_1.push_back (132000); // User 1 estimated TTI throughput from PSS
+ estThrPssDl_1.push_back (132000); // User 2 estimated TTI throughput from PSS
+
+ AddTestCase (new LenaDeactivateBearerTestCase (dist_1,estThrPssDl_1,packetSize_1,1,errorModel), TestCase::QUICK);
+}
+
+static LenaTestBearerDeactivateSuite lenaTestBearerDeactivateSuite;
+
+
+std::string
+LenaDeactivateBearerTestCase::BuildNameString (uint16_t nUser, std::vector<uint16_t> dist)
+{
+ std::ostringstream oss;
+ oss << "distances (m) = [ ";
+ for (std::vector<uint16_t>::iterator it = dist.begin (); it != dist.end (); ++it)
+ {
+ oss << *it << " ";
+ }
+ oss << "]";
+ return oss.str ();
+}
+
+LenaDeactivateBearerTestCase::LenaDeactivateBearerTestCase (std::vector<uint16_t> dist, std::vector<uint32_t> estThrPssDl, std::vector<uint16_t> packetSize, uint16_t interval,bool errorModelEnabled)
+ : TestCase (BuildNameString (dist.size (), dist)),
+ m_nUser (dist.size ()),
+ m_dist (dist),
+ m_packetSize (packetSize),
+ m_interval (interval),
+ m_estThrPssDl (estThrPssDl),
+ m_errorModelEnabled (errorModelEnabled)
+{
+}
+
+LenaDeactivateBearerTestCase::~LenaDeactivateBearerTestCase ()
+{
+}
+
+void
+LenaDeactivateBearerTestCase::DoRun (void)
+{
+ if (!m_errorModelEnabled)
+ {
+ Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
+ Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
+ }
+
+ Config::SetDefault ("ns3::LteHelper::UseIdealRrc", BooleanValue (true));
+
+
+ Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
+ Ptr<PointToPointEpcHelper> epcHelper = CreateObject<PointToPointEpcHelper> ();
+ lteHelper->SetEpcHelper (epcHelper);
+
+ Ptr<Node> pgw = epcHelper->GetPgwNode ();
+
+ // Create a single RemoteHost
+ NodeContainer remoteHostContainer;
+ remoteHostContainer.Create (1);
+ Ptr<Node> remoteHost = remoteHostContainer.Get (0);
+ InternetStackHelper internet;
+ internet.Install (remoteHostContainer);
+
+ // Create the Internet
+ PointToPointHelper p2ph;
+ p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
+ p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
+ p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.001)));
+ NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
+ Ipv4AddressHelper ipv4h;
+ ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
+ Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
+ // interface 0 is localhost, 1 is the p2p device
+ Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1);
+
+ Ipv4StaticRoutingHelper ipv4RoutingHelper;
+ Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
+ remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
+
+ LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL);
+
+ LogComponentEnable ("LenaTestDeactivateBearer", LOG_LEVEL_ALL);
+ LogComponentEnable ("LteHelper", logLevel);
+ LogComponentEnable ("EpcHelper", logLevel);
+ LogComponentEnable ("EpcEnbApplication", logLevel);
+ LogComponentEnable ("EpcSgwPgwApplication", logLevel);
+ LogComponentEnable ("EpcMme", logLevel);
+ LogComponentEnable ("LteEnbRrc", logLevel);
+
+ lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
+
+ // Create Nodes: eNodeB and UE
+ NodeContainer enbNodes;
+ NodeContainer ueNodes;
+ enbNodes.Create (1);
+ ueNodes.Create (m_nUser);
+
+ // Install Mobility Model
+ MobilityHelper mobility;
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+ mobility.Install (enbNodes);
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+ mobility.Install (ueNodes);
+
+ // Create Devices and install them in the Nodes (eNB and UE)
+ NetDeviceContainer enbDevs;
+ NetDeviceContainer ueDevs;
+ lteHelper->SetSchedulerType ("ns3::PssFfMacScheduler");
+ enbDevs = lteHelper->InstallEnbDevice (enbNodes);
+ ueDevs = lteHelper->InstallUeDevice (ueNodes);
+
+ Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
+ Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
+ enbPhy->SetAttribute ("TxPower", DoubleValue (30.0));
+ enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
+
+ // Set UEs' position and power
+ for (int i = 0; i < m_nUser; i++)
+ {
+ Ptr<ConstantPositionMobilityModel> mm = ueNodes.Get (i)->GetObject<ConstantPositionMobilityModel> ();
+ mm->SetPosition (Vector (m_dist.at (i), 0.0, 0.0));
+ Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (i)->GetObject<LteUeNetDevice> ();
+ Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
+ uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
+ uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
+ }
+
+ // Install the IP stack on the UEs
+ internet.Install (ueNodes);
+ Ipv4InterfaceContainer ueIpIface;
+ ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevs));
+
+ // Assign IP address to UEs
+ for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
+ {
+ Ptr<Node> ueNode = ueNodes.Get (u);
+ // Set the default gateway for the UE
+ Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
+ ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
+ }
+
+ // Attach a UE to a eNB
+ lteHelper->Attach (ueDevs, enbDevs.Get (0));
+
+ // Activate an EPS bearer on all UEs
+
+ for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
+ {
+ Ptr<NetDevice> ueDevice = ueDevs.Get (u);
+ GbrQosInformation qos;
+ qos.gbrDl = (m_packetSize.at (u) + 32) * (1000 / m_interval) * 8; // bit/s, considering IP, UDP, RLC, PDCP header size
+ qos.gbrUl = (m_packetSize.at (u) + 32) * (1000 / m_interval) * 8;
+ qos.mbrDl = qos.gbrDl;
+ qos.mbrUl = qos.gbrUl;
+
+ enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
+ EpsBearer bearer (q, qos);
+ bearer.arp.priorityLevel = 15 - (u + 1);
+ bearer.arp.preemptionCapability = true;
+ bearer.arp.preemptionVulnerability = true;
+ lteHelper->ActivateDedicatedEpsBearer (ueDevice, bearer, EpcTft::Default ());
+ }
+
+
+ // Install downlink and uplink applications
+ uint16_t dlPort = 1234;
+ uint16_t ulPort = 2000;
+ PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), dlPort));
+ PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), ulPort));
+ ApplicationContainer clientApps;
+ ApplicationContainer serverApps;
+ for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
+ {
+ ++ulPort;
+ serverApps.Add (dlPacketSinkHelper.Install (ueNodes.Get (u))); // receive packets from remotehost
+ serverApps.Add (ulPacketSinkHelper.Install (remoteHost)); // receive packets from UEs
+
+ UdpClientHelper dlClient (ueIpIface.GetAddress (u), dlPort); // uplink packets generator
+ dlClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
+ dlClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
+ dlClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize.at (u)));
+
+ UdpClientHelper ulClient (remoteHostAddr, ulPort); // downlink packets generator
+ ulClient.SetAttribute ("Interval", TimeValue (MilliSeconds (m_interval)));
+ ulClient.SetAttribute ("MaxPackets", UintegerValue (1000000));
+ ulClient.SetAttribute ("PacketSize", UintegerValue (m_packetSize.at (u)));
+
+ clientApps.Add (dlClient.Install (remoteHost));
+ clientApps.Add (ulClient.Install (ueNodes.Get (u)));
+ }
+
+
+ serverApps.Start (Seconds (0.030));
+ clientApps.Start (Seconds (0.030));
+
+ double statsStartTime = 0.04; // need to allow for RRC connection establishment + SRS
+ double statsDuration = 1.0;
+ double tolerance = 0.1;
+
+ lteHelper->EnableRlcTraces ();
+ Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
+ rlcStats->SetAttribute ("StartTime", TimeValue (Seconds (statsStartTime)));
+ rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (statsDuration)));
+
+
+ //get ue device pointer for UE-ID 0 IMSI 1
+ Ptr<NetDevice> ueDevice = ueDevs.Get (0);
+ Time deActivateTime (Seconds (1.5));
+
+ /*
+ * Schedule dedicated bearer de-activation at 'deActivateTime'
+ * Instantiate De-activation in sequence (Time deActivateTime, Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice, uint8_t bearerId)
+ */
+
+ lteHelper->DeActivateDedicatedEpsBearer (deActivateTime,ueDevice,enbDevs.Get (0), 2);
+
+ //stop simulation after 3 seconds
+ Simulator::Stop (Seconds (3.0));
+
+ Simulator::Run ();
+
+ NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s)");
+ std::vector <uint64_t> dlDataRxed;
+ std::vector <uint64_t> dlDataTxed;
+ for (int i = 0; i < m_nUser; i++)
+ {
+ // get the imsi
+ uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
+ // get the lcId
+ // lcId is hard-coded, since only one dedicated bearer is added
+ uint8_t lcId = 4;
+ dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
+ dlDataTxed.push_back (rlcStats->GetDlTxData (imsi, lcId));
+ NS_LOG_INFO ("\tUser " << i << " dist " << m_dist.at (i) << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / statsDuration << " ref " << m_estThrPssDl.at (i));
+ NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes txed " << (double)dlDataTxed.at (i) << " thr " << (double)dlDataTxed.at (i) / statsDuration);
+ }
+
+ for (int i = 0; i < m_nUser; i++)
+ {
+ uint64_t imsi = ueDevs.Get (i)->GetObject<LteUeNetDevice> ()->GetImsi ();
+
+ /*
+ * For UE ID-0 IMSI 1, LCID=4 is deactivated hence If traffic seen on it, test case should fail
+ * Else For other UE's, test case should validate throughput
+ */
+ if (imsi == 1)
+ {
+ NS_TEST_ASSERT_MSG_EQ ((double)dlDataTxed.at (i), 0, "Invalid LCID in Statistics ");
+ }
+ else
+ {
+ NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataTxed.at (i) / statsDuration, m_estThrPssDl.at (i), m_estThrPssDl.at (i) * tolerance, " Unfair Throughput!");
+ }
+ }
+
+ Simulator::Destroy ();
+}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-test-deactivate-bearer.h Thu Nov 27 16:01:05 2014 +0100
@@ -0,0 +1,37 @@
+#ifndef LENA_TEST_DEACTIVATE_BEARER_H
+#define LENA_TEST_DEACTIVATE_BEARER_H
+
+#include "ns3/simulator.h"
+#include "ns3/test.h"
+
+
+namespace ns3 {
+
+class LenaDeactivateBearerTestCase : public TestCase
+{
+public:
+ LenaDeactivateBearerTestCase (std::vector<uint16_t> dist, std::vector<uint32_t> estThrPssDl, std::vector<uint16_t> packetSize, uint16_t interval, bool errorModelEnabled);
+ virtual ~LenaDeactivateBearerTestCase ();
+
+private:
+ static std::string BuildNameString (uint16_t nUser, std::vector<uint16_t> dist);
+ virtual void DoRun (void);
+ uint16_t m_nUser;
+ std::vector<uint16_t> m_dist;
+ std::vector<uint16_t> m_packetSize; // byte
+ uint16_t m_interval; // ms
+ std::vector<uint32_t> m_estThrPssDl;
+ bool m_errorModelEnabled;
+};
+
+
+
+class LenaTestBearerDeactivateSuite : public TestSuite
+{
+public:
+ LenaTestBearerDeactivateSuite ();
+};
+
+} // namespace ns3
+
+#endif
--- a/src/lte/wscript Sun Jun 15 08:54:48 2014 -0700
+++ b/src/lte/wscript Thu Nov 27 16:01:05 2014 +0100
@@ -155,6 +155,7 @@
'test/lte-test-cell-selection.cc',
'test/test-lte-handover-delay.cc',
'test/test-lte-handover-target.cc',
+ 'test/lte-test-deactivate-bearer.cc',
]
headers = bld(features='ns3header')