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