model: Enabling face operations based on NFD's face
Refs: #2215
diff --git a/model/ndn-app-face.cpp b/model/ndn-app-face.cpp
index 0af1432..9759771 100644
--- a/model/ndn-app-face.cpp
+++ b/model/ndn-app-face.cpp
@@ -36,8 +36,9 @@
namespace ndn {
AppFace::AppFace(Ptr<App> app)
- // : Face(app->GetNode())
- : m_app(app)
+ : LocalFace(FaceUri("appFace://"), FaceUri("appFace://"))
+ , m_node(app->GetNode())
+ , m_app(app)
{
NS_LOG_FUNCTION(this << app);
@@ -49,18 +50,31 @@
NS_LOG_FUNCTION_NOARGS();
}
-bool
-AppFace::SendInterest(shared_ptr<const Interest> interest)
+void
+AppFace::close()
{
- NS_LOG_FUNCTION(this << interest);
- return false;
}
-bool
-AppFace::SendData(shared_ptr<const Data> data)
+void
+AppFace::sendInterest(const Interest& interest)
{
- NS_LOG_FUNCTION(this << data);
- return false;
+ NS_LOG_FUNCTION(this << &interest);
+
+ this->onSendInterest(interest);
+
+ // to decouple callbacks
+ Simulator::ScheduleNow(&App::OnInterest, m_app, interest.shared_from_this());
+}
+
+void
+AppFace::sendData(const Data& data)
+{
+ NS_LOG_FUNCTION(this << &data);
+
+ this->onSendData(data);
+
+ // to decouple callbacks
+ Simulator::ScheduleNow(&App::OnData, m_app, data.shared_from_this());
}
} // namespace ndn
diff --git a/model/ndn-app-face.hpp b/model/ndn-app-face.hpp
index 9abc4cf..eeef73e 100644
--- a/model/ndn-app-face.hpp
+++ b/model/ndn-app-face.hpp
@@ -23,13 +23,13 @@
#define NDN_APP_FACE_H
#include "ns3/ndnSIM/model/ndn-common.hpp"
-
-#include "ndn-face.hpp"
-#include "ns3/traced-callback.h"
+#include "ns3/ndnSIM/NFD/daemon/face/local-face.hpp"
+#include "ns3/ndnSIM/model/ndn-face.hpp"
namespace ns3 {
class Packet;
+class Node;
namespace ndn {
@@ -43,25 +43,39 @@
* component responsible for actual delivery of data packet to and
* from Ndn stack
*
- * \see AppFace, NdnNetDeviceFace, NdnIpv4Face, NdnUdpFace
+ * \see AppFace, NdnNetDeviceFace
*/
-class AppFace : public Face {
+class AppFace : public nfd::LocalFace {
public:
/**
* \brief Default constructor
*/
AppFace(Ptr<App> app);
+
virtual ~AppFace();
- ////////////////////////////////////////////////////////////////////
- // methods overloaded from Face
- virtual bool
- SendInterest(shared_ptr<const Interest> interest);
+public: // from nfd::Face
+ /**
+ * @brief Send Interest towards application
+ *
+ * @note To send Interest from application, use `AppFace::onReceiveInterest(interest)`
+ */
+ virtual void
+ sendInterest(const Interest& interest);
- virtual bool
- SendData(shared_ptr<const Data> data);
+ /**
+ * @brief Send Data towards application
+ *
+ * @note To send Data from application, use `AppFace::onReceiveData(data)`
+ */
+ virtual void
+ sendData(const Data& data);
+
+ virtual void
+ close();
private:
+ Ptr<Node> m_node;
Ptr<App> m_app;
};
diff --git a/model/ndn-common.cpp b/model/ndn-common.cpp
new file mode 100644
index 0000000..e2a498a
--- /dev/null
+++ b/model/ndn-common.cpp
@@ -0,0 +1,28 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2011-2015 Regents of the University of California.
+ *
+ * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
+ * contributors.
+ *
+ * ndnSIM is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndnSIM 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
+ * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "ndn-common.hpp"
+
+namespace ns3 {
+namespace ndn {
+
+ATTRIBUTE_HELPER_CPP(Name);
+
+} // namespace ndn
+} // namespace ns3
diff --git a/model/ndn-common.hpp b/model/ndn-common.hpp
index 97e722a..8b1a692 100644
--- a/model/ndn-common.hpp
+++ b/model/ndn-common.hpp
@@ -22,6 +22,8 @@
#include "ns3/nstime.h"
#include "ns3/simulator.h"
+#include "ns3/attribute.h"
+#include "ns3/attribute-helper.h"
#include <ndn-cxx/interest.hpp>
#include <ndn-cxx/encoding/block.hpp>
@@ -39,6 +41,8 @@
using ::ndn::Name;
namespace name = ::ndn::name;
+ATTRIBUTE_HELPER_HEADER(Name);
+
namespace time = ::ndn::time;
using ::ndn::Exclude;
diff --git a/model/ndn-face.hpp b/model/ndn-face.hpp
index 73d4fb3..e1b35e0 100644
--- a/model/ndn-face.hpp
+++ b/model/ndn-face.hpp
@@ -20,21 +20,27 @@
#ifndef NDNSIM_NDN_FACE_HPP
#define NDNSIM_NDN_FACE_HPP
-#include <boost/noncopyable.hpp>
+#include "ns3/ndnSIM/NFD/daemon/face/face.hpp"
+#include <ndn-cxx/util/face-uri.hpp>
namespace ns3 {
namespace ndn {
-class Face : boost::noncopyable {
-};
+using nfd::Face;
+using ::ndn::util::FaceUri;
+
+} // namespace ndn
+} // namespace ns3
+
+namespace nfd {
inline std::ostream&
operator<<(std::ostream& os, const Face& face)
{
+ os << face.getLocalUri();
return os;
}
-} // namespace ndn
-} // namespace ns3
+} // namespace nfd
#endif // NDNSIM_NDN_FACE_HPP
diff --git a/model/ndn-global-router.hpp b/model/ndn-global-router.hpp
index 74cf5f1..0465cb8 100644
--- a/model/ndn-global-router.hpp
+++ b/model/ndn-global-router.hpp
@@ -22,6 +22,7 @@
#define NDN_GLOBAL_ROUTER_H
#include "ns3/ndnSIM/model/ndn-common.hpp"
+#include "ns3/ndnSIM/model/ndn-face.hpp"
#include "ns3/object.h"
#include "ns3/ptr.h"
@@ -36,7 +37,6 @@
namespace ndn {
class L3Protocol;
-class Face;
/**
* @ingroup ndn
diff --git a/model/ndn-l3-protocol.hpp b/model/ndn-l3-protocol.hpp
index 73ca77b..03618d5 100644
--- a/model/ndn-l3-protocol.hpp
+++ b/model/ndn-l3-protocol.hpp
@@ -22,6 +22,7 @@
#define NDN_L3_PROTOCOL_H
#include "ns3/ndnSIM/model/ndn-common.hpp"
+#include "ns3/ndnSIM/model/ndn-face.hpp"
#include <list>
#include <vector>
@@ -33,14 +34,11 @@
namespace ns3 {
class Packet;
-class NetDevice;
class Node;
class Header;
namespace ndn {
-class Face;
-
/**
* \defgroup ndn ndnSIM: NDN simulation module
*
@@ -64,8 +62,6 @@
*/
class L3Protocol : public Object {
public:
- typedef std::vector<shared_ptr<Face>> FaceList;
-
/**
* \brief Interface ID
*
diff --git a/model/ndn-net-device-face.cpp b/model/ndn-net-device-face.cpp
index ae9de5d..03d95db 100644
--- a/model/ndn-net-device-face.cpp
+++ b/model/ndn-net-device-face.cpp
@@ -22,6 +22,8 @@
#include "ndn-net-device-face.hpp"
#include "ndn-l3-protocol.hpp"
+#include "ndn-ns3.hpp"
+
#include "ns3/net-device.h"
#include "ns3/log.h"
#include "ns3/packet.h"
@@ -32,29 +34,39 @@
#include "ns3/point-to-point-net-device.h"
#include "ns3/channel.h"
+#include "../utils/ndn-fw-hop-count-tag.hpp"
+
NS_LOG_COMPONENT_DEFINE("ndn.NetDeviceFace");
namespace ns3 {
namespace ndn {
-/**
- * By default, Ndn face are created in the "down" state. Before
- * becoming useable, the user must invoke SetUp on the face
- */
NetDeviceFace::NetDeviceFace(Ptr<Node> node, const Ptr<NetDevice>& netDevice)
- // : Face(node)
- : m_netDevice(netDevice)
+ : Face(FaceUri("netDeviceFace://"), FaceUri("netDeviceFace://"))
+ , m_node(node)
+ , m_netDevice(netDevice)
{
NS_LOG_FUNCTION(this << netDevice);
- // SetMetric(1); // default metric
+ setMetric(1); // default metric
NS_ASSERT_MSG(m_netDevice != 0, "NetDeviceFace needs to be assigned a valid NetDevice");
+
+ m_node->RegisterProtocolHandler(MakeCallback(&NetDeviceFace::receiveFromNetDevice, this),
+ L3Protocol::ETHERNET_FRAME_TYPE, m_netDevice,
+ true /*promiscuous mode*/);
}
NetDeviceFace::~NetDeviceFace()
{
NS_LOG_FUNCTION_NOARGS();
+
+ m_node->UnregisterProtocolHandler(MakeCallback(&NetDeviceFace::receiveFromNetDevice, this));
+}
+
+void
+NetDeviceFace::close()
+{
}
Ptr<NetDevice>
@@ -63,21 +75,70 @@
return m_netDevice;
}
-bool
-NetDeviceFace::Send(Ptr<Packet> packet)
+void
+NetDeviceFace::send(Ptr<Packet> packet)
{
- return false;
+ NS_ASSERT_MSG(packet->GetSize() <= m_netDevice->GetMtu(),
+ "Packet size " << packet->GetSize() << " exceeds device MTU "
+ << m_netDevice->GetMtu());
+
+ FwHopCountTag tag;
+ packet->RemovePacketTag(tag);
+ tag.Increment();
+ packet->AddPacketTag(tag);
+
+ m_netDevice->Send(packet, m_netDevice->GetBroadcast(), L3Protocol::ETHERNET_FRAME_TYPE);
+}
+
+void
+NetDeviceFace::sendInterest(const Interest& interest)
+{
+ NS_LOG_FUNCTION(this << &interest);
+
+ this->onSendInterest(interest);
+
+ Ptr<Packet> packet = Convert::ToPacket(interest);
+ send(packet);
+}
+
+void
+NetDeviceFace::sendData(const Data& data)
+{
+ NS_LOG_FUNCTION(this << &data);
+
+ this->onSendData(data);
+
+ Ptr<Packet> packet = Convert::ToPacket(data);
+ send(packet);
}
// callback
void
-NetDeviceFace::ReceiveFromNetDevice(Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol,
+NetDeviceFace::receiveFromNetDevice(Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol,
const Address& from, const Address& to,
NetDevice::PacketType packetType)
{
NS_LOG_FUNCTION(device << p << protocol << from << to << packetType);
- // Receive(p);
+
+ Ptr<Packet> packet = p->Copy();
+ try {
+ uint32_t type = Convert::getPacketType(p);
+ if (type == ::ndn::tlv::Interest) {
+ shared_ptr<const Interest> i = Convert::FromPacket<Interest>(packet);
+ this->onReceiveInterest(*i);
+ }
+ else if (type == ::ndn::tlv::Data) {
+ shared_ptr<const Data> d = Convert::FromPacket<Data>(packet);
+ this->onReceiveData(*d);
+ }
+ else {
+ NS_LOG_ERROR("Unsupported TLV packet");
+ }
+ }
+ catch (::ndn::tlv::Error&) {
+ NS_LOG_ERROR("Unrecognized TLV packet");
+ }
}
-} // namespace ndnsim
+} // namespace ndn
} // namespace ns3
diff --git a/model/ndn-net-device-face.hpp b/model/ndn-net-device-face.hpp
index f832b52..5432ee1 100644
--- a/model/ndn-net-device-face.hpp
+++ b/model/ndn-net-device-face.hpp
@@ -22,8 +22,8 @@
#define NDN_NET_DEVICE_FACE_H
#include "ns3/ndnSIM/model/ndn-common.hpp"
+#include "ns3/ndnSIM/model/ndn-face.hpp"
-#include "ndn-face.hpp"
#include "ns3/net-device.h"
namespace ns3 {
@@ -53,11 +53,18 @@
* this face will be associate
*/
NetDeviceFace(Ptr<Node> node, const Ptr<NetDevice>& netDevice);
+
virtual ~NetDeviceFace();
-protected:
- virtual bool
- Send(Ptr<Packet> p);
+public: // from nfd::Face
+ virtual void
+ sendInterest(const Interest& interest);
+
+ virtual void
+ sendData(const Data& data);
+
+ virtual void
+ close();
public:
/**
@@ -69,12 +76,16 @@
GetNetDevice() const;
private:
+ void
+ send(Ptr<Packet> packet);
+
/// \brief callback from lower layers
void
- ReceiveFromNetDevice(Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol,
+ receiveFromNetDevice(Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol,
const Address& from, const Address& to, NetDevice::PacketType packetType);
private:
+ Ptr<Node> m_node;
Ptr<NetDevice> m_netDevice; ///< \brief Smart pointer to NetDevice
};
diff --git a/wscript b/wscript
index 7bd46d3..0810d72 100644
--- a/wscript
+++ b/wscript
@@ -87,7 +87,7 @@
excl=['model/ip-faces/*',
'apps/*',
'helper/*',
- 'utils/**/*'])
+ 'utils/*/*'])
module.full_headers = [p.path_from(bld.path) for p in bld.path.ant_glob(
['%s/**/*.hpp' % dir for dir in module_dirs])]