A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tgax-virtual-desktop.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 DERONNE SOFTWARE ENGINEERING
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
7 */
8
10
11#include "ns3/attribute-container.h"
12#include "ns3/double.h"
13#include "ns3/enum.h"
14#include "ns3/inet-socket-address.h"
15#include "ns3/inet6-socket-address.h"
16#include "ns3/log.h"
17#include "ns3/node.h"
18#include "ns3/nstime.h"
19#include "ns3/packet-socket-address.h"
20#include "ns3/packet.h"
21#include "ns3/pair.h"
22#include "ns3/pointer.h"
23#include "ns3/random-variable-stream.h"
24#include "ns3/simulator.h"
25#include "ns3/socket-factory.h"
26#include "ns3/socket.h"
27#include "ns3/string.h"
28
29#include <cmath>
30
31namespace ns3
32{
33
34NS_LOG_COMPONENT_DEFINE("TgaxVirtualDesktop");
35
37
40{
41 static TypeId tid =
42 TypeId("ns3::TgaxVirtualDesktop")
44 .SetGroupName("Applications")
45 .AddConstructor<TgaxVirtualDesktop>()
46 .AddAttribute("ModelPresets",
47 "The model presets to use (Custom for custom settings)",
49 TypeId::ATTR_CONSTRUCT, // prevent setting after construction
53 "Custom",
55 "Downlink",
57 "Uplink"))
58 .AddAttribute(
59 "Protocol",
60 "The type of protocol to use. This should be a subclass of ns3::SocketFactory",
61 TypeIdValue(TypeId::LookupByName("ns3::TcpSocketFactory")),
64 .AddAttribute(
65 "CustomInitialPacketArrival",
66 "A uniform random variable to generate the initial packet arrival in nanoseconds.",
67 StringValue("ns3::UniformRandomVariable[Min=0|Max=20000000]"),
70 .AddAttribute("CustomInterPacketArrivals",
71 "An exponential random variable to generate the inter packet arrivals in "
72 "nanoseconds.",
73 StringValue("ns3::ExponentialRandomVariable[Mean=60226900]"),
76 .AddAttribute(
77 "CustomParametersPacketSize",
78 "The mean value and standard deviation for each mode of the multimodal normal "
79 "distribution used to calculate packet sizes.",
80 StringValue("41.0 3.2;1478.3 11.6"),
86 return tid;
87}
88
93
98
99int64_t
101{
102 NS_LOG_FUNCTION(this << stream);
103 auto currentStream = stream;
104 m_initialArrivalUniform->SetStream(currentStream++);
105 m_interArrivalExponential->SetStream(currentStream++);
106 if (m_pktSizeDistributions.size() > 1)
107 {
108 m_dlModeSelection->SetStream(currentStream++);
109 }
110 for (auto& pktSizeDistribution : m_pktSizeDistributions)
111 {
112 pktSizeDistribution->SetStream(currentStream++);
113 }
114 return (currentStream - stream);
115}
116
117void
118TgaxVirtualDesktop::SetParametersPacketSize(const std::vector<std::pair<double, double>>& params)
119{
121 NS_LOG_FUNCTION(this << params.size());
122 for (const auto& [mean, std] : params)
123 {
125 normal->SetAttribute("Mean", DoubleValue(mean));
126 normal->SetAttribute("Variance", DoubleValue(std::pow(std, 2)));
128 }
129 if ((m_pktSizeDistributions.size() > 1) && !m_dlModeSelection)
130 {
133 DoubleValue(22.4 / 76.1));
134 }
135}
136
137void
139{
140 NS_LOG_FUNCTION(this);
142
144 {
145 std::vector<std::pair<double, double>> params;
147 {
148 // Downlink model presets
149 params = {{41.0, 3.2}, {1478.3, 11.6}};
150 m_initialArrivalUniform->SetAttribute("Min", DoubleValue(0.0));
151 m_initialArrivalUniform->SetAttribute("Max", DoubleValue(20000000.0));
152 m_interArrivalExponential->SetAttribute("Mean", DoubleValue(60226900.0));
153 }
155 {
156 // Uplink model presets
157 params = {{50.598, 5.0753}};
158 m_initialArrivalUniform->SetAttribute("Min", DoubleValue(0.0));
159 m_initialArrivalUniform->SetAttribute("Max", DoubleValue(20000000.0));
160 m_interArrivalExponential->SetAttribute("Mean", DoubleValue(48287000.0));
161 }
163 }
164}
165
166void
168{
169 NS_LOG_FUNCTION(this);
170
171 m_socket->SetDataSentCallback(MakeCallback(&TgaxVirtualDesktop::TxDone, this));
172 m_socket->SetSendCallback(MakeCallback(&TgaxVirtualDesktop::TxAvailable, this));
173 m_socket->SetAllowBroadcast(true);
174 m_socket->ShutdownRecv();
175
176 if (m_connected)
177 {
178 ScheduleNext();
179 }
180}
181
182void
184{
185 NS_LOG_FUNCTION(this);
186 m_txEvent.Cancel();
187 if (m_unsentPacket)
188 {
189 NS_LOG_DEBUG("Discarding cached packet upon CancelEvents ()");
190 }
191 m_unsentPacket = nullptr;
192 m_initialPacket = true;
193}
194
195Time
197{
198 if (m_unsentPacket)
199 {
200 return Time();
201 }
202 if (m_initialPacket)
203 {
204 return NanoSeconds(m_initialArrivalUniform->GetValue());
205 }
206 return NanoSeconds(m_interArrivalExponential->GetValue());
207}
208
211{
212 const auto mode = (m_pktSizeDistributions.size() > 1) ? m_dlModeSelection->GetValue() : 0;
213 return m_pktSizeDistributions.at(mode)->GetValue();
214}
215
216void
223
224void
226{
227 NS_LOG_FUNCTION(this);
228
229 NS_ASSERT(m_txEvent.IsExpired());
230
231 Ptr<Packet> packet;
232 if (m_unsentPacket)
233 {
234 packet = m_unsentPacket;
235 }
236 else
237 {
238 packet = Create<Packet>(GetPacketSize());
239 }
240
241 unsigned int actualSize = m_socket->Send(packet);
242 if (actualSize == packet->GetSize())
243 {
244 m_txTrace(packet);
245 m_unsentPacket = nullptr;
246 Address localAddress;
247 m_socket->GetSockName(localAddress);
249 {
250 NS_LOG_INFO("At time " << Simulator::Now().As(Time::S) << " VDI traffic source sent "
251 << (m_initialPacket ? "initial packet of " : "packet of ")
252 << packet->GetSize() << " bytes to "
253 << InetSocketAddress::ConvertFrom(m_peer).GetIpv4() << " port "
255 }
257 {
258 NS_LOG_INFO("At time " << Simulator::Now().As(Time::S) << " VDI traffic source sent "
259 << (m_initialPacket ? "initial packet of " : "packet of ")
260 << packet->GetSize() << " bytes to "
261 << Inet6SocketAddress::ConvertFrom(m_peer).GetIpv6() << " port "
263 }
264 }
265 else
266 {
267 NS_LOG_DEBUG("Unable to send VDI packet; actual " << actualSize << " size "
268 << packet->GetSize()
269 << "; caching for later attempt");
270 m_unsentPacket = packet;
271 }
272
273 if (m_initialPacket)
274 {
275 m_initialPacket = false;
276 }
277
278 ScheduleNext();
279}
280
281void
287
288void
290{
291 NS_LOG_FUNCTION(this << socket << size);
292 if (m_unsentPacket)
293 {
294 ScheduleNext();
295 }
296}
297
298void
300{
301 NS_LOG_FUNCTION(this << socket << available);
302 if (m_unsentPacket)
303 {
304 ScheduleNext();
305 }
306}
307
308} // Namespace ns3
a polymophic address class
Definition address.h:114
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
Hold variables of type enum.
Definition enum.h:52
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
static bool IsMatchingType(const Address &addr)
If the address match.
static bool IsMatchingType(const Address &address)
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
virtual void DoInitialize()
Initialize() implementation.
Definition object.cc:437
AttributeValue implementation for Pair.
Definition pair.h:54
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:580
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:191
TypeId m_protocolTid
Protocol TypeId value.
SourceApplication(bool allowPacketSocket=true)
Constructor.
Ptr< Socket > m_socket
Socket.
TracedCallback< Ptr< const Packet > > m_txTrace
Traced Callback: transmitted packets.
bool m_connected
flag whether socket is connected
Address m_peer
Peer address.
Hold variables of type string.
Definition string.h:45
Generate Virtual Desktop Infrastructure (VDI) traffic.
EventId m_txEvent
Event id of pending TX event.
Ptr< Packet > m_unsentPacket
Unsent packet cached for future attempt.
void TxDone(Ptr< Socket > socket, uint32_t size)
Handle a Data Sent event.
void SendPacket()
Transmit the next VDI packet.
std::vector< Ptr< NormalRandomVariable > > m_pktSizeDistributions
Single or multi modal normal random variables to generate packet sizes in bytes.
void DoStartApplication() override
Application specific startup code for child subclasses.
Ptr< ExponentialRandomVariable > m_interArrivalExponential
Exponential random variable to generate packet arrival times in nanoseconds.
uint32_t GetPacketSize() const
Get the size in bytes of the next VDI packet to send.
void SetParametersPacketSize(const std::vector< std::pair< double, double > > &params)
Set the parameters of the normal random variable used to generate the VDI packet sizes.
ModelPresets m_modelPresets
Model presets to use to configure the VDI traffic model parameters.
Ptr< UniformRandomVariable > m_initialArrivalUniform
Uniform random variable to generate initial packet arrival in nanoseconds.
void ScheduleNext()
Schedule the next TX.
void TxAvailable(Ptr< Socket > socket, uint32_t available)
Handle a Send event.
void DoConnectionSucceeded(Ptr< Socket > socket) override
Application specific code for child subclasses upon a Connection Succeed event.
static TypeId GetTypeId()
Get the type ID.
void CancelEvents() override
Cancel all pending events.
int64_t AssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this Application object.
Time GetInterArrival() const
Get the duration to use to schedule the TX of the next VDI packet.
Ptr< BernoulliRandomVariable > m_dlModeSelection
Uniform random variable to select mode for downlink bimodal distribution.
bool m_initialPacket
True if the next packet to send is the initial packet.
void DoInitialize() override
Initialize() implementation.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
@ S
second
Definition nstime.h:106
a unique identifier for an interface.
Definition type-id.h:50
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition type-id.cc:870
@ ATTR_GET
The attribute can be read.
Definition type-id.h:55
@ ATTR_CONSTRUCT
The attribute can be written at construction-time.
Definition type-id.h:57
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
AttributeValue implementation for TypeId.
Definition type-id.h:649
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
Ptr< AttributeChecker > MakeAttributeContainerChecker(const AttributeContainerValue< A, Sep, C > &value)
Make AttributeContainerChecker from AttributeContainerValue.
Ptr< const AttributeAccessor > MakeAttributeContainerAccessor(T1 a1)
Make AttributeContainerAccessor using explicit types.
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition enum.h:223
Ptr< AttributeChecker > MakePairChecker(const PairValue< A, B > &value)
Make a PairChecker from a PairValue.
Definition pair.h:272
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition pointer.h:250
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:273
Ptr< const AttributeChecker > MakeTypeIdChecker()
Definition type-id.cc:1333
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition type-id.h:649
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
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:260
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:267
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:627
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:454
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1324
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition enum.h:181
STL namespace.