src: Adding retry in case of prefix registration fails

Change-Id: Ia124ab393c665b29f03216903128de98bd68de9d
diff --git a/src/adjacency-list.cpp b/src/adjacency-list.cpp
index 9d026af..f2e0aaf 100644
--- a/src/adjacency-list.cpp
+++ b/src/adjacency-list.cpp
@@ -261,6 +261,20 @@
   return 0;
 }
 
+uint64_t
+AdjacencyList::getFaceId(const std::string& faceUri)
+{
+  std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
+                                                  m_adjList.end(),
+                                                  ndn::bind(&Adjacent::compareFaceUri,
+                                                            _1, faceUri));
+  if (it != m_adjList.end()) {
+    return it->getFaceId();
+  }
+
+  return 0;
+}
+
 void
 AdjacencyList::writeLog()
 {
diff --git a/src/adjacency-list.hpp b/src/adjacency-list.hpp
index 38debed..320dc40 100644
--- a/src/adjacency-list.hpp
+++ b/src/adjacency-list.hpp
@@ -104,6 +104,9 @@
   Adjacent*
   findAdjacent(uint64_t faceId);
 
+  uint64_t
+  getFaceId(const std::string& faceUri);
+
   void
   writeLog();
 
diff --git a/src/adjacent.hpp b/src/adjacent.hpp
index dd2c2e2..967265f 100644
--- a/src/adjacent.hpp
+++ b/src/adjacent.hpp
@@ -21,6 +21,7 @@
  *
  **/
 #include <string>
+#include <cmath>
 #include <boost/cstdint.hpp>
 #include <ndn-cxx/face.hpp>
 
@@ -69,10 +70,11 @@
     m_connectingFaceUri = cfu;
   }
 
-  double
+  uint64_t
   getLinkCost() const
   {
-    return m_linkCost;
+    uint64_t linkCost = static_cast<uint64_t>(ceil(m_linkCost));
+    return linkCost;
   }
 
   void
@@ -132,6 +134,12 @@
     return m_faceId == faceId;
   }
 
+  inline bool
+  compareFaceUri(std::string& faceUri)
+  {
+    return m_connectingFaceUri == faceUri;
+  }
+
   void
   writeLog();
 
diff --git a/src/hello-protocol.cpp b/src/hello-protocol.cpp
index 4fe528c..7bcf3bb 100644
--- a/src/hello-protocol.cpp
+++ b/src/hello-protocol.cpp
@@ -217,29 +217,32 @@
 HelloProtocol::registerPrefixes(const ndn::Name& adjName, const std::string& faceUri,
                                double linkCost, const ndn::time::milliseconds& timeout)
 {
-  ndn::Name broadcastKeyPrefix = DEFAULT_BROADCAST_PREFIX;
-  broadcastKeyPrefix.append("KEYS");
-  m_nlsr.getFib().registerPrefix(adjName, faceUri, linkCost, timeout,
+  m_nlsr.getFib().registerPrefix(adjName, faceUri, linkCost, timeout, 0,
                                  ndn::bind(&HelloProtocol::onRegistrationSuccess,
-                                           this, _1, adjName),
+                                           this, _1, adjName,timeout),
                                  ndn::bind(&HelloProtocol::onRegistrationFailure,
                                            this, _1, _2, adjName));
-  m_nlsr.getFib().registerPrefix(m_nlsr.getConfParameter().getChronosyncPrefix(),
-                                 faceUri, linkCost, timeout);
-  m_nlsr.getFib().registerPrefix(m_nlsr.getConfParameter().getLsaPrefix(),
-                                 faceUri, linkCost, timeout);
-  m_nlsr.getFib().registerPrefix(broadcastKeyPrefix,
-                                 faceUri, linkCost, timeout);
-  m_nlsr.setStrategies();
 }
 
 void
 HelloProtocol::onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
-                                     const ndn::Name& neighbor)
+                                     const ndn::Name& neighbor,const ndn::time::milliseconds& timeout)
 {
   Adjacent *adjacent = m_nlsr.getAdjacencyList().findAdjacent(neighbor);
   if (adjacent != 0) {
     adjacent->setFaceId(commandSuccessResult.getFaceId());
+    ndn::Name broadcastKeyPrefix = DEFAULT_BROADCAST_PREFIX;
+    broadcastKeyPrefix.append("KEYS");
+    std::string faceUri = adjacent->getConnectingFaceUri();
+    double linkCost = adjacent->getLinkCost();
+    m_nlsr.getFib().registerPrefix(m_nlsr.getConfParameter().getChronosyncPrefix(),
+                                 faceUri, linkCost, timeout, 0);
+    m_nlsr.getFib().registerPrefix(m_nlsr.getConfParameter().getLsaPrefix(),
+                                 faceUri, linkCost, timeout, 0);
+    m_nlsr.getFib().registerPrefix(broadcastKeyPrefix,
+                                 faceUri, linkCost, timeout, 0);
+    m_nlsr.setStrategies();
+
     /* interest name: /<neighbor>/NLSR/INFO/<router> */
     ndn::Name interestName(neighbor);
     interestName.append(NLSR_COMPONENT);
diff --git a/src/hello-protocol.hpp b/src/hello-protocol.hpp
index b1ccd56..fa2528c 100644
--- a/src/hello-protocol.hpp
+++ b/src/hello-protocol.hpp
@@ -73,7 +73,7 @@
 
   void
   onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
-                        const ndn::Name& neighbor);
+                        const ndn::Name& neighbor, const ndn::time::milliseconds& timeout);
 
   void
   registerPrefixes(const ndn::Name& adjName, const std::string& faceUri,
diff --git a/src/nlsr.cpp b/src/nlsr.cpp
index 51bf86a..4065482 100644
--- a/src/nlsr.cpp
+++ b/src/nlsr.cpp
@@ -148,7 +148,13 @@
   m_defaultIdentity = m_confParam.getRouterPrefix();
   m_defaultIdentity.append("NLSR");
 
-  m_keyChain.deleteIdentity(m_defaultIdentity);
+  try
+  {
+    m_keyChain.deleteIdentity(m_defaultIdentity);
+  }
+  catch (std::exception& e)
+  {
+  }
 
   ndn::Name keyName = m_keyChain.generateRsaKeyPairAsDefault(m_defaultIdentity, true);
 
diff --git a/src/route/fib.cpp b/src/route/fib.cpp
index ade99d5..b99d7a2 100644
--- a/src/route/fib.cpp
+++ b/src/route/fib.cpp
@@ -74,7 +74,6 @@
                                                   m_table.end(),
                                                   bind(&fibEntryNameCompare, _1, name));
   if (it != m_table.end()) {
-    cancelScheduledExpiringEvent((*it).getExpiringEventId());
     _LOG_DEBUG("Refreshing the FIB entry. Name: " <<  name);
     for (std::list<NextHop>::iterator nhit =
            (*it).getNexthopList().getNextHops().begin();
@@ -83,7 +82,7 @@
       if (isPrefixUpdatable(it->getName())) {
         registerPrefix(it->getName(), nhit->getConnectingFaceUri(),
                        std::ceil(nhit->getRouteCost()),
-                       ndn::time::seconds(m_refreshTime + GRACE_PERIOD));
+                       ndn::time::seconds(m_refreshTime + GRACE_PERIOD), 0);
       }
     }
     // increase sequence number and schedule refresh again
@@ -139,7 +138,7 @@
         if (isPrefixUpdatable(name)) {
           registerPrefix(name, nhit->getConnectingFaceUri(),
                          std::ceil(nhit->getRouteCost()),
-                         ndn::time::seconds(m_refreshTime + GRACE_PERIOD));
+                         ndn::time::seconds(m_refreshTime + GRACE_PERIOD), 0);
         }
       }
       newEntry.getNexthopList().sort();
@@ -163,7 +162,7 @@
         if (isPrefixUpdatable(name)) {
           registerPrefix(name, nhit->getConnectingFaceUri(),
                          std::ceil(nhit->getRouteCost()),
-                         ndn::time::seconds(m_refreshTime + GRACE_PERIOD));
+                         ndn::time::seconds(m_refreshTime + GRACE_PERIOD), 0);
         }
         removeHop(it->getNexthopList(), nhit->getConnectingFaceUri(), name);
         it->getNexthopList().reset();
@@ -176,7 +175,7 @@
           if (isPrefixUpdatable(name)) {
             registerPrefix(name, nhit->getConnectingFaceUri(),
                            std::ceil(nhit->getRouteCost()),
-                           ndn::time::seconds(m_refreshTime + GRACE_PERIOD));
+                           ndn::time::seconds(m_refreshTime + GRACE_PERIOD), 0);
           }
         }
       }
@@ -292,12 +291,19 @@
 
 void
 Fib::registerPrefix(const ndn::Name& namePrefix, const std::string& faceUri,
-                    uint64_t faceCost, const ndn::time::milliseconds& timeout)
+                    uint64_t faceCost, const ndn::time::milliseconds& timeout,
+                    uint8_t times)
 {
-  createFace(faceUri,
-             ndn::bind(&Fib::registerPrefixInNfd, this,_1, namePrefix, faceCost, timeout,
-                       faceUri),
-             ndn::bind(&Fib::onFailure, this, _1, _2,"Failed in name registration"));
+  uint64_t faceId = m_nlsr.getAdjacencyList().getFaceId(faceUri);
+  if (faceId != 0) {
+    _LOG_DEBUG("Registering prefix: " << namePrefix << " Face Uri: " << faceUri
+               << " Face Id: " << faceId);
+    registerPrefixInNfd(namePrefix, faceId,
+                        faceCost, timeout, faceUri, times);
+  }
+  else {
+    _LOG_DEBUG("Error: No Face Id for face uri: " << faceUri);
+  }
 }
 
 void
@@ -305,26 +311,30 @@
                     const std::string& faceUri,
                     uint64_t faceCost,
                     const ndn::time::milliseconds& timeout,
+                    uint8_t times,
                     const CommandSucceedCallback& onSuccess,
                     const CommandFailCallback& onFailure)
 
 {
  createFace(faceUri,
             ndn::bind(&Fib::registerPrefixInNfd, this,_1,
-                      namePrefix, faceCost, timeout, onSuccess, onFailure),
+                      namePrefix, faceCost,
+                      timeout, times, onSuccess, onFailure),
             onFailure);
 }
 
 void
-Fib::registerPrefixInNfd(const ndn::nfd::ControlParameters& faceCreateResult, 
-                         const ndn::Name& namePrefix, uint64_t faceCost,
+Fib::registerPrefixInNfd(const ndn::Name& namePrefix,
+                         uint64_t faceId,
+                         uint64_t faceCost,
                          const ndn::time::milliseconds& timeout,
-                         const std::string& faceUri)
+                         const std::string& faceUri,
+                         uint8_t times)
 {
   ndn::nfd::ControlParameters controlParameters;
   controlParameters
     .setName(namePrefix)
-    .setFaceId(faceCreateResult.getFaceId())
+    .setFaceId(faceId)
     .setCost(faceCost)
     .setExpirationPeriod(timeout)
     .setOrigin(128);
@@ -332,14 +342,18 @@
                                                    ndn::bind(&Fib::onRegistration, this, _1,
                                                              "Successful in name registration",
                                                              faceUri),
-                                                   ndn::bind(&Fib::onFailure, this, _1, _2,
-                                                             "Failed in name registration"));
+                                                   ndn::bind(&Fib::onRegistrationFailure,
+                                                             this, _1, _2,
+                                                             "Failed in name registration",
+                                                             namePrefix, faceUri, faceCost,
+                                                             timeout, times));
 }
 
 void
 Fib::registerPrefixInNfd(const ndn::nfd::ControlParameters& faceCreateResult,
                          const ndn::Name& namePrefix, uint64_t faceCost,
                          const ndn::time::milliseconds& timeout,
+                         uint8_t times,
                          const CommandSucceedCallback& onSuccess,
                          const CommandFailCallback& onFailure)
 {
@@ -369,7 +383,8 @@
     m_controller.start<ndn::nfd::RibUnregisterCommand>(controlParameters,
                                                      ndn::bind(&Fib::onUnregistration, this, _1,
                                                                "Successful in unregistering name"),
-                                                     ndn::bind(&Fib::onFailure, this, _1, _2,
+                                                     ndn::bind(&Fib::onUnregistrationFailure,
+                                                               this, _1, _2,
                                                                "Failed in unregistering name"));
   }
 }
@@ -411,8 +426,26 @@
 }
 
 void
-Fib::onFailure(uint32_t code, const std::string& error,
-               const std::string& message)
+Fib::onRegistrationFailure(uint32_t code, const std::string& error,
+                           const std::string& message,
+                           const ndn::Name& namePrefix, const std::string& faceUri,
+                           uint64_t faceCost, const ndn::time::milliseconds& timeout,
+                           uint8_t times)
+{
+  _LOG_DEBUG(message << ": " << error << " (code: " << code << ")");
+  _LOG_DEBUG("Prefix: " << namePrefix << " failed for: " << times);
+  if (times < 3) {
+    _LOG_DEBUG("Trying to register again...");
+    registerPrefix(namePrefix, faceUri, faceCost, timeout, times+1);
+  }
+  else {
+    _LOG_DEBUG("Registration trial given up");
+  }
+}
+
+void
+Fib::onUnregistrationFailure(uint32_t code, const std::string& error,
+                            const std::string& message)
 {
   _LOG_DEBUG(message << ": " << error << " (code: " << code << ")");
 }
diff --git a/src/route/fib.hpp b/src/route/fib.hpp
index c593a5b..4c54a79 100644
--- a/src/route/fib.hpp
+++ b/src/route/fib.hpp
@@ -94,13 +94,14 @@
   void
   registerPrefix(const ndn::Name& namePrefix, const std::string& faceUri,
                  uint64_t faceCost,
-                 const ndn::time::milliseconds& timeout);
+                 const ndn::time::milliseconds& timeout, uint8_t times);
 
   void
   registerPrefix(const ndn::Name& namePrefix,
                  const std::string& faceUri,
                  uint64_t faceCost,
                  const ndn::time::milliseconds& timeout,
+                 uint8_t times,
                  const CommandSucceedCallback& onSuccess,
                  const CommandFailCallback& onFailure);
   
@@ -122,15 +123,18 @@
              const CommandFailCallback& onFailure);
 
   void
-  registerPrefixInNfd(const ndn::nfd::ControlParameters& faceCreateResult,
-                      const ndn::Name& namePrefix, uint64_t faceCost,
+  registerPrefixInNfd(const ndn::Name& namePrefix,
+                      uint64_t faceId,
+                      uint64_t faceCost,
                       const ndn::time::milliseconds& timeout,
-                      const std::string& faceUri);
+                      const std::string& faceUri,
+                      uint8_t times);
 
   void
   registerPrefixInNfd(const ndn::nfd::ControlParameters& faceCreateResult,
                       const ndn::Name& namePrefix, uint64_t faceCost,
                       const ndn::time::milliseconds& timeout,
+                      uint8_t times,
                       const CommandSucceedCallback& onSuccess,
                       const CommandFailCallback& onFailure);
 
@@ -151,7 +155,15 @@
                    const std::string& message);
 
   void
-  onFailure(uint32_t code, const std::string& error, const std::string& message);
+  onRegistrationFailure(uint32_t code, const std::string& error,
+                        const std::string& message,
+                        const ndn::Name& namePrefix, const std::string& faceUri,
+                        uint64_t faceCost, const ndn::time::milliseconds& timeout,
+                        uint8_t times);
+
+  void
+  onUnregistrationFailure(uint32_t code, const std::string& error,
+                        const std::string& message);
 
   void
   onSetStrategySuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
diff --git a/src/route/nexthop.hpp b/src/route/nexthop.hpp
index ecd84fa..a354752 100644
--- a/src/route/nexthop.hpp
+++ b/src/route/nexthop.hpp
@@ -24,6 +24,7 @@
 #define NLSR_NEXTHOP_HPP
 
 #include <iostream>
+#include <cmath>
 #include <boost/cstdint.hpp>
 
 namespace nlsr {
@@ -54,10 +55,11 @@
     m_connectingFaceUri = cfu;
   }
 
-  double
+  uint64_t
   getRouteCost() const
   {
-    return m_routeCost;
+    uint64_t routeCost = static_cast<uint64_t>(ceil(m_routeCost));
+    return routeCost;
   }
 
   void