A Discrete-Event Network Simulator
API
athstats-helper.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 CTTC
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Nicola Baldo <nbaldo@cttc.es>
18  */
19 
20 #include "athstats-helper.h"
21 
22 #include "ns3/config.h"
23 #include "ns3/log.h"
24 #include "ns3/net-device-container.h"
25 #include "ns3/node-container.h"
26 #include "ns3/simulator.h"
27 #include "ns3/wifi-mode.h"
28 #include "ns3/wifi-phy-common.h"
29 #include "ns3/wifi-phy-state.h"
30 
31 #include <fstream>
32 #include <iomanip>
33 
34 namespace ns3
35 {
36 
37 NS_LOG_COMPONENT_DEFINE("Athstats");
38 
40  : m_interval(Seconds(1.0))
41 {
42 }
43 
44 void
45 AthstatsHelper::EnableAthstats(std::string filename, uint32_t nodeid, uint32_t deviceid)
46 {
47  Ptr<AthstatsWifiTraceSink> athstats = CreateObject<AthstatsWifiTraceSink>();
48  std::ostringstream oss;
49  oss << filename << "_" << std::setfill('0') << std::setw(3) << std::right << nodeid << "_"
50  << std::setfill('0') << std::setw(3) << std::right << deviceid;
51  athstats->Open(oss.str());
52 
53  oss.str("");
54  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
55  std::string devicepath = oss.str();
56 
57  Config::Connect(devicepath + "/Mac/MacTx",
59  Config::Connect(devicepath + "/Mac/MacRx",
61 
62  Config::Connect(devicepath + "/RemoteStationManager/MacTxRtsFailed",
64  Config::Connect(devicepath + "/RemoteStationManager/MacTxDataFailed",
66  Config::Connect(devicepath + "/RemoteStationManager/MacTxFinalRtsFailed",
68  Config::Connect(devicepath + "/RemoteStationManager/MacTxFinalDataFailed",
70 
71  Config::Connect(devicepath + "/Phy/State/RxOk",
73  Config::Connect(devicepath + "/Phy/State/RxError",
75  Config::Connect(devicepath + "/Phy/State/Tx",
77  Config::Connect(devicepath + "/Phy/State/State",
79 }
80 
81 void
83 {
84  EnableAthstats(filename, nd->GetNode()->GetId(), nd->GetIfIndex());
85 }
86 
87 void
89 {
90  for (NetDeviceContainer::Iterator i = d.Begin(); i != d.End(); ++i)
91  {
92  Ptr<NetDevice> dev = *i;
93  EnableAthstats(filename, dev->GetNode()->GetId(), dev->GetIfIndex());
94  }
95 }
96 
97 void
99 {
100  NetDeviceContainer devs;
101  for (NodeContainer::Iterator i = n.Begin(); i != n.End(); ++i)
102  {
103  Ptr<Node> node = *i;
104  for (std::size_t j = 0; j < node->GetNDevices(); ++j)
105  {
106  devs.Add(node->GetDevice(j));
107  }
108  }
109  EnableAthstats(filename, devs);
110 }
111 
113 
114 TypeId
116 {
117  static TypeId tid = TypeId("ns3::AthstatsWifiTraceSink")
118  .SetParent<Object>()
119  .SetGroupName("Wifi")
120  .AddConstructor<AthstatsWifiTraceSink>()
121  .AddAttribute("Interval",
122  "Time interval between reports",
123  TimeValue(Seconds(1.0)),
125  MakeTimeChecker());
126  return tid;
127 }
128 
130  : m_txCount(0),
131  m_rxCount(0),
132  m_shortRetryCount(0),
133  m_longRetryCount(0),
134  m_exceededRetryCount(0),
135  m_phyRxOkCount(0),
136  m_phyRxErrorCount(0),
137  m_phyTxCount(0),
138  m_writer(nullptr)
139 {
141 }
142 
144 {
145  NS_LOG_FUNCTION(this);
146 
147  if (m_writer != nullptr)
148  {
149  NS_LOG_LOGIC("m_writer nonzero " << m_writer);
150  if (m_writer->is_open())
151  {
152  NS_LOG_LOGIC("m_writer open. Closing " << m_writer);
153  m_writer->close();
154  }
155 
156  NS_LOG_LOGIC("Deleting writer " << m_writer);
157  delete m_writer;
158 
159  NS_LOG_LOGIC("m_writer = 0");
160  m_writer = nullptr;
161  }
162  else
163  {
164  NS_LOG_LOGIC("m_writer == 0");
165  }
166 }
167 
168 void
170 {
171  m_txCount = 0;
172  m_rxCount = 0;
173  m_shortRetryCount = 0;
174  m_longRetryCount = 0;
176  m_phyRxOkCount = 0;
177  m_phyRxErrorCount = 0;
178  m_phyTxCount = 0;
179 }
180 
181 void
183 {
184  NS_LOG_FUNCTION(this << context << p);
185  ++m_txCount;
186 }
187 
188 void
190 {
191  NS_LOG_FUNCTION(this << context << p);
192  ++m_rxCount;
193 }
194 
195 void
197 {
198  NS_LOG_FUNCTION(this << context << address);
200 }
201 
202 void
204 {
205  NS_LOG_FUNCTION(this << context << address);
207 }
208 
209 void
211 {
212  NS_LOG_FUNCTION(this << context << address);
214 }
215 
216 void
218 {
219  NS_LOG_FUNCTION(this << context << address);
221 }
222 
223 void
225  Ptr<const Packet> packet,
226  double snr,
227  WifiMode mode,
228  WifiPreamble preamble)
229 {
230  NS_LOG_FUNCTION(this << context << packet << " mode=" << mode << " snr=" << snr
231  << "preamble=" << preamble);
232  ++m_phyRxOkCount;
233 }
234 
235 void
236 AthstatsWifiTraceSink::PhyRxErrorTrace(std::string context, Ptr<const Packet> packet, double snr)
237 {
238  NS_LOG_FUNCTION(this << context << packet << " snr=" << snr);
240 }
241 
242 void
244  Ptr<const Packet> packet,
245  WifiMode mode,
246  WifiPreamble preamble,
247  uint8_t txPower)
248 {
249  NS_LOG_FUNCTION(this << context << packet << "PHYTX mode=" << mode << "Preamble=" << preamble
250  << "Power=" << txPower);
251  ++m_phyTxCount;
252 }
253 
254 void
256  Time start,
257  Time duration,
258  WifiPhyState state)
259 {
260  NS_LOG_FUNCTION(this << context << start << duration << state);
261 }
262 
263 void
264 AthstatsWifiTraceSink::Open(const std::string& name)
265 {
266  NS_LOG_FUNCTION(this << name);
268  m_writer == nullptr,
269  "AthstatsWifiTraceSink::Open (): m_writer already allocated (std::ofstream leak detected)");
270 
271  m_writer = new std::ofstream();
272  NS_ABORT_MSG_UNLESS(m_writer, "AthstatsWifiTraceSink::Open (): Cannot allocate m_writer");
273 
274  NS_LOG_LOGIC("Created writer " << m_writer);
275 
276  m_writer->open(name, std::ios_base::binary | std::ios_base::out);
277  NS_ABORT_MSG_IF(m_writer->fail(),
278  "AthstatsWifiTraceSink::Open (): m_writer->open (" << name << ") failed");
279 
280  NS_ASSERT_MSG(m_writer->is_open(), "AthstatsWifiTraceSink::Open (): m_writer not open");
281 
282  NS_LOG_LOGIC("Writer opened successfully");
283 }
284 
285 void
287 {
288  NS_LOG_FUNCTION(this);
289  // The comments below refer to how each value maps to madwifi's athstats
290  // I know C strings are ugly but that's the quickest way to use exactly the same format as in
291  // madwifi
292  char str[200];
293  snprintf(
294  str,
295  200,
296  "%8u %8u %7u %7u %7u %6u %6u %6u %7u %4u %3uM\n",
297  (unsigned int)m_txCount, // /proc/net/dev transmitted packets to which we should subtract
298  // management frames
299  (unsigned int)
300  m_rxCount, // /proc/net/dev received packets but subtracts management frames from it
301  (unsigned int)0, // ast_tx_altrate
302  (unsigned int)m_shortRetryCount, // ast_tx_shortretry
303  (unsigned int)m_longRetryCount, // ast_tx_longretry
304  (unsigned int)m_exceededRetryCount, // ast_tx_xretries
305  (unsigned int)m_phyRxErrorCount, // ast_rx_crcerr
306  (unsigned int)0, // ast_rx_badcrypt
307  (unsigned int)0, // ast_rx_phyerr
308  (unsigned int)0, // ast_rx_rssi
309  (unsigned int)0 // rate
310  );
311 
312  if (m_writer)
313  {
314  *m_writer << str;
315 
316  ResetCounters();
318  }
319 }
320 
321 } // namespace ns3
void EnableAthstats(std::string filename, uint32_t nodeid, uint32_t deviceid)
Enable athstats.
trace sink for wifi device that mimics madwifi's athstats tool.
void TxFinalRtsFailedTrace(std::string context, Mac48Address address)
Function to be called when the transmission of a RTS frame has exceeded the retry limit.
void Open(const std::string &name)
Open a file for output.
static TypeId GetTypeId()
Get the type ID.
void TxFinalDataFailedTrace(std::string context, Mac48Address address)
Function to be called when the transmission of a data frame has exceeded the retry limit.
void PhyRxOkTrace(std::string context, Ptr< const Packet > packet, double snr, WifiMode mode, WifiPreamble preamble)
Function to be called when the PHY layer of the considered device receives a frame.
uint32_t m_txCount
transmit count
void DevRxTrace(std::string context, Ptr< const Packet > p)
function to be called when the net device receives a packet
std::ofstream * m_writer
output stream
uint32_t m_rxCount
receive count
uint32_t m_shortRetryCount
short retry count
void WriteStats()
Write status function.
void TxRtsFailedTrace(std::string context, Mac48Address address)
Function to be called when a RTS frame transmission by the considered device has failed.
void PhyStateTrace(std::string context, Time start, Time duration, WifiPhyState state)
Function to be called when the PHY layer of the considered device changes state.
void PhyRxErrorTrace(std::string context, Ptr< const Packet > packet, double snr)
Function to be called when a frame reception by the PHY layer of the considered device resulted in an...
void DevTxTrace(std::string context, Ptr< const Packet > p)
function to be called when the net device transmits a packet
uint32_t m_longRetryCount
long retry count
void PhyTxTrace(std::string context, Ptr< const Packet > packet, WifiMode mode, WifiPreamble preamble, uint8_t txPower)
Function to be called when a frame is being transmitted by the PHY layer of the considered device.
uint32_t m_phyTxCount
PHY transmit count.
void TxDataFailedTrace(std::string context, Mac48Address address)
Function to be called when a data frame transmission by the considered device has failed.
uint32_t m_phyRxOkCount
PHY receive OK count.
uint32_t m_phyRxErrorCount
PHY receive error count.
void ResetCounters()
Reset counters function.
uint32_t m_exceededRetryCount
exceeded retry count
an EUI-48 address
Definition: mac48-address.h:46
holds a vector of ns3::NetDevice pointers
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
Iterator Begin() const
Get an iterator which refers to the first NetDevice in the container.
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Iterator End() const
Get an iterator which indicates past-the-last NetDevice in the container.
keep track of a set of node pointers.
Iterator End() const
Get an iterator which indicates past-the-last Node in the container.
std::vector< Ptr< Node > >::const_iterator Iterator
Node container iterator.
Iterator Begin() const
Get an iterator which refers to the first Node in the container.
uint32_t GetNDevices() const
Definition: node.cc:162
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:152
A base class which provides memory management and object aggregation.
Definition: object.h:89
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:606
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1423
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
represent a single transmission mode
Definition: wifi-mode.h:50
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: nstime.h:1424
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:975
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:707
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535
WifiPhyState
The state of the PHY layer.