A Discrete-Event Network Simulator
API
trace-helper.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 University of Washington
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */
18 
19 #include <stdint.h>
20 #include <string>
21 #include <fstream>
22 
23 #include "ns3/abort.h"
24 #include "ns3/assert.h"
25 #include "ns3/log.h"
26 #include "ns3/ptr.h"
27 #include "ns3/node.h"
28 #include "ns3/names.h"
29 #include "ns3/net-device.h"
30 #include "ns3/pcap-file-wrapper.h"
31 
32 #include "trace-helper.h"
33 
34 namespace ns3 {
35 
36 NS_LOG_COMPONENT_DEFINE ("TraceHelper");
37 
39 {
41 }
42 
44 {
46 }
47 
50  std::string filename,
51  std::ios::openmode filemode,
52  DataLinkType dataLinkType,
53  uint32_t snapLen,
54  int32_t tzCorrection)
55 {
56  NS_LOG_FUNCTION (filename << filemode << dataLinkType << snapLen << tzCorrection);
57 
58  Ptr<PcapFileWrapper> file = CreateObject<PcapFileWrapper> ();
59  file->Open (filename, filemode);
60  NS_ABORT_MSG_IF (file->Fail (), "Unable to Open " << filename << " for mode " << filemode);
61 
62  file->Init (dataLinkType, snapLen, tzCorrection);
63  NS_ABORT_MSG_IF (file->Fail (), "Unable to Init " << filename);
64 
65  //
66  // Note that the pcap helper promptly forgets all about the pcap file. We
67  // rely on the reference count of the file object which will soon be owned
68  // by the caller to keep the object alive. If the caller uses the file
69  // object to hook a trace source, ownership of the file object will be
70  // implicitly transferred to the callback which keeps the object alive.
71  // When the callback is destroyed (when either the trace is disconnected or
72  // the object with the trace source is deleted) the callback will be destroyed
73  // and the file object will be destroyed, releasing the pointer and closing
74  // the file.
75  //
76  return file;
77 }
78 
79 std::string
80 PcapHelper::GetFilenameFromDevice (std::string prefix, Ptr<NetDevice> device, bool useObjectNames)
81 {
82  NS_LOG_FUNCTION (prefix << device << useObjectNames);
83  NS_ABORT_MSG_UNLESS (prefix.size (), "Empty prefix string");
84 
85  std::ostringstream oss;
86  oss << prefix << "-";
87 
88  std::string nodename;
89  std::string devicename;
90 
91  Ptr<Node> node = device->GetNode ();
92 
93  if (useObjectNames)
94  {
95  nodename = Names::FindName (node);
96  devicename = Names::FindName (device);
97  }
98 
99  if (nodename.size ())
100  {
101  oss << nodename;
102  }
103  else
104  {
105  oss << node->GetId ();
106  }
107 
108  oss << "-";
109 
110  if (devicename.size ())
111  {
112  oss << devicename;
113  }
114  else
115  {
116  oss << device->GetIfIndex ();
117  }
118 
119  oss << ".pcap";
120 
121  return oss.str ();
122 }
123 
124 std::string
125 PcapHelper::GetFilenameFromInterfacePair (std::string prefix, Ptr<Object> object, uint32_t interface, bool useObjectNames)
126 {
127  NS_LOG_FUNCTION (prefix << object << interface << useObjectNames);
128  NS_ABORT_MSG_UNLESS (prefix.size (), "Empty prefix string");
129 
130  std::ostringstream oss;
131  oss << prefix << "-";
132 
133  std::string objname;
134  std::string nodename;
135 
136  Ptr<Node> node = object->GetObject<Node> ();
137 
138  if (useObjectNames)
139  {
140  objname = Names::FindName (object);
141  nodename = Names::FindName (node);
142  }
143 
144  if (objname.size ())
145  {
146  oss << objname;
147  }
148  else if (nodename.size ())
149  {
150  oss << nodename;
151  }
152  else
153  {
154  oss << "n" << node->GetId ();
155  }
156 
157  oss << "-i" << interface << ".pcap";
158 
159  return oss.str ();
160 }
161 
162 //
163 // The basic default trace sink. This one just writes the packet to the pcap
164 // file which is good enough for most kinds of captures.
165 //
166 void
168 {
169  NS_LOG_FUNCTION (file << p);
170  file->Write (Simulator::Now (), p);
171 }
172 
173 void
175 {
176  NS_LOG_FUNCTION (file << p);
177  file->Write (Simulator::Now (), header, p);
178 }
179 
181 {
183 }
184 
186 {
188 }
189 
191 AsciiTraceHelper::CreateFileStream (std::string filename, std::ios::openmode filemode)
192 {
193  NS_LOG_FUNCTION (filename << filemode);
194 
195  Ptr<OutputStreamWrapper> StreamWrapper = Create<OutputStreamWrapper> (filename, filemode);
196 
197  //
198  // Note that the ascii trace helper promptly forgets all about the trace file.
199  // We rely on the reference count of the file object which will soon be owned
200  // by the caller to keep the object alive. If the caller uses the stream
201  // object to hook a trace source, ownership of the stream object will be
202  // implicitly transferred to the callback which keeps the object alive.
203  // When the callback is destroyed (when either the trace is disconnected or
204  // the object with the trace source is deleted) the callback will be destroyed
205  // and the stream object will be destroyed, releasing the pointer and closing
206  // the underlying file.
207  //
208  return StreamWrapper;
209 }
210 
211 std::string
212 AsciiTraceHelper::GetFilenameFromDevice (std::string prefix, Ptr<NetDevice> device, bool useObjectNames)
213 {
214  NS_LOG_FUNCTION (prefix << device << useObjectNames);
215  NS_ABORT_MSG_UNLESS (prefix.size (), "Empty prefix string");
216 
217  std::ostringstream oss;
218  oss << prefix << "-";
219 
220  std::string nodename;
221  std::string devicename;
222 
223  Ptr<Node> node = device->GetNode ();
224 
225  if (useObjectNames)
226  {
227  nodename = Names::FindName (node);
228  devicename = Names::FindName (device);
229  }
230 
231  if (nodename.size ())
232  {
233  oss << nodename;
234  }
235  else
236  {
237  oss << node->GetId ();
238  }
239 
240  oss << "-";
241 
242  if (devicename.size ())
243  {
244  oss << devicename;
245  }
246  else
247  {
248  oss << device->GetIfIndex ();
249  }
250 
251  oss << ".tr";
252 
253  return oss.str ();
254 }
255 
256 std::string
258  std::string prefix,
259  Ptr<Object> object,
260  uint32_t interface,
261  bool useObjectNames)
262 {
263  NS_LOG_FUNCTION (prefix << object << interface << useObjectNames);
264  NS_ABORT_MSG_UNLESS (prefix.size (), "Empty prefix string");
265 
266  std::ostringstream oss;
267  oss << prefix << "-";
268 
269  std::string objname;
270  std::string nodename;
271 
272  Ptr<Node> node = object->GetObject<Node> ();
273 
274  if (useObjectNames)
275  {
276  objname = Names::FindName (object);
277  nodename = Names::FindName (node);
278  }
279 
280  if (objname.size ())
281  {
282  oss << objname;
283  }
284  else if (nodename.size ())
285  {
286  oss << nodename;
287  }
288  else
289  {
290  oss << "n" << node->GetId ();
291  }
292 
293  oss << "-i" << interface << ".tr";
294 
295  return oss.str ();
296 }
297 
298 //
299 // One of the basic default trace sink sets. Enqueue:
300 //
301 // When a packet has been sent to a device for transmission, the device is
302 // expected to place the packet onto a transmit queue even if it does not
303 // have to delay the packet at all, if only to trigger this event. This
304 // event will eventually translate into a '+' operation in the trace file.
305 //
306 // This is typically implemented by hooking the "TxQueue/Enqueue" trace hook
307 // in the device (actually the Queue in the device).
308 //
309 void
311 {
312  NS_LOG_FUNCTION (stream << p);
313  *stream->GetStream () << "+ " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
314 }
315 
316 void
318 {
319  NS_LOG_FUNCTION (stream << p);
320  *stream->GetStream () << "+ " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
321 }
322 
323 //
324 // One of the basic default trace sink sets. Drop:
325 //
326 // When a packet has been sent to a device for transmission, the device is
327 // expected to place the packet onto a transmit queue. If this queue is
328 // full the packet will be dropped. The device is expected to trigger an
329 // event to indicate that an outbound packet is being dropped. This event
330 // will eventually translate into a 'd' operation in the trace file.
331 //
332 // This is typically implemented by hooking the "TxQueue/Drop" trace hook
333 // in the device (actually the Queue in the device).
334 //
335 void
337 {
338  NS_LOG_FUNCTION (stream << p);
339  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
340 }
341 
342 void
344 {
345  NS_LOG_FUNCTION (stream << p);
346  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
347 }
348 
349 //
350 // One of the basic default trace sink sets. Dequeue:
351 //
352 // When a packet has been sent to a device for transmission, the device is
353 // expected to place the packet onto a transmit queue even if it does not
354 // have to delay the packet at all. The device removes the packet from the
355 // transmit queue when the packet is ready to send, and this dequeue will
356 // fire a corresponding event. This event will eventually translate into a
357 // '-' operation in the trace file.
358 //
359 // This is typically implemented by hooking the "TxQueue/Dequeue" trace hook
360 // in the device (actually the Queue in the device).
361 //
362 void
364 {
365  NS_LOG_FUNCTION (stream << p);
366  *stream->GetStream () << "- " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
367 }
368 
369 void
371 {
372  NS_LOG_FUNCTION (stream << p);
373  *stream->GetStream () << "- " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
374 }
375 
376 //
377 // One of the basic default trace sink sets. Receive:
378 //
379 // When a packet is received by a device for transmission, the device is
380 // expected to trigger this event to indicate the reception has occurred.
381 // This event will eventually translate into an 'r' operation in the trace
382 // file.
383 //
384 // This is typically implemented by hooking the "MacRx" trace hook in the
385 // device.
386 void
388 {
389  NS_LOG_FUNCTION (stream << p);
390  *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
391 }
392 
393 void
395 {
396  NS_LOG_FUNCTION (stream << p);
397  *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
398 }
399 
400 void
401 PcapHelperForDevice::EnablePcap (std::string prefix, Ptr<NetDevice> nd, bool promiscuous, bool explicitFilename)
402 {
403  EnablePcapInternal (prefix, nd, promiscuous, explicitFilename);
404 }
405 
406 void
407 PcapHelperForDevice::EnablePcap (std::string prefix, std::string ndName, bool promiscuous, bool explicitFilename)
408 {
409  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
410  EnablePcap (prefix, nd, promiscuous, explicitFilename);
411 }
412 
413 void
414 PcapHelperForDevice::EnablePcap (std::string prefix, NetDeviceContainer d, bool promiscuous)
415 {
416  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
417  {
418  Ptr<NetDevice> dev = *i;
419  EnablePcap (prefix, dev, promiscuous);
420  }
421 }
422 
423 void
424 PcapHelperForDevice::EnablePcap (std::string prefix, NodeContainer n, bool promiscuous)
425 {
426  NetDeviceContainer devs;
427  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
428  {
429  Ptr<Node> node = *i;
430  for (uint32_t j = 0; j < node->GetNDevices (); ++j)
431  {
432  devs.Add (node->GetDevice (j));
433  }
434  }
435  EnablePcap (prefix, devs, promiscuous);
436 }
437 
438 void
439 PcapHelperForDevice::EnablePcapAll (std::string prefix, bool promiscuous)
440 {
441  EnablePcap (prefix, NodeContainer::GetGlobal (), promiscuous);
442 }
443 
444 void
445 PcapHelperForDevice::EnablePcap (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool promiscuous)
446 {
448 
449  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
450  {
451  Ptr<Node> node = *i;
452  if (node->GetId () != nodeid)
453  {
454  continue;
455  }
456 
457  NS_ABORT_MSG_IF (deviceid >= node->GetNDevices (), "PcapHelperForDevice::EnablePcap(): Unknown deviceid = "
458  << deviceid);
459  Ptr<NetDevice> nd = node->GetDevice (deviceid);
460  EnablePcap (prefix, nd, promiscuous);
461  return;
462  }
463 }
464 
465 //
466 // Public API
467 //
468 void
469 AsciiTraceHelperForDevice::EnableAscii (std::string prefix, Ptr<NetDevice> nd, bool explicitFilename)
470 {
471  EnableAsciiInternal (Ptr<OutputStreamWrapper> (), prefix, nd, explicitFilename);
472 }
473 
474 //
475 // Public API
476 //
477 void
479 {
480  EnableAsciiInternal (stream, std::string (), nd, false);
481 }
482 
483 //
484 // Public API
485 //
486 void
487 AsciiTraceHelperForDevice::EnableAscii (std::string prefix, std::string ndName, bool explicitFilename)
488 {
489  EnableAsciiImpl (Ptr<OutputStreamWrapper> (), prefix, ndName, explicitFilename);
490 }
491 
492 //
493 // Public API
494 //
495 void
497 {
498  EnableAsciiImpl (stream, std::string (), ndName, false);
499 }
500 
501 //
502 // Private API
503 //
504 void
506  Ptr<OutputStreamWrapper> stream,
507  std::string prefix,
508  std::string ndName,
509  bool explicitFilename)
510 {
511  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
512  EnableAsciiInternal (stream, prefix, nd, explicitFilename);
513 }
514 
515 //
516 // Public API
517 //
518 void
520 {
522 }
523 
524 //
525 // Public API
526 //
527 void
529 {
530  EnableAsciiImpl (stream, std::string (), d);
531 }
532 
533 //
534 // Private API
535 //
536 void
538 {
539  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
540  {
541  Ptr<NetDevice> dev = *i;
542  EnableAsciiInternal (stream, prefix, dev, false);
543  }
544 }
545 
546 //
547 // Public API
548 //
549 void
551 {
553 }
554 
555 //
556 // Public API
557 //
558 void
560 {
561  EnableAsciiImpl (stream, std::string (), n);
562 }
563 
564 //
565 // Private API
566 //
567 void
569 {
570  NetDeviceContainer devs;
571  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
572  {
573  Ptr<Node> node = *i;
574  for (uint32_t j = 0; j < node->GetNDevices (); ++j)
575  {
576  devs.Add (node->GetDevice (j));
577  }
578  }
579  EnableAsciiImpl (stream, prefix, devs);
580 }
581 
582 //
583 // Public API
584 //
585 void
587 {
589 }
590 
591 //
592 // Public API
593 //
594 void
596 {
597  EnableAsciiImpl (stream, std::string (), NodeContainer::GetGlobal ());
598 }
599 
600 //
601 // Public API
602 //
603 void
604 AsciiTraceHelperForDevice::EnableAscii (Ptr<OutputStreamWrapper> stream, uint32_t nodeid, uint32_t deviceid)
605 {
606  EnableAsciiImpl (stream, std::string (), nodeid, deviceid, false);
607 }
608 
609 //
610 // Public API
611 //
612 void
614  std::string prefix,
615  uint32_t nodeid,
616  uint32_t deviceid,
617  bool explicitFilename)
618 {
619  EnableAsciiImpl (Ptr<OutputStreamWrapper> (), prefix, nodeid, deviceid, explicitFilename);
620 }
621 
622 //
623 // Private API
624 //
625 void
627  Ptr<OutputStreamWrapper> stream,
628  std::string prefix,
629  uint32_t nodeid,
630  uint32_t deviceid,
631  bool explicitFilename)
632 {
634 
635  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
636  {
637  Ptr<Node> node = *i;
638  if (node->GetId () != nodeid)
639  {
640  continue;
641  }
642 
643  NS_ABORT_MSG_IF (deviceid >= node->GetNDevices (),
644  "AsciiTraceHelperForDevice::EnableAscii(): Unknown deviceid = " << deviceid);
645 
646  Ptr<NetDevice> nd = node->GetDevice (deviceid);
647 
648  EnableAsciiInternal (stream, prefix, nd, explicitFilename);
649  return;
650  }
651 }
652 
653 } // namespace ns3
654 
Protocol header serialization and deserialization.
Definition: header.h:42
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
static void DefaultEnqueueSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Enqueue default trace sink.
uint32_t GetId(void) const
Definition: node.cc:107
void EnableAsciiImpl(Ptr< OutputStreamWrapper > stream, std::string prefix, uint32_t nodeid, uint32_t deviceid, bool explicitFilename)
Enable ascii trace output on the device specified by a global node-id (of a previously created node) ...
std::vector< Ptr< Node > >::const_iterator Iterator
Node container iterator.
Iterator End(void) const
Get an iterator which indicates past-the-last NetDevice in the container.
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:142
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:355
static void DefaultDropSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Drop default trace sink.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we&#39;ll use to write the traced bits. ...
std::string GetFilenameFromDevice(std::string prefix, Ptr< NetDevice > device, bool useObjectNames=true)
Let the ascii trace helper figure out a reasonable filename to use for an ascii trace file associated...
Ptr< PcapFileWrapper > CreateFile(std::string filename, std::ios::openmode filemode, DataLinkType dataLinkType, uint32_t snapLen=std::numeric_limits< uint32_t >::max(), int32_t tzCorrection=0)
Create and initialize a pcap file.
Definition: trace-helper.cc:49
static void DefaultReceiveSinkWithoutContext(Ptr< OutputStreamWrapper > file, Ptr< const Packet > p)
Basic Receive default trace sink.
static void SinkWithHeader(Ptr< PcapFileWrapper > file, const Header &header, Ptr< const Packet > p)
This trace sink passes a header separately from the packet to prevent creating a new packet (for perf...
DataLinkType
This enumeration holds the data link types that will be written to the pcap file. ...
Definition: trace-helper.h:50
std::string GetFilenameFromDevice(std::string prefix, Ptr< NetDevice > device, bool useObjectNames=true)
Let the pcap helper figure out a reasonable filename to use for a pcap file associated with a device...
Definition: trace-helper.cc:80
void EnablePcapAll(std::string prefix, bool promiscuous=false)
Enable pcap output on each device (which is of the appropriate type) in the set of all nodes created ...
Iterator Begin(void) const
Get an iterator which refers to the first NetDevice in the container.
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
holds a vector of ns3::NetDevice pointers
static void DefaultEnqueueSinkWithoutContext(Ptr< OutputStreamWrapper > file, Ptr< const Packet > p)
Basic Enqueue default trace sink.
std::string GetFilenameFromInterfacePair(std::string prefix, Ptr< Object > object, uint32_t interface, bool useObjectNames=true)
Let the pcap helper figure out a reasonable filename to use for the pcap file associated with a node...
static void DefaultDequeueSinkWithoutContext(Ptr< OutputStreamWrapper > file, Ptr< const Packet > p)
Basic Dequeue default trace sink.
static void DefaultReceiveSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Receive default trace sink.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:459
static void DefaultSink(Ptr< PcapFileWrapper > file, Ptr< const Packet > p)
The basic default trace sink.
static void DefaultDequeueSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Dequeue default trace sink.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
virtual void EnablePcapInternal(std::string prefix, Ptr< NetDevice > nd, bool promiscuous, bool explicitFilename)=0
Enable pcap output the indicated net device.
AsciiTraceHelper()
Create an ascii trace helper.
static void DefaultDropSinkWithoutContext(Ptr< OutputStreamWrapper > file, Ptr< const Packet > p)
Basic Drop default trace sink.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
PcapHelper()
Create a pcap helper.
Definition: trace-helper.cc:38
static NodeContainer GetGlobal(void)
Create a NodeContainer that contains a list of all nodes created through NodeContainer::Create() and ...
void EnableAscii(std::string prefix, Ptr< NetDevice > nd, bool explicitFilename=false)
Enable ascii trace output on the indicated net device.
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
A network Node.
Definition: node.h:56
std::string GetFilenameFromInterfacePair(std::string prefix, Ptr< Object > object, uint32_t interface, bool useObjectNames=true)
Let the ascii trace helper figure out a reasonable filename to use for an ascii trace file associated...
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
virtual void EnableAsciiInternal(Ptr< OutputStreamWrapper > stream, std::string prefix, Ptr< NetDevice > nd, bool explicitFilename)=0
Enable ascii trace output on the indicated net device.
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and...
Definition: names.cc:819
void EnableAsciiAll(std::string prefix)
Enable ascii trace output on each device (which is of the appropriate type) in the set of all nodes c...
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
~AsciiTraceHelper()
Destroy an ascii trace helper.
~PcapHelper()
Destroy a pcap helper.
Definition: trace-helper.cc:43
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
uint32_t GetNDevices(void) const
Definition: node.cc:150