--- /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