A Discrete-Event Network Simulator
Models

RadioWatcher Application

The RadioWatcher application collects MAC and PHY layer statistics for an ns-3 WifiNetDevice and periodically sends these over a local TCP socket to external listeners outside the simulation. The statistic reports are formatted in JSON to allow for an easy processing.

The typical use case of the RadioWatcher application is an emulation scenario (using the ns-3 realtime scheduler) in combination with real applications running outside the emulation environment. In such a scenario the wireless communication including the node topology is emulated by ns-3 while the transmitted data is generated and processed in real-time by applications the outside applications. The ns-3 nodes represent the radio device (e.g. WiFi) and are connected to the external applications using tap bridges and the TapBridge module. The RadioWatcher allows for the real-time monitoring of the radio state and channel characteristics as they are seen by each node. The RadioWatcher collects statistics aggregated for the whole radio device as well as grouped by the individual communication peers, i.e. separately for each wireless link. Thus, it delivers detailed state information for the active wireless links of a node. By connecting to the TCP port provided by a RadioWatcher, an external application receives periodical updates of the collected radio and channel parameters. These may be used for different purposes like cross-layer processing, usage in routing metrics or network visualization.

An overview of the described concept is given in the following figure Concept of using the RadioWatcher application.

_images/RadioWatcherArchitecture.png

Concept of using the RadioWatcher application

Dependencies

libjsoncpp-dev

To integrate the library in the ns-3 build, add the following line to /src/applications/wscript:

module.env.append_value(“LIB”, [“jsoncpp”])

Model Description

The source code for the RadioWatcher model and its data structures (l2info) lives in the directory src/applications/model.

List of source files:

  • /src/applications/helper/radiowatcher-helper.cc
  • /src/applications/helper/radiowatcher-helper.h
  • /src/applications/model/radiowatcher.cc
  • /src/applications/model/radiowatcher.h
  • /src/applications/model/l2info.cc
  • /src/applications/model/l2info.h

Design

The RadioWatcher application connects to several trace sources of the ns3::WifiPhy, ns3::WifiPhyStateHelper, ns3::WifiMac, ns3::RegularWifiMac, and ns3::WifiRemoteStationManager classes of a node’s WifiNetDevice.

List of used trace sources:

  • /Mac/MacTx
  • /Mac/MacRx
  • /Mac/$ns3::RegularWifiMac/TxOkHeader
  • /Mac/$ns3::RegularWifiMac/TxErrHeader
  • /RemoteStationManager/TxRtsFailed
  • /RemoteStationManager/MacTxDataFailed
  • /RemoteStationManager/MacTxFinalRtsFailed
  • /RemoteStationManager/MacTxFinalDataFailed
  • /Phy/State/RxOk
  • /Phy/State/RxError
  • /Phy/State/Tx
  • /Phy/State/State
  • /Phy/MonitorSnifferRx
  • /Phy/MonitorSnifferTx

The gathered statistics are stored in data structures defined in /src/applications/model/l2info.cc. They contain for each link (i.e. communication peer) a set of PacketStatistics and LinkUsageStatistics:

/**
 * Data class to hold packet related statistics.
 *
 */
class PacketStatistics
{
private:
  Time m_lastActivity;
  uint32_t m_rxPackets;
  uint32_t m_txPackets;
  uint32_t m_rxFrames;
  uint32_t m_txFrames;
  uint32_t m_rxBit;
  uint32_t m_txBit;
  uint32_t m_rxFrameErrors;
  uint32_t m_txFrameErrors;
  uint32_t m_rxPacketErrors;
  uint32_t m_txPacketErrors;
  uint32_t m_collisions;          // not used yet
  uint32_t m_rxLatency;           // not used yet
  uint32_t m_txLatency;           // not used yet
  uint32_t m_rxJitter;            // not used yet
  uint32_t m_txJitter;            // not used yet
};

/**
 * Data class to hold statistics related to link usage.
 *
 */
class LinkUsageStatistics
{
private:
  Time m_lastReset;
  /* summed up durations within current interval */
  Time m_durationTx;
  Time m_durationRx;
  Time m_durationCcaBusy;
  Time m_durationSleep;
  Time m_durationIdle;
};

Furthermore, the parameters lastSNR, lastTxDataRate, and lastRxDataRate are monitored for each link.

For relaying the gathered link information to external applications, the RadioWatcher opens a TCP server port on the host system and sends the statistics in JSON format to connected clients at a specified interval (c.f. class L2StatServer in l2info.cc). The variables of PacketStatistics and LinkUsageStatistics are reset to zero after each interval. Each node containing a RadioWatcher application uses a distinct TCP server port for its L2StatServer. The usual scheme is to provide a local IPv4 or IPv6 address and a starting port number to the RadioWatcherHelper which then assigns port numbers to the RadioWatchers of all nodes in an incremental fashion.

In order to only include established links (e.g. that can be used in a routing decision) within the statistic reports, the RadioWatcher allows to specify a LinkTimeout value in seconds. A link is only included in the statistic report if there has been an activity on the link within the last period specified by LinkTimeout. As activity we considere all frame receive events as well as successful frame transmissions (an unsuccessful transmission does not give information whether the link is still established).

Scope and Limitations

References

Usage

Helpers

For installing the RadioWatcher within nodes, there exists a RadioWatcherHelper class in the directory src/applications/helper.

The local IP address used for the L2StatServer of all RadioWatcher instances can be set with ns3::RadioWatcherHelper::SetLocalSocketAddress(char const *ipV4address) for a local IPv4 address or with ns3::RadioWatcherHelper::SetLocalSocketv6Address(char const *ipV6address) for a local IPv6 address, respectively. The starting port used for the L2StatServers is set with ns3::RadioWatcherHelper::SetLocalSocketBasePort(uint16t port);

Having set a local socket address and starting port, RadioWatcher applications can be added to a set of nodes using ns3::RadioWatcherHelper::Install(NodeContainer container);

RadioWatcherHelper radiowatcher;
radiowatcher.SetLocalSocketBasePort(8000);
radiowatcher.SetLocalSocketAddress("0.0.0.0"); // optional, defaults to localhost
radiowatcher.SetInterval(1.0); // Interval between Json messages in seconds

ApplicationContainer rwApps;
rwApps = radiowatcher.Install (nodes);
rwApps.Start(Seconds (0));
rwApps.Stop(Seconds (param_duration - 1));

Attributes

The RadioWatcher application has two attributes: Interval Defines the time interval in seconds between layer2 statistic reports sent by the RadioWatcher over its L2StatServer. LinkTimeout Defines the timeout in seconds after which a link is considered to be inactive if no frames have been sent or received on the link within the timeout. When a link has timed out it is no longer included in the layer2 statistic report. Note that unsuccessfully sent frames on a link do not reset the timer.

Output

Example JSON output:

{
“nodeid” : 8
“deviceid” : 0,
“linkProvider” : {
“localLinkAddress” : “00:00:00:00:00:09”,
“mediaType” : “”,
“name” : “Node8_Dev0”,
“noise_level” : -100.5520583329438,
“packetStat” : {
“collisions” : 0,
“lastActivity” : 643143,
“rxBit” : 580,
“rxFrameErrors” : 0,
“rxFrames” : 4,
“rxJitter” : 0,
“rxLatency” : 0,
“rxPacketErrors” : 0,
“rxPackets” : 4,
“txBit” : 326,
“txFrameErrors” : 0,
“txFrames” : 2,
“txJitter” : 0,
“txLatency” : 0,
“txPacketErrors” : 0,
“txPackets” : 2
},
“state” : 2,
“usageStat” : {
“avgLoad” : 0.010,
“durationCcaBusy” : 0,
“durationIdle” : 2088004,
“durationRx” : 6560,
“durationSleep” : 0,
“durationTx” : 3440,
“loadInterval” : 1000000
}
},
“links” : [
{
“lastRxDataRate” : 1000000,
“lastSNR” : 30859144976.27373,
“lastTxDataRate” : 0,
“neighborAddress” : “16:38:0c:07:76:f2”,
“packetStat” : {
“collisions” : 0,
“lastActivity” : 915901,
“rxBit” : 0,
“rxFrameErrors” : 0,
“rxFrames” : 2,
“rxJitter” : 0,
“rxLatency” : 0,
“rxPacketErrors” : 0,
“rxPackets” : 0,
“txBit” : 0,
“txFrameErrors” : 0,
“txFrames” : 0,
“txJitter” : 0,
“txLatency” : 0,
“txPacketErrors” : 0,
“txPackets” : 0
},
“usageStat” : {
“avgLoad” : 0.0,
“durationCcaBusy” : 0,
“durationIdle” : 0,
“durationRx” : 0,
“durationSleep” : 0,
“durationTx” : 0,
“loadInterval” : 3000000
}
},
{
“lastRxDataRate” : 1000000,
“lastSNR” : 30859144976.27373,
“lastTxDataRate” : 0,
“neighborAddress” : “f2:a5:53:47:24:a5”,
“packetStat” : {
“collisions” : 0,
“lastActivity” : 732334,
“rxBit” : 0,
“rxFrameErrors” : 0,
“rxFrames” : 2,
“rxJitter” : 0,
“rxLatency” : 0,
“rxPacketErrors” : 0,
“rxPackets” : 0,
“txBit” : 0,
“txFrameErrors” : 0,
“txFrames” : 0,
“txJitter” : 0,

“txLatency” : 0,
“txPacketErrors” : 0,
“txPackets” : 0
},
“usageStat” : {
“avgLoad” : 0.0,
“durationCcaBusy” : 0,
“durationIdle” : 0,
“durationRx” : 0,
“durationSleep” : 0,
“durationTx” : 0,
“loadInterval” : 1000000
}
}
],
}

Tracing

Logging

The RadioWatcher defines a logging component which can be enabled in the simulation script using LogComponentEnable("RadioWatcher", LOG_LEVEL_DEBUG)

Examples

Caveats

Table Of Contents

This Page