added AthstatsWifiTraceSink and AthstatsHelper

This commit is contained in:
Nicola Baldo
2009-08-24 13:32:06 +02:00
parent 53f3c0654d
commit 2dcc93a0ae
4 changed files with 545 additions and 0 deletions

View File

@@ -26,6 +26,7 @@
#include "ns3/mobility-module.h"
#include "ns3/contrib-module.h"
#include "ns3/wifi-module.h"
#include "ns3/athstats-helper.h"
#include <iostream>
@@ -110,6 +111,9 @@ AdvancePosition (Ptr<Node> node)
int main (int argc, char *argv[])
{
CommandLine cmd;
cmd.Parse (argc, argv);
Packet::EnablePrinting ();
// enable rts cts all the time.
@@ -175,6 +179,10 @@ int main (int argc, char *argv[])
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/RxError", MakeCallback (&PhyRxErrorTrace));
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/Tx", MakeCallback (&PhyTxTrace));
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/State", MakeCallback (&PhyStateTrace));
AthstatsHelper athstats;
athstats.EnableAthstats("athstats-sta", stas);
athstats.EnableAthstats("athstats-ap", ap);
Simulator::Run ();

View File

@@ -0,0 +1,309 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2009 CTTC
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Nicola Baldo <nbaldo@cttc.es>
*/
#include "ns3/log.h"
#include "ns3/assert.h"
#include "ns3/abort.h"
#include "ns3/simulator.h"
#include "ns3/nstime.h"
#include "ns3/config.h"
#include "athstats-helper.h"
#include <iomanip>
#include <iostream>
#include <fstream>
NS_LOG_COMPONENT_DEFINE("Athstats");
namespace ns3 {
AthstatsHelper::AthstatsHelper ()
: m_interval (Seconds (1.0))
{
}
void
AthstatsHelper::EnableAthstats (std::string filename, uint32_t nodeid, uint32_t deviceid)
{
Ptr<AthstatsWifiTraceSink> athstats = CreateObject<AthstatsWifiTraceSink> ();
std::ostringstream oss;
oss << filename
<< "_" << std::setfill ('0') << std::setw (3) << std::right << nodeid
<< "_" << std::setfill ('0') << std::setw (3) << std::right << deviceid;
athstats->Open (oss.str ());
oss.str ("");
oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
std::string devicepath = oss.str ();
Config::Connect (devicepath + "/Mac/MacTx", MakeCallback (&AthstatsWifiTraceSink::DevTxTrace, athstats));
Config::Connect (devicepath + "/Mac/MacRx", MakeCallback (&AthstatsWifiTraceSink::DevRxTrace, athstats));
Config::Connect (devicepath + "/RemoteStationManager/TxRtsFailed", MakeCallback (&AthstatsWifiTraceSink::TxRtsFailedTrace, athstats));
Config::Connect (devicepath + "/RemoteStationManager/MacTxDataFailed", MakeCallback (&AthstatsWifiTraceSink::TxDataFailedTrace, athstats));
Config::Connect (devicepath + "/RemoteStationManager/MacTxFinalRtsFailed", MakeCallback (&AthstatsWifiTraceSink::TxFinalRtsFailedTrace, athstats));
Config::Connect (devicepath + "/RemoteStationManager/MacTxFinalDataFailed", MakeCallback (&AthstatsWifiTraceSink::TxFinalDataFailedTrace, athstats));
Config::Connect (devicepath + "/Phy/State/RxOk", MakeCallback (&AthstatsWifiTraceSink::PhyRxOkTrace, athstats));
Config::Connect (devicepath + "/Phy/State/RxError", MakeCallback (&AthstatsWifiTraceSink::PhyRxErrorTrace, athstats));
Config::Connect (devicepath + "/Phy/State/Tx", MakeCallback (&AthstatsWifiTraceSink::PhyTxTrace, athstats));
Config::Connect (devicepath + "/Phy/State/State", MakeCallback (&AthstatsWifiTraceSink::PhyStateTrace, athstats));
}
void
AthstatsHelper::EnableAthstats (std::string filename, Ptr<NetDevice> nd)
{
EnableAthstats (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
}
void
AthstatsHelper::EnableAthstats (std::string filename, NetDeviceContainer d)
{
for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
{
Ptr<NetDevice> dev = *i;
EnableAthstats (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
}
}
void
AthstatsHelper::EnableAthstats (std::string filename, NodeContainer n)
{
NetDeviceContainer devs;
for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
{
Ptr<Node> node = *i;
for (uint32_t j = 0; j < node->GetNDevices (); ++j)
{
devs.Add (node->GetDevice (j));
}
}
EnableAthstats (filename, devs);
}
NS_OBJECT_ENSURE_REGISTERED (AthstatsWifiTraceSink);
TypeId
AthstatsWifiTraceSink::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::AthstatsWifiTraceSink")
.SetParent<Object> ()
.AddConstructor<AthstatsWifiTraceSink> ()
.AddAttribute ("Interval",
"Time interval between reports",
TimeValue (Seconds(1.0)),
MakeTimeAccessor (&AthstatsWifiTraceSink::m_interval),
MakeTimeChecker ())
;
return tid;
}
AthstatsWifiTraceSink::AthstatsWifiTraceSink ()
: m_txCount (0),
m_rxCount (0),
m_shortRetryCount (0),
m_longRetryCount (0),
m_exceededRetryCount (0),
m_phyRxOkCount (0),
m_phyRxErrorCount (0),
m_phyTxCount (0),
m_writer (0)
{
Simulator::ScheduleNow (&AthstatsWifiTraceSink::WriteStats, this);
}
AthstatsWifiTraceSink::~AthstatsWifiTraceSink ()
{
NS_LOG_FUNCTION (this);
if (m_writer != 0)
{
NS_LOG_LOGIC ("m_writer nonzero " << m_writer);
if (m_writer->is_open ())
{
NS_LOG_LOGIC ("m_writer open. Closing " << m_writer);
m_writer->close ();
}
NS_LOG_LOGIC ("Deleting writer " << m_writer);
delete m_writer;
NS_LOG_LOGIC ("m_writer = 0");
m_writer = 0;
}
else
{
NS_LOG_LOGIC ("m_writer == 0");
}
}
void
AthstatsWifiTraceSink::ResetCounters ()
{
m_txCount = 0;
m_rxCount = 0;
m_shortRetryCount = 0;
m_longRetryCount = 0;
m_exceededRetryCount = 0;
m_phyRxOkCount = 0;
m_phyRxErrorCount = 0;
m_phyTxCount = 0;
}
void
AthstatsWifiTraceSink::DevTxTrace (std::string context, Ptr<const Packet> p)
{
NS_LOG_FUNCTION (this << context <<p);
++m_txCount;
}
void
AthstatsWifiTraceSink::DevRxTrace (std::string context, Ptr<const Packet> p)
{
NS_LOG_FUNCTION (this << context <<p);
++m_rxCount;
}
void
AthstatsWifiTraceSink::TxRtsFailedTrace (std::string context, Mac48Address address)
{
NS_LOG_FUNCTION (this << context << address);
++m_shortRetryCount;
}
void
AthstatsWifiTraceSink::TxDataFailedTrace (std::string context, Mac48Address address)
{
NS_LOG_FUNCTION (this << context << address);
++m_longRetryCount;
}
void
AthstatsWifiTraceSink::TxFinalRtsFailedTrace (std::string context, Mac48Address address)
{
NS_LOG_FUNCTION (this << context << address);
++m_exceededRetryCount;
}
void
AthstatsWifiTraceSink::TxFinalDataFailedTrace (std::string context, Mac48Address address)
{
NS_LOG_FUNCTION (this << context << address);
++m_exceededRetryCount;
}
void
AthstatsWifiTraceSink::PhyRxOkTrace (std::string context, Ptr<const Packet> packet, double snr, WifiMode mode, enum WifiPreamble preamble)
{
NS_LOG_FUNCTION (this << context <<packet<< " mode=" << mode << " snr=" << snr );
++m_phyRxOkCount;
}
void
AthstatsWifiTraceSink::PhyRxErrorTrace (std::string context, Ptr<const Packet> packet, double snr)
{
NS_LOG_FUNCTION (this << context <<packet <<" snr=" << snr );
++m_phyRxErrorCount;
}
void
AthstatsWifiTraceSink::PhyTxTrace (std::string context, Ptr<const Packet> packet, WifiMode mode, WifiPreamble preamble, uint8_t txPower)
{
NS_LOG_FUNCTION (this << context << packet << "PHYTX mode=" << mode );
++m_phyTxCount;
}
void
AthstatsWifiTraceSink::PhyStateTrace (std::string context, Time start, Time duration, enum WifiPhy::State state)
{
NS_LOG_FUNCTION (this << context << start << duration << state);
}
void
AthstatsWifiTraceSink::Open (std::string const &name)
{
NS_LOG_FUNCTION (this << name);
NS_ABORT_MSG_UNLESS (m_writer == 0, "AthstatsWifiTraceSink::Open (): m_writer already allocated (std::ofstream leak detected)");
m_writer = new std::ofstream ();
NS_ABORT_MSG_UNLESS (m_writer, "AthstatsWifiTraceSink::Open (): Cannot allocate m_writer");
NS_LOG_LOGIC ("Created writer " << m_writer);
m_writer->open (name.c_str (), std::ios_base::binary | std::ios_base::out);
NS_ABORT_MSG_IF (m_writer->fail (), "AthstatsWifiTraceSink::Open (): m_writer->open (" << name.c_str () << ") failed");
NS_ASSERT_MSG (m_writer->is_open (), "AthstatsWifiTraceSink::Open (): m_writer not open");
NS_LOG_LOGIC ("Writer opened successfully");
}
void
AthstatsWifiTraceSink::WriteStats ()
{
NS_ABORT_MSG_UNLESS (this, "function called with null this pointer, now=" << Now () );
// the comments below refer to how each value maps to madwifi's athstats
// I know C strings are ugly but that's the quickest way to use exactly the same format as in madwifi
char str[200];
snprintf (str, 200, "%8u %8u %7u %7u %7u %6u %6u %6u %7u %4u %3uM\n",
m_txCount, // /proc/net/dev transmitted packets to which we should subract mgmt frames
m_rxCount, // /proc/net/dev received packets but subracts mgmt frames from it
0, // ast_tx_altrate,
m_shortRetryCount, // ast_tx_shortretry,
m_longRetryCount, // ast_tx_longretry,
m_exceededRetryCount, // ast_tx_xretries,
m_phyRxErrorCount, // ast_rx_crcerr,
0, // ast_rx_badcrypt,
0, // ast_rx_phyerr,
0, // ast_rx_rssi,
0 // rate
);
if (m_writer)
{
*m_writer << str;
ResetCounters ();
Simulator::Schedule (m_interval, &AthstatsWifiTraceSink::WriteStats, this);
}
}
} // namespace ns3

View File

@@ -0,0 +1,226 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2009 CTTC
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Nicola Baldo <nbaldo@cttc.es>
*/
#ifndef ATHSTATS_HELPER_H
#define ATHSTATS_HELPER_H
#include<string>
#include "ns3/object.h"
#include "ns3/attribute.h"
#include "ns3/object-factory.h"
#include "ns3/node-container.h"
#include "ns3/net-device-container.h"
#include "ns3/nstime.h"
#include "ns3/wifi-phy.h"
#include "ns3/double.h"
#include "ns3/mac48-address.h"
namespace ns3 {
class NetDevice;
/**
* @brief create AthstatsWifiTraceSink instances and connect them to wifi devices
*
*
*/
class AthstatsHelper
{
public:
AthstatsHelper ();
void EnableAthstats (std::string filename, uint32_t nodeid, uint32_t deviceid);
void EnableAthstats (std::string filename, Ptr<NetDevice> nd);
void EnableAthstats (std::string filename, NetDeviceContainer d);
void EnableAthstats (std::string filename, NodeContainer n);
private:
Time m_interval;
};
/**
* @brief trace sink for wifi device that mimics madwifi's athstats tool.
*
* The AthstatsWifiTraceSink class is a trace sink to be connected to several of the traces
* available within a wifi device. The purpose of AthstatsWifiTraceSink is to
* mimic the behavior of the athstats tool distributed wih the madwifi
* driver. In particular, the reproduced behavior is that obtained
* when executing athstats without parameters: a report written in
* text format is produced every fixed interval, based on the events
* observed by the wifi device.
*
* Differences with the "real" athstats:
*
* - AthstatsWifiTraceSink is expected to write its output to a file
* (not to stdout).
*
* - only a subset of the metrics supported by athstats is supported
* by AthstatsWifiTraceSink
*
* - AthstatsWifiTraceSink does never produce a cumulative report.
*/
class AthstatsWifiTraceSink : public Object
{
public:
static TypeId GetTypeId (void);
AthstatsWifiTraceSink ();
virtual ~AthstatsWifiTraceSink ();
/**
* function to be called when the net device transmittes a packet
*
* @param context
* @param p the packet being transmitted
*/
void DevTxTrace (std::string context, Ptr<const Packet> p);
/**
* function to be called when the net device receives a packet
*
* @param context
* @param p the packet being received
*/
void DevRxTrace (std::string context, Ptr<const Packet> p);
/**
* Function to be called when a RTS frame transmission by the considered
* device has failed
*
* @param context
* @param address the MAC address of the remote station
*/
void TxRtsFailedTrace (std::string context, Mac48Address address);
/**
* Function to be called when a data frame transmission by the considered
* device has failed
*
* @param context
* @param address the MAC address of the remote station
*/
void TxDataFailedTrace (std::string context, Mac48Address address);
/**
* Function to be called when the transmission of a RTS frame has
* exceeded the retry limit
*
* @param context
* @param address the MAC address of the remote station
*/
void TxFinalRtsFailedTrace (std::string context, Mac48Address address);
/**
* Function to be called when the transmission of a data frame has
* exceeded the retry limit
*
* @param context
* @param address the MAC address of the remote station
*/
void TxFinalDataFailedTrace (std::string context, Mac48Address address);
/**
* Function to be called when the PHY layer of the considered
* device receives a frame
*
* @param context
* @param packet
* @param snr
* @param mode
* @param preamble
*/
void PhyRxOkTrace (std::string context, Ptr<const Packet> packet, double snr, WifiMode mode, enum WifiPreamble preamble);
/**
* Function to be called when a frame reception by the PHY
* layer of the considered device resulted in an error due to a failure in the CRC check of
* the frame
*
* @param context
* @param packet
* @param snr
*/
void PhyRxErrorTrace (std::string context, Ptr<const Packet> packet, double snr);
/**
* Function to be called when a frame is being transmitted by the
* PHY layer of the considered device
*
* @param context
* @param packet
* @param mode
* @param preamble
* @param txPower
*/
void PhyTxTrace (std::string context, Ptr<const Packet> packet, WifiMode mode, WifiPreamble preamble, uint8_t txPower);
/**
* Function to be called when the PHY layer of the considered device
* changes state
*
* @param context
* @param start
* @param duration
* @param state
*/
void PhyStateTrace (std::string context, Time start, Time duration, enum WifiPhy::State state);
/**
* Open a file for output
*
* @param name the name of the file to be opened.
*/
void Open (std::string const& name);
private:
void WriteStats ();
void ResetCounters ();
uint32_t m_txCount;
uint32_t m_rxCount;
uint32_t m_shortRetryCount;
uint32_t m_longRetryCount;
uint32_t m_exceededRetryCount;
uint32_t m_phyRxOkCount;
uint32_t m_phyRxErrorCount;
uint32_t m_phyTxCount;
std::ofstream *m_writer;
Time m_interval;
}; // class AthstatsWifiTraceSink
} // namespace ns3
#endif /* ATHSTATS_HELPER_H */

View File

@@ -28,6 +28,7 @@ def build(bld):
'ipv4-global-routing-helper.cc',
'ipv4-list-routing-helper.cc',
'ipv4-routing-helper.cc',
'athstats-helper.cc',
'ipv6-address-helper.cc',
'ipv6-interface-container.cc',
'ipv6-static-routing-helper.cc',
@@ -64,6 +65,7 @@ def build(bld):
'ipv4-global-routing-helper.h',
'ipv4-list-routing-helper.h',
'ipv4-routing-helper.h',
'athstats-helper.h',
'ipv6-address-helper.h',
'ipv6-interface-container.h',
'ipv6-static-routing-helper.h',