A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tgax-virtual-desktop-example.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006,2007 INRIA
3 * Copyright (c) 2016 Magister Solutions
4 * Copyright (c) 2025 Tom Henderson
5 *
6 * SPDX-License-Identifier: GPL-2.0-only
7 *
8 * Borrows from examples/wireless/wifi-ap.cc for overall Wi-Fi network setup pattern
9 * Borrows from src/applications/examples/three-gpp-http-example.cc for overall simulation flow
10 */
11
12/**
13 * @file tgax-virtual-desktop-example.cc
14 * @brief A simple Virtual Desktop Infrastructure (VDI) traffic generator example over Wi-Fi
15 *
16 * This example demonstrates how to set up a basic ns-3 simulation with VDI traffic
17 * over a Wi-Fi network. VDI traffic models remote desktop applications where a server
18 * sends desktop display data to clients.
19 *
20 * The simulation consists of:
21 * - A simple Wi-Fi network with one AP (Access Point) and one STA (Station)
22 * - VDI traffic flowing from the AP (server) to the STA (client) for downlink
23 * - Optional uplink traffic from STA to AP for navigation/feedback
24 * - Application-level tracing to observe VDI packets being sent
25 *
26 * The VDI traffic model follows IEEE 802.11-14/0571r12 TGAX evaluation methodology:
27 * - Packet inter-arrival times follow an exponential distribution
28 * - Packet sizes follow a normal distribution (bimodal for downlink)
29 * - Initial packet arrival is uniformly distributed in [0, 20ms]
30 *
31 * Traffic direction parameters from the specification:
32 * - Downlink (AP to STA): Mean arrival 60.2269ms, bimodal packet size (41/1478 bytes)
33 * - Uplink (STA to AP): Mean arrival 48.2870ms, normal packet size (mean 50.598 bytes)
34 *
35 * To run downlink traffic (default): ./ns3 run tgax-virtual-desktop-example
36 * To run uplink traffic: ./ns3 run "tgax-virtual-desktop-example --direction=uplink"
37 * To run bidirectional: ./ns3 run "tgax-virtual-desktop-example --direction=bidirectional"
38 *
39 * To disable verbose logging: ./ns3 run "tgax-virtual-desktop-example --verbose=false"
40 */
41
42#include "ns3/applications-module.h"
43#include "ns3/core-module.h"
44#include "ns3/internet-module.h"
45#include "ns3/mobility-module.h"
46#include "ns3/network-module.h"
47#include "ns3/wifi-module.h"
48
49using namespace ns3;
50
51NS_LOG_COMPONENT_DEFINE("TgaxVirtualDesktopExample");
52
53/**
54 * Callback invoked when a VDI packet is transmitted
55 * @param context The context string identifying the source
56 * @param packet The transmitted packet
57 */
58void VdiPacketSent(std::string context, Ptr<const Packet> packet);
59
60/**
61 * Callback invoked when the PacketSink receives a packet
62 * @param context The context string
63 * @param packet The received packet
64 * @param address The sender's address
65 */
66void PacketReceived(std::string context, Ptr<const Packet> packet, const Address& address);
67
68int
69main(int argc, char* argv[])
70{
71 Time duration{Seconds(10)}; // Simulation time in seconds
72 std::string direction{"downlink"}; // Traffic direction: downlink, uplink, or bidirectional
73 bool verbose = true; // Enable/disable verbose logging
74
75 CommandLine cmd(__FILE__);
76 cmd.Usage("Virtual Desktop Infrastructure (VDI) traffic example");
77 cmd.AddValue("duration", "Duration of traffic flow, in seconds", duration);
78 cmd.AddValue("direction",
79 "Traffic direction (downlink, uplink, or bidirectional). Default: downlink",
80 direction);
81 cmd.AddValue("verbose",
82 "Enable verbose logging of TgaxVirtualDesktop, PacketSink, and this program",
83 verbose);
84 cmd.Parse(argc, argv);
85
86 if (verbose)
87 {
89 "TgaxVirtualDesktopExample",
92 "TgaxVirtualDesktop",
95 "PacketSink",
97 }
98
99 NodeContainer wifiNodes;
100 wifiNodes.Create(2); // Create 2 nodes: one will be AP, one will be STA
101
102 Ptr<Node> apNode = wifiNodes.Get(0);
103 Ptr<Node> staNode = wifiNodes.Get(1);
104
107 phy.SetChannel(channel.Create());
108
111 wifi.SetStandard(WIFI_STANDARD_80211ax);
112
115
116 // Configure AP
117 Ssid ssid = Ssid("vdi-network");
118 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
119 apDevices = wifi.Install(phy, mac, apNode);
120
121 // Configure STA
122 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
123 staDevices = wifi.Install(phy, mac, staNode);
124
126 mobility.SetPositionAllocator("ns3::GridPositionAllocator",
127 "MinX",
128 DoubleValue(0.0),
129 "MinY",
130 DoubleValue(0.0),
131 "DeltaX",
132 DoubleValue(5.0),
133 "DeltaY",
134 DoubleValue(5.0),
135 "GridWidth",
136 UintegerValue(2),
137 "LayoutType",
138 StringValue("RowFirst"));
139 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
140 mobility.Install(wifiNodes);
141
143 internet.Install(wifiNodes);
144
146 ipv4.SetBase("10.1.1.0", "255.255.255.0");
147
148 NetDeviceContainer allDevices;
149 allDevices.Add(apDevices);
150 allDevices.Add(staDevices);
151 Ipv4InterfaceContainer ipv4Interfaces = ipv4.Assign(allDevices);
152
153 NS_LOG_INFO("AP address: " << ipv4Interfaces.GetAddress(0));
154 NS_LOG_INFO("STA address: " << ipv4Interfaces.GetAddress(1));
155
156 // VDI uses TCP as specified in the standard
157 std::string protocolFactory = "ns3::TcpSocketFactory";
158 uint16_t dlPort = 5000; // Downlink port
159 uint16_t ulPort = 5001; // Uplink port
160
161 ApplicationContainer sourceApps;
162 ApplicationContainer sinkApps;
163
164 // Configure downlink traffic (AP -> STA)
165 if (direction == "downlink" || direction == "bidirectional")
166 {
168 dlSourceHelper.SetAttribute("Protocol", TypeIdValue(TypeId::LookupByName(protocolFactory)));
169
170 // Downlink parameters from IEEE 802.11-14/0571r12:
171 // - Mean inter-arrival: 60.2269 ms
172 // - Packet size: Bimodal Normal (mu1=41.0, sigma1=3.2; mu2=1478.3, sigma2=11.6)
173 // Default attributes already match downlink specification
174
175 Address dlRemoteAddr = InetSocketAddress(ipv4Interfaces.GetAddress(1), dlPort);
176 dlSourceHelper.SetAttribute("Remote", AddressValue(dlRemoteAddr));
177
178 auto dlSourceApp = dlSourceHelper.Install(apNode);
179 dlSourceApp.Start(Seconds(1.0));
180 dlSourceApp.Stop(Seconds(1.0) + duration);
181 sourceApps.Add(dlSourceApp);
182
183 PacketSinkHelper dlSinkHelper(protocolFactory,
185 auto dlSinkApp = dlSinkHelper.Install(staNode);
186 dlSinkApp.Start(Seconds(0.0));
187 dlSinkApp.Stop(Seconds(2.0) + duration);
188 sinkApps.Add(dlSinkApp);
189
190 NS_LOG_INFO("Downlink VDI traffic configured (AP -> STA)");
191 NS_LOG_INFO(" Mean inter-arrival: 60.2269 ms");
192 NS_LOG_INFO(" Packet size: Bimodal Normal (41.0/1478.3 bytes)");
193 }
194
195 // Configure uplink traffic (STA -> AP)
196 if (direction == "uplink" || direction == "bidirectional")
197 {
199 ulSourceHelper.SetAttribute("Protocol", TypeIdValue(TypeId::LookupByName(protocolFactory)));
200
201 // Uplink parameters from IEEE 802.11-14/0571r12:
202 // - Mean inter-arrival: 48.2870 ms
203 // - Packet size: Normal (mu=50.598, sigma=5.0753)
205 "Mean",
206 DoubleValue(48287000.0)); // 48.287 ms in nanoseconds
207 ulSourceHelper.SetAttribute("InterPacketArrivals", PointerValue(ulInterArrival));
208 ulSourceHelper.SetAttribute("ParametersPacketSize", StringValue("50.598 5.0753"));
209
210 Address ulRemoteAddr = InetSocketAddress(ipv4Interfaces.GetAddress(0), ulPort);
211 ulSourceHelper.SetAttribute("Remote", AddressValue(ulRemoteAddr));
212
213 auto ulSourceApp = ulSourceHelper.Install(staNode);
214 ulSourceApp.Start(Seconds(1.0));
215 ulSourceApp.Stop(Seconds(1.0) + duration);
216 sourceApps.Add(ulSourceApp);
217
218 PacketSinkHelper ulSinkHelper(protocolFactory,
220 auto ulSinkApp = ulSinkHelper.Install(apNode);
221 ulSinkApp.Start(Seconds(0.0));
222 ulSinkApp.Stop(Seconds(2.0) + duration);
223 sinkApps.Add(ulSinkApp);
224
225 NS_LOG_INFO("Uplink VDI traffic configured (STA -> AP)");
226 NS_LOG_INFO(" Mean inter-arrival: 48.2870 ms");
227 NS_LOG_INFO(" Packet size: Normal (mean 50.598 bytes)");
228 }
229
230 if (direction != "downlink" && direction != "uplink" && direction != "bidirectional")
231 {
232 NS_FATAL_ERROR("Invalid direction: " << direction
233 << ". Use 'downlink', 'uplink', or 'bidirectional'.");
234 }
235
236 // Connect to VDI TX trace
237 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::TgaxVirtualDesktop/Tx",
239
240 // Connect to RX trace
241 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx",
243
244 NS_LOG_INFO("Starting simulation for traffic duration: " << duration.As(Time::S));
245 NS_LOG_INFO("Traffic direction: " << direction);
246
247 Simulator::Stop(Seconds(2) + duration);
249
250 // Get statistics from packet sink applications
251 for (uint32_t i = 0; i < sinkApps.GetN(); ++i)
252 {
254 if (sink)
255 {
256 uint32_t bytesRx = sink->GetTotalRx();
257 NS_LOG_INFO("Sink " << i << " received: " << bytesRx << " bytes");
258 }
259 }
260
262
263 return 0;
264}
265
266void
267VdiPacketSent(std::string context, Ptr<const Packet> packet)
268{
269 NS_LOG_INFO("VDI TX [" << context << "]: Packet size (bytes): " << packet->GetSize());
270}
271
272void
273PacketReceived(std::string context, Ptr<const Packet> packet, const Address& address)
274{
275 NS_LOG_INFO("Packet RX [" << context << "]: Size(bytes): " << packet->GetSize());
276}
a polymophic address class
Definition address.h:114
AttributeValue implementation for Address.
Definition address.h:329
holds a vector of ns3::Application pointers.
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
uint32_t GetN() const
Get the number of Ptr<Application> stored in this container.
void Add(ApplicationContainer other)
Append the contents of another ApplicationContainer to the end of this container.
A helper to make it easier to instantiate an application on a set of nodes.
Parse command-line arguments.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
static Ipv4Address GetAny()
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
AttributeValue implementation for Pointer.
Definition pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:125
static void Run()
Run the simulation.
Definition simulator.cc:161
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:169
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
AttributeValue implementation for Ssid.
Definition ssid.h:85
Hold variables of type string.
Definition string.h:45
static TypeId GetTypeId()
Get the type ID.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:408
@ S
second
Definition nstime.h:106
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition type-id.cc:870
AttributeValue implementation for TypeId.
Definition type-id.h:649
Hold an unsigned integer type.
Definition uinteger.h:34
helps to create WifiNetDevice objects
create MAC layers for a ns3::WifiNetDevice.
manage and create wifi channel objects for the YANS model.
static YansWifiChannelHelper Default()
Create a channel helper in a default working state.
Make it easy to create and manage PHY objects for the YANS model.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:690
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:970
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:267
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1273
@ WIFI_STANDARD_80211ax
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition log.cc:279
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:605
LogLevel
Logging severity classes and levels.
Definition log.h:86
@ LOG_LEVEL_ALL
Print everything.
Definition log.h:108
@ LOG_PREFIX_FUNC
Prefix all trace prints with function.
Definition log.h:110
@ LOG_PREFIX_TIME
Prefix all trace prints with simulation time.
Definition log.h:111
@ LOG_PREFIX_NODE
Prefix all trace prints with simulation node.
Definition log.h:112
@ LOG_LEVEL_INFO
LOG_INFO and above.
Definition log.h:96
staDevices
Definition third.py:87
ssid
Definition third.py:82
channel
Definition third.py:77
mac
Definition third.py:81
wifi
Definition third.py:84
apDevices
Definition third.py:90
mobility
Definition third.py:92
phy
Definition third.py:78
bool verbose
void PacketReceived(std::string context, Ptr< const Packet > packet, const Address &address)
Callback invoked when the PacketSink receives a packet.
void PacketReceived(std::string context, Ptr< const Packet > packet, const Address &address)
Callback invoked when the PacketSink receives a packet.
void VdiPacketSent(std::string context, Ptr< const Packet > packet)
Callback invoked when a VDI packet is transmitted.
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition wifi-tcp.cc:44