diff --git a/doc/tutorial/tracing.texi b/doc/tutorial/tracing.texi index 6b029f3bb..387a26dec 100644 --- a/doc/tutorial/tracing.texi +++ b/doc/tutorial/tracing.texi @@ -18,7 +18,7 @@ * Background:: * Overview:: * A Real Example:: -* Using Mid-Level Helpers:: +* Using Mid-Level Trace Helpers:: @end menu @c ============================================================================ @@ -574,7 +574,7 @@ are familiar with @code{GetObject}, we have asked the system to do the following We are now at the last Object in the path, so we turn our attention to the Attributes of that Object. The @code{MobilityModel} class defines an Attribute -called ``CourseChange.'' You can see this by looking at the source code in +called ``CourseChange''. You can see this by looking at the source code in @code{src/mobility/mobility-model.cc} and searching for ``CourseChange'' in your favorite editor. You should find, @@ -624,7 +624,7 @@ In the example, the only code registering an interest was the code that provided the config path. Therefore, the @code{CourseChange} function that was hooked from Node number seven will be the only Callback called. -The final piece of the puzzle is the ``context.'' Recall that we saw an output +The final piece of the puzzle is the ``context''. Recall that we saw an output looking something like the following from @code{third.cc}: @verbatim @@ -669,7 +669,7 @@ see three extremely useful links: @item The list of all global values @end itemize -The list of interest to us here is ``the list of all trace sources.'' Go +The list of interest to us here is ``the list of all trace sources''. Go ahead and select that link. You will see, perhaps not too surprisingly, a list of all of the trace sources available in the @code{ns-3} core. @@ -714,7 +714,7 @@ the NS-3 documentation tree by clicking its ``+'' box. You will now see a list of all of the classes in @code{ns-3}. Scroll down until you see the entry for @code{ns3::RandomWalk2dMobilityModel} and follow that link. You should now be looking at the ``ns3::RandomWalk2dMobilityModel Class -Reference.'' +Reference''. If you now scroll down to the ``Member Function Documentation'' section, you will see documentation for the @code{GetTypeId} function. You constructed one @@ -1263,7 +1263,7 @@ This will point out a couple of promising candidates: We haven't visited any of the test code yet, so let's take a look there. You will typically find that test code is fairly minimal, so this is probably a very good bet. Open @code{src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc} in your -favorite editor and search for ``CongestionWindow.'' You will find, +favorite editor and search for ``CongestionWindow''. You will find, @verbatim ns3TcpSocket->TraceConnectWithoutContext (``CongestionWindow'', @@ -1798,7 +1798,7 @@ Recall that we coded an @code{Application} so we could take that @code{Socket} we just made (during configuration time) and use it in simulation time. We now have to instantiate that @code{Application}. We didn't go to any trouble to create a helper to manage the @code{Application} so we are going to have to -create and install it ``manually.'' This is actually quite easy: +create and install it ``manually''. This is actually quite easy: @verbatim Ptr app = CreateObject (); @@ -1903,11 +1903,7 @@ file ``cwnd.png'' in all of its glory, that looks like: @sp 1 @center @image{figures/cwnd,,,,png} -@c ============================================================================ -@c Using Mid-Level Helpers -@c ============================================================================ -@node Using Mid-Level Helpers -@section Using Mid-Level Helpers +@subsection Using Mid-Level Helpers In the previous section, we showed how to hook a trace source and get hopefully interesting information out of a simulation. Perhaps you will recall that we @@ -1929,7 +1925,7 @@ the example @code{fifth.cc } to disk in separate files. The cwnd changes are stored as a tab-separated ASCII file and the drop events are stored in a pcap file. The changes to make this happen are quite small. -@subsection A sixth.cc Walkthrough +@subsubsection A sixth.cc Walkthrough Let's take a look at the changes required to go from @code{fifth.cc} to @code{sixth.cc}. Open @code{examples/tutorial/fifth.cc} in your favorite @@ -2133,6 +2129,841 @@ core code involved, and we did this in only 18 lines of code: PcapHelper pcapHelper; Ptr file = pcapHelper.CreateFile ("sixth.pcap", "w", PcapHelper::DLT_PPP); devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file)); -@end varbatim +@end verbatim +@c ============================================================================ +@c Using Trace Helpers +@c ============================================================================ +@node Using Trace Helpers +@section Using Trace Helpers +The @code{ns-3} trace helpers provide a rich environment for configuring and +selecting different trace events and writing them to files. In previous +sections, primarily ``Building Topologies,'' we have seen several varieties +of the trace helper methods designed for use inside other (device) helpers. + +Perhaps you will recall seeing some of these variations: + +@verbatim + pointToPoint.EnablePcapAll ("second"); + pointToPoint.EnablePcap ("second", p2pNodes.Get (0)->GetId (), 0); + csma.EnablePcap ("third", csmaDevices.Get (0), true); + pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr")); +@end verbatim + +What may not be obvious, though, is that there is a consistent model for all of +the trace-related methods found in the system. We will now take a little time + and take a look at the ``big picture''. + +There are currently two primary use cases of the tracing helpers in @code{ns-3}: +Device helpers and protocol helpers. Device helpers look at the problem +of specifying which traces should be enabled through a node, device pair. For +example, you may want to specify that pcap tracing should be enabled on a +particular device on a specific node. This follows from the @code{ns-3} device +conceptual model, and also the conceptual models of the various device helpers. +Following naturallyu from this, the files created follow a +-- naming convention. + +Protocol helpers look at the problem of specifying which traces should be +enabled through a protocol and interface pair. This follows from the @code{ns-3} +protocol stack conceptual model, and also the conceptual models of internet +stack helpers. Naturally, the trace files should follow a +-- naming convention. + +The trace helpers therefore fall naturally into a two-dimensional taxonomy. +There are subtleties that prevent all four classes from behaving identically, +but we do strive to make them all work as similarly as possible; and whenever +possible there are analogs for all methods in all classes. + +@verbatim + | pcap | ascii | + -----------------+------+-------| + Device Helper | | | + -----------------+------+-------| + Protocol Helper | | | + -----------------+------+-------| +@end verbatim + +Let's take a quick look at all four of these cases. + +@subsection Pcap Tracing Device Helpers + +The goal of these helpers is to make it easy to add a consistent pcap trace +facility to an @code{ns-3} device. We want all of the various flavors of +pcap tracing to work the same across all devices, so the methods of these +helpers are inherited by device helpers. Take a look at +@code{src/helper/pcap-helper.h} if you want to follow the discussion while +looking at real code. + +The class @code{PcapUserHelperForDevice} provides the high level functionality for +using pcap tracing in an @code{ns-3} device. Every device must implement a +single virtual method inherited from this class. + +@verbatim + virtual void EnablePcapInternal (std::string prefix, Ptr nd, bool promiscuous) = 0; +@end verbatim + +The signature of this method reflects the device-centric view of the situation +at this level. All of the public methods inherited from class +2@code{PcapUserHelperForDevice} reduce to calling this single device-dependent +implementation method. For example, the lowest level pcap method, + +@verbatim + void EnablePcap (std::string prefix, Ptr nd, bool promiscuous = false); +@verbatim + +will call the device implementation of @code{EnablePcapInternal} directly. All +other public pcap tracing methods build on this implementation to provide +additional user-level functionality. What this means to the user is that all +device helpers in the system will have all of the pcap trace methods available; +and these methods will all work in the same way across devices if the device +implements @code{EnablePcapInternal} correctly. + +@subsubsection Pcap Tracing Device Helper Methods + +@verbatim + void EnablePcap (std::string prefix, Ptr nd, bool promiscuous = false); + void EnablePcap (std::string prefix, std::string ndName, bool promiscuous = false); + void EnablePcap (std::string prefix, NetDeviceContainer d, bool promiscuous = false); + void EnablePcap (std::string prefix, NodeContainer n, bool promiscuous = false); + void EnablePcap (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool promiscuous = false); + void EnablePcapAll (std::string prefix, bool promiscuous = false); +@end verbatim + +You are encouraged to peruse the Doxygen for class @code{PcapUserHelperForDevice} +to find the details of these methods; but to summarize ... + +You can enable pcap tracing on a particular node/net-device pair by providing a +@code{Ptr} to an @code{EnablePcap} method. The @code{Ptr} is +implicit since the net device must belong to exactly one @code{Node}. +For example, + +@verbatim + Ptr nd; + ... + helper.EnablePcap ("prefix", nd); +@end verbatim + +You can enable pcap tracing on a particular node/net-device pair by providing a +@code{std::string} representing an object name service string to an +@code{EnablePcap} method. The @code{Ptr} is looked up from the name +string. Again, the @code is implicit since the named net device must +belong to exactly one @code{Node}. For example, + +@verbatim + Names::Add ("server" ...); + Names::Add ("server/eth0" ...); + ... + helper.EnablePcap ("prefix", "server/ath0"); +@end verbatim + +You can enable pcap tracing on a collection of node/net-device pairs by +providing a @code{NetDeviceContainer}. For each @code{NetDevice} in the container +the type is checked. For each device of the proper type (the same type as is +managed by the device helper), tracing is enabled. Again, the @code is +implicit since the found net device must belong to exactly one @code{Node}. +For example, + +@verbatim + NetDeviceContainer d = ...; + ... + helper.EnablePcap ("prefix", d); +@end verbatim + +You can enable pcap tracing on a collection of node/net-device pairs by +providing a @code{NodeContainer}. For each @code{Node} in the @code{NodeContainer} +its attached @code{NetDevices} are iterated. For each @code{NetDevice} attached +to each node in the container, the type of that device is checked. For each +device of the proper type (the same type as is managed by the device helper), +tracing is enabled. + +@verbatim + NodeContainer n; + ... + helper.EnablePcap ("prefix", n); +@end verbatim + +You can enable pcap tracing on the basis of node ID and device ID as well as +with explicit @code{Ptr}. Each @code{Node} in the system has an integer node ID +and each device connected to a node has an integer device ID. + +@verbatim + helper.EnablePcap ("prefix", 21, 1); +@end verbatim + +Finally, you can enable pcap tracing for all devices in the system, with the +same type as that managed by the device helper. + +@verbatim + helper.EnablePcapAll ("prefix"); +@end verbatim + +In each of these cases, there is an additional parameter that defaults to false. +This parameter indicates that the trace should not be gathered in promiscuous +mode. If you do want your traces to include all traffic seen by the device +(and the device supports promiscuous mode) simply add a true parameter to any +of the calls above. For example, + +@verbatim + Ptr nd; + ... + helper.EnablePcap ("prefix", nd, true); +@end verbatim + +will enable promiscuous mode captures on the @code{NetDevice} specified by @code{nd}. + +@subsubsection Pcap Tracing Device Helper Filename Selection + +Implicit in all of the method descriptions above is the construction of the +complete filenames by the implementation method. By convention, pcap traces +in the @code{ns-3} system are of the form ``--.pcap'' + +As previously mentioned, every node in the system will have a system-assigned +node id; and every device will have an interface index (also called a device id) +relative to its node. By default, then, a pcap trace file created as a result +of enabling tracing on the first device of node 21 using the prefix ``prefix'' +would be ``prefix-21-1.pcap''. + +You can always use the @code{ns-3} object name service to make this more clear. +For example, if you use the object name service to assign the name ``server'' +to node 21, the resulting pcap trace file name will automatically become, +``prefix-server-1.pcap'' and if you also assign the name ``eth0'' to the +device, your pcap file name will automatically pick this up and be called +``prefix-server-eth0.pcap''. + +@subsection Ascii Tracing Device Helpers + +The behavior of the ascii trace helpers is substantially similar to the pcap +case. Take a look at @code{src/helper/ascii-trace-helper.h} if you want to +follow the discussion while looking at real code. + +The class @code{AsciitraceUserHelperForDevice} provides the high level +functionality for using ascii tracing in an @code{ns-3} device. Every device + must implement a single virtual method inherited from this class. + +@verbatim + virtual void EnableAsciiInternal (Ptr stream, std::string prefix, Ptr nd) = 0; +@end verbatim + +The signature of this method reflects the device-centric view of the situation +at this level; and also the fact that the helper may be writing to a shared +output stream. All of the public methods inherited from class +@code{AsciiTraceUserHelperForDevice} reduce to calling this single device- +dependent implementation method. For example, the lowest level ascii trace +methods, + +@verbatim + void EnableAscii (std::string prefix, Ptr nd); + void EnableAscii (Ptr stream, Ptr nd); +@verbatim + +will call the device implementation of @code{EnablePcapInternal} directly, +providing either the prefix or the stream. All other public ascii tracing +methods will build on these low-level functions to provide additional user-level +functionality. What this means to the user is that all device helpers in the +system will have all of the ascii trace methods available; and these methods +will all work in the same way across devices if the devices implement +@code{EnablAsciiInternal} correctly. + +@subsubsection Ascii Tracing Device Helper Methods + +@verbatim + void EnableAscii (std::string prefix, Ptr nd); + void EnableAscii (Ptr stream, Ptr nd); + + void EnableAscii (std::string prefix, std::string ndName); + void EnableAscii (Ptr stream, std::string ndName); + + void EnableAscii (std::string prefix, NetDeviceContainer d); + void EnableAscii (Ptr stream, NetDeviceContainer d); + + void EnableAscii (std::string prefix, NodeContainer n); + void EnableAscii (Ptr stream, NodeContainer n); + + void EnableAscii (std::string prefix, uint32_t nodeid, uint32_t deviceid); + void EnableAscii (Ptr stream, uint32_t nodeid, uint32_t deviceid); + + void EnableAsciiAll (std::string prefix); + void EnableAsciiAll (Ptr stream); +@end verbatim + +You are encouraged to peruse the Doxygen for class @code{PcapUserHelperForDevice} +to find the details of these methods; but to summarize ... + +There are twice as many methods available for ascii tracing as there were for +pcap tracing. This is because, in addition to the pcap-style model where traces +from each unique node/device pair are written to a unique file, we support a model +in which trace information for many node/device pairs is written to a common file. +This means that the -- file name generation mechanism is +replaced by a mechanism to refer to a common file; and the number of API methods +is doubled to allow all combinations. + +Just as in pcap tracing, you can enable ascii tracing on a particular +node/net-device pair by providing a @code{Ptr} to an @code{EnableAscii} +method. The @code{Ptr} is implicit since the net device must belong to +exactly one @code{Node}. For example, + +@verbatim + Ptr nd; + ... + helper.EnableAscii ("prefix", nd); +@end verbatim + +In this case, no trace contexts are written to the ascii trace file since they +would be redundant. The system will pick the file name to be created using +the same rules as described in the pcap section, except that the file will +have the suffix ``.tr'' instead of ``.pcap''. + +If you want to enable ascii tracing on more than one net device and have all +traces sent to a single file, you can do that as well by using an object to +refer to a single file. We have already seen this in the ``cwnd'' example +above: + +@verbatim + Ptr nd1; + Ptr nd2; + ... + Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + ... + helper.EnableAscii (stream, nd1); + helper.EnableAscii (stream, nd2); +@verbatim + +In this case, trace contexts are written to the ascii trace file since they +are required to disambiguate traces from the two devices. Note that since the +user is completely specifying the file name, the string should include the ``,tr'' +for consistency. + +You can enable ascii tracing on a particular node/net-device pair by providing a +@code{std::string} representing an object name service string to an +@code{EnablePcap} method. The @code{Ptr} is looked up from the name +string. Again, the @code is implicit since the named net device must +belong to exactly one @code{Node}. For example, + +@verbatim + Names::Add ("client" ...); + Names::Add ("client/eth0" ...); + Names::Add ("server" ...); + Names::Add ("server/eth0" ...); + ... + helper.EnableAscii ("prefix", "client/eth0"); + helper.EnableAscii ("prefix", "server/eth0"); +@end verbatim + +This would result in two files named ``prefix-client-eth0.tr'' and +``prefix-server-eth0.tr'' with traces for each device in the respective trace +file. Since all of the EnableAscii functions are overloaded to take a stream object, +you can use that form as well: + +@verbatim + Names::Add ("client" ...); + Names::Add ("client/eth0" ...); + Names::Add ("server" ...); + Names::Add ("server/eth0" ...); + ... + Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + ... + helper.EnableAscii (stream, "client/eth0"); + helper.EnableAscii (stream, "server/eth0"); +@end verbatim + +This would result in a single trace file called ``trace-file-name.tr'' that +contains all of the trace events for both devices. The events would be +disambiguated by trace context strings. + +You can enable ascii tracing on a collection of node/net-device pairs by +providing a @code{NetDeviceContainer}. For each @code{NetDevice} in the container +the type is checked. For each device of the proper type (the same type as is +managed by the device helper), tracing is enabled. Again, the @code is +implicit since the found net device must belong to exactly one @code{Node}. +For example, + +@verbatim + NetDeviceContainer d = ...; + ... + helper.EnableAscii ("prefix", d); +@end verbatim + +This would result in a number of ascii trace files being created, each of which +follows the --.tr convention. Combining all of the +traces into a single file is accomplished similarly to the examples above: + +@verbatim + NetDeviceContainer d = ...; + ... + Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + ... + helper.EnableAscii (stream, d); +@end verbatim + +You can enable ascii tracing on a collection of node/net-device pairs by +providing a @code{NodeContainer}. For each @code{Node} in the @code{NodeContainer} +its attached @code{NetDevices} are iterated. For each @code{NetDevice} attached +to each node in the container, the type of that device is checked. For each +device of the proper type (the same type as is managed by the device helper), +tracing is enabled. + +@verbatim + NodeContainer n; + ... + helper.EnableAscii ("prefix", n); +@end verbatim + +This would result in a number of ascii trace files being created, each of which +follows the --.tr convention. Combining all of the +traces into a single file is accomplished similarly to the examples above: + +You can enable pcap tracing on the basis of node ID and device ID as well as +with explicit @code{Ptr}. Each @code{Node} in the system has an integer node ID +and each device connected to a node has an integer device ID. + +@verbatim + helper.EnableAscii ("prefix", 21, 1); +@end verbatim + +Of course, the traces can be combined into a single file as shown above. + +Finally, you can enable pcap tracing for all devices in the system, with the +same type as that managed by the device helper. + +@verbatim + helper.EnableAsciiAll ("prefix"); +@end verbatim + +This would result in a number of ascii trace files being created, one for +every device in the system of the type managed by the helper. All of these +files will follow the --.tr convention. Combining +all of the traces into a single file is accomplished similarly to the examples +above. + +@subsubsection Ascii Tracing Device Helper Filename Selection + +Implicit in the prefix-style method descriptions above is the construction of the +complete filenames by the implementation method. By convention, ascii traces +in the @code{ns-3} system are of the form ``--.tr'' + +As previously mentioned, every node in the system will have a system-assigned +node id; and every device will have an interface index (also called a device id) +relative to its node. By default, then, an ascii trace file created as a result +of enabling tracing on the first device of node 21, using the prefix ``prefix'', +would be ``prefix-21-1.tr''. + +You can always use the @code{ns-3} object name service to make this more clear. +For example, if you use the object name service to assign the name ``server'' +to node 21, the resulting ascii trace file name will automatically become, +``prefix-server-1.tr'' and if you also assign the name ``eth0'' to the +device, your ascii trace file name will automatically pick this up and be called +``prefix-server-eth0.tr''. + +@subsection Pcap Tracing Protocol Helpers + +The goal of these helpers is to make it easy to add a consistent pcap trace +facility to protocols. We want all of the various flavors of pcap tracing to +work the same across all protocols, so the methods of these helpers are +inherited by stack helpers. Take a look at @code{src/helper/pcap-helper.h} +if you want to follow the discussion while looking at real code. + +In this section we will be illustrating the methods as applied to the protocol +@code{Ipv4}. To specify traces in similar protocols, just substitute the +appropriate type. For example, use a @code{Ptr} instead of a +@code{Ptr}. + +The class @code{PcapUserHelperForIpv4} provides the high level functionality for +using pcap tracing in the @code{Ipv4} protocol. Every protocol enabling these +methods must implement a single virtual method inherited from this class. There +will be a separate implementation for @code{Ipv6}, for examle, but the only +difference will be in the method signatures. + +@verbatim + virtual void EnablePcapInternal (std::string prefix, Ptr ipv4, uint32_t interface) = 0; +@end verbatim + +The signature of this method reflects the protocol and interface-centric view +of the situation at this level. All of the public methods inherited from class +2@code{PcapUserHelperForIpv4} reduce to calling this single device-dependent +implementation method. For example, the lowest level pcap method, + +@verbatim + void EnablePcap (std::string prefix, Ptr ipv4, uint32_t interface); +@verbatim + +will call the device implementation of @code{EnablePcapInternal} directly. All +other public pcap tracing methods build on this implementation to provide +additional user-level functionality. What this means to the user is that all +protocol helpers in the system will have all of the pcap trace methods +available; and these methods will all work in the same way across +protocols if the helper implements @code{EnablePcapInternal} correctly. + +@subsubsection Pcap Tracing Protocol Helper Methods + +These methods are designed to be in one-to-one correspondence with the @code{Node}- +and @code{NetDevice}- centric versions of the device versions. Instead of +@code{Node} and @code{NetDevice} pair constraints, we use protocol and interface +constraints. + +Note that just like in the device version, there are six methods: + +@verbatim + void EnablePcap (std::string prefix, Ptr ipv4, uint32_t interface); + void EnablePcap (std::string prefix, std::string ipv4Name, uint32_t interface); + void EnablePcap (std::string prefix, Ipv4InterfaceContainer c); + void EnablePcap (std::string prefix, NodeContainer n); + void EnablePcap (std::string prefix, uint32_t nodeid, uint32_t interface); + void EnablePcapAll (std::string prefix); +@end verbatim + +You are encouraged to peruse the Doxygen for class @code{PcapUserHelperForIpv4} +to find the details of these methods; but to summarize ... + +You can enable pcap tracing on a particular protocol/interface pair by providing a +@code{Ptr} and @code{interface} to an @code{EnablePcap} method. For example, + +@verbatim + Ptr ipv4 = node->GetObject (); + ... + helper.EnablePcap ("prefix", ipv4, 0); +@end verbatim + +You can enable pcap tracing on a particular node/net-device pair by providing a +@code{std::string} representing an object name service string to an +@code{EnablePcap} method. The @code{Ptr} is looked up from the name +string. For example, + +@verbatim + Names::Add ("serverIPv4" ...); + ... + helper.EnablePcap ("prefix", "serverIpv4", 1); +@end verbatim + +You can enable pcap tracing on a collection of protocol/interface pairs by +providing an @code{Ipv4InterfaceContainer}. For each @code{Ipv4} / interface +pair in the container the protocol type is checked. For each protocol of the +proper type (the same type as is managed by the device helper), tracing is +enabled for the corresponding interface. For example, + +@verbatim + NodeContainer nodes; + ... + NetDeviceContainer devices = deviceHelper.Install (nodes); + ... + Ipv4AddressHelper ipv4; + ipv4.SetBase ("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer interfaces = ipv4.Assign (devices); + ... + helper.EnablePcap ("prefix", interfaces); +@end verbatim + +You can enable pcap tracing on a collection of protocol/interface pairs by +providing a @code{NodeContainer}. For each @code{Node} in the @code{NodeContainer} +the appropriate protocol is found. For each protocol, its interfaces are +enumerated and tracing is enabled on the resulting pairs. For example, + +@verbatim + NodeContainer n; + ... + helper.EnablePcap ("prefix", n); +@end verbatim + +You can enable pcap tracing on the basis of node ID and interface as well. In +this case, the node-id is translated to a @code{Ptr{Node} and the appropriate +protocol is looked up in the node. The resulting protocol and interface are +used to specify the resulting trace source. + +@verbatim + helper.EnablePcap ("prefix", 21, 1); +@end verbatim + +Finally, you can enable pcap tracing for all interfaces in the system, with +associated protocol being the same type as that managed by the device helper. + +@verbatim + helper.EnablePcapAll ("prefix"); +@end verbatim + +@subsubsection Pcap Tracing Protocol Helper Filename Selection + +Implicit in all of the method descriptions above is the construction of the +complete filenames by the implementation method. By convention, pcap traces +taken for devices in the @code{ns-3} system are of the form +``--.pcap''. In the case of protocol traces, +there is a one-to-one correspondence between protocols and @code{Nodes}. +This is because protocol @code{Objects} are aggregated to @code{Node Objects}. +Since there is no global protocol id in the system, we use the corresponding +node id in file naming. Threfore there is a possibility for file name +collisions in automatically chosen trace file names. For this reason, the +file name convention is changed for protocol traces. + +As previously mentioned, every node in the system will have a system-assigned +node id. Since there is a one-to-one correspondence between protocol instances +and node instances we use the node id. Each interface has an interface id +relative to its protocol. We use the convention +"-n-i.pcap" for trace file naming in protocol +helpers. + +Therefore, by default, a pcap trace file created as a result of enabling tracing +on interface 1 of the Ipv4 protocol of node 21 using the prefix ``prefix'' +would be ``prefix-n21-i1.pcap''. + +You can always use the @code{ns-3} object name service to make this more clear. +For example, if you use the object name service to assign the name ``serverIpv4'' +to the Ptr on node 21, the resulting pcap trace file name will +automatically become, ``prefix-nserverIpv4-i1.pcap''. + +@subsection Ascii Tracing Protocol Helpers + +The behavior of the ascii trace helpers is substantially similar to the pcap +case. Take a look at @code{src/helper/ascii-trace-helper.h} if you want to +follow the discussion while looking at real code. + +The class @code{AsciitraceUserHelperForIpv4} provides the high level +functionality for using ascii tracing in an @code{ns-3} protocol. Every +protocol must implement a single virtual method inherited from this class. + +@verbatim + virtual void EnableAsciiInternal (Ptr stream, std::string prefix, + Ptr ipv4, uint32_t interface) = 0; +@end verbatim + +The signature of this method reflects the protocol- and interface-centric view +of the situation at this level; and also the fact that the helper may be writing +to a shared output stream. All of the public methods inherited from class +@code{AsciiTraceUserHelperForIpv4} reduce to calling this single device- +dependent implementation method. For example, the lowest level ascii trace +methods, + +@verbatim + void EnableAscii (std::string prefix, Ptr ipv4, uint32_t interface); + void EnableAscii (Ptr stream, Ptr ipv4, uint32_t interface); +@verbatim + +will call the device implementation of @code{EnablePcapInternal} directly, +providing either the prefix or the stream. All other public ascii tracing +methods will build on these low-level functions to provide additional user-level +functionality. What this means to the user is that all device helpers in the +system will have all of the ascii trace methods available; and these methods +will all work in the same way across protocols if the protocols implement +@code{EnablAsciiInternal} correctly. + +@subsubsection Ascii Tracing Device Helper Methods + +@verbatim + void EnableAscii (std::string prefix, Ptr ipv4, uint32_t interface); + void EnableAscii (Ptr stream, Ptr ipv4, uint32_t interface); + + void EnableAscii (std::string prefix, std::string ipv4Name, uint32_t interface); + void EnableAscii (Ptr stream, std::string ipv4Name, uint32_t interface); + + void EnableAscii (std::string prefix, Ipv4InterfaceContainer c); + void EnableAscii (Ptr stream, Ipv4InterfaceContainer c); + + void EnableAscii (std::string prefix, NodeContainer n); + void EnableAscii (Ptr stream, NodeContainer n); + + void EnableAscii (std::string prefix, uint32_t nodeid, uint32_t deviceid); + void EnableAscii (Ptr stream, uint32_t nodeid, uint32_t interface); + + void EnableAsciiAll (std::string prefix); + void EnableAsciiAll (Ptr stream); +@end verbatim + +You are encouraged to peruse the Doxygen for class @code{PcapUserHelperForIpv4} +to find the details of these methods; but to summarize ... + +There are twice as many methods available for ascii tracing as there were for +pcap tracing. This is because, in addition to the pcap-style model where traces +from each unique protocol/interface pair are written to a unique file, we +support a model in which trace information for many protocol/interface pairs is +written to a common file. This means that the -n- +file name generation mechanism is replaced by a mechanism to refer to a common +file; and the number of API methods is doubled to allow all combinations. + +Just as in pcap tracing, you can enable ascii tracing on a particular +protocol/interface pair by providing a @code{Ptr} and an @code{interface} +to an @code{EnableAscii} method. +For example, + +@verbatim + Ptr ipv4; + ... + helper.EnableAscii ("prefix", ipv4, 1); +@end verbatim + +In this case, no trace contexts are written to the ascii trace file since they +would be redundant. The system will pick the file name to be created using +the same rules as described in the pcap section, except that the file will +have the suffix ``.tr'' instead of ``.pcap''. + +If you want to enable ascii tracing on more than one interface and have all +traces sent to a single file, you can do that as well by using an object to +refer to a single file. We have already something similar to this in the +``cwnd'' example above: + +@verbatim + Ptr protocol1 = node1->GetObject (); + Ptr protocol2 = node2->GetObject (); + ... + Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + ... + helper.EnableAscii (stream, protocol1, 1); + helper.EnableAscii (stream, protocol2, 1); +@verbatim + +In this case, trace contexts are written to the ascii trace file since they +are required to disambiguate traces from the two interfaces. Note that since +the user is completely specifying the file name, the string should include the +``,tr'' for consistency. + +You can enable ascii tracing on a particular protocol by providing a +@code{std::string} representing an object name service string to an +@code{EnablePcap} method. The @code{Ptr} is looked up from the name +string. The @code in the resulting filenames is implicit since there +is a one-to-one correspondence between protocol instances and nodes, +For example, + +@verbatim + Names::Add ("node1Ipv4" ...); + Names::Add ("node2Ipv4" ...); + ... + helper.EnableAscii ("prefix", "node1Ipv4", 1); + helper.EnableAscii ("prefix", "node2Ipv4", 1); +@end verbatim + +This would result in two files named ``prefix-nnode1Ipv4-i1.tr'' and +``prefix-nnode2Ipv4-i1.tr'' with traces for each interface in the respective +trace file. Since all of the EnableAscii functions are overloaded to take a +stream object, you can use that form as well: + +@verbatim + Names::Add ("node1Ipv4" ...); + Names::Add ("node2Ipv4" ...); + ... + Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + ... + helper.EnableAscii (stream, "node1Ipv4", 1); + helper.EnableAscii (stream, "node2Ipv4", 1); +@end verbatim + +This would result in a single trace file called ``trace-file-name.tr'' that +contains all of the trace events for both interfaces. The events would be +disambiguated by trace context strings. + +You can enable ascii tracing on a collection of protocol/interface pairs by +providing an @code{Ipv4InterfaceContainer}. For each protocol of the proper +type (the same type as is managed by the device helper), tracing is enabled +for the corresponding interface. Again, the @code is implicit since +there is a one-to-one correspondence between each protocol and its node. +For example, + +@verbatim + NodeContainer nodes; + ... + NetDeviceContainer devices = deviceHelper.Install (nodes); + ... + Ipv4AddressHelper ipv4; + ipv4.SetBase ("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer interfaces = ipv4.Assign (devices); + ... + ... + helper.EnableAscii ("prefix", interfaces); +@end verbatim + +This would result in a number of ascii trace files being created, each of which +follows the -n-i.tr convention. Combining all of the +traces into a single file is accomplished similarly to the examples above: + +@verbatim + NodeContainer nodes; + ... + NetDeviceContainer devices = deviceHelper.Install (nodes); + ... + Ipv4AddressHelper ipv4; + ipv4.SetBase ("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer interfaces = ipv4.Assign (devices); + ... + Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr"); + ... + helper.EnableAscii (stream, interfaces); +@end verbatim + +You can enable ascii tracing on a collection of protocol/interface pairs by +providing a @code{NodeContainer}. For each @code{Node} in the @code{NodeContainer} +the appropriate protocol is found. For each protocol, its interfaces are +enumerated and tracing is enabled on the resulting pairs. For example, + +@verbatim + NodeContainer n; + ... + helper.EnableAscii ("prefix", n); +@end verbatim + +This would result in a number of ascii trace files being created, each of which +follows the --.tr convention. Combining all of the +traces into a single file is accomplished similarly to the examples above: + +You can enable pcap tracing on the basis of node ID and device ID as well. In +this case, the node-id is translated to a @code{Ptr{Node} and the appropriate +protocol is looked up in the node. The resulting protocol and interface are +used to specify the resulting trace source. + +@verbatim + helper.EnableAscii ("prefix", 21, 1); +@end verbatim + +Of course, the traces can be combined into a single file as shown above. + +Finally, you can enable ascii tracing for all interfaces in the system, with +associated protocol being the same type as that managed by the device helper. + +@verbatim + helper.EnableAsciiAll ("prefix"); +@end verbatim + +This would result in a number of ascii trace files being created, one for +every interface in the system related to a protocol of the type managed by the +helper. All of these files will follow the -n-i--.tr'' + +As previously mentioned, every node in the system will have a system-assigned +node id. Since there is a one-to-one correspondence between protocols and nodes +we use to node-id to identify the protocol identity. Every interface on a +given rotocol will have an interface index (also called simply an interface) +relative to its protocol. By default, then, an ascii trace file created as a result +of enabling tracing on the first device of node 21, using the prefix ``prefix'', +would be ``prefix-n21-i1.tr''. Use the prefix to disambiguate multiple protocols +per node. + +You can always use the @code{ns-3} object name service to make this more clear. +For example, if you use the object name service to assign the name ``serverIpv4'' +to the protocol on node 21, and also specify interface one, the resulting ascii +trace file name will automatically become, ``prefix-nserverIpv4-1.tr''. + +@c ============================================================================ +@c Summary +@c ============================================================================ +@node Summary +@section Summary + +@code{ns-3} includes an extremely rich environment allowing users at several +levels to customize the kinds of information that can be extracted from +simulations. + +There are high-level helper functions that allow users to simply control the +collection of pre-defined outputs to a fine granularity. There are mid-level +helper functions to allow more sophisticated users to customize how information +is extracted and saved; and there are low-level core functions to allow expert +users to alter the system to present new and previously unexported information +in a way that will be immediatly accessible to users at higher levels. + +This is a very comprehensive system, and we realize that it is a lot to +digest, especially for new users or those not intimately familiar with C++ +and its idioms. We do consider the tracing system a very important part of +@code{ns-3} and so recommend becoming as familiar as possible with it. It is +probably the case that understanding the rest of the @code{ns-3} system will +be quite simple once you have mastered the tracing system