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 
42  "A global switch to enable all checksums for all protocols",
43  BooleanValue (false),
44  MakeBooleanChecker ());
45 
46 TypeId
48 {
49  static TypeId tid = TypeId ("ns3::Node")
50  .SetParent<Object> ()
51  .AddConstructor<Node> ()
52  .AddAttribute ("DeviceList", "The list of devices associated to this Node.",
55  MakeObjectVectorChecker<NetDevice> ())
56  .AddAttribute ("ApplicationList", "The list of applications associated to this Node.",
59  MakeObjectVectorChecker<Application> ())
60  .AddAttribute ("Id", "The id (unique integer) of this Node.",
61  TypeId::ATTR_GET, // allow only getting it.
62  UintegerValue (0),
63  MakeUintegerAccessor (&Node::m_id),
64  MakeUintegerChecker<uint32_t> ())
65  ;
66  return tid;
67 }
68 
70  : m_id (0),
71  m_sid (0)
72 {
73  Construct ();
74 }
75 
76 Node::Node(uint32_t sid)
77  : m_id (0),
78  m_sid (sid)
79 {
80  Construct ();
81 }
82 
83 void
85 {
86  m_id = NodeList::Add (this);
87 }
88 
90 {
91 }
92 
93 uint32_t
94 Node::GetId (void) const
95 {
96  return m_id;
97 }
98 
99 uint32_t
100 Node::GetSystemId (void) const
101 {
102  return m_sid;
103 }
104 
105 uint32_t
107 {
108  uint32_t index = m_devices.size ();
109  m_devices.push_back (device);
110  device->SetNode (this);
111  device->SetIfIndex (index);
114  &NetDevice::Start, device);
115  NotifyDeviceAdded (device);
116  return index;
117 }
119 Node::GetDevice (uint32_t index) const
120 {
121  NS_ASSERT_MSG (index < m_devices.size (), "Device index " << index <<
122  " is out of range (only have " << m_devices.size () << " devices).");
123  return m_devices[index];
124 }
125 uint32_t
126 Node::GetNDevices (void) const
127 {
128  return m_devices.size ();
129 }
130 
131 uint32_t
133 {
134  uint32_t index = m_applications.size ();
135  m_applications.push_back (application);
136  application->SetNode (this);
138  &Application::Start, application);
139  return index;
140 }
142 Node::GetApplication (uint32_t index) const
143 {
144  NS_ASSERT_MSG (index < m_applications.size (), "Application index " << index <<
145  " is out of range (only have " << m_applications.size () << " applications).");
146  return m_applications[index];
147 }
148 uint32_t
150 {
151  return m_applications.size ();
152 }
153 
154 void
156 {
157  m_deviceAdditionListeners.clear ();
158  m_handlers.clear ();
159  for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
160  i != m_devices.end (); i++)
161  {
162  Ptr<NetDevice> device = *i;
163  device->Dispose ();
164  *i = 0;
165  }
166  m_devices.clear ();
167  for (std::vector<Ptr<Application> >::iterator i = m_applications.begin ();
168  i != m_applications.end (); i++)
169  {
170  Ptr<Application> application = *i;
171  application->Dispose ();
172  *i = 0;
173  }
174  m_applications.clear ();
176 }
177 void
179 {
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->Start ();
185  }
186  for (std::vector<Ptr<Application> >::iterator i = m_applications.begin ();
187  i != m_applications.end (); i++)
188  {
189  Ptr<Application> application = *i;
190  application->Start ();
191  }
192 
193  Object::DoStart ();
194 }
195 
196 void
198  uint16_t protocolType,
199  Ptr<NetDevice> device,
200  bool promiscuous)
201 {
202  struct Node::ProtocolHandlerEntry entry;
203  entry.handler = handler;
204  entry.protocol = protocolType;
205  entry.device = device;
206  entry.promiscuous = promiscuous;
207 
208  // On demand enable promiscuous mode in netdevices
209  if (promiscuous)
210  {
211  if (device == 0)
212  {
213  for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
214  i != m_devices.end (); i++)
215  {
216  Ptr<NetDevice> dev = *i;
218  }
219  }
220  else
221  {
223  }
224  }
225 
226  m_handlers.push_back (entry);
227 }
228 
229 void
231 {
232  for (ProtocolHandlerList::iterator i = m_handlers.begin ();
233  i != m_handlers.end (); i++)
234  {
235  if (i->handler.IsEqual (handler))
236  {
237  m_handlers.erase (i);
238  break;
239  }
240  }
241 }
242 
243 bool
245 {
246  BooleanValue val;
248  return val.Get ();
249 }
250 
251 bool
253  const Address &from, const Address &to, NetDevice::PacketType packetType)
254 {
255  NS_LOG_FUNCTION (this);
256  return ReceiveFromDevice (device, packet, protocol, from, to, packetType, true);
257 }
258 
259 bool
261  const Address &from)
262 {
263  NS_LOG_FUNCTION (this);
264  return ReceiveFromDevice (device, packet, protocol, from, device->GetAddress (), NetDevice::PacketType (0), false);
265 }
266 
267 bool
268 Node::ReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
269  const Address &from, const Address &to, NetDevice::PacketType packetType, bool promiscuous)
270 {
271  NS_ASSERT_MSG (Simulator::GetContext () == GetId (), "Received packet with erroneous context ; " <<
272  "make sure the channels in use are correctly updating events context " <<
273  "when transfering events from one node to another.");
274  NS_LOG_DEBUG ("Node " << GetId () << " ReceiveFromDevice: dev "
275  << device->GetIfIndex () << " (type=" << device->GetInstanceTypeId ().GetName ()
276  << ") Packet UID " << packet->GetUid ());
277  bool found = false;
278 
279  for (ProtocolHandlerList::iterator i = m_handlers.begin ();
280  i != m_handlers.end (); i++)
281  {
282  if (i->device == 0 ||
283  (i->device != 0 && i->device == device))
284  {
285  if (i->protocol == 0 ||
286  i->protocol == protocol)
287  {
288  if (promiscuous == i->promiscuous)
289  {
290  i->handler (device, packet, protocol, from, to, packetType);
291  found = true;
292  }
293  }
294  }
295  }
296  return found;
297 }
298 void
300 {
301  m_deviceAdditionListeners.push_back (listener);
302  // and, then, notify the new listener about all existing devices.
303  for (std::vector<Ptr<NetDevice> >::const_iterator i = m_devices.begin ();
304  i != m_devices.end (); ++i)
305  {
306  listener (*i);
307  }
308 }
309 void
311 {
312  for (DeviceAdditionListenerList::iterator i = m_deviceAdditionListeners.begin ();
313  i != m_deviceAdditionListeners.end (); i++)
314  {
315  if ((*i).IsEqual (listener))
316  {
317  m_deviceAdditionListeners.erase (i);
318  break;
319  }
320  }
321 }
322 
323 void
325 {
326  for (DeviceAdditionListenerList::iterator i = m_deviceAdditionListeners.begin ();
327  i != m_deviceAdditionListeners.end (); i++)
328  {
329  (*i) (device);
330  }
331 }
332 
333 
334 } // namespace ns3