src/network/model/node.cc
changeset 6823 a27f86fb4e55
parent 6526 1f6962c1083c
child 7182 5ecfee5d17de
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network/model/node.cc	Mon Feb 21 09:11:37 2011 -0800
@@ -0,0 +1,301 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 Georgia Tech Research Corporation, INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Authors: George F. Riley<riley@ece.gatech.edu>
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "node.h"
+#include "node-list.h"
+#include "net-device.h"
+#include "application.h"
+#include "ns3/packet.h"
+#include "ns3/simulator.h"
+#include "ns3/object-vector.h"
+#include "ns3/uinteger.h"
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/global-value.h"
+#include "ns3/boolean.h"
+#include "ns3/simulator.h"
+
+NS_LOG_COMPONENT_DEFINE ("Node");
+
+namespace ns3{
+
+NS_OBJECT_ENSURE_REGISTERED (Node);
+
+GlobalValue g_checksumEnabled  = GlobalValue ("ChecksumEnabled",
+                                              "A global switch to enable all checksums for all protocols",
+                                              BooleanValue (false),
+                                              MakeBooleanChecker ());
+
+TypeId 
+Node::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Node")
+    .SetParent<Object> ()
+    .AddConstructor<Node> ()
+    .AddAttribute ("DeviceList", "The list of devices associated to this Node.",
+                   ObjectVectorValue (),
+                   MakeObjectVectorAccessor (&Node::m_devices),
+                   MakeObjectVectorChecker<NetDevice> ())
+    .AddAttribute ("ApplicationList", "The list of applications associated to this Node.",
+                   ObjectVectorValue (),
+                   MakeObjectVectorAccessor (&Node::m_applications),
+                   MakeObjectVectorChecker<Application> ())
+    .AddAttribute ("Id", "The id (unique integer) of this Node.",
+                   TypeId::ATTR_GET, // allow only getting it.
+                   UintegerValue (0),
+                   MakeUintegerAccessor (&Node::m_id),
+                   MakeUintegerChecker<uint32_t> ())
+    ;
+  return tid;
+}
+
+Node::Node()
+  : m_id(0), 
+    m_sid(0)
+{
+  Construct ();
+}
+
+Node::Node(uint32_t sid)
+  : m_id(0), 
+    m_sid(sid)
+{ 
+  Construct ();
+}
+
+void
+Node::Construct (void)
+{
+  m_id = NodeList::Add (this);
+}
+  
+Node::~Node ()
+{}
+
+uint32_t 
+Node::GetId (void) const
+{
+  return m_id;
+}
+
+uint32_t 
+Node::GetSystemId (void) const
+{
+  return m_sid;
+}
+
+uint32_t 
+Node::AddDevice (Ptr<NetDevice> device)
+{
+  uint32_t index = m_devices.size ();
+  m_devices.push_back (device);
+  device->SetNode (this);
+  device->SetIfIndex(index);
+  device->SetReceiveCallback (MakeCallback (&Node::NonPromiscReceiveFromDevice, this));
+  Simulator::ScheduleWithContext (GetId (), Seconds (0.0), 
+                                  &NetDevice::Start, device);
+  NotifyDeviceAdded (device);
+  return index;
+}
+Ptr<NetDevice>
+Node::GetDevice (uint32_t index) const
+{
+  NS_ASSERT_MSG (index < m_devices.size (), "Device index " << index <<
+                 " is out of range (only have " << m_devices.size () << " devices).");
+  return m_devices[index];
+}
+uint32_t 
+Node::GetNDevices (void) const
+{
+  return m_devices.size ();
+}
+
+uint32_t 
+Node::AddApplication (Ptr<Application> application)
+{
+  uint32_t index = m_applications.size ();
+  m_applications.push_back (application);
+  application->SetNode (this);
+  Simulator::ScheduleWithContext (GetId (), Seconds (0.0), 
+                                  &Application::Start, application);
+  return index;
+}
+Ptr<Application> 
+Node::GetApplication (uint32_t index) const
+{
+  NS_ASSERT_MSG (index < m_applications.size (), "Application index " << index <<
+                 " is out of range (only have " << m_applications.size () << " applications).");
+  return m_applications[index];
+}
+uint32_t 
+Node::GetNApplications (void) const
+{
+  return m_applications.size ();
+}
+
+void 
+Node::DoDispose()
+{
+  m_handlers.clear ();
+  for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
+       i != m_devices.end (); i++)
+    {
+      Ptr<NetDevice> device = *i;
+      device->Dispose ();
+      *i = 0;
+    }
+  m_devices.clear ();
+  for (std::vector<Ptr<Application> >::iterator i = m_applications.begin ();
+       i != m_applications.end (); i++)
+    {
+      Ptr<Application> application = *i;
+      application->Dispose ();
+      *i = 0;
+    }
+  m_applications.clear ();
+  Object::DoDispose ();
+}
+void 
+Node::DoStart (void)
+{
+  for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
+       i != m_devices.end (); i++)
+    {
+      Ptr<NetDevice> device = *i;
+      device->Start ();
+    }
+  for (std::vector<Ptr<Application> >::iterator i = m_applications.begin ();
+       i != m_applications.end (); i++)
+    {
+      Ptr<Application> application = *i;
+      application->Start ();
+    }
+  
+  Object::DoStart ();
+}
+
+void 
+Node::NotifyDeviceAdded (Ptr<NetDevice> device)
+{}
+
+void
+Node::RegisterProtocolHandler (ProtocolHandler handler, 
+                               uint16_t protocolType,
+                               Ptr<NetDevice> device,
+                               bool promiscuous)
+{
+  struct Node::ProtocolHandlerEntry entry;
+  entry.handler = handler;
+  entry.protocol = protocolType;
+  entry.device = device;
+  entry.promiscuous = promiscuous;
+
+  // On demand enable promiscuous mode in netdevices
+  if (promiscuous)
+    {
+      if (device == 0)
+        {
+          for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
+               i != m_devices.end (); i++)
+            {
+              Ptr<NetDevice> dev = *i;
+              dev->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this));
+            }
+        }
+      else
+        {
+          device->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this));
+        }
+    }
+
+  m_handlers.push_back (entry);
+}
+
+void
+Node::UnregisterProtocolHandler (ProtocolHandler handler)
+{
+  for (ProtocolHandlerList::iterator i = m_handlers.begin ();
+       i != m_handlers.end (); i++)
+    {
+      if (i->handler.IsEqual (handler))
+        {
+          m_handlers.erase (i);
+          break;
+        }
+    }
+}
+
+bool
+Node::ChecksumEnabled (void)
+{
+  BooleanValue val;
+  g_checksumEnabled.GetValue (val);
+  return val.Get ();
+}
+
+bool
+Node::PromiscReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
+                                const Address &from, const Address &to, NetDevice::PacketType packetType)
+{
+  NS_LOG_FUNCTION(this);
+  return ReceiveFromDevice (device, packet, protocol, from, to, packetType, true);
+}
+
+bool
+Node::NonPromiscReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
+                                   const Address &from)
+{
+  NS_LOG_FUNCTION(this);
+  return ReceiveFromDevice (device, packet, protocol, from, device->GetAddress(), NetDevice::PacketType (0), false);
+}
+
+bool
+Node::ReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
+                         const Address &from, const Address &to, NetDevice::PacketType packetType, bool promiscuous)
+{
+  NS_ASSERT_MSG (Simulator::GetContext () == GetId (), "Received packet with erroneous context ; " <<
+                 "make sure the channels in use are correctly updating events context " <<
+                 "when transfering events from one node to another.");
+  NS_LOG_DEBUG("Node " << GetId () << " ReceiveFromDevice:  dev "
+               << device->GetIfIndex () << " (type=" << device->GetInstanceTypeId ().GetName ()
+               << ") Packet UID " << packet->GetUid ());
+  bool found = false;
+
+  for (ProtocolHandlerList::iterator i = m_handlers.begin ();
+       i != m_handlers.end (); i++)
+    {
+      if (i->device == 0 ||
+          (i->device != 0 && i->device == device))
+        {
+          if (i->protocol == 0 || 
+              i->protocol == protocol)
+            {
+              if (promiscuous == i->promiscuous)
+                {
+                  i->handler (device, packet, protocol, from, to, packetType);
+                  found = true;
+                }
+            }
+        }
+    }
+  return found;
+}
+
+}//namespace ns3