A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
node.cc
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 #include "ns3/arp-l3-protocol.h"
35 
37 
38 namespace ns3 {
39 
40 NS_OBJECT_ENSURE_REGISTERED (Node);
41 
42 GlobalValue g_checksumEnabled = GlobalValue ("ChecksumEnabled",
43  "A global switch to enable all checksums for all protocols",
44  BooleanValue (false),
45  MakeBooleanChecker ());
46 
47 TypeId
48 Node::GetTypeId (void)
49 {
50  static TypeId tid = TypeId ("ns3::Node")
51  .SetParent<Object> ()
52  .AddConstructor<Node> ()
53  .AddAttribute ("DeviceList", "The list of devices associated to this Node.",
54  ObjectVectorValue (),
55  MakeObjectVectorAccessor (&Node::m_devices),
56  MakeObjectVectorChecker<NetDevice> ())
57  .AddAttribute ("ApplicationList", "The list of applications associated to this Node.",
58  ObjectVectorValue (),
59  MakeObjectVectorAccessor (&Node::m_applications),
60  MakeObjectVectorChecker<Application> ())
61  .AddAttribute ("Id", "The id (unique integer) of this Node.",
62  TypeId::ATTR_GET, // allow only getting it.
63  UintegerValue (0),
64  MakeUintegerAccessor (&Node::m_id),
65  MakeUintegerChecker<uint32_t> ())
66  .AddAttribute ("SystemId", "The systemId of this node: a unique integer used for parallel simulations.",
68  UintegerValue (0),
69  MakeUintegerAccessor (&Node::m_sid),
70  MakeUintegerChecker<uint32_t> ())
71  ;
72  return tid;
73 }
74 
75 Node::Node()
76  : m_id (0),
77  m_sid (0),
78  m_isCognitiveRadio (false)
79 {
80  NS_LOG_FUNCTION (this);
81  Construct ();
82 }
83 
84 Node::Node(uint32_t sid)
85  : m_id (0),
86  m_sid (sid)
87 {
88  NS_LOG_FUNCTION (this << sid);
89  Construct ();
90 }
91 
92 void
93 Node::Construct (void)
94 {
95  NS_LOG_FUNCTION (this);
96  m_id = NodeList::Add (this);
97 }
98 
99 Node::~Node ()
100 {
101  NS_LOG_FUNCTION (this);
102 }
103 
104 uint32_t
105 Node::GetId (void) const
106 {
107  NS_LOG_FUNCTION (this);
108  return m_id;
109 }
110 
111 uint32_t
112 Node::GetSystemId (void) const
113 {
114  NS_LOG_FUNCTION (this);
115  return m_sid;
116 }
117 
118 uint32_t
120 {
121  NS_LOG_FUNCTION (this << device);
122  uint32_t index = m_devices.size ();
123  m_devices.push_back (device);
124  device->SetNode (this);
125  device->SetIfIndex (index);
126  device->SetReceiveCallback (MakeCallback (&Node::NonPromiscReceiveFromDevice, this));
128  &NetDevice::Initialize, device);
129  NotifyDeviceAdded (device);
130  return index;
131 }
133 Node::GetDevice (uint32_t index) const
134 {
135  NS_LOG_FUNCTION (this << index);
136  NS_ASSERT_MSG (index < m_devices.size (), "Device index " << index <<
137  " is out of range (only have " << m_devices.size () << " devices).");
138  return m_devices[index];
139 }
140 uint32_t
141 Node::GetNDevices (void) const
142 {
143  NS_LOG_FUNCTION (this);
144  return m_devices.size ();
145 }
146 
147 uint32_t
149 {
150  NS_LOG_FUNCTION (this << application);
151  uint32_t index = m_applications.size ();
152  m_applications.push_back (application);
153  application->SetNode (this);
155  &Application::Initialize, application);
156  return index;
157 }
159 Node::GetApplication (uint32_t index) const
160 {
161  NS_LOG_FUNCTION (this << index);
162  NS_ASSERT_MSG (index < m_applications.size (), "Application index " << index <<
163  " is out of range (only have " << m_applications.size () << " applications).");
164  return m_applications[index];
165 }
166 uint32_t
168 {
169  NS_LOG_FUNCTION (this);
170  return m_applications.size ();
171 }
172 
173 void
175 {
176  NS_LOG_FUNCTION (this);
177  m_deviceAdditionListeners.clear ();
178  m_handlers.clear ();
179  for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
180  i != m_devices.end (); i++)
181  {
182  Ptr<NetDevice> device = *i;
183  device->Dispose ();
184  *i = 0;
185  }
186  m_devices.clear ();
187  for (std::vector<Ptr<Application> >::iterator i = m_applications.begin ();
188  i != m_applications.end (); i++)
189  {
190  Ptr<Application> application = *i;
191  application->Dispose ();
192  *i = 0;
193  }
194  m_applications.clear ();
196 }
197 void
199 {
200  NS_LOG_FUNCTION (this);
201  for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
202  i != m_devices.end (); i++)
203  {
204  Ptr<NetDevice> device = *i;
205  device->Initialize ();
206  }
207  for (std::vector<Ptr<Application> >::iterator i = m_applications.begin ();
208  i != m_applications.end (); i++)
209  {
210  Ptr<Application> application = *i;
211  application->Initialize ();
212  }
213 
215 }
216 
217 void
219  uint16_t protocolType,
220  Ptr<NetDevice> device,
221  bool promiscuous)
222 {
223  NS_LOG_FUNCTION (this << &handler << protocolType << device << promiscuous);
224  struct Node::ProtocolHandlerEntry entry;
225  entry.handler = handler;
226  entry.protocol = protocolType;
227  entry.device = device;
228  entry.promiscuous = promiscuous;
229 
230  // On demand enable promiscuous mode in netdevices
231  if (promiscuous)
232  {
233  if (device == 0)
234  {
235  for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
236  i != m_devices.end (); i++)
237  {
238  Ptr<NetDevice> dev = *i;
239  dev->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this));
240  }
241  }
242  else
243  {
244  device->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this));
245  }
246  }
247 
248  m_handlers.push_back (entry);
249 }
250 
251 void
253 {
254  NS_LOG_FUNCTION (this << &handler);
255  for (ProtocolHandlerList::iterator i = m_handlers.begin ();
256  i != m_handlers.end (); i++)
257  {
258  if (i->handler.IsEqual (handler))
259  {
260  m_handlers.erase (i);
261  break;
262  }
263  }
264 }
265 
266 bool
268 {
270  BooleanValue val;
271  g_checksumEnabled.GetValue (val);
272  return val.Get ();
273 }
274 
275 bool
276 Node::PromiscReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
277  const Address &from, const Address &to, NetDevice::PacketType packetType)
278 {
279  NS_LOG_FUNCTION (this << device << packet << protocol << &from << &to << packetType);
280  return ReceiveFromDevice (device, packet, protocol, from, to, packetType, true);
281 }
282 
283 bool
284 Node::NonPromiscReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
285  const Address &from)
286 {
287  NS_LOG_FUNCTION (this << device << packet << protocol << &from);
288  return ReceiveFromDevice (device, packet, protocol, from, device->GetAddress (), NetDevice::PacketType (0), false);
289 }
290 
291 bool
292 Node::ReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
293  const Address &from, const Address &to, NetDevice::PacketType packetType, bool promiscuous)
294 {
295  NS_LOG_FUNCTION (this << device << packet << protocol << &from << &to << packetType << promiscuous);
296  NS_ASSERT_MSG (Simulator::GetContext () == GetId (), "Received packet with erroneous context ; " <<
297  "make sure the channels in use are correctly updating events context " <<
298  "when transfering events from one node to another.");
299  NS_LOG_DEBUG ("Node " << GetId () << " ReceiveFromDevice: dev "
300  << device->GetIfIndex () << " (type=" << device->GetInstanceTypeId ().GetName ()
301  << ") Packet UID " << packet->GetUid ());
302  bool found = false;
303 
304  for (ProtocolHandlerList::iterator i = m_handlers.begin ();
305  i != m_handlers.end (); i++)
306  {
307  if (i->device == 0 ||
308  (i->device != 0))// && i->device == device))
309  {
310  if (i->protocol == 0 ||
311  i->protocol == protocol)
312  {
313  /* Discard broadcast arp packets on interface TX & RX */
314  if (device != GetDevice(CONTROL_RADIO) && protocol == ArpL3Protocol::PROT_NUMBER)
315  return false;
316  if (promiscuous == i->promiscuous)
317  {
318  if (device->GetInstanceTypeId().GetName() == "ns3::LoopbackNetDevice") {
319  i->handler(device, packet, protocol, from, to, packetType);
320  }
321  else
322  i->handler(GetDevice(CONTROL_RADIO), packet, protocol, from, to, packetType);
323  found = true;
324  break;
325  }
326  }
327  }
328  }
329  return found;
330 }
331 void
333 {
334  NS_LOG_FUNCTION (this << &listener);
335  m_deviceAdditionListeners.push_back (listener);
336  // and, then, notify the new listener about all existing devices.
337  for (std::vector<Ptr<NetDevice> >::const_iterator i = m_devices.begin ();
338  i != m_devices.end (); ++i)
339  {
340  listener (*i);
341  }
342 }
343 void
345 {
346  NS_LOG_FUNCTION (this << &listener);
347  for (DeviceAdditionListenerList::iterator i = m_deviceAdditionListeners.begin ();
348  i != m_deviceAdditionListeners.end (); i++)
349  {
350  if ((*i).IsEqual (listener))
351  {
352  m_deviceAdditionListeners.erase (i);
353  break;
354  }
355  }
356 }
357 
358 void
359 Node::NotifyDeviceAdded (Ptr<NetDevice> device)
360 {
361  NS_LOG_FUNCTION (this << device);
362  for (DeviceAdditionListenerList::iterator i = m_deviceAdditionListeners.begin ();
363  i != m_deviceAdditionListeners.end (); i++)
364  {
365  (*i) (device);
366  }
367 }
368 
369 void
370 Node::SetCognitiveRadio(bool isCR)
371 {
372  m_isCognitiveRadio = isCR;
373 }
374 
375 bool
376 Node::IsCognitiveRadio(void)
377 {
378  return m_isCognitiveRadio;
379 }
380 
381 } // namespace ns3
uint32_t AddApplication(Ptr< Application > application)
Definition: node.cc:148
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
Hold a bool native type.
Definition: boolean.h:38
uint32_t GetNApplications(void) const
Definition: node.cc:167
virtual void DoInitialize(void)
Definition: node.cc:198
static bool ChecksumEnabled(void)
Definition: node.cc:267
static uint32_t GetContext(void)
Definition: simulator.cc:299
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual void DoDispose(void)
Definition: object.cc:335
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
uint32_t GetSystemId(void) const
Definition: node.cc:112
void UnregisterProtocolHandler(ProtocolHandler handler)
Definition: node.cc:252
a polymophic address class
Definition: address.h:86
Ptr< Application > GetApplication(uint32_t index) const
Definition: node.cc:159
virtual void DoDispose(void)
Definition: node.cc:174
static uint32_t Add(Ptr< Node > node)
Definition: node-list.cc:174
Ptr< NetDevice > GetDevice(uint32_t index) const
Definition: node.cc:133
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
static void ScheduleWithContext(uint32_t context, Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:900
uint32_t GetNDevices(void) const
Definition: node.cc:141
void RegisterDeviceAdditionListener(DeviceAdditionListener listener)
Definition: node.cc:332
Definition: node.h:219
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:218
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
uint32_t AddDevice(Ptr< NetDevice > device)
Definition: node.cc:119
uint32_t GetId(void) const
Definition: node.cc:105
void UnregisterDeviceAdditionListener(DeviceAdditionListener listener)
Definition: node.cc:344
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
void Initialize(void)
Definition: object.cc:179
virtual void DoInitialize(void)
Definition: object.cc:342
void GetValue(AttributeValue &value) const