diff --git a/examples/wireless/examples-to-run.py b/examples/wireless/examples-to-run.py index 7f5930b76..859d5567b 100755 --- a/examples/wireless/examples-to-run.py +++ b/examples/wireless/examples-to-run.py @@ -31,6 +31,7 @@ cpp_examples = [ ("ofdm-validation", "True", "True"), ("ofdm-vht-validation", "True", "True"), ("mixed-bg-network", "True", "True"), + ("wifi-tcp", "True", "True"), ] # A list of Python examples to run in order to ensure that they remain diff --git a/examples/wireless/wifi-tcp.cc b/examples/wireless/wifi-tcp.cc new file mode 100644 index 000000000..92bfb3219 --- /dev/null +++ b/examples/wireless/wifi-tcp.cc @@ -0,0 +1,197 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2015, IMDEA Networks Institute + * + * 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: Hany Assasa +.* + * 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/applications-module.h" +#include "ns3/core-module.h" +#include "ns3/internet-module.h" +#include "ns3/mobility-module.h" +#include "ns3/network-module.h" +#include "ns3/point-to-point-module.h" +#include "ns3/wifi-module.h" + +NS_LOG_COMPONENT_DEFINE ("wifi-tcp"); + +using namespace ns3; + +Ptr sink; /* Pointer to the packet sink application */ +uint64_t lastTotalRx = 0; /* The value of the last total received bytes */ + +void +CalculateThroughput () +{ + Time now = Simulator::Now (); /* Return the simulator's virtual time. */ + double cur = (sink->GetTotalRx() - lastTotalRx) * (double) 8/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. */ + std::string dataRate = "100Mbps"; /* Application layer datarate. */ + std::string tcpVariant = "ns3::TcpNewReno"; /* TCP variant type. */ + std::string phyRate = "HtMcs7"; /* Physical layer bitrate. */ + double simulationTime = 10; /* Simulation time in seconds. */ + bool pcapTracing = false; /* PCAP Tracing is enabled or not. */ + + /* Command line argument parser setup. */ + CommandLine cmd; + cmd.AddValue ("payloadSize", "Payload size in bytes", payloadSize); + cmd.AddValue ("dataRate", "Application data ate", dataRate); + cmd.AddValue ("tcpVariant", "Transport protocol to use: TcpTahoe, TcpReno, TcpNewReno, TcpWestwood, TcpWestwoodPlus ", 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); + + /* No fragmentation and no RTS/CTS */ + Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("999999")); + Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("999999")); + + /* Configure TCP Options */ + Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (payloadSize)); + + WifiMacHelper wifiMac; + WifiHelper wifiHelper; + wifiHelper.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ); + + /* Set up Legacy Channel */ + YansWifiChannelHelper wifiChannel ; + wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel"); + wifiChannel.AddPropagationLoss ("ns3::FriisPropagationLossModel", "Frequency", DoubleValue (5e9)); + + /* Setup Physical Layer */ + YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default (); + wifiPhy.SetChannel (wifiChannel.Create ()); + wifiPhy.Set ("TxPowerStart", DoubleValue (10.0)); + wifiPhy.Set ("TxPowerEnd", DoubleValue (10.0)); + wifiPhy.Set ("TxPowerLevels", UintegerValue (1)); + wifiPhy.Set ("TxGain", DoubleValue (0)); + wifiPhy.Set ("RxGain", DoubleValue (0)); + wifiPhy.Set ("RxNoiseFigure", DoubleValue (10)); + wifiPhy.Set ("CcaMode1Threshold", DoubleValue (-79)); + wifiPhy.Set ("EnergyDetectionThreshold", DoubleValue (-79 + 3)); + wifiPhy.SetErrorRateModel ("ns3::YansErrorRateModel"); + wifiHelper.SetRemoteStationManager ("ns3::ConstantRateWifiManager", + "DataMode", StringValue (phyRate), + "ControlMode", StringValue ("HtMcs0")); + + NodeContainer networkNodes; + networkNodes.Create (2); + Ptr apWifiNode = networkNodes.Get (0); + Ptr 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), + "ActiveProbing", BooleanValue (false)); + + NetDeviceContainer staDevices; + staDevices = wifiHelper.Install (wifiPhy, wifiMac, staWifiNode); + + /* Mobility model */ + MobilityHelper mobility; + Ptr positionAlloc = CreateObject (); + 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 (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 (YansWifiPhyHelper::DLT_IEEE802_11_RADIO); + wifiPhy.EnablePcap ("AccessPoint", apDevice); + wifiPhy.EnablePcap ("Station", staDevices); + } + + /* Start Simulation */ + Simulator::Stop (Seconds (simulationTime + 1)); + Simulator::Run (); + Simulator::Destroy (); + + double averageThroughput = ((sink->GetTotalRx() * 8) / (1e6 * simulationTime)); + if (averageThroughput < 50) + { + NS_LOG_ERROR ("Obtained throughput is not in the expected boundaries!"); + exit (1); + } + std::cout << "\nAverage throughtput: " << averageThroughput << " Mbit/s" << std::endl; + return 0; +} diff --git a/examples/wireless/wscript b/examples/wireless/wscript index e51e99984..e106238c3 100644 --- a/examples/wireless/wscript +++ b/examples/wireless/wscript @@ -84,3 +84,6 @@ def build(bld): obj = bld.create_ns3_program('mixed-bg-network', ['internet', 'mobility', 'wifi', 'applications']) obj.source = 'mixed-bg-network.cc' + + obj = bld.create_ns3_program('wifi-tcp', ['internet', 'mobility', 'wifi', 'applications']) + obj.source = 'wifi-tcp.cc'