Files
unison/examples/wireless/wifi-tcp.cc
2024-09-06 19:32:31 +00:00

202 lines
7.3 KiB
C++

/*
* Copyright (c) 2015, IMDEA Networks Institute
*
* SPDX-License-Identifier: GPL-2.0-only
*
* Author: Hany Assasa <hany.assasa@gmail.com>
.*
* This is a simple example to test TCP over 802.11n (with MPDU aggregation enabled).
*
* Network topology:
*
* Ap STA
* * *
* | |
* n1 n2
*
* In this example, an HT station sends TCP packets to the access point.
* We report the total throughput received during a window of 100ms.
* The user can specify the application data rate and choose the variant
* of TCP i.e. congestion control algorithm to use.
*/
#include "ns3/command-line.h"
#include "ns3/config.h"
#include "ns3/internet-stack-helper.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/log.h"
#include "ns3/mobility-helper.h"
#include "ns3/mobility-model.h"
#include "ns3/on-off-helper.h"
#include "ns3/packet-sink-helper.h"
#include "ns3/packet-sink.h"
#include "ns3/ssid.h"
#include "ns3/string.h"
#include "ns3/tcp-westwood-plus.h"
#include "ns3/yans-wifi-channel.h"
#include "ns3/yans-wifi-helper.h"
NS_LOG_COMPONENT_DEFINE("wifi-tcp");
using namespace ns3;
Ptr<PacketSink> sink; //!< Pointer to the packet sink application
uint64_t lastTotalRx = 0; //!< The value of the last total received bytes
/**
* Calculate the throughput
*/
void
CalculateThroughput()
{
Time now = Simulator::Now(); /* Return the simulator's virtual time. */
double cur = (sink->GetTotalRx() - lastTotalRx) * 8.0 /
1e5; /* Convert Application RX Packets to MBits. */
std::cout << now.GetSeconds() << "s: \t" << cur << " Mbit/s" << std::endl;
lastTotalRx = sink->GetTotalRx();
Simulator::Schedule(MilliSeconds(100), &CalculateThroughput);
}
int
main(int argc, char* argv[])
{
uint32_t payloadSize{1472}; /* Transport layer payload size in bytes. */
DataRate dataRate{"100Mb/s"}; /* Application layer datarate. */
std::string tcpVariant{"TcpNewReno"}; /* TCP variant type. */
std::string phyRate{"HtMcs7"}; /* Physical layer bitrate. */
Time simulationTime{"10s"}; /* Simulation time. */
bool pcapTracing{false}; /* PCAP Tracing is enabled or not. */
/* Command line argument parser setup. */
CommandLine cmd(__FILE__);
cmd.AddValue("payloadSize", "Payload size in bytes", payloadSize);
cmd.AddValue("dataRate", "Application data ate", dataRate);
cmd.AddValue("tcpVariant",
"Transport protocol to use: TcpNewReno, "
"TcpHybla, TcpHighSpeed, TcpHtcp, TcpVegas, TcpScalable, TcpVeno, "
"TcpBic, TcpYeah, TcpIllinois, TcpWestwood, TcpWestwoodPlus, TcpLedbat ",
tcpVariant);
cmd.AddValue("phyRate", "Physical layer bitrate", phyRate);
cmd.AddValue("simulationTime", "Simulation time in seconds", simulationTime);
cmd.AddValue("pcap", "Enable/disable PCAP Tracing", pcapTracing);
cmd.Parse(argc, argv);
tcpVariant = std::string("ns3::") + tcpVariant;
// Select TCP variant
TypeId tcpTid;
NS_ABORT_MSG_UNLESS(TypeId::LookupByNameFailSafe(tcpVariant, &tcpTid),
"TypeId " << tcpVariant << " not found");
Config::SetDefault("ns3::TcpL4Protocol::SocketType",
TypeIdValue(TypeId::LookupByName(tcpVariant)));
/* Configure TCP Options */
Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(payloadSize));
WifiMacHelper wifiMac;
WifiHelper wifiHelper;
wifiHelper.SetStandard(WIFI_STANDARD_80211n);
/* Set up Legacy Channel */
YansWifiChannelHelper wifiChannel;
wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
wifiChannel.AddPropagationLoss("ns3::FriisPropagationLossModel", "Frequency", DoubleValue(5e9));
/* Setup Physical Layer */
YansWifiPhyHelper wifiPhy;
wifiPhy.SetChannel(wifiChannel.Create());
wifiPhy.SetErrorRateModel("ns3::YansErrorRateModel");
wifiHelper.SetRemoteStationManager("ns3::ConstantRateWifiManager",
"DataMode",
StringValue(phyRate),
"ControlMode",
StringValue("HtMcs0"));
NodeContainer networkNodes;
networkNodes.Create(2);
Ptr<Node> apWifiNode = networkNodes.Get(0);
Ptr<Node> staWifiNode = networkNodes.Get(1);
/* Configure AP */
Ssid ssid = Ssid("network");
wifiMac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
NetDeviceContainer apDevice;
apDevice = wifiHelper.Install(wifiPhy, wifiMac, apWifiNode);
/* Configure STA */
wifiMac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
NetDeviceContainer staDevices;
staDevices = wifiHelper.Install(wifiPhy, wifiMac, staWifiNode);
/* Mobility model */
MobilityHelper mobility;
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
positionAlloc->Add(Vector(0.0, 0.0, 0.0));
positionAlloc->Add(Vector(1.0, 1.0, 0.0));
mobility.SetPositionAllocator(positionAlloc);
mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
mobility.Install(apWifiNode);
mobility.Install(staWifiNode);
/* Internet stack */
InternetStackHelper stack;
stack.Install(networkNodes);
Ipv4AddressHelper address;
address.SetBase("10.0.0.0", "255.255.255.0");
Ipv4InterfaceContainer apInterface;
apInterface = address.Assign(apDevice);
Ipv4InterfaceContainer staInterface;
staInterface = address.Assign(staDevices);
/* Populate routing table */
Ipv4GlobalRoutingHelper::PopulateRoutingTables();
/* Install TCP Receiver on the access point */
PacketSinkHelper sinkHelper("ns3::TcpSocketFactory",
InetSocketAddress(Ipv4Address::GetAny(), 9));
ApplicationContainer sinkApp = sinkHelper.Install(apWifiNode);
sink = StaticCast<PacketSink>(sinkApp.Get(0));
/* Install TCP/UDP Transmitter on the station */
OnOffHelper server("ns3::TcpSocketFactory", (InetSocketAddress(apInterface.GetAddress(0), 9)));
server.SetAttribute("PacketSize", UintegerValue(payloadSize));
server.SetAttribute("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1]"));
server.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=0]"));
server.SetAttribute("DataRate", DataRateValue(DataRate(dataRate)));
ApplicationContainer serverApp = server.Install(staWifiNode);
/* Start Applications */
sinkApp.Start(Seconds(0.0));
serverApp.Start(Seconds(1.0));
Simulator::Schedule(Seconds(1.1), &CalculateThroughput);
/* Enable Traces */
if (pcapTracing)
{
wifiPhy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO);
wifiPhy.EnablePcap("AccessPoint", apDevice);
wifiPhy.EnablePcap("Station", staDevices);
}
/* Start Simulation */
Simulator::Stop(simulationTime + Seconds(1.0));
Simulator::Run();
auto averageThroughput =
(static_cast<double>(sink->GetTotalRx() * 8) / simulationTime.GetMicroSeconds());
Simulator::Destroy();
if (averageThroughput < 50)
{
NS_LOG_ERROR("Obtained throughput is not in the expected boundaries!");
exit(1);
}
std::cout << "\nAverage throughput: " << averageThroughput << " Mbit/s" << std::endl;
return 0;
}