face: send and receive NACK

refs #2930

Change-Id: I70c969ac12b493d2c83fa892beffae936cc23791
diff --git a/src/detail/pending-interest.hpp b/src/detail/pending-interest.hpp
index 41f6b37..bac5836 100644
--- a/src/detail/pending-interest.hpp
+++ b/src/detail/pending-interest.hpp
@@ -28,31 +28,32 @@
 #include "../util/time.hpp"
 #include "../util/scheduler.hpp"
 #include "../util/scheduler-scoped-event-id.hpp"
+#include "../lp/nack.hpp"
 
 namespace ndn {
 
 class PendingInterest : noncopyable
 {
 public:
-  typedef function<void(const Interest&, Data&)> OnData;
-  typedef function<void(const Interest&)> OnTimeout;
-
   /**
    * @brief Create a new PitEntry and set the timeout based on the current time and
-   *        the interest lifetime.
-   *
-   * @param interest A shared_ptr for the interest
-   * @param onData A function object to call when a matching data packet is received.
-   * @param onTimeout A function object to call if the interest times out.
-   *                  If onTimeout is an empty OnTimeout(), this does not use it.
-   * @param scheduler Scheduler instance to use to schedule a timeout event.  The scheduled
-   *                  event will be automatically cancelled when pending interest is destroyed.
+   *        the Interest lifetime.
+   * @param interest shared_ptr for the Interest
+   * @param dataCallback function to call when matching Data packet is received
+   * @param nackCallback function to call when Nack matching Interest is received
+   * @param timeoutCallback function to call if Interest times out
+   * @param scheduler Scheduler instance to use to schedule a timeout event. The scheduled
+   *                  event will be automatically cancelled when pending Interest is destroyed.
    */
-  PendingInterest(shared_ptr<const Interest> interest, const OnData& onData,
-                  const OnTimeout& onTimeout, Scheduler& scheduler)
+  PendingInterest(shared_ptr<const Interest> interest,
+                  const DataCallback& dataCallback,
+                  const NackCallback& nackCallback,
+                  const TimeoutCallback& timeoutCallback,
+                  Scheduler& scheduler)
     : m_interest(interest)
-    , m_onData(onData)
-    , m_onTimeout(onTimeout)
+    , m_dataCallback(dataCallback)
+    , m_nackCallback(nackCallback)
+    , m_timeoutCallback(timeoutCallback)
     , m_timeoutEvent(scheduler)
   {
     m_timeoutEvent =
@@ -65,10 +66,10 @@
   /**
    * @return the Interest
    */
-  const Interest&
+  shared_ptr<const Interest>
   getInterest() const
   {
-    return *m_interest;
+    return m_interest;
   }
 
   /**
@@ -76,9 +77,19 @@
    * @note If the DataCallback is an empty function, this method does nothing.
    */
   void
-  invokeDataCallback(Data& data)
+  invokeDataCallback(const Data& data)
   {
-    m_onData(*m_interest, data);
+    m_dataCallback(*m_interest, data);
+  }
+
+  /**
+   * @brief invokes the NackCallback
+   * @note If the NackCallback is an empty function, this method does nothing.
+   */
+  void
+  invokeNackCallback(const lp::Nack& nack)
+  {
+    m_nackCallback(*m_interest, nack);
   }
 
   /**
@@ -98,8 +109,8 @@
   void
   invokeTimeoutCallback()
   {
-    if (m_onTimeout) {
-      m_onTimeout(*m_interest);
+    if (m_timeoutCallback) {
+      m_timeoutCallback(*m_interest);
     }
 
     BOOST_ASSERT(m_deleter);
@@ -108,8 +119,9 @@
 
 private:
   shared_ptr<const Interest> m_interest;
-  const OnData m_onData;
-  const OnTimeout m_onTimeout;
+  DataCallback m_dataCallback;
+  NackCallback m_nackCallback;
+  TimeoutCallback m_timeoutCallback;
   util::scheduler::ScopedEventId m_timeoutEvent;
   std::function<void()> m_deleter;
 };
@@ -133,7 +145,7 @@
   operator()(const shared_ptr<const PendingInterest>& pendingInterest) const
   {
     return (reinterpret_cast<const PendingInterestId*>(
-              &pendingInterest->getInterest()) == m_id);
+              pendingInterest->getInterest().get()) == m_id);
   }
 private:
   const PendingInterestId* m_id;