fw: integrate forwarder, strategy, tables

refs #1131, #1136

Change-Id: Ica58341cdc1ea1dc421693a87f35fc50177a707d
diff --git a/daemon/face/face.cpp b/daemon/face/face.cpp
index 6518117..9c8613b 100644
--- a/daemon/face/face.cpp
+++ b/daemon/face/face.cpp
@@ -8,8 +8,8 @@
 
 namespace nfd {
 
-Face::Face(FaceId id)
-  : m_id(id)
+Face::Face()
+  : m_id(INVALID_FACEID)
 {
 }
 
@@ -17,6 +17,18 @@
 {
 }
 
+FaceId
+Face::getId() const
+{
+  return m_id;
+}
+
+FaceId
+Face::setId(FaceId faceId)
+{
+  m_id = faceId;
+}
+
 bool
 Face::isUp() const
 {
diff --git a/daemon/face/face.hpp b/daemon/face/face.hpp
index 9ff2d20..994bc78 100644
--- a/daemon/face/face.hpp
+++ b/daemon/face/face.hpp
@@ -17,6 +17,8 @@
  */
 typedef int FaceId;
 
+const FaceId INVALID_FACEID = -1;
+
 const std::size_t MAX_NDN_PACKET_SIZE = 8800;
 
 /** \class Face
@@ -25,10 +27,13 @@
 class Face : noncopyable, public enable_shared_from_this<Face>
 {
 public:
-  Face(FaceId id);
+  Face();
   
   virtual
   ~Face();
+  
+  FaceId
+  getId() const;
 
   /// fires when an Interest is received
   EventEmitter<const Interest&> onReceiveInterest;
@@ -81,8 +86,15 @@
   // receiveData();
   
 private:
+  FaceId
+  setId(FaceId faceId);
+
+private:
   FaceId m_id;
   std::string m_description;
+  
+  // allow setting FaceId
+  friend class Forwarder;
 };
 
 } // namespace nfd
diff --git a/daemon/face/stream-face.hpp b/daemon/face/stream-face.hpp
index e0ea05b..a764a07 100644
--- a/daemon/face/stream-face.hpp
+++ b/daemon/face/stream-face.hpp
@@ -17,8 +17,7 @@
 public:
   typedef T protocol;
 
-  StreamFace(FaceId id,
-             const shared_ptr<typename protocol::socket>& socket);
+  StreamFace(const shared_ptr<typename protocol::socket>& socket);
 
 protected:
   void
@@ -39,10 +38,8 @@
 
 template <class T>
 inline
-StreamFace<T>::StreamFace(FaceId id,
-                          const shared_ptr<typename StreamFace::protocol::socket>& socket)
-  : Face(id)
-  , m_socket(socket)
+StreamFace<T>::StreamFace(const shared_ptr<typename StreamFace::protocol::socket>& socket)
+  : m_socket(socket)
 {
   m_socket->async_receive(boost::asio::buffer(m_inputBuffer, MAX_NDN_PACKET_SIZE), 0,
                           bind(&StreamFace<T>::handleReceive, this, _1, _2));
diff --git a/daemon/face/tcp-channel.cpp b/daemon/face/tcp-channel.cpp
index 25244f8..f67e9b2 100644
--- a/daemon/face/tcp-channel.cpp
+++ b/daemon/face/tcp-channel.cpp
@@ -117,10 +117,7 @@
     return;
   }
 
-  /**
-   * \todo Remove FaceId from here
-   */
-  shared_ptr<TcpFace> face = make_shared<TcpFace>(1, boost::cref(socket));
+  shared_ptr<TcpFace> face = make_shared<TcpFace>(boost::cref(socket));
   onFaceCreated(face);
 
   tcp::Endpoint remoteEndpoint = socket->remote_endpoint();
diff --git a/daemon/face/tcp-face.cpp b/daemon/face/tcp-face.cpp
index 79f9b8c..4a295ff 100644
--- a/daemon/face/tcp-face.cpp
+++ b/daemon/face/tcp-face.cpp
@@ -8,9 +8,8 @@
 
 namespace nfd {
 
-TcpFace::TcpFace(FaceId id,
-                 const shared_ptr<TcpFace::protocol::socket>& socket)
-  : StreamFace<protocol>(id, socket)
+TcpFace::TcpFace(const shared_ptr<TcpFace::protocol::socket>& socket)
+  : StreamFace<protocol>(socket)
 {
 }
 
diff --git a/daemon/face/tcp-face.hpp b/daemon/face/tcp-face.hpp
index c76cbc8..cf3188c 100644
--- a/daemon/face/tcp-face.hpp
+++ b/daemon/face/tcp-face.hpp
@@ -21,8 +21,7 @@
 public:
   typedef boost::asio::ip::tcp protocol;
 
-  TcpFace(FaceId id,
-          const shared_ptr<protocol::socket>& socket);
+  TcpFace(const shared_ptr<protocol::socket>& socket);
 
   // from Face
   virtual void
diff --git a/daemon/fw/best-route-strategy.cpp b/daemon/fw/best-route-strategy.cpp
index 12db744..3b94531 100644
--- a/daemon/fw/best-route-strategy.cpp
+++ b/daemon/fw/best-route-strategy.cpp
@@ -7,9 +7,10 @@
 #include "best-route-strategy.hpp"
 
 namespace nfd {
+namespace fw {
 
-BestRouteStrategy::BestRouteStrategy(Forwarder& fw)
-  : Strategy(fw)
+BestRouteStrategy::BestRouteStrategy(Forwarder& forwarder)
+  : Strategy(forwarder)
 {
 }
 
@@ -21,8 +22,7 @@
 BestRouteStrategy::afterReceiveInterest(const Face& inFace,
                    const Interest& interest,
                    shared_ptr<fib::Entry> fibEntry,
-                   shared_ptr<pit::Entry> pitEntry,
-                   pit::InRecordCollection::iterator pitInRecord)
+                   shared_ptr<pit::Entry> pitEntry)
 {
   const fib::NextHopList& nexthops = fibEntry->getNextHops();
   if (nexthops.size() == 0) {
@@ -34,4 +34,5 @@
   this->sendInterest(pitEntry, outFace);
 }
 
+} // namespace fw
 } // namespace nfd
diff --git a/daemon/fw/best-route-strategy.hpp b/daemon/fw/best-route-strategy.hpp
index 8e9f127..c29caae 100644
--- a/daemon/fw/best-route-strategy.hpp
+++ b/daemon/fw/best-route-strategy.hpp
@@ -8,8 +8,10 @@
 #define NFD_FW_BEST_ROUTE_STRATEGY_HPP
 
 #include "strategy.hpp"
+#include "forwarder.hpp"
 
 namespace nfd {
+namespace fw {
 
 /** \class BestRouteStrategy
  *  \brief a forwarding strategy that forwards Interest
@@ -19,7 +21,7 @@
 {
 public:
   explicit
-  BestRouteStrategy(Forwarder& fw);
+  BestRouteStrategy(Forwarder& forwarder);
   
   virtual
   ~BestRouteStrategy();
@@ -28,11 +30,10 @@
   afterReceiveInterest(const Face& inFace,
                        const Interest& interest,
                        shared_ptr<fib::Entry> fibEntry,
-                       shared_ptr<pit::Entry> pitEntry,
-                       pit::InRecordCollection::iterator pitInRecord
-                       );
+                       shared_ptr<pit::Entry> pitEntry);
 };
 
+} // namespace fw
 } // namespace nfd
 
 #endif // NFD_FW_BEST_ROUTE_STRATEGY_HPP
diff --git a/daemon/fw/forwarder.cpp b/daemon/fw/forwarder.cpp
index 1ba6808..d9850df 100644
--- a/daemon/fw/forwarder.cpp
+++ b/daemon/fw/forwarder.cpp
@@ -5,41 +5,67 @@
  */
 
 #include "forwarder.hpp"
+#include "core/logger.hpp"
+#include "best-route-strategy.hpp"
 
 namespace nfd {
 
+NFD_LOG_INIT("Forwarder");
+
 Forwarder::Forwarder(boost::asio::io_service& ioService)
   : m_scheduler(ioService)
+  , m_lastFaceId(0)
 {
-}
-
-uint64_t
-Forwarder::addFace(const shared_ptr<Face>& face)
-{
-  return -1;
+  m_strategy = make_shared<fw::BestRouteStrategy>(boost::ref(*this));
 }
 
 void
-Forwarder::removeFace(const shared_ptr<Face>& face)
+Forwarder::addFace(shared_ptr<Face> face)
 {
+  FaceId faceId = ++m_lastFaceId;
+  face->setId(faceId);
+  m_faces[faceId] = face;
+  NFD_LOG_INFO("addFace id=" << faceId);
+
+  face->onReceiveInterest += bind(&Forwarder::onInterest,
+                             this, boost::ref(*face), _1);
+  face->onReceiveData     += bind(&Forwarder::onData,
+                             this, boost::ref(*face), _1);
 }
 
 void
-Forwarder::onInterest(const Face& face, const Interest& interest)
+Forwarder::removeFace(shared_ptr<Face> face)
 {
-  this->onIncomingInterest(const_cast<Face&>(face), interest);
+  FaceId faceId = face->getId();
+  m_faces.erase(faceId);
+  face->setId(INVALID_FACEID);
+  NFD_LOG_INFO("removeFace id=" << faceId);
+  
+  // XXX This clears all subscriptions, because EventEmitter
+  //     does not support only removing Forwarder's subscription
+  face->onReceiveInterest.clear();
+  face->onReceiveData    .clear();
+  
+  m_fib.removeNextHopFromAllEntries(face);
 }
 
 void
-Forwarder::onData(const Face& face, const Data& data)
+Forwarder::onInterest(Face& face, const Interest& interest)
 {
-  this->onIncomingData(const_cast<Face&>(face), data);
+  this->onIncomingInterest(face, interest);
+}
+
+void
+Forwarder::onData(Face& face, const Data& data)
+{
+  this->onIncomingData(face, data);
 }
 
 void
 Forwarder::onIncomingInterest(Face& inFace, const Interest& interest)
 {
   // receive Interest
+  NFD_LOG_DEBUG("onIncomingInterest face=" << inFace.getId() << " interest=" << interest.getName());
   
   // PIT insert
   std::pair<shared_ptr<pit::Entry>, bool>
@@ -89,19 +115,24 @@
   // TODO use Fib::findParent(pitEntry)
   
   // dispatch to strategy
-  // TODO
+  m_strategy->afterReceiveInterest(inFace, interest, fibEntry, pitEntry);
+  // TODO dispatch according to fibEntry
 }
 
 void
 Forwarder::onInterestLoop(Face& inFace, const Interest& interest,
                           shared_ptr<pit::Entry> pitEntry)
 {
+  NFD_LOG_DEBUG("onInterestLoop face=" << inFace.getId() << " interest=" << interest.getName());
+
   // do nothing, which means Interest is dropped
 }
 
 void
 Forwarder::onOutgoingInterest(shared_ptr<pit::Entry> pitEntry, Face& outFace)
 {
+  NFD_LOG_DEBUG("onOutgoingInterest face=" << outFace.getId() << " interest=" << pitEntry->getName());
+
   // pick Interest
   const Interest& interest = pitEntry->getInterest();
   // TODO pick the last incoming Interest
@@ -120,6 +151,8 @@
 void
 Forwarder::onInterestRebuff(shared_ptr<pit::Entry> pitEntry)
 {
+  NFD_LOG_DEBUG("onInterestRebuff interest=" << pitEntry->getName());
+
   // set PIT straggler timer
   this->setStragglerTimer(pitEntry);
 }
@@ -127,6 +160,8 @@
 void
 Forwarder::onInterestUnsatisfied(shared_ptr<pit::Entry> pitEntry)
 {
+  NFD_LOG_DEBUG("onInterestUnsatisfied interest=" << pitEntry->getName());
+
   // invoke PIT unsatisfied callback
   // TODO
   
@@ -138,6 +173,7 @@
 Forwarder::onIncomingData(Face& inFace, const Data& data)
 {
   // receive Data
+  NFD_LOG_DEBUG("onIncomingData face=" << inFace.getId() << " data=" << data.getName());
   
   // PIT match
   shared_ptr<pit::DataMatchResult> pitMatches = m_pit.findAllDataMatches(data);
@@ -155,6 +191,7 @@
   for (pit::DataMatchResult::iterator it = pitMatches->begin();
        it != pitMatches->end(); ++it) {
     shared_ptr<pit::Entry> pitEntry = *it;
+    NFD_LOG_DEBUG("onIncomingData matching=" << pitEntry->getName());
     
     // cancel unsatisfy & straggler timer
     this->cancelUnsatisfyAndStragglerTimer(pitEntry);
@@ -196,11 +233,15 @@
     // CS insert
     m_cs.insert(data);
   }
+
+  NFD_LOG_DEBUG("onDataUnsolicited face=" << inFace.getId() << " data=" << data.getName() << " acceptToCache=" << acceptToCache);
 }
 
 void
 Forwarder::onOutgoingData(const Data& data, Face& outFace)
 {
+  NFD_LOG_DEBUG("onOutgoingData face=" << outFace.getId() << " data=" << data.getName());
+
   // traffic manager
   // pass through
   
diff --git a/daemon/fw/forwarder.hpp b/daemon/fw/forwarder.hpp
index 591254e..1359737 100644
--- a/daemon/fw/forwarder.hpp
+++ b/daemon/fw/forwarder.hpp
@@ -13,6 +13,7 @@
 #include "table/fib.hpp"
 #include "table/pit.hpp"
 #include "table/cs.hpp"
+#include "strategy.hpp"
 
 namespace nfd {
 
@@ -26,18 +27,28 @@
 public:
   Forwarder(boost::asio::io_service& ioService);
 
-  uint64_t
-  addFace(const shared_ptr<Face>& face);
+  void
+  addFace(shared_ptr<Face> face);
 
   void
-  removeFace(const shared_ptr<Face>& face);
+  removeFace(shared_ptr<Face> face);
 
   void
-  onInterest(const Face& face, const Interest& interest);
+  onInterest(Face& face, const Interest& interest);
 
   void
-  onData(const Face& face, const Data& data);
+  onData(Face& face, const Data& data);
   
+public:
+  Fib&
+  getFib();
+  
+  Pit&
+  getPit();
+  
+  Cs&
+  getCs();
+
 private: // pipelines
   /** \brief incoming Interest pipeline
    */
@@ -92,15 +103,39 @@
 
 private:
   Scheduler m_scheduler;
+  
+  FaceId m_lastFaceId;
+  std::map<FaceId, shared_ptr<Face> > m_faces;
+  
   Fib m_fib;
   Pit m_pit;
   Cs  m_cs;
-  // container< shared_ptr<Face> > m_faces;
+  /// the active strategy (only one strategy in mock)
+  shared_ptr<fw::Strategy> m_strategy;
   
   // allow Strategy (base class) to enter pipelines
-  friend class Strategy;
+  friend class fw::Strategy;
 };
 
+inline Fib&
+Forwarder::getFib()
+{
+  return m_fib;
+}
+
+inline Pit&
+Forwarder::getPit()
+{
+  return m_pit;
+}
+
+inline Cs&
+Forwarder::getCs()
+{
+  return m_cs;
+}
+
+
 } // namespace nfd
 
 #endif // NFD_FW_FORWARDER_HPP
diff --git a/daemon/fw/strategy.cpp b/daemon/fw/strategy.cpp
index ed1233f..f8c2f12 100644
--- a/daemon/fw/strategy.cpp
+++ b/daemon/fw/strategy.cpp
@@ -5,11 +5,13 @@
  */
 
 #include "strategy.hpp"
+#include "forwarder.hpp"
 
 namespace nfd {
+namespace fw {
 
-Strategy::Strategy(Forwarder& fw)
-  : m_fw(fw)
+Strategy::Strategy(Forwarder& forwarder)
+  : m_forwarder(forwarder)
 {
 }
 
@@ -22,13 +24,14 @@
 Strategy::sendInterest(shared_ptr<pit::Entry> pitEntry,
                        shared_ptr<Face> outFace)
 {
-  m_fw.onOutgoingInterest(pitEntry, *outFace);
+  m_forwarder.onOutgoingInterest(pitEntry, *outFace);
 }
 
 void
 Strategy::rebuffPendingInterest(shared_ptr<pit::Entry> pitEntry)
 {
-  m_fw.onInterestRebuff(pitEntry);
+  m_forwarder.onInterestRebuff(pitEntry);
 }
 
+} // namespace fw
 } // namespace nfd
diff --git a/daemon/fw/strategy.hpp b/daemon/fw/strategy.hpp
index 1a6e47f..ce21c13 100644
--- a/daemon/fw/strategy.hpp
+++ b/daemon/fw/strategy.hpp
@@ -7,10 +7,20 @@
 #ifndef NFD_FW_STRATEGY_HPP
 #define NFD_FW_STRATEGY_HPP
 
-#include "forwarder.hpp"
+#include "face/face.hpp"
 
 namespace nfd {
 
+class Forwarder;
+namespace fib {
+class Entry;
+}
+namespace pit {
+class Entry;
+}
+
+namespace fw {
+
 /** \class Strategy
  *  \brief represents a forwarding strategy
  */
@@ -18,7 +28,7 @@
 {
 public:
   explicit
-  Strategy(Forwarder& fw);
+  Strategy(Forwarder& forwarder);
   
   virtual
   ~Strategy();
@@ -27,9 +37,7 @@
   afterReceiveInterest(const Face& inFace,
                        const Interest& interest,
                        shared_ptr<fib::Entry> fibEntry,
-                       shared_ptr<pit::Entry> pitEntry,
-                       pit::InRecordCollection::iterator pitInRecord
-                       ) =0;
+                       shared_ptr<pit::Entry> pitEntry) =0;
   
   //virtual void
   //beforeExpirePendingInterest() =0;
@@ -57,9 +65,10 @@
   rebuffPendingInterest(shared_ptr<pit::Entry> pitEntry);
   
 private:
-  Forwarder& m_fw;
+  Forwarder& m_forwarder;
 };
 
+} // namespace fw
 } // namespace nfd
 
 #endif // NFD_FW_STRATEGY_HPP
diff --git a/daemon/mgmt/internal-face.cpp b/daemon/mgmt/internal-face.cpp
index cd66b4a..e3daeca 100644
--- a/daemon/mgmt/internal-face.cpp
+++ b/daemon/mgmt/internal-face.cpp
@@ -8,10 +8,7 @@
 
 namespace nfd {
 
-const FaceId INTERNAL_FACE_FACEID = 0;
-
 InternalFace::InternalFace()
-  : Face(INTERNAL_FACE_FACEID)
 {
 
 }