helper+model: GlobalRoutingHelper now interacts with NFD

This commit also changes uses of boost::tuple with std::tuple
diff --git a/helper/ndn-global-routing-helper.cpp b/helper/ndn-global-routing-helper.cpp
index 54b032b..43f0f20 100644
--- a/helper/ndn-global-routing-helper.cpp
+++ b/helper/ndn-global-routing-helper.cpp
@@ -26,10 +26,17 @@
 
 #include "ndn-global-routing-helper.hpp"
 
-#include "ns3/ndn-l3-protocol.hpp"
-#include "../model/ndn-net-device-face.hpp"
-#include "../model/ndn-global-router.hpp"
+#include "model/ndn-l3-protocol.hpp"
+#include "helper/ndn-fib-helper.hpp"
+#include "model/ndn-net-device-face.hpp"
+#include "model/ndn-global-router.hpp"
 
+#include "daemon/table/fib.hpp"
+#include "daemon/fw/forwarder.hpp"
+#include "daemon/table/fib-entry.hpp"
+#include "daemon/table/fib-nexthop.hpp"
+
+#include "ns3/object.h"
 #include "ns3/node.h"
 #include "ns3/node-container.h"
 #include "ns3/net-device.h"
@@ -44,8 +51,6 @@
 #include <boost/lexical_cast.hpp>
 #include <boost/foreach.hpp>
 #include <boost/concept/assert.hpp>
-// #include <boost/graph/graph_concepts.hpp>
-// #include <boost/graph/adjacency_list.hpp>
 #include <boost/graph/dijkstra_shortest_paths.hpp>
 
 #include "boost-graph-ndn-global-routing-helper.hpp"
@@ -54,9 +59,6 @@
 
 NS_LOG_COMPONENT_DEFINE("ndn.GlobalRoutingHelper");
 
-using namespace std;
-using namespace boost;
-
 namespace ns3 {
 namespace ndn {
 
@@ -77,8 +79,8 @@
   gr = CreateObject<GlobalRouter>();
   node->AggregateObject(gr);
 
-  for (uint32_t faceId = 0; faceId < ndn->GetNFaces(); faceId++) {
-    shared_ptr<NetDeviceFace> face = DynamicCast<NetDeviceFace>(ndn->GetFace(faceId));
+  for (auto& i : ndn->getForwarder()->getFaceTable()) {
+    shared_ptr<NetDeviceFace> face = std::dynamic_pointer_cast<NetDeviceFace>(i);
     if (face == 0) {
       NS_LOG_DEBUG("Skipping non-netdevice face");
       continue;
@@ -203,7 +205,7 @@
 {
   for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
     Ptr<GlobalRouter> gr = (*node)->GetObject<GlobalRouter>();
-    string name = Names::FindName(*node);
+    std::string name = Names::FindName(*node);
 
     if (gr != 0 && !name.empty()) {
       AddOrigin("/" + name, *node);
@@ -219,10 +221,10 @@
    * See http://www.boost.org/doc/libs/1_49_0/libs/graph/doc/table_of_contents.html for more details
    */
 
-  BOOST_CONCEPT_ASSERT((VertexListGraphConcept<NdnGlobalRouterGraph>));
-  BOOST_CONCEPT_ASSERT((IncidenceGraphConcept<NdnGlobalRouterGraph>));
+  BOOST_CONCEPT_ASSERT((boost::VertexListGraphConcept<boost::NdnGlobalRouterGraph>));
+  BOOST_CONCEPT_ASSERT((boost::IncidenceGraphConcept<boost::NdnGlobalRouterGraph>));
 
-  NdnGlobalRouterGraph graph;
+  boost::NdnGlobalRouterGraph graph;
   // typedef graph_traits < NdnGlobalRouterGraph >::vertex_descriptor vertex_descriptor;
 
   // For now we doing Dijkstra for every node.  Can be replaced with Bellman-Ford or Floyd-Warshall.
@@ -236,56 +238,52 @@
       continue;
     }
 
-    DistancesMap distances;
+    boost::DistancesMap distances;
 
     dijkstra_shortest_paths(graph, source,
                             // predecessor_map (boost::ref(predecessors))
                             // .
                             distance_map(boost::ref(distances))
-                              .distance_inf(WeightInf)
-                              .distance_zero(WeightZero)
+                              .distance_inf(boost::WeightInf)
+                              .distance_zero(boost::WeightZero)
                               .distance_compare(boost::WeightCompare())
                               .distance_combine(boost::WeightCombine()));
 
     // NS_LOG_DEBUG (predecessors.size () << ", " << distances.size ());
-    /*
-    Ptr<Fib>  fib  = source->GetObject<Fib> ();
-    if (invalidatedRoutes)
-      {
-        fib->InvalidateAll ();
+
+    Ptr<L3Protocol> L3protocol = (*node)->GetObject<L3Protocol>();
+    shared_ptr<nfd::Forwarder> forwarder = L3protocol->getForwarder();
+
+    if (invalidatedRoutes) {
+      std::vector<::nfd::fib::NextHop> NextHopList;
+      for (nfd::Fib::const_iterator fibIt = forwarder->getFib().begin();
+           fibIt != forwarder->getFib().end();) {
+        NextHopList.clear();
+        NextHopList = fibIt->getNextHops();
+        ++fibIt;
+        for (int i = 0; i < NextHopList.size(); i++) {
+          NextHopList[i].setCost(std::numeric_limits<uint64_t>::max());
+        }
       }
-    NS_ASSERT (fib != 0);
-*/
+    }
+
     NS_LOG_DEBUG("Reachability from Node: " << source->GetObject<Node>()->GetId());
-    for (DistancesMap::iterator i = distances.begin(); i != distances.end(); i++) {
-      if (i->first == source)
+    for (const auto& dist : distances) {
+      if (dist.first == source)
         continue;
       else {
-        // cout << "  Node " << i->first->GetObject<Node> ()->GetId ();
-        if (i->second.get<0>() == 0) {
+        // cout << "  Node " << dist.first->GetObject<Node> ()->GetId ();
+        if (std::get<0>(dist.second) == 0) {
           // cout << " is unreachable" << endl;
         }
         else {
-          BOOST_FOREACH (const std::shared_ptr<const Name>& prefix, i->first->GetLocalPrefixes()) {
-            NS_LOG_DEBUG(" prefix " << prefix << " reachable via face " << *i->second.get<0>()
-                                    << " with distance " << i->second.get<1>() << " with delay "
-                                    << i->second.get<2>());
+          for (const auto& prefix : dist.first->GetLocalPrefixes()) {
+            NS_LOG_DEBUG(" prefix " << prefix << " reachable via face " << *std::get<0>(dist.second)
+                         << " with distance " << std::get<1>(dist.second) << " with delay "
+                         << std::get<2>(dist.second));
 
-            // Ptr<fib::Entry> entry = fib->Add (prefix, i->second.get<0> (), i->second.get<1> ());
-            // entry->SetRealDelayToProducer (i->second.get<0> (), Seconds (i->second.get<2> ()));
-
-            // Ptr<Limits> faceLimits = i->second.get<0> ()->GetObject<Limits> ();
-
-            // Ptr<Limits> fibLimits = entry->GetObject<Limits> ();
-            // if (fibLimits != 0)
-            //{
-            // if it was created by the forwarding strategy via DidAddFibEntry event
-            // fibLimits->SetLimits (faceLimits->GetMaxRate (), 2 * i->second.get<2> () /*exact
-            // RTT*/);
-            // NS_LOG_DEBUG ("Set limit for prefix " << *prefix << " " << faceLimits->GetMaxRate ()
-            // << " / " << 2*i->second.get<2> () << "s (" << faceLimits->GetMaxRate () * 2 *
-            // i->second.get<2> () << ")");
-            //}
+            FibHelper::AddRoute(*node, *prefix, std::get<0>(dist.second),
+                                std::get<1>(dist.second));
           }
         }
       }
@@ -301,10 +299,10 @@
    * See http://www.boost.org/doc/libs/1_49_0/libs/graph/doc/table_of_contents.html for more details
    */
 
-  BOOST_CONCEPT_ASSERT((VertexListGraphConcept<NdnGlobalRouterGraph>));
-  BOOST_CONCEPT_ASSERT((IncidenceGraphConcept<NdnGlobalRouterGraph>));
+  BOOST_CONCEPT_ASSERT((boost::VertexListGraphConcept<boost::NdnGlobalRouterGraph>));
+  BOOST_CONCEPT_ASSERT((boost::IncidenceGraphConcept<boost::NdnGlobalRouterGraph>));
 
-  NdnGlobalRouterGraph graph;
+  boost::NdnGlobalRouterGraph graph;
   // typedef graph_traits < NdnGlobalRouterGraph >::vertex_descriptor vertex_descriptor;
 
   // For now we doing Dijkstra for every node.  Can be replaced with Bellman-Ford or Floyd-Warshall.
@@ -318,13 +316,22 @@
       continue;
     }
 
-    // Ptr<Fib>  fib  = source->GetObject<Fib> ();
-    if (invalidatedRoutes) {
-      // fib->InvalidateAll ();
-    }
-    // NS_ASSERT (fib != 0);
+    Ptr<L3Protocol> L3protocol = (*node)->GetObject<L3Protocol>();
+    shared_ptr<nfd::Forwarder> forwarder = L3protocol->getForwarder();
 
-    NS_LOG_DEBUG("===========");
+    if (invalidatedRoutes) {
+      std::vector<::nfd::fib::NextHop> NextHopList;
+      for (nfd::Fib::const_iterator fibIt = forwarder->getFib().begin();
+           fibIt != forwarder->getFib().end();) {
+        NextHopList.clear();
+        NextHopList = fibIt->getNextHops();
+        ++fibIt;
+        for (int i = 0; i < NextHopList.size(); i++) {
+          NextHopList[i].setCost(std::numeric_limits<uint64_t>::max());
+        }
+      }
+    }
+
     NS_LOG_DEBUG("Reachability from Node: " << source->GetObject<Node>()->GetId() << " ("
                                             << Names::FindName(source->GetObject<Node>()) << ")");
 
@@ -332,22 +339,29 @@
     NS_ASSERT(l3 != 0);
 
     // remember interface statuses
-    std::vector<uint16_t> originalMetric(l3->GetNFaces());
-    for (uint32_t faceId = 0; faceId < l3->GetNFaces(); faceId++) {
-      originalMetric[faceId] = l3->GetFace(faceId)->GetMetric();
-      l3->GetFace(faceId)
-        ->SetMetric(std::numeric_limits<uint16_t>::max()
-                    - 1); // value std::numeric_limits<uint16_t>::max () MUST NOT be used (reserved)
+    int faceNumber = 0;
+    std::vector<uint16_t> originalMetric(uint32_t(l3->getForwarder()->getFaceTable().size()));
+    for (auto& i : l3->getForwarder()->getFaceTable()) {
+      faceNumber++;
+      shared_ptr<Face> nfdFace = std::dynamic_pointer_cast<Face>(i);
+      originalMetric[uint32_t(faceNumber)] = nfdFace->getMetric();
+      nfdFace->setMetric(std::numeric_limits<uint16_t>::max() - 1);
+      // value std::numeric_limits<uint16_t>::max () MUST NOT be used (reserved)
     }
 
-    for (uint32_t enabledFaceId = 0; enabledFaceId < l3->GetNFaces(); enabledFaceId++) {
-      if (DynamicCast<ndn::NetDeviceFace>(l3->GetFace(enabledFaceId)) == 0)
+    faceNumber = 0;
+    for (auto& k : l3->getForwarder()->getFaceTable()) {
+      faceNumber++;
+      shared_ptr<NetDeviceFace> face = std::dynamic_pointer_cast<NetDeviceFace>(k);
+      if (face == 0) {
+        NS_LOG_DEBUG("Skipping non-netdevice face");
         continue;
+      }
 
       // enabling only faceId
-      l3->GetFace(enabledFaceId)->SetMetric(originalMetric[enabledFaceId]);
+      face->setMetric(originalMetric[uint32_t(faceNumber)]);
 
-      DistancesMap distances;
+      boost::DistancesMap distances;
 
       NS_LOG_DEBUG("-----------");
 
@@ -355,59 +369,48 @@
                               // predecessor_map (boost::ref(predecessors))
                               // .
                               distance_map(boost::ref(distances))
-                                .distance_inf(WeightInf)
-                                .distance_zero(WeightZero)
+                                .distance_inf(boost::WeightInf)
+                                .distance_zero(boost::WeightZero)
                                 .distance_compare(boost::WeightCompare())
                                 .distance_combine(boost::WeightCombine()));
 
       // NS_LOG_DEBUG (predecessors.size () << ", " << distances.size ());
 
-      for (DistancesMap::iterator i = distances.begin(); i != distances.end(); i++) {
-        if (i->first == source)
+      for (const auto& dist : distances) {
+        if (dist.first == source)
           continue;
         else {
-          // cout << "  Node " << i->first->GetObject<Node> ()->GetId ();
-          if (i->second.get<0>() == 0) {
+          // cout << "  Node " << dist.first->GetObject<Node> ()->GetId ();
+          if (std::get<0>(dist.second) == 0) {
             // cout << " is unreachable" << endl;
           }
           else {
-            BOOST_FOREACH (const std::shared_ptr<const Name>& prefix,
-                           i->first->GetLocalPrefixes()) {
-              NS_LOG_DEBUG(" prefix " << *prefix << " reachable via face " << *i->second.get<0>()
-                                      << " with distance " << i->second.get<1>() << " with delay "
-                                      << i->second.get<2>());
+            for (const auto& prefix : dist.first->GetLocalPrefixes()) {
+              NS_LOG_DEBUG(" prefix " << *prefix << " reachable via face "
+                           << *std::get<0>(dist.second)
+                           << " with distance " << std::get<1>(dist.second)
+                           << " with delay " << std::get<2>(dist.second));
 
-              if (i->second.get<0>()->GetMetric() == std::numeric_limits<uint16_t>::max() - 1)
+              if (std::get<0>(dist.second)->getMetric() == std::numeric_limits<uint16_t>::max() - 1)
                 continue;
 
-              // Ptr<fib::Entry> entry = fib->Add (prefix, i->second.get<0> (), i->second.get<1>
-              // ());
-              // entry->SetRealDelayToProducer (i->second.get<0> (), Seconds (i->second.get<2> ()));
-
-              // Ptr<Limits> faceLimits = i->second.get<0> ()->GetObject<Limits> ();
-
-              // Ptr<Limits> fibLimits = entry->GetObject<Limits> ();
-              // if (fibLimits != 0)
-              //{
-              // if it was created by the forwarding strategy via DidAddFibEntry event
-              // fibLimits->SetLimits (faceLimits->GetMaxRate (), 2 * i->second.get<2> () /*exact
-              // RTT*/);
-              // NS_LOG_DEBUG ("Set limit for prefix " << *prefix << " " << faceLimits->GetMaxRate
-              // () << " / " << 2*i->second.get<2> () << "s (" << faceLimits->GetMaxRate () * 2 *
-              // i->second.get<2> () << ")");
-              //}
+              FibHelper::AddRoute(*node, *prefix, std::get<0>(dist.second),
+                                  std::get<1>(dist.second));
             }
           }
         }
       }
 
       // disabling the face again
-      l3->GetFace(enabledFaceId)->SetMetric(std::numeric_limits<uint16_t>::max() - 1);
+      face->setMetric(std::numeric_limits<uint16_t>::max() - 1);
     }
 
     // recover original interface statuses
-    for (uint32_t faceId = 0; faceId < l3->GetNFaces(); faceId++) {
-      l3->GetFace(faceId)->SetMetric(originalMetric[faceId]);
+    faceNumber = 0;
+    for (auto& i : l3->getForwarder()->getFaceTable()) {
+      faceNumber++;
+      shared_ptr<Face> face = std::dynamic_pointer_cast<Face>(i);
+      face->setMetric(originalMetric[faceNumber]);
     }
   }
 }