Description
Hello,
I am currently working on a project involving mmWave UDP throughput testing using the ns-3 simulator. I have used the mmWave module from your repository and adapted it to create a simple simulation scenario. However, I am encountering an issue where the throughput result is always zero.
Below is the code I am using for the simulation:
#include "ns3/applications-module.h"
#include "ns3/config-store.h"
#include "ns3/core-module.h"
#include "ns3/global-route-manager.h"
#include "ns3/internet-module.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/log.h"
#include "ns3/mobility-module.h"
#include "ns3/network-module.h"
#include <ns3/buildings-helper.h>
#include "ns3/point-to-point-helper.h"
#include "ns3/mmwave-helper.h"
#include "ns3/mmwave-point-to-point-epc-helper.h"
using namespace ns3;
using namespace mmwave;
class UdpServerApp : public Application {
public:
UdpServerApp();
virtual ~UdpServerApp();
void Setup(Address address);
uint32_t GetTotalRx() const;
private:
virtual void StartApplication(void);
virtual void StopApplication(void);
void HandleRead(Ptr<Socket> socket);
Ptr<Socket> m_socket;
Address m_local;
uint32_t m_totalRx;
};
UdpServerApp::UdpServerApp()
: m_socket(0),
m_totalRx(0) {}
UdpServerApp::~UdpServerApp() {
m_socket = 0;
}
void UdpServerApp::Setup(Address address) {
m_local = address;
}
uint32_t UdpServerApp::GetTotalRx() const {
return m_totalRx;
}
void UdpServerApp::StartApplication(void) {
if (!m_socket) {
m_socket = Socket::CreateSocket(GetNode(), UdpSocketFactory::GetTypeId());
m_socket->Bind(m_local);
m_socket->SetRecvCallback(MakeCallback(&UdpServerApp::HandleRead, this));
}
}
void UdpServerApp::StopApplication(void) {
if (m_socket) {
m_socket->Close();
}
}
void UdpServerApp::HandleRead(Ptr socket) {
Ptr packet;
Address from;
while ((packet = socket->RecvFrom(from))) {
m_totalRx += packet->GetSize();
}
}
class UdpClientApp : public Application {
public:
UdpClientApp();
virtual ~UdpClientApp();
void Setup(Address address, uint32_t packetSize, uint32_t nPackets, Time interPacketInterval);
private:
virtual void StartApplication(void);
virtual void StopApplication(void);
void ScheduleTx(void);
void SendPacket(void);
Ptr<Socket> m_socket;
Address m_peer;
uint32_t m_packetSize;
uint32_t m_nPackets;
Time m_interval;
EventId m_sendEvent;
bool m_running;
uint32_t m_packetsSent;
};
UdpClientApp::UdpClientApp()
: m_socket(0),
m_packetSize(0),
m_nPackets(0),
m_interval(Seconds(0)),
m_running(false),
m_packetsSent(0) {}
UdpClientApp::~UdpClientApp() {
m_socket = 0;
}
void UdpClientApp::Setup(Address address, uint32_t packetSize, uint32_t nPackets, Time interPacketInterval) {
m_peer = address;
m_packetSize = packetSize;
m_nPackets = nPackets;
m_interval = interPacketInterval;
}
void UdpClientApp::StartApplication(void) {
m_running = true;
m_packetsSent = 0;
m_socket = Socket::CreateSocket(GetNode(), UdpSocketFactory::GetTypeId());
m_socket->Connect(m_peer);
SendPacket();
}
void UdpClientApp::StopApplication(void) {
m_running = false;
if (m_sendEvent.IsRunning()) {
Simulator::Cancel(m_sendEvent);
}
if (m_socket) {
m_socket->Close();
}
}
void UdpClientApp::SendPacket(void) {
Ptr packet = Create(m_packetSize);
m_socket->Send(packet);
if (++m_packetsSent < m_nPackets) {
ScheduleTx();
}
}
void UdpClientApp::ScheduleTx(void) {
if (m_running) {
m_sendEvent = Simulator::Schedule(m_interval, &UdpClientApp::SendPacket, this);
}
}
int main(int argc, char *argv[]) {
uint16_t numberOfNodes = 1;
double simTime = 60.0;
double interPacketInterval = 100;
CommandLine cmd;
cmd.AddValue("numberOfNodes", "Number of eNodeBs + UE pairs", numberOfNodes);
cmd.AddValue("simTime", "Total duration of the simulation", simTime);
cmd.AddValue("interPacketInterval", "Inter packet interval in milliseconds", interPacketInterval);
cmd.Parse(argc, argv);
Config::SetDefault("ns3::UdpClient::Interval", TimeValue(MilliSeconds(interPacketInterval)));
Config::SetDefault("ns3::UdpClient::MaxPackets", UintegerValue(1000000));
Ptr<MmWaveHelper> mmwaveHelper = CreateObject<MmWaveHelper>();
Ptr<MmWavePointToPointEpcHelper> epcHelper = CreateObject<MmWavePointToPointEpcHelper>();
mmwaveHelper->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);
PointToPointHelper p2ph;
p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
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);
Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress(1);
// Create a single UE
NodeContainer ueNodes;
NodeContainer enbNodes;
enbNodes.Create(numberOfNodes);
ueNodes.Create(numberOfNodes);
// Install Mobility Model
MobilityHelper mobility;
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Position for the eNodeB
positionAlloc->Add(Vector(20.0, 0.0, 0.0)); // Position for the UE
mobility.SetPositionAllocator(positionAlloc);
mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
mobility.Install(enbNodes);
mobility.Install(ueNodes);
NetDeviceContainer enbDevs = mmwaveHelper->InstallEnbDevice(enbNodes);
NetDeviceContainer ueDevs = mmwaveHelper->InstallUeDevice(ueNodes);
// Install the IP stack on the UEs
internet.Install(ueNodes);
Ipv4InterfaceContainer ueIpIface;
ueIpIface = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueDevs));
// Attach one UE per eNodeB
for (uint16_t i = 0; i < numberOfNodes; i++) {
mmwaveHelper->AttachToClosestEnb(ueDevs.Get(i), enbDevs);
}
// Set up the application to send and receive UDP packets
uint16_t dlPort = 1234;
Address serverAddress(InetSocketAddress(Ipv4Address::GetAny(), dlPort));
Ptr<UdpServerApp> serverApp = CreateObject<UdpServerApp>();
serverApp->Setup(serverAddress);
ueNodes.Get(0)->AddApplication(serverApp);
serverApp->SetStartTime(Seconds(0.01));
serverApp->SetStopTime(Seconds(simTime + 1));
Address clientAddress(InetSocketAddress(ueIpIface.GetAddress(0), dlPort));
Ptr<UdpClientApp> clientApp = CreateObject<UdpClientApp>();
clientApp->Setup(clientAddress, 1024, 1000000, MilliSeconds(interPacketInterval));
remoteHost->AddApplication(clientApp);
clientApp->SetStartTime(Seconds(0.01));
clientApp->SetStopTime(Seconds(simTime + 1));
mmwaveHelper->EnableTraces();
Simulator::Stop(Seconds(simTime + 1));
Simulator::Run();
Simulator::Destroy();
uint32_t totalPacketsThrough = serverApp->GetTotalRx();
double throughput = totalPacketsThrough * 8 / (simTime * 1000000.0); // Mbit/s
std::cout << "Throughput: " << throughput << " Mbit/s" << std::endl;
return 0;
}
I have also added additional logging to track packet sending and receiving, but I am still not seeing any throughput. Here are a few things I've already checked:
Connection Issues: Ensured that the UE is properly attached to the eNodeB and the IP address assignment is correct.
Application Start/Stop Times: Verified that the start and stop times for both the client and server applications are correctly set and overlap with the simulation time.
Packet Loss: Checked if packets are being dropped due to buffer overflows or any other reasons.
Traces and Logs: Enabled additional tracing and logging to see where the packets might be getting lost or if the applications are functioning correctly.
UDP Socket Binding: Ensured that the server application is properly binding to the correct address and port.
I would greatly appreciate any insights or suggestions on how to resolve this issue. Thank you in advance for your help!