A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
athstats-helper.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 CTTC
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Nicola Baldo <nbaldo@cttc.es>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/assert.h"
23 #include "ns3/abort.h"
24 #include "ns3/simulator.h"
25 #include "ns3/nstime.h"
26 #include "ns3/config.h"
27 #include "athstats-helper.h"
28 #include <iomanip>
29 #include <iostream>
30 #include <fstream>
31 
32 
33 NS_LOG_COMPONENT_DEFINE ("Athstats");
34 
35 namespace ns3 {
36 
37 
38 AthstatsHelper::AthstatsHelper ()
39  : m_interval (Seconds (1.0))
40 {
41 }
42 
43 void
44 AthstatsHelper::EnableAthstats (std::string filename, uint32_t nodeid, uint32_t deviceid)
45 {
46  Ptr<AthstatsWifiTraceSink> athstats = CreateObject<AthstatsWifiTraceSink> ();
47  std::ostringstream oss;
48  oss << filename
49  << "_" << 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", MakeCallback (&AthstatsWifiTraceSink::DevTxTrace, athstats));
58  Config::Connect (devicepath + "/Mac/MacRx", MakeCallback (&AthstatsWifiTraceSink::DevRxTrace, athstats));
59 
60  Config::Connect (devicepath + "/RemoteStationManager/TxRtsFailed", MakeCallback (&AthstatsWifiTraceSink::TxRtsFailedTrace, athstats));
61  Config::Connect (devicepath + "/RemoteStationManager/MacTxDataFailed", MakeCallback (&AthstatsWifiTraceSink::TxDataFailedTrace, athstats));
62  Config::Connect (devicepath + "/RemoteStationManager/MacTxFinalRtsFailed", MakeCallback (&AthstatsWifiTraceSink::TxFinalRtsFailedTrace, athstats));
63  Config::Connect (devicepath + "/RemoteStationManager/MacTxFinalDataFailed", MakeCallback (&AthstatsWifiTraceSink::TxFinalDataFailedTrace, athstats));
64 
65  Config::Connect (devicepath + "/Phy/State/RxOk", MakeCallback (&AthstatsWifiTraceSink::PhyRxOkTrace, athstats));
66  Config::Connect (devicepath + "/Phy/State/RxError", MakeCallback (&AthstatsWifiTraceSink::PhyRxErrorTrace, athstats));
67  Config::Connect (devicepath + "/Phy/State/Tx", MakeCallback (&AthstatsWifiTraceSink::PhyTxTrace, athstats));
68  Config::Connect (devicepath + "/Phy/State/State", MakeCallback (&AthstatsWifiTraceSink::PhyStateTrace, athstats));
69 }
70 
71 void
72 AthstatsHelper::EnableAthstats (std::string filename, Ptr<NetDevice> nd)
73 {
74  EnableAthstats (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
75 }
76 
77 
78 void
79 AthstatsHelper::EnableAthstats (std::string filename, NetDeviceContainer d)
80 {
81  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
82  {
83  Ptr<NetDevice> dev = *i;
84  EnableAthstats (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
85  }
86 }
87 
88 
89 void
90 AthstatsHelper::EnableAthstats (std::string filename, NodeContainer n)
91 {
92  NetDeviceContainer devs;
93  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
94  {
95  Ptr<Node> node = *i;
96  for (uint32_t j = 0; j < node->GetNDevices (); ++j)
97  {
98  devs.Add (node->GetDevice (j));
99  }
100  }
101  EnableAthstats (filename, devs);
102 }
103 
104 
105 
106 
107 
108 NS_OBJECT_ENSURE_REGISTERED (AthstatsWifiTraceSink);
109 
110 TypeId
111 AthstatsWifiTraceSink::GetTypeId (void)
112 {
113  static TypeId tid = TypeId ("ns3::AthstatsWifiTraceSink")
114  .SetParent<Object> ()
115  .AddConstructor<AthstatsWifiTraceSink> ()
116  .AddAttribute ("Interval",
117  "Time interval between reports",
118  TimeValue (Seconds (1.0)),
119  MakeTimeAccessor (&AthstatsWifiTraceSink::m_interval),
120  MakeTimeChecker ())
121  ;
122  return tid;
123 }
124 
125 AthstatsWifiTraceSink::AthstatsWifiTraceSink ()
126  : m_txCount (0),
127  m_rxCount (0),
128  m_shortRetryCount (0),
129  m_longRetryCount (0),
130  m_exceededRetryCount (0),
131  m_phyRxOkCount (0),
132  m_phyRxErrorCount (0),
133  m_phyTxCount (0),
134  m_writer (0)
135 {
136  Simulator::ScheduleNow (&AthstatsWifiTraceSink::WriteStats, this);
137 }
138 
139 AthstatsWifiTraceSink::~AthstatsWifiTraceSink ()
140 {
141  NS_LOG_FUNCTION (this);
142 
143  if (m_writer != 0)
144  {
145  NS_LOG_LOGIC ("m_writer nonzero " << m_writer);
146  if (m_writer->is_open ())
147  {
148  NS_LOG_LOGIC ("m_writer open. Closing " << m_writer);
149  m_writer->close ();
150  }
151 
152  NS_LOG_LOGIC ("Deleting writer " << m_writer);
153  delete m_writer;
154 
155  NS_LOG_LOGIC ("m_writer = 0");
156  m_writer = 0;
157  }
158  else
159  {
160  NS_LOG_LOGIC ("m_writer == 0");
161  }
162 }
163 
164 void
165 AthstatsWifiTraceSink::ResetCounters ()
166 {
167  m_txCount = 0;
168  m_rxCount = 0;
169  m_shortRetryCount = 0;
170  m_longRetryCount = 0;
171  m_exceededRetryCount = 0;
172  m_phyRxOkCount = 0;
173  m_phyRxErrorCount = 0;
174  m_phyTxCount = 0;
175 }
176 
177 void
178 AthstatsWifiTraceSink::DevTxTrace (std::string context, Ptr<const Packet> p)
179 {
180  NS_LOG_FUNCTION (this << context << p);
181  ++m_txCount;
182 }
183 
184 void
185 AthstatsWifiTraceSink::DevRxTrace (std::string context, Ptr<const Packet> p)
186 {
187  NS_LOG_FUNCTION (this << context << p);
188  ++m_rxCount;
189 }
190 
191 
192 void
193 AthstatsWifiTraceSink::TxRtsFailedTrace (std::string context, Mac48Address address)
194 {
195  NS_LOG_FUNCTION (this << context << address);
196  ++m_shortRetryCount;
197 }
198 
199 void
200 AthstatsWifiTraceSink::TxDataFailedTrace (std::string context, Mac48Address address)
201 {
202  NS_LOG_FUNCTION (this << context << address);
203  ++m_longRetryCount;
204 }
205 
206 void
207 AthstatsWifiTraceSink::TxFinalRtsFailedTrace (std::string context, Mac48Address address)
208 {
209  NS_LOG_FUNCTION (this << context << address);
210  ++m_exceededRetryCount;
211 }
212 
213 void
214 AthstatsWifiTraceSink::TxFinalDataFailedTrace (std::string context, Mac48Address address)
215 {
216  NS_LOG_FUNCTION (this << context << address);
217  ++m_exceededRetryCount;
218 }
219 
220 
221 
222 void
223 AthstatsWifiTraceSink::PhyRxOkTrace (std::string context, Ptr<const Packet> packet, double snr, WifiMode mode, enum WifiPreamble preamble)
224 {
225  NS_LOG_FUNCTION (this << context << packet << " mode=" << mode << " snr=" << snr );
226  ++m_phyRxOkCount;
227 }
228 
229 void
230 AthstatsWifiTraceSink::PhyRxErrorTrace (std::string context, Ptr<const Packet> packet, double snr)
231 {
232  NS_LOG_FUNCTION (this << context << packet << " snr=" << snr );
233  ++m_phyRxErrorCount;
234 }
235 
236 void
237 AthstatsWifiTraceSink::PhyTxTrace (std::string context, Ptr<const Packet> packet, WifiMode mode, WifiPreamble preamble, uint8_t txPower)
238 {
239  NS_LOG_FUNCTION (this << context << packet << "PHYTX mode=" << mode );
240  ++m_phyTxCount;
241 }
242 
243 
244 void
245 AthstatsWifiTraceSink::PhyStateTrace (std::string context, Time start, Time duration, enum WifiPhy::State state)
246 {
247  NS_LOG_FUNCTION (this << context << start << duration << state);
248 
249 }
250 
251 
252 
253 void
254 AthstatsWifiTraceSink::Open (std::string const &name)
255 {
256  NS_LOG_FUNCTION (this << name);
257  NS_ABORT_MSG_UNLESS (m_writer == 0, "AthstatsWifiTraceSink::Open (): m_writer already allocated (std::ofstream leak detected)");
258 
259  m_writer = new std::ofstream ();
260  NS_ABORT_MSG_UNLESS (m_writer, "AthstatsWifiTraceSink::Open (): Cannot allocate m_writer");
261 
262  NS_LOG_LOGIC ("Created writer " << m_writer);
263 
264  m_writer->open (name.c_str (), std::ios_base::binary | std::ios_base::out);
265  NS_ABORT_MSG_IF (m_writer->fail (), "AthstatsWifiTraceSink::Open (): m_writer->open (" << name.c_str () << ") failed");
266 
267  NS_ASSERT_MSG (m_writer->is_open (), "AthstatsWifiTraceSink::Open (): m_writer not open");
268 
269  NS_LOG_LOGIC ("Writer opened successfully");
270 }
271 
272 
273 void
274 AthstatsWifiTraceSink::WriteStats ()
275 {
276  NS_ABORT_MSG_UNLESS (this, "function called with null this pointer, now=" << Now () );
277  // the comments below refer to how each value maps to madwifi's athstats
278  // I know C strings are ugly but that's the quickest way to use exactly the same format as in madwifi
279  char str[200];
280  snprintf (str, 200, "%8u %8u %7u %7u %7u %6u %6u %6u %7u %4u %3uM\n",
281  (unsigned int) m_txCount, // /proc/net/dev transmitted packets to which we should subract mgmt frames
282  (unsigned int) m_rxCount, // /proc/net/dev received packets but subracts mgmt frames from it
283  (unsigned int) 0, // ast_tx_altrate,
284  (unsigned int) m_shortRetryCount, // ast_tx_shortretry,
285  (unsigned int) m_longRetryCount, // ast_tx_longretry,
286  (unsigned int) m_exceededRetryCount, // ast_tx_xretries,
287  (unsigned int) m_phyRxErrorCount, // ast_rx_crcerr,
288  (unsigned int) 0, // ast_rx_badcrypt,
289  (unsigned int) 0, // ast_rx_phyerr,
290  (unsigned int) 0, // ast_rx_rssi,
291  (unsigned int) 0 // rate
292  );
293 
294  if (m_writer)
295  {
296 
297  *m_writer << str;
298 
299  ResetCounters ();
300  Simulator::Schedule (m_interval, &AthstatsWifiTraceSink::WriteStats, this);
301  }
302 }
303 
304 
305 
306 
307 } // namespace ns3
308 
309 
keep track of time unit.
Definition: nstime.h:149
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:88
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if cond is false.
Definition: abort.h:131
WifiPreamble
Definition: wifi-preamble.h:29
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
an EUI-48 address
Definition: mac48-address.h:41
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:286
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if cond is true.
Definition: abort.h:98