face: Skeleton implementation for the TCP protocol (face, channel, factory)

refs: #1132, #1133, #1134, #1135

Change-Id: I4a5935a078c7289dc6ea9b33f358f1a578c4405c
diff --git a/daemon/face/channel-factory.hpp b/daemon/face/channel-factory.hpp
new file mode 100644
index 0000000..7f4a5d4
--- /dev/null
+++ b/daemon/face/channel-factory.hpp
@@ -0,0 +1,39 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_FACE_CHANNEL_FACTORY_HPP
+#define NFD_FACE_CHANNEL_FACTORY_HPP
+
+#include "common.hpp"
+
+namespace ndn {
+
+/**
+ * \brief Base class for all channel factories
+ */
+template<class E, class C>
+class ChannelFactory
+{
+public:
+  typedef E Endpoint;
+  typedef C Channel;
+  
+  /**
+   * \brief Base class for all exceptions thrown by channel factories
+   */
+  struct Error : public std::runtime_error
+  {
+    Error(const std::string& what) : std::runtime_error(what) {}
+  };
+
+protected:
+  typedef std::map<Endpoint, Channel> ChannelMap;
+  ChannelMap m_channels;  
+};
+
+} // namespace ndn
+
+#endif // NFD_FACE_CHANNEL_FACTORY_HPP
diff --git a/daemon/face/face.hpp b/daemon/face/face.hpp
index abcb3ab..8022e3d 100644
--- a/daemon/face/face.hpp
+++ b/daemon/face/face.hpp
@@ -36,11 +36,11 @@
   
   /// send an Interest
   virtual void
-  sendInterest(const Interest &interest) =0;
+  sendInterest(const Interest& interest) = 0;
   
   /// send a Data
   virtual void
-  sendData(const Data &data) =0;
+  sendData(const Data& data) = 0;
   
   /** \brief Get whether underlying communicate is up
    *  In this base class this property is always true.
diff --git a/daemon/face/stream-face.cpp b/daemon/face/stream-face.cpp
new file mode 100644
index 0000000..e84634d
--- /dev/null
+++ b/daemon/face/stream-face.cpp
@@ -0,0 +1,8 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "stream-face.hpp"
+
diff --git a/daemon/face/stream-face.hpp b/daemon/face/stream-face.hpp
new file mode 100644
index 0000000..778eb71
--- /dev/null
+++ b/daemon/face/stream-face.hpp
@@ -0,0 +1,29 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_FACE_STREAM_FACE_HPP
+#define NFD_FACE_STREAM_FACE_HPP
+
+#include "face.hpp"
+
+namespace ndn {
+
+template <class T>
+class StreamFace : public Face
+{
+public:
+  typedef T protocol;
+
+  StreamFace(FaceId id)
+    : Face(id)
+  {
+  }
+  
+};
+
+} // namespace ndn
+
+#endif // NFD_FACE_STREAM_FACE_HPP
diff --git a/daemon/face/tcp-channel-factory.cpp b/daemon/face/tcp-channel-factory.cpp
new file mode 100644
index 0000000..8ec1c3f
--- /dev/null
+++ b/daemon/face/tcp-channel-factory.cpp
@@ -0,0 +1,29 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "tcp-channel-factory.hpp"
+
+namespace ndn {
+
+shared_ptr<TcpChannel>
+TcpChannelFactory::create(const tcp::Endpoint& endpoint)
+{
+  return shared_ptr<ndn::TcpChannel>();
+}
+
+shared_ptr<TcpChannel>
+TcpChannelFactory::create(const std::string& localHost, const std::string& localPort)
+{
+  return shared_ptr<ndn::TcpChannel>();
+}
+
+shared_ptr<TcpChannel>
+TcpChannelFactory::find(const tcp::Endpoint& localEndpoint)
+{
+  return shared_ptr<ndn::TcpChannel>();
+}
+
+} // namespace ndn
diff --git a/daemon/face/tcp-channel-factory.hpp b/daemon/face/tcp-channel-factory.hpp
new file mode 100644
index 0000000..04932ca
--- /dev/null
+++ b/daemon/face/tcp-channel-factory.hpp
@@ -0,0 +1,73 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_FACE_TCP_CHANNEL_FACTORY_HPP
+#define NFD_FACE_TCP_CHANNEL_FACTORY_HPP
+
+#include "channel-factory.hpp"
+#include "tcp-channel.hpp"
+
+namespace ndn {
+
+class TcpChannelFactory : public ChannelFactory<tcp::Endpoint, TcpChannel>
+{
+public:
+  /**
+   * \brief Exception of TcpChannelFactory
+   */
+  struct Error : public ChannelFactory::Error
+  {
+    Error(const std::string& what) : ChannelFactory::Error(what) {}
+  };
+
+  /**
+   * \brief Create TCP-based channel using tcp::Endpoint
+   *
+   * tcp::Endpoint is really an alias for boost::asio::ip::tcp::endpoint.
+   *
+   * If this method called twice with the same endpoint, only one channel
+   * will be created.  The second call will just retrieve the existing
+   * channel.
+   *
+   * \returns always a valid pointer to a TcpChannel object, an exception
+   *          is thrown if it cannot be created.
+   *
+   * \throws TcpChannelFactory::Error
+   *
+   * \see http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/reference/ip__tcp/endpoint.html
+   *      for details on ways to create tcp::Endpoint
+   */
+  shared_ptr<TcpChannel>
+  create(const tcp::Endpoint& localEndpoint);
+
+  /**
+   * \brief Create TCP-based channel using specified host and port number
+   *
+   * This method will attempt to resolve the provided host and port numbers
+   * and will throw TcpChannelFactory::Error when channel cannot be created.
+   *
+   * Note that this call will **BLOCK** until resolution is done or failed.
+   *
+   * \throws TcpChannelFactory::Error
+   */
+  shared_ptr<TcpChannel>
+  create(const std::string& localHost, const std::string& localPort);
+
+  /**
+   * \brief Look up TcpChannel using specified local endpoint
+   *
+   * \returns shared pointer to the existing TcpChannel object
+   *          or empty shared pointer when such channel does not exist 
+   *
+   * \throws never
+   */
+  shared_ptr<TcpChannel>
+  find(const tcp::Endpoint& localEndpoint);
+};
+
+} // namespace ndn
+
+#endif // NFD_FACE_TCP_CHANNEL_FACTORY_HPP
diff --git a/daemon/face/tcp-channel.cpp b/daemon/face/tcp-channel.cpp
new file mode 100644
index 0000000..8aacbd6
--- /dev/null
+++ b/daemon/face/tcp-channel.cpp
@@ -0,0 +1,26 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "tcp-channel.hpp"
+
+namespace ndn {
+
+TcpChannel::TcpChannel(boost::asio::io_service& ioService,
+                       const tcp::Endpoint& endpoint)
+{
+}
+
+void
+TcpChannel::listen(const tcp::Endpoint& endpoint)
+{
+}
+
+void
+TcpChannel::connect(const tcp::Endpoint& endpoint)
+{
+}
+
+} // namespace ndn
diff --git a/daemon/face/tcp-channel.hpp b/daemon/face/tcp-channel.hpp
new file mode 100644
index 0000000..50846a9
--- /dev/null
+++ b/daemon/face/tcp-channel.hpp
@@ -0,0 +1,38 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_FACE_TCP_CHANNEL_HPP
+#define NFD_FACE_TCP_CHANNEL_HPP
+
+// #include "session-based-channel.hpp"
+
+#include "common.hpp"
+// #include <boost/asio/ip/tcp.hpp>
+
+namespace tcp {
+typedef boost::asio::ip::tcp::endpoint Endpoint;
+} // namespace tcp
+
+namespace ndn {
+
+class TcpChannel // : protected SessionBasedChannel
+{
+public:
+  TcpChannel(boost::asio::io_service& ioService, const tcp::Endpoint& endpoint);
+
+  void
+  listen(const tcp::Endpoint& endpoint);
+
+  void
+  connect(const tcp::Endpoint& endpoint);
+
+private:
+  tcp::Endpoint m_localEndpoint;
+};
+
+} // namespace ndn
+ 
+#endif // NFD_FACE_TCP_CHANNEL_HPP
diff --git a/daemon/face/tcp-face.cpp b/daemon/face/tcp-face.cpp
new file mode 100644
index 0000000..f198877
--- /dev/null
+++ b/daemon/face/tcp-face.cpp
@@ -0,0 +1,17 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "tcp-face.hpp"
+
+namespace ndn {
+
+TcpFace::TcpFace(FaceId id, const shared_ptr<TcpFace::protocol::socket>& socket)
+  : StreamFace<protocol>(id)
+  , m_socket(socket)
+{
+}
+
+} // namespace ndn
diff --git a/daemon/face/tcp-face.hpp b/daemon/face/tcp-face.hpp
new file mode 100644
index 0000000..f010495
--- /dev/null
+++ b/daemon/face/tcp-face.hpp
@@ -0,0 +1,30 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_FACE_TCP_FACE_HPP
+#define NFD_FACE_TCP_FACE_HPP
+
+#include "stream-face.hpp"
+
+namespace ndn
+{
+
+/**
+ * \brief Implementation of Face abstraction that uses TCP
+ *        as underlying transport mechanism
+ */
+class TcpFace : public StreamFace<boost::asio::ip::tcp>
+{
+public:
+  TcpFace(FaceId id, const shared_ptr<protocol::socket>& socket);
+
+private:
+  shared_ptr<protocol::socket> m_socket;
+};
+
+} // namespace ndn
+
+#endif // NFD_FACE_TCP_FACE_HPP