12#include "ns3/net-device-container.h" 
   13#include "ns3/node-container.h" 
   14#include "ns3/node-list.h" 
   16#include "ns3/pointer.h" 
   17#include "ns3/wifi-mac.h" 
   18#include "ns3/wifi-net-device.h" 
   19#include "ns3/wifi-phy-state-helper.h" 
   20#include "ns3/wifi-phy.h" 
   41                  "Invalid Start: " << startTime << 
" and Stop: " << 
stopTime << 
" Time");
 
 
   52                  "Invalid Start: " << start << 
" and Stop: " << 
m_stopTime << 
" Time");
 
   54                  "Invalid Start: " << start << 
" less than Now(): " << 
Simulator::Now());
 
 
   63                  "Invalid Start: " << 
m_startTime << 
" and Stop: " << stop << 
" Time");
 
   65                  "Invalid Stop: " << stop << 
" less than Now(): " << 
Simulator::Now());
 
 
   77        record.m_linkStateDurations.clear();
 
 
   90            netDevices.
Add(
nodes.Get(i)->GetDevice(j));
 
 
  101    for (
uint32_t j = 0; j < devices.GetN(); ++j)
 
  106            NS_LOG_INFO(
"Ignoring deviceId: " << devices.Get(j)->GetIfIndex() << 
" on nodeId: " 
  107                                              << devices.Get(j)->GetNode()->GetId()
 
  108                                              << 
" because it is not of type WifiNetDevice");
 
  114        for (
uint32_t k = 0; k < device->GetNPhys(); ++k)
 
  116            auto wifiPhyStateHelper = device->GetPhy(k)->GetState();
 
  119            wifiPhyStateHelper->TraceConnectWithoutContext(
"State", linkCallback);
 
 
  134        if (nodeName.empty())
 
  138        if (deviceName.empty())
 
  145            auto& statistics = 
m_deviceRecords[i].m_linkStateDurations.begin()->second;
 
  147               << 
"---- COT for " << nodeName << 
":" << deviceName << 
" ----" 
  151        else if (numLinks > 1)
 
  153            os << 
"\nDevice \"" << nodeName << 
":" << deviceName
 
  154               << 
"\" has statistics for multiple links: " 
  159                   << 
"---- COT for " << nodeName << 
":" << deviceName << 
"#Link" 
  160                   << std::to_string(linkStates.first) << 
" ---" 
  167            os << 
"\nDevice \"" << nodeName << 
":" << deviceName << 
"\" has no statistics." 
 
  176                                   const std::map<WifiPhyState, Time>& linkStates,
 
  180    os << 
"Showing duration by states: " 
  184    const auto showPercents = !percents.empty();
 
  186    std::vector<std::string> stateColumn{};
 
  187    std::vector<std::string> durationColumn{};
 
  188    std::vector<std::string> percentColumn{};
 
  190    for (
const auto& it : linkStates)
 
  192        std::stringstream stateStream;
 
  193        stateStream << it.first << 
": ";
 
  194        stateColumn.emplace_back(stateStream.str());
 
  196        std::stringstream durationStream;
 
  197        durationStream << std::showpoint << std::fixed << std::setprecision(2)
 
  198                       << it.second.As(unit);
 
  199        durationColumn.emplace_back(durationStream.str());
 
  203            std::stringstream percentStream;
 
  204            percentStream << std::showpoint << std::fixed << std::setprecision(2) << 
" (" 
  205                          << percents.at(it.first) << 
"%)";
 
  206            percentColumn.emplace_back(percentStream.str());
 
  218    for (
size_t i = 0; i < stateColumn.size(); ++i)
 
  220        os << stateColumn.at(i) << durationColumn.at(i);
 
  223            os << percentColumn.at(i);
 
 
  237    for (
auto& s : column)
 
  239        size_t pos = s.find_first_of(decimal);
 
  246    for (
auto& s : column)
 
  248        auto padding = std::string(maxPos - s.find_first_of(decimal), 
' ');
 
 
  258    for (
auto& s : column)
 
  260        size_t width = s.length();
 
  261        if (width > maxWidth)
 
  267    for (
auto& s : column)
 
  269        auto padding = std::string(maxWidth - s.length(), 
' ');
 
 
  274std::map<WifiPhyState, double>
 
  279    for (
const auto& it : linkStates)
 
  289    std::map<WifiPhyState, double> percents;
 
  290    for (
const auto& it : linkStates)
 
  292        percents[it.first] = it.second.GetDouble() * 100.0 / total.
GetDouble();
 
 
  298const std::vector<WifiCoTraceHelper::DeviceRecord>&
 
  316    const auto overlappingDuration =
 
  319    if (!overlappingDuration.IsZero())
 
  325        NS_ASSERT_MSG(wifiDevice, 
"Error, Device type is not WifiNetDevice.");
 
  327        auto linkId = wifiDevice->GetMac()->GetLinkForPhy(phyId);
 
  329        if (linkId.has_value())
 
  333                        << 
m_deviceRecords[idx].m_ifIndex << 
" linkId " << *linkId << 
" duration " 
  334                        << overlappingDuration.As(
Time::US) << 
" state " << state);
 
  335            m_deviceRecords[idx].AddLinkMeasurement(*linkId, start, overlappingDuration, state);
 
 
  349    NS_ASSERT_MSG(start1 >= Zero && stop1 >= Zero && start1 <= stop1,
 
  350                  "Interval: [" << start1 << 
"," << stop1 << 
"] is invalid.");
 
  351    NS_ASSERT_MSG(start2 >= Zero && stop2 >= Zero && start2 <= stop2,
 
  352                  "Interval: [" << start2 << 
"," << stop2 << 
"] is invalid.");
 
  354    const auto maxStart = 
Max(start1, start2);
 
  355    const auto minStop = 
Min(stop1, stop2);
 
  356    const auto duration = minStop - maxStart;
 
  358    return duration > Zero ? duration : Zero;
 
 
  362    : m_nodeId(device->GetNode()->GetId()),
 
  363      m_ifIndex(device->GetIfIndex())
 
 
  383    auto& stateDurations = m_linkStateDurations[linkId];
 
  384    stateDurations[state] += duration;
 
 
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and,...
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.
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
static Ptr< Node > GetNode(uint32_t n)
Smart pointer class similar to boost::intrusive_ptr.
static Time Now()
Return the current simulation virtual time.
Simulation virtual time values and global simulation resolution.
bool IsPositive() const
Exactly equivalent to t >= 0.
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Unit
The unit to use to interpret a number representing time.
double GetDouble() const
Get the raw time value, in the current resolution unit.
bool IsZero() const
Exactly equivalent to t == 0.
std::map< WifiPhyState, double > ComputePercentage(const std::map< WifiPhyState, Time > &linkStates) const
A helper function used by PrintStatistics method.
void AlignWidth(std::vector< std::string > &column) const
A helper function used by PrintLinkStates method to format the output.
Time ComputeOverlappingDuration(Time start1, Time stop1, Time start2, Time stop2)
Compute overlapping time-duration between two intervals.
void Stop(Time stopTime)
Stops the collection of statistics at a specified time.
void Enable(NodeContainer nodes)
Enables trace collection for all nodes and WifiNetDevices in the specified NodeContainer.
void PrintStatistics(std::ostream &os, Time::Unit unit=Time::Unit::AUTO) const
Print measurement results on an output stream.
Time m_stopTime
Instant at which statistics collection should stop.
void Start(Time startTime)
Starts the collection of statistics from a specified start time.
Time m_startTime
Instant at which statistics collection should start.
std::ostream & PrintLinkStates(std::ostream &os, const std::map< WifiPhyState, Time > &linkStates, Time::Unit unit) const
A helper function used by PrintStatistics method.
void NotifyWifiPhyState(std::size_t idx, std::size_t phyId, Time start, Time duration, WifiPhyState state)
A callback used to update statistics.
std::vector< DeviceRecord > m_deviceRecords
Stores the collected statistics.
const std::vector< DeviceRecord > & GetDeviceRecords() const
Returns measurement results on each installed device.
void AlignDecimal(std::vector< std::string > &column) const
A helper function used by PrintLinkStates method to format the output.
uint32_t m_numDevices
Count the number of devices traced by this helper.
void Reset()
Resets the current statistics, clearing all links and their durations.
WifiCoTraceHelper()
Default Constructor.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#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.
Time Seconds(double value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiPhyState
The state of the PHY layer.
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...
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
void AddLinkMeasurement(size_t linkId, Time start, Time duration, WifiPhyState state)
Update the duration statistics for the provided linkId and state.
std::string m_deviceName
Device name. It's empty if the name isn't configured.
DeviceRecord(Ptr< WifiNetDevice > device)
Constructor.
std::string m_nodeName
Name of Node on which the WifiNetDevice is installed.