diff --git a/src/helper/ascii-trace-helper.cc b/src/helper/ascii-trace-helper.cc deleted file mode 100644 index 1041a22ce..000000000 --- a/src/helper/ascii-trace-helper.cc +++ /dev/null @@ -1,830 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2009 University of Washington - * - * 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 - */ - -#include -#include -#include - -#include "ns3/abort.h" -#include "ns3/assert.h" -#include "ns3/log.h" -#include "ns3/ptr.h" -#include "ns3/packet.h" -#include "ns3/node.h" -#include "ns3/names.h" -#include "ns3/net-device.h" -#include "ns3/simulator.h" - -#include "ascii-trace-helper.h" - -NS_LOG_COMPONENT_DEFINE("AsciiTraceHelper"); - -namespace ns3 { - -AsciiTraceHelper::AsciiTraceHelper () -{ - NS_LOG_FUNCTION_NOARGS (); -} - -AsciiTraceHelper::~AsciiTraceHelper () -{ - NS_LOG_FUNCTION_NOARGS (); -} - -Ptr -AsciiTraceHelper::CreateFileStream (std::string filename, std::string filemode) -{ - NS_LOG_FUNCTION (filename << filemode); - - std::ofstream *ofstream = new std::ofstream; - std::ios_base::openmode mode; - - if (filemode == "a") - { - mode = std::ios_base::out | std::ios_base::app; - } - else if (filemode == "w") - { - mode = std::ios_base::out | std::ios_base::trunc; - } - else - { - NS_ABORT_MSG ("AsciiTraceHelper::CreateFileStream(): Unexpected file mode"); - } - - ofstream->open (filename.c_str (), mode); - NS_ABORT_MSG_UNLESS (ofstream->is_open (), "AsciiTraceHelper::CreateFileStream(): Unable to Open " << - filename << " for mode " << filemode); - - Ptr streamObject = CreateObject (); - streamObject->SetStream (ofstream); - - // - // Note that the ascii trace helper promptly forgets all about the trace file. - // We rely on the reference count of the file object which will soon be owned - // by the caller to keep the object alive. If the caller uses the stream - // object to hook a trace source, ownership of the stream object will be - // implicitly transferred to the callback which keeps the object alive. - // When the callback is destroyed (when either the trace is disconnected or - // the object with the trace source is deleted) the callback will be destroyed - // and the stream object will be destroyed, releasing the pointer and closing - // the underlying file. - // - return streamObject; -} - -std::string -AsciiTraceHelper::GetFilenameFromDevice (std::string prefix, Ptr device, bool useObjectNames) -{ - NS_LOG_FUNCTION (prefix << device << useObjectNames); - NS_ABORT_MSG_UNLESS (prefix.size (), "Empty prefix string"); - - std::ostringstream oss; - oss << prefix << "-"; - - std::string nodename; - std::string devicename; - - Ptr node = device->GetNode (); - - if (useObjectNames) - { - nodename = Names::FindName (node); - devicename = Names::FindName (device); - } - - if (nodename.size ()) - { - oss << nodename; - } - else - { - oss << node->GetId (); - } - - oss << "-"; - - if (devicename.size ()) - { - oss << devicename; - } - else - { - oss << device->GetIfIndex (); - } - - oss << ".tr"; - - return oss.str (); -} - -std::string -AsciiTraceHelper::GetFilenameFromInterfacePair ( - std::string prefix, - Ptr object, - uint32_t interface, - bool useObjectNames) -{ - NS_LOG_FUNCTION (prefix << object << interface << useObjectNames); - NS_ABORT_MSG_UNLESS (prefix.size (), "Empty prefix string"); - - std::ostringstream oss; - oss << prefix << "-"; - - std::string objname; - std::string nodename; - - Ptr node = object->GetObject (); - - if (useObjectNames) - { - objname = Names::FindName (object); - nodename = Names::FindName (node); - } - - if (objname.size ()) - { - oss << objname; - } - else if (nodename.size ()) - { - oss << nodename; - } - else - { - oss << "n" << node->GetId (); - } - - oss << "-i" << interface << ".tr"; - - return oss.str (); -} - -// -// One of the basic default trace sink sets. Enqueue: -// -// When a packet has been sent to a device for transmission, the device is -// expected to place the packet onto a transmit queue even if it does not -// have to delay the packet at all, if only to trigger this event. This -// event will eventually translate into a '+' operation in the trace file. -// -// This is typically implemented by hooking the "TxQueue/Enqueue" trace hook -// in the device (actually the Queue in the device). -// -void -AsciiTraceHelper::DefaultEnqueueSinkWithoutContext (Ptr file, Ptr p) -{ - NS_LOG_FUNCTION (file << p); - *file->GetStream () << "+ " << Simulator::Now ().GetSeconds () << " " << *p << std::endl; -} - -void -AsciiTraceHelper::DefaultEnqueueSinkWithContext (Ptr file, std::string context, Ptr p) -{ - NS_LOG_FUNCTION (file << p); - *file->GetStream () << "+ " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl; -} - -// -// One of the basic default trace sink sets. Drop: -// -// When a packet has been sent to a device for transmission, the device is -// expected to place the packet onto a transmit queue. If this queue is -// full the packet will be dropped. The device is expected to trigger an -// event to indicate that an outbound packet is being dropped. This event -// will eventually translate into a 'd' operation in the trace file. -// -// This is typically implemented by hooking the "TxQueue/Drop" trace hook -// in the device (actually the Queue in the device). -// -void -AsciiTraceHelper::DefaultDropSinkWithoutContext (Ptr file, Ptr p) -{ - NS_LOG_FUNCTION (file << p); - *file->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << *p << std::endl; -} - -void -AsciiTraceHelper::DefaultDropSinkWithContext (Ptr file, std::string context, Ptr p) -{ - NS_LOG_FUNCTION (file << p); - *file->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl; -} - -// -// One of the basic default trace sink sets. Dequeue: -// -// When a packet has been sent to a device for transmission, the device is -// expected to place the packet onto a transmit queue even if it does not -// have to delay the packet at all. The device removes the packet from the -// transmit queue when the packet is ready to send, and this dequeue will -// fire a corresponding event. This event will eventually translate into a -// '-' operation in the trace file. -// -// This is typically implemented by hooking the "TxQueue/Dequeue" trace hook -// in the device (actually the Queue in the device). -// -void -AsciiTraceHelper::DefaultDequeueSinkWithoutContext (Ptr file, Ptr p) -{ - NS_LOG_FUNCTION (file << p); - *file->GetStream () << "- " << Simulator::Now ().GetSeconds () << " " << *p << std::endl; -} - -void -AsciiTraceHelper::DefaultDequeueSinkWithContext (Ptr file, std::string context, Ptr p) -{ - NS_LOG_FUNCTION (file << p); - *file->GetStream () << "- " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl; -} - -// -// One of the basic default trace sink sets. Receive: -// -// When a packet is received by a device for transmission, the device is -// expected to trigger this event to indicate the reception has occurred. -// This event will eventually translate into an 'r' operation in the trace -// file. -// -// This is typically implemented by hooking the "MacRx" trace hook in the -// device. -void -AsciiTraceHelper::DefaultReceiveSinkWithoutContext (Ptr file, Ptr p) -{ - NS_LOG_FUNCTION (file << p); - *file->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << *p << std::endl; -} - -void -AsciiTraceHelper::DefaultReceiveSinkWithContext (Ptr file, std::string context, Ptr p) -{ - NS_LOG_FUNCTION (file << p); - *file->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl; -} - -// -// Public API -// -void -AsciiTraceUserHelperForDevice::EnableAscii (std::string prefix, Ptr nd) -{ - EnableAsciiInternal (Ptr (), prefix, nd); -} - -// -// Public API -// -void -AsciiTraceUserHelperForDevice::EnableAscii (Ptr stream, Ptr nd) -{ - EnableAsciiInternal (stream, std::string (), nd); -} - -// -// Public API -// -void -AsciiTraceUserHelperForDevice::EnableAscii (std::string prefix, std::string ndName) -{ - EnableAsciiImpl (Ptr (), prefix, ndName); -} - -// -// Public API -// -void -AsciiTraceUserHelperForDevice::EnableAscii (Ptr stream, std::string ndName) -{ - EnableAsciiImpl (stream, std::string (), ndName); -} - -// -// Private API -// -void -AsciiTraceUserHelperForDevice::EnableAsciiImpl (Ptr stream, std::string prefix, std::string ndName) -{ - Ptr nd = Names::Find (ndName); - EnableAsciiInternal (stream, prefix, nd); -} - -// -// Public API -// -void -AsciiTraceUserHelperForDevice::EnableAscii (std::string prefix, NetDeviceContainer d) -{ - EnableAsciiImpl (Ptr (), prefix, d); -} - -// -// Public API -// -void -AsciiTraceUserHelperForDevice::EnableAscii (Ptr stream, NetDeviceContainer d) -{ - EnableAsciiImpl (stream, std::string (), d); -} - -// -// Private API -// -void -AsciiTraceUserHelperForDevice::EnableAsciiImpl (Ptr stream, std::string prefix, NetDeviceContainer d) -{ - for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i) - { - Ptr dev = *i; - EnableAsciiInternal (stream, prefix, dev); - } -} - -// -// Public API -// -void -AsciiTraceUserHelperForDevice::EnableAscii (std::string prefix, NodeContainer n) -{ - EnableAsciiImpl (Ptr (), prefix, n); -} - -// -// Public API -// -void -AsciiTraceUserHelperForDevice::EnableAscii (Ptr stream, NodeContainer n) -{ - EnableAsciiImpl (stream, std::string (), n); -} - -// -// Private API -// -void -AsciiTraceUserHelperForDevice::EnableAsciiImpl (Ptr stream, std::string prefix, NodeContainer n) -{ - NetDeviceContainer devs; - for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) - { - Ptr node = *i; - for (uint32_t j = 0; j < node->GetNDevices (); ++j) - { - devs.Add (node->GetDevice (j)); - } - } - EnableAsciiImpl (stream, prefix, devs); -} - -// -// Public API -// -void -AsciiTraceUserHelperForDevice::EnableAsciiAll (std::string prefix) -{ - EnableAsciiImpl (Ptr (), prefix, NodeContainer::GetGlobal ()); -} - -// -// Public API -// -void -AsciiTraceUserHelperForDevice::EnableAsciiAll (Ptr stream) -{ - EnableAsciiImpl (stream, std::string (), NodeContainer::GetGlobal ()); -} - -// -// Public API -// -void -AsciiTraceUserHelperForDevice::EnableAscii (Ptr stream, uint32_t nodeid, uint32_t deviceid) -{ - EnableAsciiImpl (stream, std::string (), nodeid, deviceid); -} - -// -// Public API -// -void -AsciiTraceUserHelperForDevice::EnableAscii (std::string prefix, uint32_t nodeid, uint32_t deviceid) -{ - EnableAsciiImpl (Ptr (), prefix, nodeid, deviceid); -} - -// -// Private API -// -void -AsciiTraceUserHelperForDevice::EnableAsciiImpl ( - Ptr stream, - std::string prefix, - uint32_t nodeid, - uint32_t deviceid) -{ - NodeContainer n = NodeContainer::GetGlobal (); - - for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) - { - Ptr node = *i; - if (node->GetId () != nodeid) - { - continue; - } - - NS_ABORT_MSG_IF (deviceid >= node->GetNDevices (), - "AsciiTraceUserHelperForDevice::EnableAscii(): Unknown deviceid = " << deviceid); - - Ptr nd = node->GetDevice (deviceid); - - EnableAsciiInternal (stream, prefix, nd); - return; - } -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4 (std::string prefix, Ptr ipv4, uint32_t interface) -{ - EnableAsciiIpv4Internal (Ptr (), prefix, ipv4, interface); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4 (Ptr stream, Ptr ipv4, uint32_t interface) -{ - EnableAsciiIpv4Internal (stream, std::string (), ipv4, interface); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface) -{ - EnableAsciiIpv4Impl (Ptr (), prefix, ipv4Name, interface); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4 (Ptr stream, std::string ipv4Name, uint32_t interface) -{ - EnableAsciiIpv4Impl (stream, std::string (), ipv4Name, interface); -} - -// -// Private API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4Impl ( - Ptr stream, - std::string prefix, - std::string ipv4Name, - uint32_t interface) -{ - Ptr ipv4 = Names::Find (ipv4Name); - EnableAsciiIpv4Internal (stream, prefix, ipv4, interface); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4 (std::string prefix, Ipv4InterfaceContainer c) -{ - EnableAsciiIpv4Impl (Ptr (), prefix, c); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4 (Ptr stream, Ipv4InterfaceContainer c) -{ - EnableAsciiIpv4Impl (stream, std::string (), c); -} - -// -// Private API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4Impl (Ptr stream, std::string prefix, Ipv4InterfaceContainer c) -{ - for (Ipv4InterfaceContainer::Iterator i = c.Begin (); i != c.End (); ++i) - { - std::pair, uint32_t> pair = *i; - EnableAsciiIpv4Internal (stream, prefix, pair.first, pair.second); - } -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4 (std::string prefix, NodeContainer n) -{ - EnableAsciiIpv4Impl (Ptr (), prefix, n); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4 (Ptr stream, NodeContainer n) -{ - EnableAsciiIpv4Impl (stream, std::string (), n); -} - -// -// Private API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4Impl (Ptr stream, std::string prefix, NodeContainer n) -{ - for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) - { - Ptr node = *i; - Ptr ipv4 = node->GetObject (); - if (ipv4) - { - for (uint32_t j = 0; j < ipv4->GetNInterfaces (); ++j) - { - EnableAsciiIpv4Internal (stream, prefix, ipv4, j); - } - } - } -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4All (std::string prefix) -{ - EnableAsciiIpv4Impl (Ptr (), prefix, NodeContainer::GetGlobal ()); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4All (Ptr stream) -{ - EnableAsciiIpv4Impl (stream, std::string (), NodeContainer::GetGlobal ()); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4 (Ptr stream, uint32_t nodeid, uint32_t interface) -{ - EnableAsciiIpv4Impl (stream, std::string (), nodeid, interface); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4 (std::string prefix, uint32_t nodeid, uint32_t interface) -{ - EnableAsciiIpv4Impl (Ptr (), prefix, nodeid, interface); -} - -// -// Private API -// -void -AsciiTraceUserHelperForIpv4::EnableAsciiIpv4Impl ( - Ptr stream, - std::string prefix, - uint32_t nodeid, - uint32_t interface) -{ - NodeContainer n = NodeContainer::GetGlobal (); - - for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) - { - Ptr node = *i; - if (node->GetId () != nodeid) - { - continue; - } - - Ptr ipv4 = node->GetObject (); - if (ipv4) - { - EnableAsciiIpv4Internal (stream, prefix, ipv4, interface); - } - - return; - } -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6 (std::string prefix, Ptr ipv6, uint32_t interface) -{ - EnableAsciiIpv6Internal (Ptr (), prefix, ipv6, interface); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6 (Ptr stream, Ptr ipv6, uint32_t interface) -{ - EnableAsciiIpv6Internal (stream, std::string (), ipv6, interface); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6 (std::string prefix, std::string ipv6Name, uint32_t interface) -{ - EnableAsciiIpv6Impl (Ptr (), prefix, ipv6Name, interface); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6 (Ptr stream, std::string ipv6Name, uint32_t interface) -{ - EnableAsciiIpv6Impl (stream, std::string (), ipv6Name, interface); -} - -// -// Private API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6Impl ( - Ptr stream, - std::string prefix, - std::string ipv6Name, - uint32_t interface) -{ - Ptr ipv6 = Names::Find (ipv6Name); - EnableAsciiIpv6Internal (stream, prefix, ipv6, interface); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6 (std::string prefix, Ipv6InterfaceContainer c) -{ - EnableAsciiIpv6Impl (Ptr (), prefix, c); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6 (Ptr stream, Ipv6InterfaceContainer c) -{ - EnableAsciiIpv6Impl (stream, std::string (), c); -} - -// -// Private API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6Impl (Ptr stream, std::string prefix, Ipv6InterfaceContainer c) -{ - for (Ipv6InterfaceContainer::Iterator i = c.Begin (); i != c.End (); ++i) - { - std::pair, uint32_t> pair = *i; - EnableAsciiIpv6Internal (stream, prefix, pair.first, pair.second); - } -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6 (std::string prefix, NodeContainer n) -{ - EnableAsciiIpv6Impl (Ptr (), prefix, n); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6 (Ptr stream, NodeContainer n) -{ - EnableAsciiIpv6Impl (stream, std::string (), n); -} - -// -// Private API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6Impl (Ptr stream, std::string prefix, NodeContainer n) -{ - for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) - { - Ptr node = *i; - Ptr ipv6 = node->GetObject (); - if (ipv6) - { - for (uint32_t j = 0; j < ipv6->GetNInterfaces (); ++j) - { - EnableAsciiIpv6Internal (stream, prefix, ipv6, j); - } - } - } -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6All (std::string prefix) -{ - EnableAsciiIpv6Impl (Ptr (), prefix, NodeContainer::GetGlobal ()); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6All (Ptr stream) -{ - EnableAsciiIpv6Impl (stream, std::string (), NodeContainer::GetGlobal ()); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6 (Ptr stream, uint32_t nodeid, uint32_t interface) -{ - EnableAsciiIpv6Impl (stream, std::string (), nodeid, interface); -} - -// -// Public API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6 (std::string prefix, uint32_t nodeid, uint32_t interface) -{ - EnableAsciiIpv6Impl (Ptr (), prefix, nodeid, interface); -} - -// -// Private API -// -void -AsciiTraceUserHelperForIpv6::EnableAsciiIpv6Impl ( - Ptr stream, - std::string prefix, - uint32_t nodeid, - uint32_t interface) -{ - NodeContainer n = NodeContainer::GetGlobal (); - - for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) - { - Ptr node = *i; - if (node->GetId () != nodeid) - { - continue; - } - - Ptr ipv6 = node->GetObject (); - if (ipv6) - { - EnableAsciiIpv6Internal (stream, prefix, ipv6, interface); - } - - return; - } -} - -} // namespace ns3 - diff --git a/src/helper/ascii-trace-helper.h b/src/helper/ascii-trace-helper.h deleted file mode 100644 index 11c0b9693..000000000 --- a/src/helper/ascii-trace-helper.h +++ /dev/null @@ -1,844 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2010 University of Washington - * - * 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 - */ - -#ifndef ASCII_TRACE_HELPER_H -#define ASCII_TRACE_HELPER_H - -#include "ns3/assert.h" -#include "ns3/net-device-container.h" -#include "ns3/ipv4.h" -#include "ns3/ipv4-interface-container.h" -#include "ns3/ipv6.h" -#include "ns3/ipv6-interface-container.h" -#include "ns3/node-container.h" -#include "ns3/simulator.h" -#include "ns3/output-stream-object.h" - -namespace ns3 { - -/** - * \brief Manage ASCII trace files for device models - * - * Handling ascii trace files is a common operation for ns-3 devices. It is - * useful to provide a common base class for dealing with these ops. - */ - -class AsciiTraceHelper -{ -public: - /** - * @brief Create an ascii trace helper. - */ - AsciiTraceHelper (); - - /** - * @brief Destroy an ascii trace helper. - */ - ~AsciiTraceHelper (); - - /** - * @brief Let the ascii trace helper figure out a reasonable filename to use - * for an ascii trace file associated with a device. - */ - std::string GetFilenameFromDevice (std::string prefix, Ptr device, bool useObjectNames = true); - - /** - * @brief Let the ascii trace helper figure out a reasonable filename to use - * for an ascii trace file associated with a node. - */ - std::string GetFilenameFromInterfacePair (std::string prefix, Ptr object, - uint32_t interface, bool useObjectNames = true); - - /** - * @brief Create and initialize an output stream object we'll use to write the - * traced bits. - * - * One of the common issues users run into when trying to use tracing in ns-3 - * is actually a design decision made in the C++ stream library. It is not - * widely known that copy and assignment of iostreams is forbidden by - * std::basic_ios<>. This is because it is not possible to predict the - * semantics of the stream desired by a user. - * - * The tempting ns-3 idiom when tracing to a file is to create a bound callback - * with an ofstream as the bound object. Unfortunately, this implies a copy - * construction in order to get the ofstream object into the callback. This - * operation, as mentioned above, is forbidden by the STL. You could use a - * global ostream and pass a pointer to it, but that is pretty ugly. You - * could create an ostream on the stack and pass a pointer to it, but you may - * run into object lifetime issues. Ns-3 has a nice reference counted object - * that can solve the problem so we use one of those to carry the stream - * around and deal with the lifetime issues. - */ - Ptr CreateFileStream (std::string filename, std::string filemode = "w"); - - /** - * @brief Hook a trace source to the default enqueue operation trace sink that - * does not accept nor log a trace context. - */ - template - void HookDefaultEnqueueSinkWithoutContext (Ptr object, std::string traceName, Ptr stream); - - /** - * @brief Hook a trace source to the default enqueue operation trace sink that - * does accept and log a trace context. - */ - template - void HookDefaultEnqueueSinkWithContext (Ptr object, std::string traceName, Ptr stream); - - /** - * @brief Hook a trace source to the default drop operation trace sink that - * does not accept nor log a trace context. - */ - template - void HookDefaultDropSinkWithoutContext (Ptr object, std::string traceName, Ptr stream); - - /** - * @brief Hook a trace source to the default drop operation trace sink that - * does accept and log a trace context. - */ - template - void HookDefaultDropSinkWithContext (Ptr object, std::string traceName, Ptr stream); - - /** - * @brief Hook a trace source to the default dequeue operation trace sink - * that does not accept nor log a trace context. - */ - template - void HookDefaultDequeueSinkWithoutContext (Ptr object, std::string traceName, Ptr stream); - - /** - * @brief Hook a trace source to the default dequeue operation trace sink - * that does accept and log a trace context. - */ - template - void HookDefaultDequeueSinkWithContext (Ptr object, std::string traceName, Ptr stream); - - /** - * @brief Hook a trace source to the default receive operation trace sink - * that does not accept nor log a trace context. - */ - template - void HookDefaultReceiveSinkWithoutContext (Ptr object, std::string traceName, Ptr stream); - - /** - * @brief Hook a trace source to the default receive operation trace sink - * that does accept and log a trace context. - */ - template - void HookDefaultReceiveSinkWithContext (Ptr object, std::string traceName, Ptr stream); - - static void DefaultEnqueueSinkWithoutContext (Ptr file, Ptr p); - static void DefaultEnqueueSinkWithContext (Ptr file, std::string context, Ptr p); - - static void DefaultDropSinkWithoutContext (Ptr file, Ptr p); - static void DefaultDropSinkWithContext (Ptr file, std::string context, Ptr p); - - static void DefaultDequeueSinkWithoutContext (Ptr file, Ptr p); - static void DefaultDequeueSinkWithContext (Ptr file, std::string context, Ptr p); - - static void DefaultReceiveSinkWithoutContext (Ptr file, Ptr p); - static void DefaultReceiveSinkWithContext (Ptr file, std::string context, Ptr p); -}; - -template void -AsciiTraceHelper::HookDefaultEnqueueSinkWithoutContext (Ptr object, std::string tracename, Ptr file) -{ - bool result = object->TraceConnectWithoutContext (tracename, - MakeBoundCallback (&DefaultEnqueueSinkWithoutContext, file)); - NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultEnqueueSinkWithoutContext(): Unable to hook \"" - << tracename << "\""); -} - -template void -AsciiTraceHelper::HookDefaultEnqueueSinkWithContext (Ptr object, std::string tracename, Ptr file) -{ - std::string context ("XXX"); - bool result = object->TraceConnect (tracename, context, MakeBoundCallback (&DefaultEnqueueSinkWithContext, file)); - NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultEnqueueSinkWithContext(): Unable to hook \"" - << tracename << "\""); -} - -template void -AsciiTraceHelper::HookDefaultDropSinkWithoutContext (Ptr object, std::string tracename, Ptr file) -{ - bool result = object->TraceConnectWithoutContext (tracename, - MakeBoundCallback (&DefaultDropSinkWithoutContext, file)); - NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultDropSinkWithoutContext(): Unable to hook \"" - << tracename << "\""); -} - -template void -AsciiTraceHelper::HookDefaultDropSinkWithContext (Ptr object, std::string tracename, Ptr file) -{ - std::string context ("XXX"); - bool result = object->TraceConnect (tracename, context, MakeBoundCallback (&DefaultDropSinkWithContext, file)); - NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultDropSinkWithContext(): Unable to hook \"" - << tracename << "\""); -} - -template void -AsciiTraceHelper::HookDefaultDequeueSinkWithoutContext (Ptr object, std::string tracename, Ptr file) -{ - bool result = object->TraceConnectWithoutContext (tracename, - MakeBoundCallback (&DefaultDequeueSinkWithoutContext, file)); - NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultDequeueSinkWithoutContext(): Unable to hook \"" - << tracename << "\""); -} - -template void -AsciiTraceHelper::HookDefaultDequeueSinkWithContext (Ptr object, std::string tracename, Ptr file) -{ - std::string context ("XXX"); - bool result = object->TraceConnect (tracename, context, MakeBoundCallback (&DefaultDequeueSinkWithContext, file)); - NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultDequeueSinkWithContext(): Unable to hook \"" - << tracename << "\""); -} - -template void -AsciiTraceHelper::HookDefaultReceiveSinkWithoutContext (Ptr object, std::string tracename, Ptr file) -{ - bool result = object->TraceConnectWithoutContext (tracename, - MakeBoundCallback (&DefaultReceiveSinkWithoutContext, file)); - NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultReceiveSinkWithoutContext(): Unable to hook \"" - << tracename << "\""); -} - -template void -AsciiTraceHelper::HookDefaultReceiveSinkWithContext (Ptr object, std::string tracename, Ptr file) -{ - std::string context ("XXX"); - bool result = object->TraceConnect (tracename, context, MakeBoundCallback (&DefaultReceiveSinkWithContext, file)); - NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultReceiveSinkWithContext(): Unable to hook \"" - << tracename << "\""); -} - -/** - * @brief Class providing common pcap and ascii trace operations for helpers - * working with devices. - * - * There are two basic flavors of ascii tracing. The first kind will case a - * trace file to be created for every traced device in the form - * --.tr just like the pcap trace - * helpers would do. Additionally, if the object name service is used to - * define either the node or device, the name will be substituted in the - * file name. This form of ascii tracing does not include a context string - * and makes it easier to determine the source of the event. - * - * The second kind of tracing is more like ns-2 tracing in that there is - * one trace file into which all of the specified events of the specified - * devices are written. This form of ascii tracing does include a context - * string and interleaves the trace hits from all of the devices into a - * single file. - * - * It would be nice to make this class completely independent of the pcap - * trace user helper, but pybindgen doesn't support multiple inheritance - * no matter how well behaved, so even mixins are out of the question. - * Because of this, we have a basic tracing functionality that devices can - * add that implements pcap tracing: PcapUserHelperForDevice; and another - * class that enables both pcap and ascii tracing. - */ -class TraceUserHelperForDevice : public PcapUserHelperForDevice -{ -public: - /** - * @brief Enable ascii trace output on the indicated net device. - * @internal - * - * The implementation is expected to use a provided Ptr - * if it is non-null. If the OutputStreamObject is null, the implementation - * is expected to use a provided prefix to construct a new file name for - * each net device using the rules described in the class overview. - * - * If the prefix is provided, there will be one file per net device created. - * In this case, adding a trace context to the file would be pointless, so - * the device implementation is expected to TraceConnectWithoutContext. - * - * If the output stream object is provided, there may be many different - * devices writing to a single file. In this case, the device adding a - * trace context could be important, so the device implementation is - * expected to TraceConnect. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param prefix Filename prefix to use for ascii trace files. - * @param nd Net device for which you want to enable tracing. - */ - virtual void EnableAsciiInternal (Ptr stream, std::string prefix, Ptr nd) = 0; - - /** - * @brief Enable ascii trace output on the indicated net device. - * - * @param prefix Filename prefix to use for ascii files. - * @param nd Net device for which you want to enable tracing. - */ - void EnableAscii (std::string prefix, Ptr nd); - - /** - * @brief Enable ascii trace output on the indicated net device. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param nd Net device for which you want to enable tracing. - */ - void EnableAscii (Ptr stream, Ptr nd); - - /** - * @brief Enable ascii trace output the indicated net device using a device - * previously named using the ns-3 object name service. - * - * @param filename filename prefix to use for ascii files. - * @param ndName The name of the net device in which you want to enable tracing. - */ - void EnableAscii (std::string prefix, std::string ndName); - - /** - * @brief Enable ascii trace output the indicated net device using a device - * previously named using the ns-3 object name service. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param ndName The name of the net device in which you want to enable tracing. - */ - void EnableAscii (Ptr stream, std::string ndName); - - /** - * @brief Enable ascii trace output on each device in the container which is - * of the appropriate type. - * - * @param prefix Filename prefix to use for ascii files. - * @param d container of devices of type ns3::CsmaNetDevice - */ - void EnableAscii (std::string prefix, NetDeviceContainer d); - - /** - * @brief Enable ascii trace output on each device in the container which is - * of the appropriate type. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param d container of devices of type ns3::CsmaNetDevice - */ - void EnableAscii (Ptr stream, NetDeviceContainer d); - - /** - * @brief Enable ascii trace output on each device (which is of the - * appropriate type) in the nodes provided in the container. - * - * \param prefix Filename prefix to use for ascii files. - * \param n container of nodes. - */ - void EnableAscii (std::string prefix, NodeContainer n); - - /** - * @brief Enable ascii trace output on each device (which is of the - * appropriate type) in the nodes provided in the container. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * \param n container of nodes. - */ - void EnableAscii (Ptr stream, NodeContainer n); - - /** - * @brief Enable ascii trace output on each device (which is of the - * appropriate type) in the set of all nodes created in the simulation. - * - * @param prefix Filename prefix to use for ascii files. - */ - void EnableAsciiAll (std::string prefix); - - /** - * @brief Enable ascii trace output on each device (which is of the - * appropriate type) in the set of all nodes created in the simulation. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - */ - void EnableAsciiAll (Ptr stream); - - /** - * @brief Enable ascii trace output on the device specified by a global - * node-id (of a previously created node) and associated device-id. - * - * @param prefix Filename prefix to use when creating ascii trace files - * @param nodeid The node identifier/number of the node on which to enable - * ascii tracing - * @param deviceid The device identifier/index of the device on which to enable - * ascii tracing - */ - void EnableAscii (std::string prefix, uint32_t nodeid, uint32_t deviceid); - - /** - * @brief Enable ascii trace output on the device specified by a global - * node-id (of a previously created node) and associated device-id. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param nodeid The node identifier/number of the node on which to enable - * ascii tracing - * @param deviceid The device identifier/index of the device on which to enable - * ascii tracing - */ - void EnableAscii (Ptr stream, uint32_t nodeid, uint32_t deviceid); - -private: - /** - * @internal Avoid code duplication. - */ - void EnableAsciiImpl (Ptr stream, std::string prefix, uint32_t nodeid, uint32_t deviceid); - - /** - * @internal Avoid code duplication. - */ - void EnableAsciiImpl (Ptr stream, std::string prefix, NodeContainer n); - - /** - * @internal Avoid code duplication. - */ - void EnableAsciiImpl (Ptr stream, std::string prefix, NetDeviceContainer d); - - /** - * @internal Avoid code duplication. - */ - void EnableAsciiImpl (Ptr stream, std::string prefix, std::string ndName); - - /** - * @internal Avoid code duplication. - */ - void EnableAsciiImpl (Ptr stream, std::string prefix, Ptr nd); - -}; - -/** - * @brief Base class providing common ascii trace operations for helpers - * working with Ipv4 interfaces. - * - * There are two basic flavors of ascii tracing. The first kind will case a - * trace file to be created for every traced device in the form - * --.tr just like the pcap trace - * helpers would do. Additionally, if the object name service is used to - * define either the node or device, the name will be substituted in the - * file name. This form of ascii tracing does not include a context string - * and makes it easier to determine the source of the event. - * - * The second kind of tracing is more like ns-2 tracing in that there is - * one trace file into which all of the specified events of the specified - * devices are written. This form of ascii tracing does include a context - * string and interleaves the trace hits from all of the devices into a - * single file. - * - * It would be nice to make this class completely independent of the pcap - * trace user helper, but pybindgen doesn't support multiple inheritance - * no matter how well behaved, so even mixins are out of the question. - * Because of this, we have a basic tracing functionality that devices can - * add that implements pcap tracing: PcapUserHelperForIpv4; and another - * class that enables both pcap and ascii tracing: TraceUserHelperForIpv4. - * The inheritance tree then continues with PcapUserHelperForIpv6 inheriting - * from TraceUserHelperForIpv4. - */ -class TraceUserHelperForIpv4 : public PcapUserHelperForIpv4 -{ -public: - /** - * @brief Enable ascii trace output on the indicated Ipv4 and interface pair. - * @internal - * - * The implementation is expected to use a provided Ptr - * if it is non-null. If the OutputStreamObject is null, the implementation - * is expected to use a provided prefix to construct a new file name for - * each net device using the rules described in the class overview. - * - * If the prefix is provided, there will be one file per Ipv4 and interface pair - * created. In this case, adding a trace context to the file would be pointless, - * so the helper implementation is expected to TraceConnectWithoutContext. - * - * If the output stream object is provided, there may be many different Ipv4 - * and interface pairs writing to a single file. In this case, the trace - * context could be important, so the helper implementation is expected to - * TraceConnect. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param prefix Filename prefix to use for ascii trace files. - * @param ipv4 Ptr on which you want to enable tracing. - * @param interface The interface on which you want to enable tracing. - */ - virtual void EnableAsciiIpv4Internal (Ptr stream, std::string prefix, - Ptr ipv4, uint32_t interface) = 0; - - /** - * @brief Enable ascii trace output on the indicated Ipv4 and interface pair. - * - * @param prefix Filename prefix to use for ascii files. - * @param ipv4 Ptr on which you want to enable tracing. - * @param interface The interface on which you want to enable tracing. - */ - void EnableAsciiIpv4 (std::string prefix, Ptr ipv4, uint32_t interface); - - /** - * @brief Enable ascii trace output on the indicated Ipv4 and interface pair. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param ipv4 Ptr on which you want to enable tracing. - * @param interface The interface on which you want to enable tracing. - */ - void EnableAsciiIpv4 (Ptr stream, Ptr ipv4, uint32_t interface); - - /** - * @brief Enable ascii trace output the indicated Ipv4 and interface pair - * using an Ipv4 previously named using the ns-3 object name service. - * - * @param filename filename prefix to use for ascii files. - * @param ipv4Name The name of the Ipv4 on which you want to enable tracing. - * @param interface The interface on which you want to enable tracing. - */ - void EnableAsciiIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface); - - /** - * @brief Enable ascii trace output the indicated net device using a device - * previously named using the ns-3 object name service. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param ipv4Name The name of the Ipv4 on which you want to enable tracing. - * @param interface The interface on which you want to enable tracing. - */ - void EnableAsciiIpv4 (Ptr stream, std::string ipv4Name, uint32_t interface); - - /** - * @brief Enable ascii trace output on each Ipv4 and interface pair in the - * container - * - * @param prefix Filename prefix to use for ascii files. - * @param c Ipv4InterfaceContainer of Ipv4 and interface pairs on which to - * enable tracing. - */ - void EnableAsciiIpv4 (std::string prefix, Ipv4InterfaceContainer c); - - /** - * @brief Enable ascii trace output on each device in the container which is - * of the appropriate type. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param c Ipv4InterfaceContainer of Ipv4 and interface pairs on which to - * enable tracing. - */ - void EnableAsciiIpv4 (Ptr stream, Ipv4InterfaceContainer c); - - /** - * @brief Enable ascii trace output on all Ipv4 and interface pairs existing - * in the nodes provided in the container. - * - * \param prefix Filename prefix to use for ascii files. - * \param n container of nodes. - */ - void EnableAsciiIpv4 (std::string prefix, NodeContainer n); - - /** - * @brief Enable ascii trace output on all Ipv4 and interface pairs existing - * in the nodes provided in the container. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * \param n container of nodes. - */ - void EnableAsciiIpv4 (Ptr stream, NodeContainer n); - - /** - * @brief Enable ascii trace output on all Ipv4 and interface pairs existing - * in the set of all nodes created in the simulation. - * - * @param prefix Filename prefix to use for ascii files. - */ - void EnableAsciiIpv4All (std::string prefix); - - /** - * @brief Enable ascii trace output on each device (which is of the - * appropriate type) in the set of all nodes created in the simulation. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - */ - void EnableAsciiIpv4All (Ptr stream); - - /** - * @brief Enable pcap output on the Ipv4 and interface pair specified by a - * global node-id (of a previously created node) and interface. Since there - * can be only one Ipv4 aggregated to a node, the node-id unambiguously - * determines the Ipv4. - * - * @param prefix Filename prefix to use when creating ascii trace files - * @param nodeid The node identifier/number of the node on which to enable - * ascii tracing - * @param interface The device identifier/index of the device on which to enable - * ascii tracing - */ - void EnableAsciiIpv4 (std::string prefix, uint32_t nodeid, uint32_t deviceid); - - /** - * @brief Enable pcap output on the Ipv4 and interface pair specified by a - * global node-id (of a previously created node) and interface. Since there - * can be only one Ipv4 aggregated to a node, the node-id unambiguously - * determines the Ipv4. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param nodeid The node identifier/number of the node on which to enable - * ascii tracing - * @param interface The interface on which you want to enable tracing. - */ - void EnableAsciiIpv4 (Ptr stream, uint32_t nodeid, uint32_t interface); - -private: - /** - * @internal Avoid code duplication. - */ - void EnableAsciiIpv4Impl (Ptr stream, std::string prefix, uint32_t nodeid, uint32_t interface); - - /** - * @internal Avoid code duplication. - */ - void EnableAsciiIpv4Impl (Ptr stream, std::string prefix, NodeContainer n); - - /** - * @internal Avoid code duplication. - */ - void EnableAsciiIpv4Impl (Ptr stream, std::string prefix, Ipv4InterfaceContainer c); - - /** - * @internal Avoid code duplication. - */ - void EnableAsciiIpv4Impl (Ptr stream, std::string prefix, std::string ipv4Name, uint32_t interface); - - /** - * @internal Avoid code duplication. - */ - void EnableAsciiIpv4Impl (Ptr stream, std::string prefix, Ptr ipv4, uint32_t interface); - -}; - -/** - * @brief Base class providing common ascii trace operations for helpers - * working with Ipv6 interfaces. - * - * There are two basic flavors of ascii tracing. The first kind will case a - * trace file to be created for every traced device in the form - * --.tr just like the pcap trace - * helpers would do. Additionally, if the object name service is used to - * define either the node or device, the name will be substituted in the - * file name. This form of ascii tracing does not include a context string - * and makes it easier to determine the source of the event. - * - * The second kind of tracing is more like ns-2 tracing in that there is - * one trace file into which all of the specified events of the specified - * devices are written. This form of ascii tracing does include a context - * string and interleaves the trace hits from all of the devices into a - * single file. - */ -class AsciiTraceUserHelperForIpv6 -{ -public: - /** - * @brief Enable ascii trace output on the indicated Ipv6 and interface pair. - * @internal - * - * The implementation is expected to use a provided Ptr - * if it is non-null. If the OutputStreamObject is null, the implementation - * is expected to use a provided prefix to construct a new file name for - * each net device using the rules described in the class overview. - * - * If the prefix is provided, there will be one file per Ipv6 and interface pair - * created. In this case, adding a trace context to the file would be pointless, - * so the helper implementation is expected to TraceConnectWithoutContext. - * - * If the output stream object is provided, there may be many different Ipv6 - * and interface pairs writing to a single file. In this case, the trace - * context could be important, so the helper implementation is expected to - * TraceConnect. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param prefix Filename prefix to use for ascii trace files. - * @param ipv6 Ptr on which you want to enable tracing. - * @param interface The interface on which you want to enable tracing. - */ - virtual void EnableAsciiIpv6Internal (Ptr stream, std::string prefix, - Ptr ipv6, uint32_t interface) = 0; - - /** - * @brief Enable ascii trace output on the indicated Ipv6 and interface pair. - * - * @param prefix Filename prefix to use for ascii files. - * @param ipv6 Ptr on which you want to enable tracing. - * @param interface The interface on which you want to enable tracing. - */ - void EnableAsciiIpv6 (std::string prefix, - Ptr ipv6, uint32_t interface); - - /** - * @brief Enable ascii trace output on the indicated Ipv6 and interface pair. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param ipv6 Ptr on which you want to enable tracing. - * @param interface The interface on which you want to enable tracing. - */ - void EnableAsciiIpv6 (Ptr stream, - Ptr ipv6, uint32_t interface); - - /** - * @brief Enable ascii trace output the indicated Ipv6 and interface pair - * using an Ipv6 previously named using the ns-3 object name service. - * - * @param filename filename prefix to use for ascii files. - * @param ipv6Name The name of the Ipv6 on which you want to enable tracing. - * @param interface The interface on which you want to enable tracing. - */ - void EnableAsciiIpv6 (std::string prefix, - std::string ipv6Name, uint32_t interface); - - /** - * @brief Enable ascii trace output the indicated net device using a device - * previously named using the ns-3 object name service. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param ipv6Name The name of the Ipv6 on which you want to enable tracing. - * @param interface The interface on which you want to enable tracing. - */ - void EnableAsciiIpv6 (Ptr stream, - std::string ipv6Name, uint32_t interface); - - /** - * @brief Enable ascii trace output on each Ipv6 and interface pair in the - * container - * - * @param prefix Filename prefix to use for ascii files. - * @param c Ipv6InterfaceContainer of Ipv6 and interface pairs on which to - * enable tracing. - */ - void EnableAsciiIpv6 (std::string prefix, Ipv6InterfaceContainer c); - - /** - * @brief Enable ascii trace output on each device in the container which is - * of the appropriate type. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param c Ipv6InterfaceContainer of Ipv6 and interface pairs on which to - * enable tracing. - */ - void EnableAsciiIpv6 (Ptr stream, Ipv6InterfaceContainer c); - - /** - * @brief Enable ascii trace output on all Ipv6 and interface pairs existing - * in the nodes provided in the container. - * - * \param prefix Filename prefix to use for ascii files. - * \param n container of nodes. - */ - void EnableAsciiIpv6 (std::string prefix, NodeContainer n); - - /** - * @brief Enable ascii trace output on all Ipv6 and interface pairs existing - * in the nodes provided in the container. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * \param n container of nodes. - */ - void EnableAsciiIpv6 (Ptr stream, NodeContainer n); - - /** - * @brief Enable pcap output on the Ipv6 and interface pair specified by a - * global node-id (of a previously created node) and interface. Since there - * can be only one Ipv6 aggregated to a node, the node-id unambiguously - * determines the Ipv6. - * - * @param prefix Filename prefix to use when creating ascii trace files - * @param nodeid The node identifier/number of the node on which to enable - * ascii tracing - * @param interface The device identifier/index of the device on which to enable - * ascii tracing - */ - void EnableAsciiIpv6 (std::string prefix, uint32_t nodeid, uint32_t deviceid); - - /** - * @brief Enable pcap output on the Ipv6 and interface pair specified by a - * global node-id (of a previously created node) and interface. Since there - * can be only one Ipv6 aggregated to a node, the node-id unambiguously - * determines the Ipv6. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - * @param nodeid The node identifier/number of the node on which to enable - * ascii tracing - * @param interface The interface on which you want to enable tracing. - */ - void EnableAsciiIpv6 (Ptr stream, uint32_t nodeid, uint32_t interface); - - /** - * @brief Enable ascii trace output on all Ipv6 and interface pairs existing - * in the set of all nodes created in the simulation. - * - * @param prefix Filename prefix to use for ascii files. - */ - void EnableAsciiIpv6All (std::string prefix); - - /** - * @brief Enable ascii trace output on each device (which is of the - * appropriate type) in the set of all nodes created in the simulation. - * - * @param stream An OutputStreamObject representing an existing file to use - * when writing trace data. - */ - void EnableAsciiIpv6All (Ptr stream); - -private: - /** - * @internal Avoid code duplication. - */ - void EnableAsciiIpv6Impl (Ptr stream, std::string prefix, uint32_t nodeid, uint32_t interface); - - /** - * @internal Avoid code duplication. - */ - void EnableAsciiIpv6Impl (Ptr stream, std::string prefix, NodeContainer n); - - /** - * @internal Avoid code duplication. - */ - void EnableAsciiIpv6Impl (Ptr stream, std::string prefix, Ipv6InterfaceContainer c); - - /** - * @internal Avoid code duplication. - */ - void EnableAsciiIpv6Impl (Ptr stream, std::string prefix, std::string ipv6Name, uint32_t interface); - - /** - * @internal Avoid code duplication. - */ - void EnableAsciiIpv6Impl (Ptr stream, std::string prefix, Ptr ipv6, uint32_t interface); - -}; - -} // namespace ns3 - -#endif /* ASCIITRACE_HELPER_H */ diff --git a/src/helper/pcap-helper.cc b/src/helper/pcap-helper.cc deleted file mode 100644 index 4ce15398a..000000000 --- a/src/helper/pcap-helper.cc +++ /dev/null @@ -1,375 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2009 University of Washington - * - * 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 - */ - -#include -#include -#include - -#include "ns3/abort.h" -#include "ns3/assert.h" -#include "ns3/log.h" -#include "ns3/ptr.h" -#include "ns3/node.h" -#include "ns3/names.h" -#include "ns3/net-device.h" -#include "ns3/pcap-file-object.h" - -#include "pcap-helper.h" - -NS_LOG_COMPONENT_DEFINE("PcapHelper"); - -namespace ns3 { - -PcapHelper::PcapHelper () -{ - NS_LOG_FUNCTION_NOARGS (); -} - -PcapHelper::~PcapHelper () -{ - NS_LOG_FUNCTION_NOARGS (); -} - -Ptr -PcapHelper::CreateFile ( - std::string filename, - std::string filemode, - uint32_t dataLinkType, - uint32_t snapLen, - int32_t tzCorrection) -{ - NS_LOG_FUNCTION (filename << filemode << dataLinkType << snapLen << tzCorrection); - - Ptr file = CreateObject (); - bool err = file->Open (filename, filemode); - NS_ABORT_MSG_IF (err, "Unable to Open " << filename << " for mode " << filemode); - - err = file->Init (dataLinkType, snapLen, tzCorrection); - NS_ABORT_MSG_IF (err, "Unable to Init " << filename); - - // - // Note that the pcap helper promptly forgets all about the pcap file. We - // rely on the reference count of the file object which will soon be owned - // by the caller to keep the object alive. If the caller uses the file - // object to hook a trace source, ownership of the file object will be - // implicitly transferred to the callback which keeps the object alive. - // When the callback is destroyed (when either the trace is disconnected or - // the object with the trace source is deleted) the callback will be destroyed - // and the file object will be destroyed, releasing the pointer and closing - // the file. - // - return file; -} - -std::string -PcapHelper::GetFilenameFromDevice (std::string prefix, Ptr device, bool useObjectNames) -{ - NS_LOG_FUNCTION (prefix << device << useObjectNames); - NS_ABORT_MSG_UNLESS (prefix.size (), "Empty prefix string"); - - std::ostringstream oss; - oss << prefix << "-"; - - std::string nodename; - std::string devicename; - - Ptr node = device->GetNode (); - - if (useObjectNames) - { - nodename = Names::FindName (node); - devicename = Names::FindName (device); - } - - if (nodename.size ()) - { - oss << nodename; - } - else - { - oss << node->GetId (); - } - - oss << "-"; - - if (devicename.size ()) - { - oss << devicename; - } - else - { - oss << device->GetIfIndex (); - } - - oss << ".pcap"; - - return oss.str (); -} - -std::string -PcapHelper::GetFilenameFromInterfacePair (std::string prefix, Ptr object, uint32_t interface, bool useObjectNames) -{ - NS_LOG_FUNCTION (prefix << object << interface << useObjectNames); - NS_ABORT_MSG_UNLESS (prefix.size (), "Empty prefix string"); - - std::ostringstream oss; - oss << prefix << "-"; - - std::string objname; - std::string nodename; - - Ptr node = object->GetObject (); - - if (useObjectNames) - { - objname = Names::FindName (object); - nodename = Names::FindName (node); - } - - if (objname.size ()) - { - oss << objname; - } - else if (nodename.size ()) - { - oss << nodename; - } - else - { - oss << "n" << node->GetId (); - } - - oss << "-i" << interface << ".pcap"; - - return oss.str (); -} - -// -// The basic default trace sink. This one just writes the packet to the pcap -// file which is good enough for most kinds of captures. -// -void -PcapHelper::DefaultSink (Ptr file, Ptr p) -{ - NS_LOG_FUNCTION (file << p); - file->Write(Simulator::Now(), p); -} - -void -PcapUserHelperForDevice::EnablePcap (std::string prefix, Ptr nd, bool promiscuous) -{ - EnablePcapInternal (prefix, nd, promiscuous); -} - -void -PcapUserHelperForDevice::EnablePcap (std::string prefix, std::string ndName, bool promiscuous) -{ - Ptr nd = Names::Find (ndName); - EnablePcap (prefix, nd, promiscuous); -} - -void -PcapUserHelperForDevice::EnablePcap (std::string prefix, NetDeviceContainer d, bool promiscuous) -{ - for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i) - { - Ptr dev = *i; - EnablePcap (prefix, dev, promiscuous); - } -} - -void -PcapUserHelperForDevice::EnablePcap (std::string prefix, NodeContainer n, bool promiscuous) -{ - NetDeviceContainer devs; - for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) - { - Ptr node = *i; - for (uint32_t j = 0; j < node->GetNDevices (); ++j) - { - devs.Add (node->GetDevice (j)); - } - } - EnablePcap (prefix, devs, promiscuous); -} - -void -PcapUserHelperForDevice::EnablePcapAll (std::string prefix, bool promiscuous) -{ - EnablePcap (prefix, NodeContainer::GetGlobal (), promiscuous); -} - -void -PcapUserHelperForDevice::EnablePcap (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool promiscuous) -{ - NodeContainer n = NodeContainer::GetGlobal (); - - for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) - { - Ptr node = *i; - if (node->GetId () != nodeid) - { - continue; - } - - NS_ABORT_MSG_IF (deviceid >= node->GetNDevices (), "PcapUserHelperForDevice::EnablePcap(): Unknown deviceid = " - << deviceid); - Ptr nd = node->GetDevice (deviceid); - EnablePcap (prefix, nd, promiscuous); - return; - } -} - -void -PcapUserHelperForIpv4::EnablePcapIpv4 (std::string prefix, Ptr ipv4, uint32_t interface) -{ - EnablePcapIpv4Internal (prefix, ipv4, interface); -} - -void -PcapUserHelperForIpv4::EnablePcapIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface) -{ - Ptr ipv4 = Names::Find (ipv4Name); - EnablePcapIpv4 (prefix, ipv4, interface); -} - -void -PcapUserHelperForIpv4::EnablePcapIpv4 (std::string prefix, Ipv4InterfaceContainer c) -{ - for (Ipv4InterfaceContainer::Iterator i = c.Begin (); i != c.End (); ++i) - { - std::pair, uint32_t> pair = *i; - EnablePcapIpv4 (prefix, pair.first, pair.second); - } -} - -void -PcapUserHelperForIpv4::EnablePcapIpv4 (std::string prefix, NodeContainer n) -{ - for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) - { - Ptr node = *i; - Ptr ipv4 = node->GetObject (); - if (ipv4) - { - for (uint32_t j = 0; j < ipv4->GetNInterfaces (); ++j) - { - EnablePcapIpv4 (prefix, ipv4, j); - } - } - } -} - -void -PcapUserHelperForIpv4::EnablePcapIpv4All (std::string prefix) -{ - EnablePcapIpv4 (prefix, NodeContainer::GetGlobal ()); -} - -void -PcapUserHelperForIpv4::EnablePcapIpv4 (std::string prefix, uint32_t nodeid, uint32_t interface) -{ - NodeContainer n = NodeContainer::GetGlobal (); - - for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) - { - Ptr node = *i; - if (node->GetId () != nodeid) - { - continue; - } - - Ptr ipv4 = node->GetObject (); - if (ipv4) - { - EnablePcapIpv4 (prefix, ipv4, interface); - } - return; - } -} - -void -PcapUserHelperForIpv6::EnablePcapIpv6 (std::string prefix, Ptr ipv6, uint32_t interface) -{ - EnablePcapIpv6Internal (prefix, ipv6, interface); -} - -void -PcapUserHelperForIpv6::EnablePcapIpv6 (std::string prefix, std::string ipv6Name, uint32_t interface) -{ - Ptr ipv6 = Names::Find (ipv6Name); - EnablePcapIpv6 (prefix, ipv6, interface); -} - -void -PcapUserHelperForIpv6::EnablePcapIpv6 (std::string prefix, Ipv6InterfaceContainer c) -{ - for (Ipv6InterfaceContainer::Iterator i = c.Begin (); i != c.End (); ++i) - { - std::pair, uint32_t> pair = *i; - EnablePcapIpv6 (prefix, pair.first, pair.second); - } -} - -void -PcapUserHelperForIpv6::EnablePcapIpv6 (std::string prefix, NodeContainer n) -{ - for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) - { - Ptr node = *i; - Ptr ipv6 = node->GetObject (); - if (ipv6) - { - for (uint32_t j = 0; j < ipv6->GetNInterfaces (); ++j) - { - EnablePcapIpv6 (prefix, ipv6, j); - } - } - } -} - -void -PcapUserHelperForIpv6::EnablePcapIpv6All (std::string prefix) -{ - EnablePcapIpv6 (prefix, NodeContainer::GetGlobal ()); -} - -void -PcapUserHelperForIpv6::EnablePcapIpv6 (std::string prefix, uint32_t nodeid, uint32_t interface) -{ - NodeContainer n = NodeContainer::GetGlobal (); - - for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) - { - Ptr node = *i; - if (node->GetId () != nodeid) - { - continue; - } - - Ptr ipv6 = node->GetObject (); - if (ipv6) - { - EnablePcapIpv6 (prefix, ipv6, interface); - } - return; - } -} - -} // namespace ns3 - diff --git a/src/helper/pcap-helper.h b/src/helper/pcap-helper.h deleted file mode 100644 index 5a41dcb7a..000000000 --- a/src/helper/pcap-helper.h +++ /dev/null @@ -1,324 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2009 University of Washington - * - * 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 - */ - -#ifndef PCAP_HELPER_H -#define PCAP_HELPER_H - -#include "ns3/assert.h" -#include "ns3/net-device-container.h" -#include "ns3/ipv4-interface-container.h" -#include "ns3/ipv6-interface-container.h" -#include "ns3/node-container.h" -#include "ns3/simulator.h" -#include "ns3/pcap-file-object.h" -#include "ns3/ipv4.h" -#include "ns3/ipv6.h" - -namespace ns3 { - -/** - * \brief Manage pcap files for device models - * - * Handling pcap files is a common operation for ns-3 devices. It is useful to - * provide a common base class for dealing with these ops. - */ - -class PcapHelper -{ -public: - // - // These are the data link types that will be written to the pcap file. We - // don't include pcap-bpf.h to avoid an explicit dependency on the real pcap - // and we don't make an enumeration of all of the values to make it easy to - // pass new values in. - // - enum {DLT_NULL = 0}; - enum {DLT_EN10MB = 1}; - enum {DLT_PPP = 9}; - enum {DLT_RAW = 101}; - enum {DLT_IEEE802_11 = 105}; - enum {DLT_PRISM_HEADER = 119}; - enum {DLT_IEEE802_11_RADIO = 127}; - - /** - * @brief Create a pcap helper. - */ - PcapHelper (); - - /** - * @brief Destroy a pcap helper. - */ - ~PcapHelper (); - - /** - * @brief Let the pcap helper figure out a reasonable filename to use for a - * pcap file associated with a device. - */ - std::string GetFilenameFromDevice (std::string prefix, Ptr device, bool useObjectNames = true); - - /** - * @brief Let the pcap helper figure out a reasonable filename to use for the - * pcap file associated with a node. - */ - std::string GetFilenameFromInterfacePair (std::string prefix, Ptr object, - uint32_t interface, bool useObjectNames = true); - - /** - * @brief Create and initialize a pcap file. - */ - Ptr CreateFile (std::string filename, std::string filemode, - uint32_t dataLinkType, uint32_t snapLen = 65535, int32_t tzCorrection = 0); - /** - * @brief Hook a trace source to the default trace sink - */ - template void HookDefaultSink (Ptr object, std::string traceName, Ptr file); - -private: - static void DefaultSink (Ptr file, Ptr p); -}; - -template void -PcapHelper::HookDefaultSink (Ptr object, std::string tracename, Ptr file) -{ - bool result = object->TraceConnectWithoutContext (tracename.c_str (), MakeBoundCallback (&DefaultSink, file)); - NS_ASSERT_MSG (result == true, "PcapHelper::HookDefaultSink(): Unable to hook \"" << tracename << "\""); -} - -/** - * \brief Base class providing common user-level pcap operations for helpers - * representing net devices. - */ -class PcapUserHelperForDevice -{ -public: - /** - * @brief Enable pcap output the indicated net device. - * @internal - * - * @param prefix Filename prefix to use for pcap files. - * @param nd Net device for which you want to enable tracing. - * @param promiscuous If true capture all possible packets available at the device. - */ - virtual void EnablePcapInternal (std::string prefix, Ptr nd, bool promiscuous) = 0; - - /** - * @brief Enable pcap output the indicated net device. - * - * @param prefix Filename prefix to use for pcap files. - * @param nd Net device for which you want to enable tracing. - * @param promiscuous If true capture all possible packets available at the device. - */ - void EnablePcap (std::string prefix, Ptr nd, bool promiscuous = false); - - /** - * @brief Enable pcap output the indicated net device using a device previously - * named using the ns-3 object name service. - * - * @param filename filename prefix to use for pcap files. - * @param ndName The name of the net device in which you want to enable tracing. - * @param promiscuous If true capture all possible packets available at the device. - */ - void EnablePcap (std::string prefix, std::string ndName, bool promiscuous = false); - - /** - * @brief Enable pcap output on each device in the container which is of the - * appropriate type. - * - * @param prefix Filename prefix to use for pcap files. - * @param d container of devices of type ns3::CsmaNetDevice - * @param promiscuous If true capture all possible packets available at the device. - */ - void EnablePcap (std::string prefix, NetDeviceContainer d, bool promiscuous = false); - - /** - * @brief Enable pcap output on each device (which is of the appropriate type) - * in the nodes provided in the container. - * - * \param prefix Filename prefix to use for pcap files. - * \param n container of nodes. - * \param promiscuous If true capture all possible packets available at the device. - */ - void EnablePcap (std::string prefix, NodeContainer n, bool promiscuous = false); - - /** - * @brief Enable pcap output on the device specified by a global node-id (of - * a previously created node) and associated device-id. - * - * @param prefix Filename prefix to use for pcap files. - * @param promiscuous If true capture all possible packets available at the device. - */ - void EnablePcap (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool promiscuous = false); - - /** - * @brief Enable pcap output on each device (which is of the appropriate type) - * in the set of all nodes created in the simulation. - * - * @param prefix Filename prefix to use for pcap files. - * @param promiscuous If true capture all possible packets available at the device. - */ - void EnablePcapAll (std::string prefix, bool promiscuous = false); -}; - -/** - * \brief Base class providing common user-level pcap operations for helpers - * representing IPv4 protocols . - */ -class PcapUserHelperForIpv4 -{ -public: - /** - * @brief Enable pcap output the indicated Ipv4 and interface pair. - * @internal - * - * @param prefix Filename prefix to use for pcap files. - * @param ipv4 Ptr on which you want to enable tracing. - * @param interface Interface on ipv4 on which you want to enable tracing. - */ - virtual void EnablePcapIpv4Internal (std::string prefix, Ptr ipv4, uint32_t interface) = 0; - - /** - * @brief Enable pcap output the indicated Ipv4 and interface pair. - * - * @param prefix Filename prefix to use for pcap files. - * @param ipv4 Ptr on which you want to enable tracing. - * @param interface Interface on ipv4 on which you want to enable tracing. - */ - void EnablePcapIpv4 (std::string prefix, Ptr ipv4, uint32_t interface); - - /** - * @brief Enable pcap output the indicated Ipv4 and interface pair using a - * Ptr previously named using the ns-3 object name service. - * - * @param filename filename prefix to use for pcap files. - * @param ipv4Name Name of the Ptr on which you want to enable tracing. - * @param interface Interface on ipv4 on which you want to enable tracing. - */ - void EnablePcapIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface); - - /** - * @brief Enable pcap output on each Ipv4 and interface pair in the container. - * - * @param prefix Filename prefix to use for pcap files. - * @param c Ipv4InterfaceContainer of Ipv4 and interface pairs - */ - void EnablePcapIpv4 (std::string prefix, Ipv4InterfaceContainer c); - - /** - * @brief Enable pcap output on all Ipv4 and interface pairs existing in the - * nodes provided in the container. - * - * \param prefix Filename prefix to use for pcap files. - * \param n container of nodes. - */ - void EnablePcapIpv4 (std::string prefix, NodeContainer n); - - /** - * @brief Enable pcap output on the Ipv4 and interface pair specified by a - * global node-id (of a previously created node) and interface. Since there - * can be only one Ipv4 aggregated to a node, the node-id unambiguously - * determines the Ipv4. - * - * @param prefix Filename prefix to use for pcap files. - */ - void EnablePcapIpv4 (std::string prefix, uint32_t nodeid, uint32_t interface); - - /** - * @brief Enable pcap output on all Ipv4 and interface pairs existing in the - * set of all nodes created in the simulation. - * - * @param prefix Filename prefix to use for pcap files. - */ - void EnablePcapIpv4All (std::string prefix); - -}; - -/** - * \brief Base class providing common user-level pcap operations for helpers - * representing IPv6 protocols . - */ -class PcapUserHelperForIpv6 -{ -public: - /** - * @brief Enable pcap output the indicated Ipv6 and interface pair. - * @internal - * - * @param prefix Filename prefix to use for pcap files. - * @param ipv6 Ptr on which you want to enable tracing. - * @param interface Interface on ipv6 on which you want to enable tracing. - */ - virtual void EnablePcapIpv6Internal (std::string prefix, Ptr ipv6, uint32_t interface) = 0; - - /** - * @brief Enable pcap output the indicated Ipv6 and interface pair. - * - * @param prefix Filename prefix to use for pcap files. - * @param ipv6 Ptr on which you want to enable tracing. - * @param interface Interface on ipv6 on which you want to enable tracing. - */ - void EnablePcapIpv6 (std::string prefix, Ptr ipv6, uint32_t interface); - - /** - * @brief Enable pcap output the indicated Ipv6 and interface pair using a - * Ptr previously named using the ns-3 object name service. - * - * @param filename filename prefix to use for pcap files. - * @param ipv6Name Name of the Ptr on which you want to enable tracing. - * @param interface Interface on ipv6 on which you want to enable tracing. - */ - void EnablePcapIpv6 (std::string prefix, std::string ipv6Name, uint32_t interface); - - /** - * @brief Enable pcap output on each Ipv6 and interface pair in the container. - * - * @param prefix Filename prefix to use for pcap files. - * @param c Ipv6InterfaceContainer of Ipv6 and interface pairs - */ - void EnablePcapIpv6 (std::string prefix, Ipv6InterfaceContainer c); - - /** - * @brief Enable pcap output on all Ipv6 and interface pairs existing in the - * nodes provided in the container. - * - * \param prefix Filename prefix to use for pcap files. - * \param n container of nodes. - */ - void EnablePcapIpv6 (std::string prefix, NodeContainer n); - - /** - * @brief Enable pcap output on the Ipv6 and interface pair specified by a - * global node-id (of a previously created node) and interface. Since there - * can be only one Ipv6 aggregated to a node, the node-id unambiguously - * determines the Ipv6. - * - * @param prefix Filename prefix to use for pcap files. - */ - void EnablePcapIpv6 (std::string prefix, uint32_t nodeid, uint32_t interface); - - /** - * @brief Enable pcap output on all Ipv6 and interface pairs existing in the - * set of all nodes created in the simulation. - * - * @param prefix Filename prefix to use for pcap files. - */ - void EnablePcapIpv6All (std::string prefix); -}; - -} // namespace ns3 - -#endif /* PCAP_HELPER_H */