9#include "ns3/application-container.h"
10#include "ns3/application-helper.h"
11#include "ns3/config.h"
12#include "ns3/double.h"
13#include "ns3/internet-stack-helper.h"
14#include "ns3/node-container.h"
16#include "ns3/nstime.h"
17#include "ns3/packet-sink-helper.h"
18#include "ns3/packet-sink.h"
19#include "ns3/packet-socket-address.h"
20#include "ns3/simple-net-device-helper.h"
22#include "ns3/tgax-voip-traffic.h"
23#include "ns3/traced-callback.h"
42const double tol = 0.1;
77 void DoRun()
override;
124 std::vector<std::pair<TgaxVoipTraffic::VoiceActivityState, Time>>
131 std::optional<VoipParams> params)
140 NS_LOG_FUNCTION(
this << packet << packet->GetSize() << packet->GetUid() << jitter);
144 (
m_sent.rbegin()->first + 1),
145 "Packets should arrive in order if there is no jitter");
147 m_sent.try_emplace(packet->GetUid(),
172 const auto simulationTime{
Seconds(300)};
185 internet.Install(
nodes);
211 auto sourceApp = sourceHelper.
Install(sender);
212 const auto startAppTime =
Seconds(1.0);
213 sourceApp.Start(startAppTime);
214 sourceApp.Stop(startAppTime + simulationTime);
218 auto sinkApp = sinkHelper.
Install(receiver);
220 sinkApp.Stop(
Seconds(2.0) + simulationTime);
222 int64_t streamNumber = 10;
226 "/NodeList/*/$ns3::Node/ApplicationList/*/$ns3::TgaxVoipTraffic/StateUpdate",
230 "/NodeList/*/$ns3::Node/ApplicationList/*/$ns3::TgaxVoipTraffic/TxWithJitter",
244 std::accumulate(
m_sent.cbegin(),
m_sent.cend(), 0ULL, [](
auto sum,
const auto& elem) {
245 return sum + elem.second.size;
253 std::optional<TxInfo> prevTx{};
254 for (
const auto& [
id, info] :
m_sent)
259 info.tstamp - info.jitter - offset,
260 [](
Time value,
const auto& state) { return value <= state.second; });
275 const auto interval = info.tstamp - prevTx->tstamp;
276 const auto jitterCorrection = info.jitter - prevTx->jitter;
277 const auto expectedInterval =
282 expectedInterval + jitterCorrection,
283 "Unexpected encoder frame interval");
288 std::vector<Time> inactiveDurations;
292 std::back_inserter(inactiveDurations),
293 [](
const auto& lhs,
const auto& rhs) {
294 return (lhs.first == TgaxVoipTraffic::VoiceActivityState::INACTIVE_SILENCE)
295 ? (rhs.second - lhs.second)
298 auto noZeroEnd = std::remove_if(inactiveDurations.begin(),
299 inactiveDurations.end(),
300 [&](
const auto& t) { return t.IsZero(); });
301 inactiveDurations.erase(noZeroEnd, inactiveDurations.end());
302 const auto totalInactiveDuration =
303 std::accumulate(inactiveDurations.cbegin(),
304 inactiveDurations.cend(),
306 [](
auto sum,
const auto t) {
return sum + t; });
308 std::vector<Time> activeDurations;
312 std::back_inserter(activeDurations),
313 [](
const auto& lhs,
const auto& rhs) {
314 return (lhs.first == TgaxVoipTraffic::VoiceActivityState::ACTIVE_TALKING)
315 ? (rhs.second - lhs.second)
318 noZeroEnd = std::remove_if(activeDurations.begin(), activeDurations.end(), [&](
const auto& t) {
321 activeDurations.erase(noZeroEnd, activeDurations.end());
322 const auto totalActiveDuration =
323 std::accumulate(activeDurations.cbegin(),
324 activeDurations.cend(),
326 [](
auto sum,
const auto t) {
return sum + t; });
328 const auto averageActiveDuration = totalActiveDuration / activeDurations.size();
329 const auto expectedAverageActiveStateDurationMs =
332 expectedAverageActiveStateDurationMs,
333 tol * expectedAverageActiveStateDurationMs,
334 "Unexpected average active state duration");
336 const auto averageInactiveDuration = totalInactiveDuration / inactiveDurations.size();
337 const auto expectedAverageInactiveStateDurationMs =
340 expectedAverageInactiveStateDurationMs,
341 tol * expectedAverageInactiveStateDurationMs,
342 "Unexpected average inactive state duration");
344 const auto totalDuration = totalInactiveDuration + totalActiveDuration;
345 const auto voiceActivityFactor =
static_cast<double>(totalActiveDuration.GetMicroSeconds()) /
346 totalDuration.GetMicroSeconds();
347 const auto expectedVoiceActivityFactor =
349 (
m_params->silenceToVoiceProbability +
m_params->voiceToSilenceProbability))
352 expectedVoiceActivityFactor,
354 "Unexpected voice activity factor");
356 const double totalJitterUs =
357 std::accumulate(
m_sent.cbegin(),
m_sent.cend(), 0.0, [](
double sum,
const auto& elem) {
358 return sum + elem.second.jitter.GetMicroSeconds();
360 const auto avgJitterMs = (totalJitterUs /
m_sent.size()) / 1000;
TGax voice-over-IP traffic test.
void StateUpdated(TgaxVoipTraffic::VoiceActivityState state, Time duration)
Record a change in VoIP voice activity state.
uint64_t m_received
number of bytes received
std::vector< std::pair< TgaxVoipTraffic::VoiceActivityState, Time > > m_states
Hold voice activity states and the time at which it started.
TgaxVoipTrafficTestCase(const std::string &name, std::optional< VoipParams > params={})
Constructor.
void ReceiveRx(std::string context, Ptr< const Packet > p, const Address &addr)
Record a packet successfully received.
std::optional< VoipParams > m_params
VoIP parameters.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void PacketSent(Ptr< const Packet > packet, Time jitter)
Record a packets successfully sent.
void DoRun() override
Implementation to actually run this TestCase.
std::map< uint64_t, TxInfo > m_sent
transmitted VoIP packets
TgaxVoipTraffic TestSuite.
TgaxVoipTrafficTestSuite()
a polymophic address class
AttributeValue implementation for Address.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
A helper to make it easier to instantiate an application on a set of nodes.
ApplicationContainer Install(NodeContainer c)
Install an application on each node of the input container configured with all the attributes set wit...
int64_t AssignStreams(NodeContainer c, int64_t stream)
Assigns a unique (monotonically increasing) stream number to all applications that match the configur...
void SetAttribute(const std::string &name, const AttributeValue &value)
Helper function used to set the underlying application attributes.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
aggregate IP/TCP/UDP functionality to existing Nodes.
keep track of a set of node pointers.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Smart pointer class similar to boost::intrusive_ptr.
build a set of SimpleNetDevice objects
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::SimpleChannel with the attributes configured by SimpleNetDeviceHelper::Se...
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
static Time Now()
Return the current simulation virtual time.
static void Run()
Run the simulation.
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
TestCase(const TestCase &)=delete
Caller graph was not generated because of its size.
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
VoiceActivityState
Voice activity states.
static TypeId GetTypeId()
Get the type ID.
Simulation virtual time values and global simulation resolution.
AttributeValue implementation for Time.
Hold an unsigned integer type.
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...
void Connect(std::string path, const CallbackBase &cb)
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Seconds(double value)
Construct a Time in the indicated unit.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
const double tol
some tolerance for floating point comparisons
const uint32_t voicePayloadSize
payload size of voice packets in bytes
const uint32_t compressedProtocolHeader
size of compressed protocol header (assumes IPv4)
const uint32_t silencePayloadSize
payload size of silence packets in bytes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint32_t size
size of the packet in bytes
Time jitter
delay jitter applied to the packet
TxInfo(uint32_t s, Time t, Time j)
Constructor.
Time tstamp
timestamp at which the packet is transmitted
Information about VoIP parameters.
double voiceToSilenceProbability
Probability to transition from active to inactive state.
Time scaleDelayJitter
Scale of laplacian distribution used for delay jitter.
Time meanActiveStateDuration
Mean duration of active/talking state.
double silenceToVoiceProbability
Probability to transition from inactive to active state.
Time boundDelayJitter
Bound of laplacian distribution used for delay jitter.
Time meanInactiveStateDuration
Mean duration of inactive/silence state.
static TgaxVoipTrafficTestSuite g_TgaxVoipTrafficTestSuite
Static variable for test initialization.