helper+model: GlobalRoutingHelper now interacts with NFD

This commit also changes uses of boost::tuple with std::tuple
diff --git a/helper/boost-graph-ndn-global-routing-helper.hpp b/helper/boost-graph-ndn-global-routing-helper.hpp
index 87d02f5..da96213 100644
--- a/helper/boost-graph-ndn-global-routing-helper.hpp
+++ b/helper/boost-graph-ndn-global-routing-helper.hpp
@@ -29,11 +29,12 @@
 #include <boost/graph/properties.hpp>
 #include <boost/ref.hpp>
 
-#include "ns3/ndn-face.hpp"
-#include "ns3/ndn-limits.hpp"
+#include "ns3/ndnSIM/model/ndn-face.hpp"
+#include "ns3/ndnSIM/model/ndn-global-router.hpp"
+
 #include "ns3/node-list.h"
 #include "ns3/channel-list.h"
-#include "../model/ndn-global-router.hpp"
+
 #include <list>
 #include <map>
 
@@ -103,13 +104,13 @@
 inline graph_traits<NdnGlobalRouterGraph>::vertex_descriptor
 source(graph_traits<NdnGlobalRouterGraph>::edge_descriptor e, const NdnGlobalRouterGraph& g)
 {
-  return e.get<0>();
+  return std::get<0>(e);
 }
 
 inline graph_traits<NdnGlobalRouterGraph>::vertex_descriptor
 target(graph_traits<NdnGlobalRouterGraph>::edge_descriptor e, const NdnGlobalRouterGraph& g)
 {
-  return e.get<2>();
+  return std::get<2>(e);
 }
 
 inline std::pair<graph_traits<NdnGlobalRouterGraph>::vertex_iterator,
@@ -176,8 +177,8 @@
 template<>
 struct property_traits<EdgeWeights> {
   // Metric property map
-  typedef tuple<ns3::Ptr<ns3::ndn::Face>, uint16_t, double> value_type;
-  typedef tuple<ns3::Ptr<ns3::ndn::Face>, uint16_t, double> reference;
+  typedef std::tuple<std::shared_ptr<nfd::Face>, uint16_t, double> value_type;
+  typedef std::tuple<std::shared_ptr<nfd::Face>, uint16_t, double> reference;
   typedef ns3::ndn::GlobalRouter::Incidency key_type;
   typedef readable_property_map_tag category;
 };
@@ -189,16 +190,16 @@
 struct WeightCompare : public std::binary_function<property_traits<EdgeWeights>::reference,
                                                    property_traits<EdgeWeights>::reference, bool> {
   bool
-  operator()(tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> a,
-             tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> b) const
+  operator()(std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double> a,
+             std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double> b) const
   {
-    return a.get<1>() < b.get<1>();
+    return std::get<1>(a) < std::get<1>(b);
   }
 
   bool
   operator()(property_traits<EdgeWeights>::reference a, uint32_t b) const
   {
-    return a.get<1>() < b;
+    return std::get<1>(a) < b;
   }
 
   bool
@@ -213,17 +214,19 @@
   uint32_t
   operator()(uint32_t a, property_traits<EdgeWeights>::reference b) const
   {
-    return a + b.get<1>();
+    return a + std::get<1>(b);
   }
 
-  tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double>
-  operator()(tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> a,
+  std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double>
+  operator()(std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double> a,
              property_traits<EdgeWeights>::reference b) const
   {
-    if (a.get<0>() == 0)
-      return make_tuple(b.get<0>(), a.get<1>() + b.get<1>(), a.get<2>() + b.get<2>());
+    if (std::get<0>(a) == 0)
+      return std::make_tuple(std::get<0>(b), std::get<1>(a) + std::get<1>(b),
+                             std::get<2>(a) + std::get<2>(b));
     else
-      return make_tuple(a.get<0>(), a.get<1>() + b.get<1>(), a.get<2>() + b.get<2>());
+      return std::make_tuple(std::get<0>(a), std::get<1>(a) + std::get<1>(b),
+                             std::get<2>(a) + std::get<2>(b));
   }
 };
 
@@ -267,17 +270,13 @@
 inline property_traits<EdgeWeights>::reference
 get(const boost::EdgeWeights&, ns3::ndn::GlobalRouter::Incidency& edge)
 {
-  if (edge.get<1>() == 0)
+  if (std::get<1>(edge) == 0)
     return property_traits<EdgeWeights>::reference(0, 0, 0.0);
   else {
-    ns3::Ptr<ns3::ndn::Limits> limits = edge.get<1>()->GetObject<ns3::ndn::Limits>();
-    double delay = 0.0;
-    if (limits != 0) // valid limits object
-    {
-      delay = limits->GetLinkDelay();
-    }
-    return property_traits<EdgeWeights>::reference(edge.get<1>(), edge.get<1>()->GetMetric(),
-                                                   delay);
+    return property_traits<EdgeWeights>::reference(std::get<1>(edge),
+                                                   static_cast<uint16_t>(
+                                                     std::get<1>(edge)->getMetric()),
+                                                   0.0);
   }
 }
 
@@ -295,26 +294,25 @@
 };
 
 struct DistancesMap : public std::map<ns3::Ptr<ns3::ndn::GlobalRouter>,
-                                      tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double>> {
+                                      std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double>> {
 };
 
 template<>
 struct property_traits<reference_wrapper<DistancesMap>> {
   // Metric property map
-  typedef tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> value_type;
-  typedef tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> reference;
+  typedef std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double> value_type;
+  typedef std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double> reference;
   typedef ns3::Ptr<ns3::ndn::GlobalRouter> key_type;
   typedef read_write_property_map_tag category;
 };
 
-inline tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double>
+inline std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double>
 get(DistancesMap& map, ns3::Ptr<ns3::ndn::GlobalRouter> key)
 {
   boost::DistancesMap::iterator i = map.find(key);
   if (i == map.end())
-    return tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double>(0,
-                                                             std::numeric_limits<uint32_t>::max(),
-                                                             0.0);
+    return std::tuple<std::shared_ptr<nfd::Face>, uint32_t,
+                      double>(0, std::numeric_limits<uint32_t>::max(), 0.0);
   else
     return i->second;
 }
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]);
     }
   }
 }
diff --git a/model/ndn-global-router.cpp b/model/ndn-global-router.cpp
index b718689..634678f 100644
--- a/model/ndn-global-router.cpp
+++ b/model/ndn-global-router.cpp
@@ -20,8 +20,8 @@
 
 #include "ndn-global-router.hpp"
 
-#include "ndn-l3-protocol.hpp"
-#include "ndn-face.hpp"
+#include "model/ndn-l3-protocol.hpp"
+#include "model/ndn-face.hpp"
 
 #include "ns3/channel.h"
 
@@ -75,7 +75,7 @@
 void
 GlobalRouter::AddIncidency(shared_ptr<Face> face, Ptr<GlobalRouter> gr)
 {
-  m_incidencies.push_back(boost::make_tuple(this, face, gr));
+  m_incidencies.push_back(std::make_tuple(this, face, gr));
 }
 
 GlobalRouter::IncidencyList&
diff --git a/model/ndn-global-router.hpp b/model/ndn-global-router.hpp
index 0465cb8..ba7990d 100644
--- a/model/ndn-global-router.hpp
+++ b/model/ndn-global-router.hpp
@@ -28,7 +28,7 @@
 #include "ns3/ptr.h"
 
 #include <list>
-#include <boost/tuple/tuple.hpp>
+#include <tuple>
 
 namespace ns3 {
 
@@ -47,7 +47,7 @@
   /**
    * @brief Graph edge
    */
-  typedef boost::tuple<Ptr<GlobalRouter>, shared_ptr<Face>, Ptr<GlobalRouter>> Incidency;
+  typedef std::tuple<Ptr<GlobalRouter>, shared_ptr<Face>, Ptr<GlobalRouter>> Incidency;
   /**
    * @brief List of graph edges
    */
@@ -113,7 +113,7 @@
 protected:
   virtual void
   NotifyNewAggregate(); ///< @brief Notify when the object is aggregated to another object (e.g.,
-  /// Node)
+                        /// Node)
 
 private:
   uint32_t m_id;
@@ -128,7 +128,8 @@
 inline bool
 operator==(const GlobalRouter::Incidency& a, const GlobalRouter::Incidency& b)
 {
-  return a.get<0>() == b.get<0>() && a.get<1>() == b.get<1>() && a.get<2>() == b.get<2>();
+  return std::get<0>(a) == std::get<0>(b) && std::get<1>(a) == std::get<1>(b)
+         && std::get<2>(a) == std::get<2>(b);
 }
 
 inline bool
diff --git a/wscript b/wscript
index e7012d6..97bfc0b 100644
--- a/wscript
+++ b/wscript
@@ -91,7 +91,8 @@
     module.source += bld.path.ant_glob(['helper/ndn-face-container.cpp',
                                         'helper/ndn-stack-helper.cpp',
                                         'helper/ndn-fib-helper.cpp',
-                                        'helper/ndn-strategy-choice-helper.cpp'])
+                                        'helper/ndn-strategy-choice-helper.cpp',
+                                        'helper/ndn-global-routing-helper.cpp'])
 
     module.full_headers = [p.path_from(bld.path) for p in bld.path.ant_glob(
         ['%s/**/*.hpp' % dir for dir in module_dirs])]