added release bearer functionality

This commit is contained in:
Gaurav Sathe
2014-11-27 16:01:05 +01:00
parent e6fc8c2ad2
commit 07a422bf86
25 changed files with 1081 additions and 58 deletions

View File

@@ -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)

View File

@@ -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
----------

View File

@@ -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):

View 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;
}

View File

@@ -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'

View File

@@ -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

View File

@@ -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;

View File

@@ -26,8 +26,7 @@
#include <vector>
#include <algorithm>
namespace ns3
{
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("RadioBearerStatsCalculator");

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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
*

View File

@@ -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);
}

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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
*

View File

@@ -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 ();

View File

@@ -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)
{

View 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 ();
}
}

View 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

View File

@@ -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')