#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#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-module.h>
#include "ns3/epc-ue-nas.h"
using namespace ns3;
Ptr <LteHelper> ltehelper = CreateObject<LteHelper>();
Ptr<LteUeRrc> lteuerrc = CreateObject<LteUeRrc>();
NodeContainer enbNodes;
NetDeviceContainer ueDevs,enbDevs;
uint8_t bearerIdForDetach;
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
EpsBearer bearer (q);
static const std::string g_ueRrcStateName[LteUeRrc::NUM_STATES] =
{
"IDLE_START",
"IDLE_CELL_SEARCH",
"IDLE_WAIT_MIB_SIB1",
"IDLE_WAIT_MIB",
"IDLE_WAIT_SIB1",
"IDLE_CAMPED_NORMALLY",
"IDLE_WAIT_SIB2",
"IDLE_RANDOM_ACCESS",
"IDLE_CONNECTING",
"CONNECTED_NORMALLY",
"CONNECTED_HANDOVER",
"CONNECTED_PHY_PROBLEM",
"CONNECTED_REESTABLISHING"
};
static const std::string & ToString (LteUeRrc::State s)
{
return g_ueRrcStateName[s];
}
static void StateTransitionCallback ( std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, LteUeRrc::State oldState, LteUeRrc::State newState)
{
std::cout << " UE IMSI " << imsi
<< " CellId " << cellId
<< " RNTI " << rnti
<< " State changed from: " << ToString(oldState)
<< " to: " << ToString(newState)
<< std::endl;
}
void handler (){
lteuerrc->ReleaseRrcResource ();
ltehelper->Attach (ueDevs.Get (0),enbDevs.Get (0));
}
int main (int argc , char * argv[]){
CommandLine cmd;
cmd.Parse (argc, argv);
double interPacketInterval = 100;
GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
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.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;
ueNodes.Create (1);
enbNodes.Create (2);
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
for (uint16_t i = 1; i <=2; i++)
{
if (i==2){
positionAlloc->Add (Vector(10, 0, 0));
}
else{
positionAlloc->Add (Vector(1000,0,0));
}
mobility.SetPositionAllocator(positionAlloc);
mobility.Install (enbNodes);
}
// positionAlloc->Add (Vector(10, 0, 0));
// mobility.SetPositionAllocator(positionAlloc);
// mobility.Install (enbNodes);
Ptr<ListPositionAllocator> positionAlloc2 = CreateObject<ListPositionAllocator> ();
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
positionAlloc2->Add (Vector(50,0,0));
mobility.SetPositionAllocator (positionAlloc2);
mobility.Install (ueNodes);
// NetDeviceContainer ueDevs,enbDevs;
enbDevs = ltehelper->InstallEnbDevice (enbNodes);
ueDevs = ltehelper->InstallUeDevice (ueNodes);
// Install the IP stack on the UEs
internet.Install (ueNodes);
Ipv4InterfaceContainer ueIpIface;
ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevs));
// 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);
}
ltehelper->Attach (ueDevs.Get (0),enbDevs.Get (0));
bearerIdForDetach = ltehelper->ActivateDedicatedEpsBearer(ueDevs, bearer,EpcTft::Default ());
Ptr <NetDevice> ueDevice = ueDevs.Get(0);
Ptr <LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice>();
lteuerrc = ueLteDevice->GetRrc();
uint16_t dlPort = 1234;
uint16_t ulPort = 2000;
uint16_t otherPort = 3000;
ApplicationContainer clientApps;
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
++ulPort;
++otherPort;
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)));
}
}
clientApps.Start (Seconds(0.01));
clientApps.Stop (Seconds(3));
ltehelper->EnablePhyTraces ();
ltehelper->EnableMacTraces ();
ltehelper->EnableRlcTraces ();
ltehelper->EnablePdcpTraces ();
Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/StateTransition",
MakeCallback(&StateTransitionCallback));
Simulator::Stop (Seconds(20));
Simulator::Schedule(Seconds(5),&handler);
Simulator::Run ();
Simulator::Destroy ();
return 0;
}