A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tgax-video-traffic.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/double.h"
12#include "ns3/enum.h"
13#include "ns3/inet-socket-address.h"
14#include "ns3/inet6-socket-address.h"
15#include "ns3/log.h"
16#include "ns3/node.h"
17#include "ns3/nstime.h"
18#include "ns3/packet-socket-address.h"
19#include "ns3/packet.h"
20#include "ns3/random-variable-stream.h"
21#include "ns3/simulator.h"
22#include "ns3/socket-factory.h"
23#include "ns3/socket.h"
24#include "ns3/tcp-socket-factory.h"
25#include "ns3/udp-socket-factory.h"
26#include "ns3/uinteger.h"
27
28#include <limits>
29
30namespace ns3
31{
32
33NS_LOG_COMPONENT_DEFINE("TgaxVideoTraffic");
34
36
37// clang-format off
39 {
40 {TrafficModelClassIdentifier::BUFFERED_VIDEO_1, {{"2Mbps"}, 6950, 0.8099}},
41 {TrafficModelClassIdentifier::BUFFERED_VIDEO_2, {{"4Mbps"}, 13900, 0.8099}},
42 {TrafficModelClassIdentifier::BUFFERED_VIDEO_3, {{"6Mbps"}, 20850, 0.8099}},
43 {TrafficModelClassIdentifier::BUFFERED_VIDEO_4, {{"8Mbps"}, 27800, 0.8099}},
44 {TrafficModelClassIdentifier::BUFFERED_VIDEO_5, {{"10Mbps"}, 34750, 0.8099}},
45 {TrafficModelClassIdentifier::BUFFERED_VIDEO_6, {{"15600Kbps"}, 54210, 0.8099}},
46 {TrafficModelClassIdentifier::MULTICAST_VIDEO_1, {{"3Mbps"}, 10425, 0.8099}},
47 {TrafficModelClassIdentifier::MULTICAST_VIDEO_2, {{"6Mbps"}, 20850, 0.8099}}
48 }
49};
50
51// clang-format on
52
55{
56 static TypeId tid =
57 TypeId("ns3::TgaxVideoTraffic")
59 .SetGroupName("Applications")
60 .AddConstructor<TgaxVideoTraffic>()
61 .AddAttribute(
62 "TrafficModelClassIdentifier",
63 "The Traffic Model Class Identifier to use (use Custom for custom settings)",
64 TypeId::ATTR_GET | TypeId::ATTR_CONSTRUCT, // prevent setting after construction
69 "Custom",
71 "BV1",
73 "BV2",
75 "BV3",
77 "BV4",
79 "BV5",
81 "BV6",
83 "MC1",
85 "MC2"))
86 .AddAttribute(
87 "Protocol",
88 "The type of protocol to use. This should be a subclass of ns3::SocketFactory",
89 TypeId::ATTR_GET | TypeId::ATTR_CONSTRUCT, // prevent setting after construction
93 .AddAttribute("CustomVideoBitRate",
94 "The video bit rate (if TrafficModelClassIdentifier is Custom).",
96 TypeId::ATTR_CONSTRUCT, // prevent setting after construction
97 DataRateValue(DataRate("2Mbps")),
100 .AddAttribute("CustomFrameSizeScale",
101 "Scale parameter for the Weibull distribution to calculate the video "
102 "frame size in bytes (if TrafficModelClassIdentifier is Custom).",
104 TypeId::ATTR_CONSTRUCT, // prevent setting after construction
105 DoubleValue(6950),
108 .AddAttribute("CustomFrameSizeShape",
109 "Shape parameter for the Weibull distribution to calculate the video "
110 "frame size in bytes (if TrafficModelClassIdentifier is Custom).",
112 TypeId::ATTR_CONSTRUCT, // prevent setting after construction
113 DoubleValue(0.8099),
116 .AddAttribute("LatencyShape",
117 "Shape parameter for the Gamma distribution to calculate the network "
118 "latency in milliseconds.",
120 TypeId::ATTR_CONSTRUCT, // prevent setting after construction
121 DoubleValue(0.2463),
124 .AddAttribute("LatencyScale",
125 "Rate parameter for the Gamma distribution to calculate the network "
126 "latency in milliseconds. If set to 0 (default), no latency is added."
127 "In the reference model, this is set to 60.227ms because it uses a link "
128 "simulator that doesn't actually have queues and TCP models.",
130 TypeId::ATTR_CONSTRUCT, // prevent setting after construction
131 DoubleValue(0),
134 .AddTraceSource(
135 "TxWithLatency",
136 "A video packet is sent, this trace also reports the latency applied to the packet",
138 "ns3::TgaxVideoTraffic::TxTracedCallback")
139 .AddTraceSource("VideoFrameGenerated",
140 "A video frame is generated, this trace reports the amount of payload "
141 "bytes in the generated frame",
143 "ns3::TracedValueCallback::Uint32");
144 return tid;
145}
146
153
158
159int64_t
161{
162 NS_LOG_FUNCTION(this << stream);
163 auto currentStream = stream;
164 m_frameSizeBytes->SetStream(currentStream++);
165 m_latencyMs->SetStream(currentStream++);
166 return (currentStream - stream);
167}
168
169void
171{
172 NS_LOG_FUNCTION(this);
174
176 {
177 const auto it = m_trafficModels.find(m_trafficModelClassId);
178 NS_ASSERT(it != m_trafficModels.cend());
183 "Cannot use TCP protocol with multicast video traffic model");
184 m_bitRate = it->second.bitRate;
185 m_frameSizeBytesScale = it->second.frameSizeBytesScale;
186 m_frameSizeBytesShape = it->second.frameSizeBytesShape;
187 }
188
189 m_frameSizeBytes->SetAttribute("Scale", DoubleValue(m_frameSizeBytesScale));
190 m_frameSizeBytes->SetAttribute("Shape", DoubleValue(m_frameSizeBytesShape));
191 m_latencyMs->SetAttribute("Alpha", DoubleValue(m_latencyMsScale));
192 m_latencyMs->SetAttribute("Beta", DoubleValue(m_latencyMsShape));
193
194 auto averageFrameSize = static_cast<uint32_t>(m_frameSizeBytes->GetMean());
195 m_interArrival = m_bitRate.CalculateBytesTxTime(averageFrameSize);
196}
197
198void
200{
201 NS_LOG_FUNCTION(this);
202
204 {
205 UintegerValue uintegerValue;
206 m_socket->GetAttribute("SegmentSize", uintegerValue);
207 m_maxSize = uintegerValue.Get();
208 }
209
210 m_socket->SetDataSentCallback(MakeCallback(&TgaxVideoTraffic::TxDone, this));
211 m_socket->SetSendCallback(MakeCallback(&TgaxVideoTraffic::TxAvailable, this));
212 m_socket->SetAllowBroadcast(true);
213 m_socket->ShutdownRecv();
214
215 if (m_connected)
216 {
218 }
219}
220
221void
223{
224 NS_LOG_FUNCTION(this);
225 m_generateFrameEvent.Cancel();
226 for (auto& sendEvent : m_sendEvents)
227 {
228 sendEvent.second.Cancel();
229 }
230 m_sendEvents.clear();
231 m_unsentPackets.clear();
232}
233
234void
243
244void
246{
247 NS_LOG_FUNCTION(this);
248
249 uint32_t frameSize{0};
250 while (frameSize == 0)
251 {
252 frameSize = static_cast<uint32_t>(m_frameSizeBytes->GetValue());
253 }
254
255 m_frameGeneratedTrace(frameSize);
256 m_generatedFrames.push_back(frameSize);
257
259
261}
262
265{
266 auto frameSize = m_remainingSize;
267 if (frameSize == 0)
268 {
270 frameSize = m_generatedFrames.front();
271 m_generatedFrames.pop_front();
272 }
273
274 if (const auto limit = m_maxSize.value_or(m_socket->GetTxAvailable()); frameSize > limit)
275 {
276 m_remainingSize = frameSize - limit;
277 frameSize = limit;
278 }
279 else
280 {
281 m_remainingSize = 0;
282 }
283
284 return frameSize;
285}
286
287void
289{
290 NS_LOG_FUNCTION(this);
291
292 auto size = GetNextPayloadSize();
293 NS_ASSERT(size > 0);
294
295 auto latency{Time::FromDouble(m_latencyMs->GetValue(), Time::MS)};
296 NS_LOG_INFO("At time " << Simulator::Now().As(Time::S)
297 << " video traffic source schedule to sent " << size
298 << " bytes after latency of " << latency.As(Time::US));
299
301 Simulator::Schedule(latency, &TgaxVideoTraffic::Send, this, m_nextEventId, size, latency);
303}
304
305void
306TgaxVideoTraffic::Send(uint64_t eventId, uint32_t size, Time latency)
307{
308 NS_LOG_FUNCTION(this << eventId << size << latency << m_unsentPackets.size());
309
310 auto it = m_sendEvents.find(eventId);
311 NS_ASSERT(it != m_sendEvents.end());
312 NS_ASSERT(it->second.IsExpired());
313
314 auto packet = m_unsentPackets.empty() ? Create<Packet>(size) : m_unsentPackets.front().packet;
315 const auto actual = static_cast<unsigned int>(m_socket->Send(packet));
316 if (actual == size)
317 {
318 if (!m_unsentPackets.empty())
319 {
320 m_unsentPackets.pop_front();
321 }
322 m_txTrace(packet);
323 m_txLatencyTrace(packet, latency);
324 m_sendEvents.erase(it);
326 {
327 NS_LOG_INFO("At time " << Simulator::Now().As(Time::S) << " video traffic source sent "
328 << size << " bytes to "
329 << InetSocketAddress::ConvertFrom(m_peer).GetIpv4() << " port "
331 }
333 {
334 NS_LOG_INFO("At time " << Simulator::Now().As(Time::S) << " video traffic source sent "
335 << size << " bytes to "
336 << Inet6SocketAddress::ConvertFrom(m_peer).GetIpv6() << " port "
338 }
339 }
340 else
341 {
342 NS_LOG_DEBUG("Unable to send packet; actual " << actual << " size " << size
343 << "; caching for later attempt");
344 if (m_unsentPackets.empty())
345 {
346 m_unsentPackets.push_back({eventId, packet, latency});
347 }
348 }
349}
350
351void
357
358void
360{
361 NS_LOG_FUNCTION(this << socket << size);
362 if (m_unsentPackets.empty() && !m_generatedFrames.empty() && m_socket->GetTxAvailable() > 0)
363 {
365 }
366}
367
368void
370{
371 NS_LOG_FUNCTION(this << socket << available);
372 if (m_unsentPackets.empty())
373 {
374 if (!m_generatedFrames.empty() && m_socket->GetTxAvailable() > 0)
375 {
377 }
378 return;
379 }
380 const auto& unsentPacketInfo = m_unsentPackets.front();
381 const auto size = unsentPacketInfo.packet->GetSize();
382 if (available >= size)
383 {
384 // Do not add additional networking latency when this is another TX attempt
385 NS_LOG_DEBUG("Retry packet " << unsentPacketInfo.id << " with size " << size);
386 Send(unsentPacketInfo.id, size, unsentPacketInfo.latency);
387 }
388}
389
390} // Namespace ns3
Class for representing data rates.
Definition data-rate.h:78
AttributeValue implementation for DataRate.
Definition data-rate.h:252
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
The gamma distribution Random Number Generator (RNG) that allows stream numbers to be set determinist...
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
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.
static TypeId GetTypeId()
Get the type ID.
Generate video traffic.
static const TrafficModels m_trafficModels
Traffic models as defined in Table 5 from IEEE 802.11-14/0571r12 - 11ax Evaluation Methodology.
void TxAvailable(Ptr< Socket > socket, uint32_t available)
Handle a Send event.
std::map< uint64_t, EventId > m_sendEvents
Event IDs of pending TX events.
Ptr< GammaRandomVariable > m_latencyMs
Gamma random variable to generate latency (in milliseconds).
std::deque< UnsentPacketInfo > m_unsentPackets
Hold unsent packet for later attempt.
void SendWithLatency()
Schedule send of a packet with a random latency.
void CancelEvents() override
Cancel all pending events.
void Send(uint64_t eventId, uint32_t size, Time latency)
Effectively send a packet once the latency has elapsed.
double m_frameSizeBytesShape
Shape parameter for the Weibull distribution used to generate size of video frames (if model is custo...
void DoStartApplication() override
Application specific startup code for child subclasses.
DataRate m_bitRate
Video bit rate (if model is custom).
TracedCallback< Ptr< const Packet >, Time > m_txLatencyTrace
Traced Callback: transmitted packets and their latencies.
EventId m_generateFrameEvent
Event ID of pending frame generation event.
Ptr< WeibullRandomVariable > m_frameSizeBytes
Weibull random variable to generate size of video frames (in bytes).
double m_latencyMsShape
Shape parameter for the Gamma distribution used to generate latency.
Time m_interArrival
Calculated inter arrival duration between two generated packets.
std::deque< uint32_t > m_generatedFrames
Hold size of generated video frames.
static TypeId GetTypeId()
Get the type ID.
void DoInitialize() override
Initialize() implementation.
std::map< TrafficModelClassIdentifier, TrafficModelParameters > TrafficModels
Parameters for each traffic model.
void DoConnectionSucceeded(Ptr< Socket > socket) override
Application specific code for child subclasses upon a Connection Succeed event.
uint32_t m_remainingSize
Number of bytes to send directly to the socket because current video frame is too large to be sent at...
double m_latencyMsScale
Scale parameter for the Gamma distribution used to generate latency.
double m_frameSizeBytesScale
Scale parameter for the Weibull distribution used to generate size of video frames (if model is custo...
void ScheduleNextFrame()
Schedule the next frame generation.
uint64_t m_nextEventId
The next event ID.
void GenerateVideoFrame()
Generate new video frame.
std::optional< uint32_t > m_maxSize
Limit on the number of bytes that can be sent at once over the network, hence we limit at application...
TrafficModelClassIdentifier m_trafficModelClassId
The Traffic Model Class Identifier.
void TxDone(Ptr< Socket > socket, uint32_t size)
Handle a Data Sent event.
int64_t AssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this Application object.
TracedCallback< uint32_t > m_frameGeneratedTrace
Traced Callback: generated frames (amount of payload bytes).
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
@ US
microsecond
Definition nstime.h:108
@ MS
millisecond
Definition nstime.h:107
@ S
second
Definition nstime.h:106
static Time FromDouble(double value, Unit unit)
Create a Time equal to value in unit unit.
Definition nstime.h:517
a unique identifier for an interface.
Definition type-id.h:50
@ 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
Hold an unsigned integer type.
Definition uinteger.h:34
uint64_t Get() const
Definition uinteger.cc:25
The Weibull distribution Random Number Generator (RNG) which allows stream numbers to be set determin...
#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< const AttributeAccessor > MakeDataRateAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition data-rate.h:252
Ptr< const AttributeChecker > MakeDataRateChecker()
Definition data-rate.cc:20
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition double.h:32
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< 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_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#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
#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
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
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