added release bearer functionality
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -156,3 +156,4 @@ Florian Westphal (fw@strlen.de)
|
||||
He Wu (mdzz@u.washington.edu)
|
||||
Yoshihiko Yazawa (yoshiyaz@gmail.com)
|
||||
Dizhi Zhou (dizhi.zhou@gmail.com)
|
||||
Gaurav Sathe (gaurav.sathe@tcs.com)
|
||||
|
||||
@@ -48,6 +48,11 @@ New user-visible features
|
||||
- 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
|
||||
----------
|
||||
|
||||
@@ -2878,6 +2878,11 @@ def register_Ns3EpcEnbS1SapProvider_methods(root_module, cls):
|
||||
'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 @@ def register_Ns3EpcS11SapMme_methods(root_module, cls):
|
||||
'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 @@ def register_Ns3EpcS11SapSgw_methods(root_module, cls):
|
||||
'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 @@ def register_Ns3EpcS1apSapMme_methods(root_module, cls):
|
||||
'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):
|
||||
|
||||
234
src/lte/examples/lena-deactivate-bearer.cc
Normal file
234
src/lte/examples/lena-deactivate-bearer.cc
Normal file
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -34,6 +34,9 @@ def build(bld):
|
||||
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'
|
||||
|
||||
@@ -813,8 +813,8 @@ DrbActivator::ActivateDrb (uint64_t imsi, uint16_t cellId, uint16_t rnti)
|
||||
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 @@ LteHelper::DoHandoverRequest (Ptr<NetDevice> ueDev, Ptr<NetDevice> sourceEnbDev,
|
||||
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
|
||||
|
||||
@@ -325,6 +325,17 @@ public:
|
||||
*/
|
||||
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 @@ public:
|
||||
*/
|
||||
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 @@ private:
|
||||
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;
|
||||
|
||||
|
||||
@@ -26,8 +26,7 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
namespace ns3 {
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("RadioBearerStatsCalculator");
|
||||
|
||||
|
||||
@@ -310,8 +310,18 @@ EpcEnbApplication::SendToS1uSocket (Ptr<Packet> packet, uint32_t teid)
|
||||
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
|
||||
|
||||
@@ -150,6 +150,15 @@ private:
|
||||
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
|
||||
|
||||
@@ -49,6 +49,13 @@ public:
|
||||
*/
|
||||
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 @@ public:
|
||||
|
||||
// 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 @@ void MemberEpcEnbS1SapProvider<C>::InitialUeMessage (uint64_t imsi, uint16_t rnt
|
||||
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)
|
||||
|
||||
@@ -221,4 +221,66 @@ EpcMme::DoModifyBearerResponse (EpcS11SapMme::ModifyBearerResponseMessage msg)
|
||||
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
|
||||
|
||||
@@ -115,11 +115,13 @@ private:
|
||||
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
|
||||
@@ -152,6 +154,13 @@ private:
|
||||
*/
|
||||
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
|
||||
*
|
||||
|
||||
@@ -103,6 +103,27 @@ public:
|
||||
*/
|
||||
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 @@ public:
|
||||
*/
|
||||
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 @@ public:
|
||||
// inherited from EpcS11SapMme
|
||||
virtual void CreateSessionResponse (CreateSessionResponseMessage msg);
|
||||
virtual void ModifyBearerResponse (ModifyBearerResponseMessage msg);
|
||||
virtual void DeleteBearerRequest (DeleteBearerRequestMessage msg);
|
||||
|
||||
private:
|
||||
MemberEpcS11SapMme ();
|
||||
@@ -223,6 +282,12 @@ void MemberEpcS11SapMme<C>::CreateSessionResponse (CreateSessionResponseMessage
|
||||
m_owner->DoCreateSessionResponse (msg);
|
||||
}
|
||||
|
||||
template <class C>
|
||||
void MemberEpcS11SapMme<C>::DeleteBearerRequest (DeleteBearerRequestMessage msg)
|
||||
{
|
||||
m_owner->DoDeleteBearerRequest (msg);
|
||||
}
|
||||
|
||||
template <class C>
|
||||
void MemberEpcS11SapMme<C>::ModifyBearerResponse (ModifyBearerResponseMessage msg)
|
||||
{
|
||||
@@ -247,6 +312,8 @@ public:
|
||||
// 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 @@ void MemberEpcS11SapSgw<C>::ModifyBearerRequest (ModifyBearerRequestMessage msg)
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -60,6 +60,24 @@ public:
|
||||
virtual void InitialUeMessage (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, uint64_t stmsi, uint16_t ecgi) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* 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 @@ public:
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -199,6 +219,12 @@ void MemberEpcS1apSapMme<C>::InitialUeMessage (uint64_t mmeUeS1Id, uint16_t enbU
|
||||
m_owner->DoInitialUeMessage (mmeUeS1Id, enbUeS1Id, imsi, ecgi);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -51,6 +51,13 @@ EpcSgwPgwApplication::UeInfo::AddBearer (Ptr<EpcTft> tft, uint8_t bearerId, uint
|
||||
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 @@ EpcSgwPgwApplication::RecvFromTunDevice (Ptr<Packet> packet, const Address& sour
|
||||
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 @@ EpcSgwPgwApplication::SendToS1uSocket (Ptr<Packet> packet, Ipv4Address enbAddr,
|
||||
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 @@ EpcSgwPgwApplication::DoModifyBearerRequest (EpcS11SapSgw::ModifyBearerRequestMe
|
||||
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
|
||||
|
||||
@@ -156,12 +156,16 @@ private:
|
||||
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 @@ private:
|
||||
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
|
||||
|
||||
@@ -544,13 +544,13 @@ LteEnbMac::DoSubframeIndication (uint32_t frameNo, uint32_t subframeNo)
|
||||
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 @@ LteEnbMac::DoSubframeIndication (uint32_t frameNo, uint32_t subframeNo)
|
||||
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 @@ LteEnbMac::DoReceivePhyPdu (Ptr<Packet> p)
|
||||
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 @@ LteEnbMac::DoReconfigureLc (LteEnbCmacSapProvider::LcInfo lcinfo)
|
||||
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 @@ LteEnbMac::DoTransmitPdu (LteMacSapProvider::TransmitPduParameters params)
|
||||
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 @@ LteEnbMac::DoSchedDlConfigInd (FfMacSchedSapUser::SchedDlConfigIndParameters ind
|
||||
{
|
||||
// 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 @@ LteEnbMac::DoSchedDlConfigInd (FfMacSchedSapUser::SchedDlConfigIndParameters ind
|
||||
}
|
||||
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 @@ LteEnbMac::DoDlInfoListElementHarqFeeback (DlInfoListElement_s params)
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -458,14 +458,29 @@ UeManager::ReleaseDataRadioBearer (uint8_t drbid)
|
||||
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,8 +657,17 @@ UeManager::SendData (uint8_t bid, Ptr<Packet> p)
|
||||
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;
|
||||
|
||||
@@ -852,6 +876,11 @@ UeManager::RecvRrcConnectionReconfigurationCompleted (LteRrcSap::RrcConnectionRe
|
||||
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 @@ LteEnbRrc::DoRecvHandoverRequest (EpcX2SapUser::HandoverRequestParams req)
|
||||
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 @@ LteEnbRrc::GetNewSrsConfigurationIndex ()
|
||||
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);
|
||||
|
||||
@@ -686,6 +686,14 @@ public:
|
||||
*/
|
||||
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
|
||||
*
|
||||
|
||||
@@ -297,7 +297,7 @@ LteUeMac::DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters
|
||||
|
||||
|
||||
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 @@ LteUeMac::DoReceiveLteControlMessage (Ptr<LteControlMessage> msg)
|
||||
{
|
||||
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 @@ LteUeMac::DoReceiveLteControlMessage (Ptr<LteControlMessage> msg)
|
||||
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 @@ LteUeMac::DoReceiveLteControlMessage (Ptr<LteControlMessage> msg)
|
||||
}
|
||||
}
|
||||
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 @@ LteUeMac::DoReceiveLteControlMessage (Ptr<LteControlMessage> msg)
|
||||
}
|
||||
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 @@ LteUeMac::DoSubframeIndication (uint32_t frameNo, uint32_t subframeNo)
|
||||
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 ();
|
||||
|
||||
@@ -404,6 +404,8 @@ LteUeRrc::DoSendData (Ptr<Packet> packet, uint8_t bid)
|
||||
|
||||
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 @@ LteUeRrc::DoSendData (Ptr<Packet> packet, uint8_t bid)
|
||||
<< " (LCID " << (uint32_t) params.lcid << ")"
|
||||
<< " (" << packet->GetSize () << " bytes)");
|
||||
it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitPdcpSdu (params);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1250,6 +1253,8 @@ LteUeRrc::ApplyRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedic
|
||||
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 @@ LteUeRrc::ApplyMeasConfig (LteRrcSap::MeasConfig mc)
|
||||
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 @@ LteUeRrc::SaveUeMeasurements (uint16_t cellId, double rsrp, double rsrq,
|
||||
{
|
||||
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 @@ uint8_t
|
||||
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)
|
||||
{
|
||||
|
||||
347
src/lte/test/lte-test-deactivate-bearer.cc
Normal file
347
src/lte/test/lte-test-deactivate-bearer.cc
Normal file
@@ -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 ();
|
||||
}
|
||||
}
|
||||
37
src/lte/test/lte-test-deactivate-bearer.h
Normal file
37
src/lte/test/lte-test-deactivate-bearer.h
Normal file
@@ -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
|
||||
@@ -155,6 +155,7 @@ def build(bld):
|
||||
'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')
|
||||
|
||||
Reference in New Issue
Block a user