A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
node.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2006 Georgia Tech Research Corporation, INRIA
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  * Authors: George F. Riley<riley@ece.gatech.edu>
19  * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  */
21 #include "node.h"
22 #include "node-list.h"
23 #include "net-device.h"
24 #include "application.h"
25 #include "ns3/packet.h"
26 #include "ns3/simulator.h"
27 #include "ns3/object-vector.h"
28 #include "ns3/uinteger.h"
29 #include "ns3/log.h"
30 #include "ns3/assert.h"
31 #include "ns3/global-value.h"
32 #include "ns3/boolean.h"
33 #include "ns3/simulator.h"
34 
36 
37 namespace ns3 {
38 
40 
44 static GlobalValue g_checksumEnabled = GlobalValue ("ChecksumEnabled",
45  "A global switch to enable all checksums for all protocols",
46  BooleanValue (false),
47  MakeBooleanChecker ());
48 
49 TypeId
51 {
52  static TypeId tid = TypeId ("ns3::Node")
53  .SetParent<Object> ()
54  .AddConstructor<Node> ()
55  .AddAttribute ("DeviceList", "The list of devices associated to this Node.",
58  MakeObjectVectorChecker<NetDevice> ())
59  .AddAttribute ("ApplicationList", "The list of applications associated to this Node.",
62  MakeObjectVectorChecker<Application> ())
63  .AddAttribute ("Id", "The id (unique integer) of this Node.",
64  TypeId::ATTR_GET, // allow only getting it.
65  UintegerValue (0),
66  MakeUintegerAccessor (&Node::m_id),
67  MakeUintegerChecker<uint32_t> ())
68  .AddAttribute ("SystemId", "The systemId of this node: a unique integer used for parallel simulations.",
70  UintegerValue (0),
71  MakeUintegerAccessor (&Node::m_sid),
72  MakeUintegerChecker<uint32_t> ())
73  ;
74  return tid;
75 }
76 
78  : m_id (0),
79  m_sid (0)
80 {
81  NS_LOG_FUNCTION (this);
82  Construct ();
83 }
84 
85 Node::Node(uint32_t sid)
86  : m_id (0),
87  m_sid (sid)
88 {
89  NS_LOG_FUNCTION (this << sid);
90  Construct ();
91 }
92 
93 void
95 {
96  NS_LOG_FUNCTION (this);
97  m_id = NodeList::Add (this);
98 }
99 
101 {
102  NS_LOG_FUNCTION (this);
103 }
104 
105 uint32_t
106 Node::GetId (void) const
107 {
108  NS_LOG_FUNCTION (this);
109  return m_id;
110 }
111 
112 uint32_t
113 Node::GetSystemId (void) const
114 {
115  NS_LOG_FUNCTION (this);
116  return m_sid;
117 }
118 
119 uint32_t
121 {
122  NS_LOG_FUNCTION (this << device);
123  uint32_t index = m_devices.size ();
124  m_devices.push_back (device);
125  device->SetNode (this);
126  device->SetIfIndex (index);
127  device->SetReceiveCallback (MakeCallback (&Node::NonPromiscReceiveFromDevice, this));
128  Simulator::ScheduleWithContext (GetId (), Seconds (0.0),
129  &NetDevice::Initialize, device);
130  NotifyDeviceAdded (device);
131  return index;
132 }
134 Node::GetDevice (uint32_t index) const
135 {
136  NS_LOG_FUNCTION (this << index);
137  NS_ASSERT_MSG (index < m_devices.size (), "Device index " << index <<
138  " is out of range (only have " << m_devices.size () << " devices).");
139  return m_devices[index];
140 }
141 uint32_t
142 Node::GetNDevices (void) const
143 {
144  NS_LOG_FUNCTION (this);
145  return m_devices.size ();
146 }
147 
148 uint32_t
150 {
151  NS_LOG_FUNCTION (this << application);
152  uint32_t index = m_applications.size ();
153  m_applications.push_back (application);
154  application->SetNode (this);
155  Simulator::ScheduleWithContext (GetId (), Seconds (0.0),
156  &Application::Initialize, application);
157  return index;
158 }
160 Node::GetApplication (uint32_t index) const
161 {
162  NS_LOG_FUNCTION (this << index);
163  NS_ASSERT_MSG (index < m_applications.size (), "Application index " << index <<
164  " is out of range (only have " << m_applications.size () << " applications).");
165  return m_applications[index];
166 }
167 uint32_t
169 {
170  NS_LOG_FUNCTION (this);
171  return m_applications.size ();
172 }
173 
174 void
176 {
177  NS_LOG_FUNCTION (this);
178  m_deviceAdditionListeners.clear ();
179  m_handlers.clear ();
180  for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
181  i != m_devices.end (); i++)
182  {
183  Ptr<NetDevice> device = *i;
184  device->Dispose ();
185  *i = 0;
186  }
187  m_devices.clear ();
188  for (std::vector<Ptr<Application> >::iterator i = m_applications.begin ();
189  i != m_applications.end (); i++)
190  {
191  Ptr<Application> application = *i;
192  application->Dispose ();
193  *i = 0;
194  }
195  m_applications.clear ();
197 }
198 void
200 {
201  NS_LOG_FUNCTION (this);
202  for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
203  i != m_devices.end (); i++)
204  {
205  Ptr<NetDevice> device = *i;
206  device->Initialize ();
207  }
208  for (std::vector<Ptr<Application> >::iterator i = m_applications.begin ();
209  i != m_applications.end (); i++)
210  {
211  Ptr<Application> application = *i;
212  application->Initialize ();
213  }
214 
216 }
217 
218 void
220  uint16_t protocolType,
221  Ptr<NetDevice> device,
222  bool promiscuous)
223 {
224  NS_LOG_FUNCTION (this << &handler << protocolType << device << promiscuous);
225  struct Node::ProtocolHandlerEntry entry;
226  entry.handler = handler;
227  entry.protocol = protocolType;
228  entry.device = device;
229  entry.promiscuous = promiscuous;
230 
231  // On demand enable promiscuous mode in netdevices
232  if (promiscuous)
233  {
234  if (device == 0)
235  {
236  for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
237  i != m_devices.end (); i++)
238  {
239  Ptr<NetDevice> dev = *i;
240  dev->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this));
241  }
242  }
243  else
244  {
245  device->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this));
246  }
247  }
248 
249  m_handlers.push_back (entry);
250 }
251 
252 void
254 {
255  NS_LOG_FUNCTION (this << &handler);
256  for (ProtocolHandlerList::iterator i = m_handlers.begin ();
257  i != m_handlers.end (); i++)
258  {
259  if (i->handler.IsEqual (handler))
260  {
261  m_handlers.erase (i);
262  break;
263  }
264  }
265 }
266 
267 bool
269 {
271  BooleanValue val;
273  return val.Get ();
274 }
275 
276 bool
278  const Address &from, const Address &to, NetDevice::PacketType packetType)
279 {
280  NS_LOG_FUNCTION (this << device << packet << protocol << &from << &to << packetType);
281  return ReceiveFromDevice (device, packet, protocol, from, to, packetType, true);
282 }
283 
284 bool
286  const Address &from)
287 {
288  NS_LOG_FUNCTION (this << device << packet << protocol << &from);
289  return ReceiveFromDevice (device, packet, protocol, from, device->GetAddress (), NetDevice::PacketType (0), false);
290 }
291 
292 bool
293 Node::ReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
294  const Address &from, const Address &to, NetDevice::PacketType packetType, bool promiscuous)
295 {
296  NS_LOG_FUNCTION (this << device << packet << protocol << &from << &to << packetType << promiscuous);
297  NS_ASSERT_MSG (Simulator::GetContext () == GetId (), "Received packet with erroneous context ; " <<
298  "make sure the channels in use are correctly updating events context " <<
299  "when transfering events from one node to another.");
300  NS_LOG_DEBUG ("Node " << GetId () << " ReceiveFromDevice: dev "
301  << device->GetIfIndex () << " (type=" << device->GetInstanceTypeId ().GetName ()
302  << ") Packet UID " << packet->GetUid ());
303  bool found = false;
304 
305  for (ProtocolHandlerList::iterator i = m_handlers.begin ();
306  i != m_handlers.end (); i++)
307  {
308  if (i->device == 0 ||
309  (i->device != 0 && i->device == device))
310  {
311  if (i->protocol == 0 ||
312  i->protocol == protocol)
313  {
314  if (promiscuous == i->promiscuous)
315  {
316  i->handler (device, packet, protocol, from, to, packetType);
317  found = true;
318  }
319  }
320  }
321  }
322  return found;
323 }
324 void
326 {
327  NS_LOG_FUNCTION (this << &listener);
328  m_deviceAdditionListeners.push_back (listener);
329  // and, then, notify the new listener about all existing devices.
330  for (std::vector<Ptr<NetDevice> >::const_iterator i = m_devices.begin ();
331  i != m_devices.end (); ++i)
332  {
333  listener (*i);
334  }
335 }
336 void
338 {
339  NS_LOG_FUNCTION (this << &listener);
340  for (DeviceAdditionListenerList::iterator i = m_deviceAdditionListeners.begin ();
341  i != m_deviceAdditionListeners.end (); i++)
342  {
343  if ((*i).IsEqual (listener))
344  {
345  m_deviceAdditionListeners.erase (i);
346  break;
347  }
348  }
349 }
350 
351 void
353 {
354  NS_LOG_FUNCTION (this << device);
355  for (DeviceAdditionListenerList::iterator i = m_deviceAdditionListeners.begin ();
356  i != m_deviceAdditionListeners.end (); i++)
357  {
358  (*i) (device);
359  }
360 }
361 
362 
363 } // namespace ns3
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberContainer)
Definition: object-vector.h:51
uint32_t AddApplication(Ptr< Application > application)
Definition: node.cc:149
bool Get(void) const
Definition: boolean.cc:45
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:60
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Hold a bool native type.
Definition: boolean.h:38
uint32_t GetNApplications(void) const
Definition: node.cc:168
virtual void DoInitialize(void)
This method is called only once by Object::Initialize.
Definition: node.cc:199
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
DeviceAdditionListenerList m_deviceAdditionListeners
Device addition listeners in the node.
Definition: node.h:279
static bool ChecksumEnabled(void)
Definition: node.cc:268
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:393
void NotifyDeviceAdded(Ptr< NetDevice > device)
Notifies all the DeviceAdditionListener about the new device added.
Definition: node.cc:352
static uint32_t GetContext(void)
Definition: simulator.cc:300
ProtocolHandler handler
the protocol handler
Definition: node.h:263
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:335
std::vector< Ptr< NetDevice > > m_devices
Devices associated to this node.
Definition: node.h:276
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
hold a so-called 'global value'.
Definition: global-value.h:48
uint32_t GetSystemId(void) const
Definition: node.cc:113
void UnregisterProtocolHandler(ProtocolHandler handler)
Definition: node.cc:253
a polymophic address class
Definition: address.h:86
The attribute can be read.
Definition: type-id.h:56
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:285
uint32_t m_sid
System id for this node.
Definition: node.h:275
static GlobalValue g_checksumEnabled
A global switch to enable all checksums for all protocols.
Definition: node.cc:44
Ptr< Application > GetApplication(uint32_t index) const
Definition: node.cc:160
virtual void DoDispose(void)
The dispose method.
Definition: node.cc:175
Ptr< NetDevice > device
the NetDevice
Definition: node.h:264
Hold an unsigned integer type.
Definition: uinteger.h:46
static uint32_t Add(Ptr< Node > node)
Definition: node-list.cc:222
Ptr< NetDevice > GetDevice(uint32_t index) const
Definition: node.cc:134
uint16_t protocol
the protocol number
Definition: node.h:265
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1242
static void ScheduleWithContext(uint32_t context, Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event with the given context.
Definition: simulator.h:905
uint32_t GetNDevices(void) const
Definition: node.cc:142
ProtocolHandlerList m_handlers
Protocol handlers in the node.
Definition: node.h:278
void RegisterDeviceAdditionListener(DeviceAdditionListener listener)
Definition: node.cc:325
The attribute can be written.
Definition: type-id.h:57
void SetNode(Ptr< Node > node)
Definition: application.cc:110
std::vector< Ptr< Application > > m_applications
Applications associated to this node.
Definition: node.h:277
Protocol handler entry.
Definition: node.h:262
uint32_t m_id
Node id for this node.
Definition: node.h:274
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:219
#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:84
static TypeId GetTypeId(void)
Get the type ID.
Definition: node.cc:50
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:293
uint32_t AddDevice(Ptr< NetDevice > device)
Definition: node.cc:120
uint32_t GetId(void) const
Definition: node.cc:106
void UnregisterDeviceAdditionListener(DeviceAdditionListener listener)
Definition: node.cc:337
virtual ~Node()
Definition: node.cc:100
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
void Initialize(void)
This method calls the virtual DoInitialize method on all the objects aggregated to this object...
Definition: object.cc:179
a base class which provides memory management and object aggregation
Definition: object.h:64
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:274
contain a set of ns3::Object pointers.
a unique identifier for an interface.
Definition: type-id.h:49
void Construct(void)
Finish node's construction by setting the correct node ID.
Definition: node.cc:94
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
void Dispose(void)
Run the DoDispose methods of this object and all the objects aggregated to it.
Definition: object.cc:204
virtual void DoInitialize(void)
This method is called only once by Object::Initialize.
Definition: object.cc:342
void GetValue(AttributeValue &value) const
bool promiscuous
true if it is a promiscuous handler
Definition: node.h:266
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:277
Node()
Definition: node.cc:77