A Discrete-Event Network Simulator
API
node.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006 Georgia Tech Research Corporation, INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Authors: George F. Riley<riley@ece.gatech.edu>
18  * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include "node.h"
22 
23 #include "application.h"
24 #include "net-device.h"
25 #include "node-list.h"
26 #include "packet.h"
27 
28 #include "ns3/assert.h"
29 #include "ns3/boolean.h"
30 #include "ns3/global-value.h"
31 #include "ns3/log.h"
32 #include "ns3/object-vector.h"
33 #include "ns3/simulator.h"
34 #include "ns3/uinteger.h"
35 
36 namespace ns3
37 {
38 
40 
42 
48 static GlobalValue g_checksumEnabled =
49  GlobalValue("ChecksumEnabled",
50  "A global switch to enable all checksums for all protocols",
51  BooleanValue(false),
53 
54 TypeId
56 {
57  static TypeId tid =
58  TypeId("ns3::Node")
59  .SetParent<Object>()
60  .SetGroupName("Network")
61  .AddConstructor<Node>()
62  .AddAttribute("DeviceList",
63  "The list of devices associated to this Node.",
66  MakeObjectVectorChecker<NetDevice>())
67  .AddAttribute("ApplicationList",
68  "The list of applications associated to this Node.",
71  MakeObjectVectorChecker<Application>())
72  .AddAttribute("Id",
73  "The id (unique integer) of this Node.",
74  TypeId::ATTR_GET, // allow only getting it.
75  UintegerValue(0),
77  MakeUintegerChecker<uint32_t>())
78  .AddAttribute(
79  "SystemId",
80  "The systemId of this node: a unique integer used for parallel simulations.",
82  UintegerValue(0),
84  MakeUintegerChecker<uint32_t>());
85  return tid;
86 }
87 
89  : m_id(0),
90  m_sid(0)
91 {
92  NS_LOG_FUNCTION(this);
93  Construct();
94 }
95 
96 Node::Node(uint32_t sid)
97  : m_id(0),
98  m_sid(sid)
99 {
100  NS_LOG_FUNCTION(this << sid);
101  Construct();
102 }
103 
104 void
106 {
107  NS_LOG_FUNCTION(this);
108  m_id = NodeList::Add(this);
109 }
110 
112 {
113  NS_LOG_FUNCTION(this);
114 }
115 
116 uint32_t
117 Node::GetId() const
118 {
119  NS_LOG_FUNCTION(this);
120  return m_id;
121 }
122 
123 Time
125 {
126  NS_LOG_FUNCTION(this);
127  return Simulator::Now();
128 }
129 
130 uint32_t
132 {
133  NS_LOG_FUNCTION(this);
134  return m_sid;
135 }
136 
137 uint32_t
139 {
140  NS_LOG_FUNCTION(this << device);
141  uint32_t index = m_devices.size();
142  m_devices.push_back(device);
143  device->SetNode(this);
144  device->SetIfIndex(index);
145  device->SetReceiveCallback(MakeCallback(&Node::NonPromiscReceiveFromDevice, this));
147  NotifyDeviceAdded(device);
148  return index;
149 }
150 
152 Node::GetDevice(uint32_t index) const
153 {
154  NS_LOG_FUNCTION(this << index);
155  NS_ASSERT_MSG(index < m_devices.size(),
156  "Device index " << index << " is out of range (only have " << m_devices.size()
157  << " devices).");
158  return m_devices[index];
159 }
160 
161 uint32_t
163 {
164  NS_LOG_FUNCTION(this);
165  return m_devices.size();
166 }
167 
168 uint32_t
170 {
171  NS_LOG_FUNCTION(this << application);
172  uint32_t index = m_applications.size();
173  m_applications.push_back(application);
174  application->SetNode(this);
176  return index;
177 }
178 
180 Node::GetApplication(uint32_t index) const
181 {
182  NS_LOG_FUNCTION(this << index);
183  NS_ASSERT_MSG(index < m_applications.size(),
184  "Application index " << index << " is out of range (only have "
185  << m_applications.size() << " applications).");
186  return m_applications[index];
187 }
188 
189 uint32_t
191 {
192  NS_LOG_FUNCTION(this);
193  return m_applications.size();
194 }
195 
196 void
198 {
199  NS_LOG_FUNCTION(this);
201  m_handlers.clear();
202  for (auto i = m_devices.begin(); i != m_devices.end(); i++)
203  {
204  Ptr<NetDevice> device = *i;
205  device->Dispose();
206  *i = nullptr;
207  }
208  m_devices.clear();
209  for (auto i = m_applications.begin(); i != m_applications.end(); i++)
210  {
211  Ptr<Application> application = *i;
212  application->Dispose();
213  *i = nullptr;
214  }
215  m_applications.clear();
217 }
218 
219 void
221 {
222  NS_LOG_FUNCTION(this);
223  for (auto i = m_devices.begin(); i != m_devices.end(); i++)
224  {
225  Ptr<NetDevice> device = *i;
226  device->Initialize();
227  }
228  for (auto i = m_applications.begin(); i != m_applications.end(); i++)
229  {
230  Ptr<Application> application = *i;
231  application->Initialize();
232  }
233 
235 }
236 
237 void
239  uint16_t protocolType,
240  Ptr<NetDevice> device,
241  bool promiscuous)
242 {
243  NS_LOG_FUNCTION(this << &handler << protocolType << device << promiscuous);
245  entry.handler = handler;
246  entry.protocol = protocolType;
247  entry.device = device;
248  entry.promiscuous = promiscuous;
249 
250  // On demand enable promiscuous mode in netdevices
251  if (promiscuous)
252  {
253  if (!device)
254  {
255  for (auto i = m_devices.begin(); i != m_devices.end(); i++)
256  {
257  Ptr<NetDevice> dev = *i;
258  dev->SetPromiscReceiveCallback(MakeCallback(&Node::PromiscReceiveFromDevice, this));
259  }
260  }
261  else
262  {
263  device->SetPromiscReceiveCallback(MakeCallback(&Node::PromiscReceiveFromDevice, this));
264  }
265  }
266 
267  m_handlers.push_back(entry);
268 }
269 
270 void
272 {
273  NS_LOG_FUNCTION(this << &handler);
274  for (auto i = m_handlers.begin(); i != m_handlers.end(); i++)
275  {
276  if (i->handler.IsEqual(handler))
277  {
278  m_handlers.erase(i);
279  break;
280  }
281  }
282 }
283 
284 bool
286 {
288  BooleanValue val;
290  return val.Get();
291 }
292 
293 bool
295  Ptr<const Packet> packet,
296  uint16_t protocol,
297  const Address& from,
298  const Address& to,
299  NetDevice::PacketType packetType)
300 {
301  NS_LOG_FUNCTION(this << device << packet << protocol << &from << &to << packetType);
302  return ReceiveFromDevice(device, packet, protocol, from, to, packetType, true);
303 }
304 
305 bool
307  Ptr<const Packet> packet,
308  uint16_t protocol,
309  const Address& from)
310 {
311  NS_LOG_FUNCTION(this << device << packet << protocol << &from);
312  return ReceiveFromDevice(device,
313  packet,
314  protocol,
315  from,
316  device->GetAddress(),
318  false);
319 }
320 
321 bool
323  Ptr<const Packet> packet,
324  uint16_t protocol,
325  const Address& from,
326  const Address& to,
327  NetDevice::PacketType packetType,
328  bool promiscuous)
329 {
330  NS_LOG_FUNCTION(this << device << packet << protocol << &from << &to << packetType
331  << promiscuous);
333  "Received packet with erroneous context ; "
334  << "make sure the channels in use are correctly updating events context "
335  << "when transferring events from one node to another.");
336  NS_LOG_DEBUG("Node " << GetId() << " ReceiveFromDevice: dev " << device->GetIfIndex()
337  << " (type=" << device->GetInstanceTypeId().GetName() << ") Packet UID "
338  << packet->GetUid());
339  bool found = false;
340 
341  for (auto i = m_handlers.begin(); i != m_handlers.end(); i++)
342  {
343  if (!i->device || (i->device == device))
344  {
345  if (i->protocol == 0 || i->protocol == protocol)
346  {
347  if (promiscuous == i->promiscuous)
348  {
349  i->handler(device, packet, protocol, from, to, packetType);
350  found = true;
351  }
352  }
353  }
354  }
355  return found;
356 }
357 
358 void
360 {
361  NS_LOG_FUNCTION(this << &listener);
362  m_deviceAdditionListeners.push_back(listener);
363  // and, then, notify the new listener about all existing devices.
364  for (auto i = m_devices.begin(); i != m_devices.end(); ++i)
365  {
366  listener(*i);
367  }
368 }
369 
370 void
372 {
373  NS_LOG_FUNCTION(this << &listener);
374  for (auto i = m_deviceAdditionListeners.begin(); i != m_deviceAdditionListeners.end(); i++)
375  {
376  if ((*i).IsEqual(listener))
377  {
378  m_deviceAdditionListeners.erase(i);
379  break;
380  }
381  }
382 }
383 
384 void
386 {
387  NS_LOG_FUNCTION(this << device);
388  for (auto i = m_deviceAdditionListeners.begin(); i != m_deviceAdditionListeners.end(); i++)
389  {
390  (*i)(device);
391  }
392 }
393 
394 } // namespace ns3
a polymophic address class
Definition: address.h:101
void SetNode(Ptr< Node > node)
Definition: application.cc:115
bool Get() const
Definition: boolean.cc:55
Hold a so-called 'global value'.
Definition: global-value.h:76
void GetValue(AttributeValue &value) const
Get the value.
Definition: global-value.cc:98
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:300
A network Node.
Definition: node.h:57
void UnregisterProtocolHandler(ProtocolHandler handler)
Definition: node.cc:271
uint32_t GetSystemId() const
Definition: node.cc:131
void DoDispose() override
The dispose method.
Definition: node.cc:197
bool PromiscReceiveFromDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Receive a packet from a device in promiscuous mode.
Definition: node.cc:294
static GlobalValue g_checksumEnabled
Definition: node.cc:48
DeviceAdditionListenerList m_deviceAdditionListeners
Device addition listeners in the node.
Definition: node.h:306
std::vector< Ptr< Application > > m_applications
Applications associated to this node.
Definition: node.h:304
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:138
uint32_t m_id
Node id for this node.
Definition: node.h:301
uint32_t GetNDevices() const
Definition: node.cc:162
uint32_t GetNApplications() const
Definition: node.cc:190
Ptr< Application > GetApplication(uint32_t index) const
Retrieve the index-th Application associated to this node.
Definition: node.cc:180
bool ReceiveFromDevice(Ptr< NetDevice > device, Ptr< const Packet >, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType, bool promisc)
Receive a packet from a device.
Definition: node.cc:322
bool NonPromiscReceiveFromDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, const Address &from)
Receive a packet from a device in non-promiscuous mode.
Definition: node.cc:306
uint32_t m_sid
System id for this node.
Definition: node.h:302
ProtocolHandlerList m_handlers
Protocol handlers in the node.
Definition: node.h:305
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:169
void Construct()
Finish node's construction by setting the correct node ID.
Definition: node.cc:105
static TypeId GetTypeId()
Get the type ID.
Definition: node.cc:55
uint32_t GetId() const
Definition: node.cc:117
Node()
Definition: node.cc:88
Time GetLocalTime() const
In the future, ns3 nodes may have clock that returned a local time different from the virtual time Si...
Definition: node.cc:124
void RegisterDeviceAdditionListener(DeviceAdditionListener listener)
Definition: node.cc:359
void DoInitialize() override
Initialize() implementation.
Definition: node.cc:220
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:152
~Node() override
Definition: node.cc:111
void NotifyDeviceAdded(Ptr< NetDevice > device)
Notifies all the DeviceAdditionListener about the new device added.
Definition: node.cc:385
static bool ChecksumEnabled()
Definition: node.cc:285
void UnregisterDeviceAdditionListener(DeviceAdditionListener listener)
Definition: node.cc:371
std::vector< Ptr< NetDevice > > m_devices
Devices associated to this node.
Definition: node.h:303
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:238
static uint32_t Add(Ptr< Node > node)
Definition: node-list.cc:230
A base class which provides memory management and object aggregation.
Definition: object.h:89
void Initialize()
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:186
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:359
void Dispose()
Dispose of this Object.
Definition: object.cc:219
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:352
uint64_t GetUid() const
Returns the packet's Uid.
Definition: packet.cc:412
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition: simulator.h:588
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static uint32_t GetContext()
Get the current simulation context.
Definition: simulator.cc:318
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
@ ATTR_GET
The attribute can be read.
Definition: type-id.h:64
@ ATTR_SET
The attribute can be written.
Definition: type-id.h:65
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Definition: object-vector.h:40
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:76
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
Protocol handler entry.
Definition: node.h:289
bool promiscuous
true if it is a promiscuous handler
Definition: node.h:293
uint16_t protocol
the protocol number
Definition: node.h:292
Ptr< NetDevice > device
the NetDevice
Definition: node.h:291
ProtocolHandler handler
the protocol handler
Definition: node.h:290