helper: Extending manual route creating in ndn::StackHelper

Now it is possible to specify to nodes (or node names, registered using
Names::Add) and StackHelper will find which face should be used for
that.

Note that this works only for P2P links.
diff --git a/examples/ndn-congestion-alt-topo-plugin.cc b/examples/ndn-congestion-alt-topo-plugin.cc
index bb98008..5d593f6 100644
--- a/examples/ndn-congestion-alt-topo-plugin.cc
+++ b/examples/ndn-congestion-alt-topo-plugin.cc
@@ -115,20 +115,20 @@
     }
 
   // Manually configure FIB routes
-  ndn::StackHelper::AddRoute	("c1", "/data", 0, 1); // link to n1
-  ndn::StackHelper::AddRoute	("c2", "/data", 0, 1); // link to n1
-  ndn::StackHelper::AddRoute	("c3", "/data", 0, 1); // link to n1
-  ndn::StackHelper::AddRoute	("c4", "/data", 0, 1); // link to n1
+  ndn::StackHelper::AddRoute	("c1", "/data", "n1", 1); // link to n1
+  ndn::StackHelper::AddRoute	("c2", "/data", "n1", 1); // link to n1
+  ndn::StackHelper::AddRoute	("c3", "/data", "n1", 1); // link to n1
+  ndn::StackHelper::AddRoute	("c4", "/data", "n1", 1); // link to n1
 
-  ndn::StackHelper::AddRoute	("n1", "/data", 4, 1); // link to n2
-  ndn::StackHelper::AddRoute	("n1", "/data", 5, 2); // link to n12
+  ndn::StackHelper::AddRoute	("n1", "/data", "n2", 1); // link to n2
+  ndn::StackHelper::AddRoute	("n1", "/data", "n12", 2); // link to n12
 
-  ndn::StackHelper::AddRoute	("n12", "/data", 1, 2); // link to n2
+  ndn::StackHelper::AddRoute	("n12", "/data", "n2", 1); // link to n2
 
-  ndn::StackHelper::AddRoute	("n2", "/data/p1", 2, 2); // link to p1
-  ndn::StackHelper::AddRoute	("n2", "/data/p2", 3, 2); // link to p2
-  ndn::StackHelper::AddRoute	("n2", "/data/p3", 4, 2); // link to p3
-  ndn::StackHelper::AddRoute	("n2", "/data/p4", 5, 2); // link to p4
+  ndn::StackHelper::AddRoute	("n2", "/data/p1", "p1", 1); // link to p1
+  ndn::StackHelper::AddRoute	("n2", "/data/p2", "p2", 1); // link to p2
+  ndn::StackHelper::AddRoute	("n2", "/data/p3", "p3", 1); // link to p3
+  ndn::StackHelper::AddRoute	("n2", "/data/p4", "p4", 1); // link to p4
 
   // Schedule simulation time and run the simulation
   Simulator::Stop (Seconds (20.0));
diff --git a/helper/ndn-stack-helper.cc b/helper/ndn-stack-helper.cc
index 983c8cf..5f7f7a6 100644
--- a/helper/ndn-stack-helper.cc
+++ b/helper/ndn-stack-helper.cc
@@ -95,10 +95,10 @@
 
 void 
 StackHelper::SetForwardingStrategy (const std::string &strategy,
-                                        const std::string &attr1, const std::string &value1,
-                                        const std::string &attr2, const std::string &value2,
-                                        const std::string &attr3, const std::string &value3,
-                                        const std::string &attr4, const std::string &value4)
+                                    const std::string &attr1, const std::string &value1,
+                                    const std::string &attr2, const std::string &value2,
+                                    const std::string &attr3, const std::string &value3,
+                                    const std::string &attr4, const std::string &value4)
 {
   m_strategyFactory.SetTypeId (strategy);
   if (attr1 != "")
@@ -113,10 +113,10 @@
 
 void
 StackHelper::SetContentStore (const std::string &contentStore,
-                                  const std::string &attr1, const std::string &value1,
-                                  const std::string &attr2, const std::string &value2,
-                                  const std::string &attr3, const std::string &value3,
-                                  const std::string &attr4, const std::string &value4)
+                              const std::string &attr1, const std::string &value1,
+                              const std::string &attr2, const std::string &value2,
+                              const std::string &attr3, const std::string &value3,
+                              const std::string &attr4, const std::string &value4)
 {
   m_contentStoreFactory.SetTypeId (contentStore);
   if (attr1 != "")
@@ -131,10 +131,10 @@
 
 void
 StackHelper::SetPit (const std::string &pitClass,
-                         const std::string &attr1, const std::string &value1,
-                         const std::string &attr2, const std::string &value2,
-                         const std::string &attr3, const std::string &value3,
-                         const std::string &attr4, const std::string &value4)
+                     const std::string &attr1, const std::string &value1,
+                     const std::string &attr2, const std::string &value2,
+                     const std::string &attr3, const std::string &value3,
+                     const std::string &attr4, const std::string &value4)
 {
   m_pitFactory.SetTypeId (pitClass);
   if (attr1 != "")
@@ -149,10 +149,10 @@
 
 void
 StackHelper::SetFib (const std::string &fibClass,
-                         const std::string &attr1, const std::string &value1,
-                         const std::string &attr2, const std::string &value2,
-                         const std::string &attr3, const std::string &value3,
-                         const std::string &attr4, const std::string &value4)
+                     const std::string &attr1, const std::string &value1,
+                     const std::string &attr2, const std::string &value2,
+                     const std::string &attr3, const std::string &value3,
+                     const std::string &attr4, const std::string &value4)
 {
   m_fibFactory.SetTypeId (fibClass);
   if (attr1 != "")
@@ -174,9 +174,9 @@
 
 void
 StackHelper::EnableLimits (bool enable/* = true*/,
-                               Time avgRtt/*=Seconds(0.1)*/,
-                               uint32_t avgContentObject/*=1100*/,
-                               uint32_t avgInterest/*=40*/)
+                           Time avgRtt/*=Seconds(0.1)*/,
+                           uint32_t avgContentObject/*=1100*/,
+                           uint32_t avgInterest/*=40*/)
 {
   NS_LOG_INFO ("EnableLimits: " << enable);
   m_limitsEnabled = enable;
@@ -186,7 +186,7 @@
 }
 
 Ptr<FaceContainer>
-StackHelper::Install (NodeContainer c) const
+StackHelper::Install (const NodeContainer &c) const
 {
   Ptr<FaceContainer> faces = Create<FaceContainer> ();
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
@@ -197,7 +197,7 @@
 }
 
 Ptr<FaceContainer>
-StackHelper::InstallAll (void) const
+StackHelper::InstallAll () const
 {
   return Install (NodeContainer::GetGlobal ());
 }
@@ -250,7 +250,7 @@
       if (m_needSetDefaultRoutes)
         {
           // default route with lowest priority possible
-          AddRoute (node, "/", face, std::numeric_limits<int32_t>::max ()); 
+          AddRoute (node, "/", StaticCast<Face> (face), std::numeric_limits<int32_t>::max ()); 
         }
       
       if (m_limitsEnabled)
@@ -294,7 +294,7 @@
 }
 
 Ptr<FaceContainer>
-StackHelper::Install (std::string nodeName) const
+StackHelper::Install (const std::string &nodeName) const
 {
   Ptr<Node> node = Names::Find<Node> (nodeName);
   return Install (node);
@@ -302,7 +302,7 @@
 
 
 void
-StackHelper::AddRoute (Ptr<Node> node, std::string prefix, Ptr<Face> face, int32_t metric)
+StackHelper::AddRoute (Ptr<Node> node, const std::string &prefix, Ptr<Face> face, int32_t metric)
 {
   NS_LOG_LOGIC ("[" << node->GetId () << "]$ route add " << prefix << " via " << *face << " metric " << metric);
 
@@ -314,7 +314,7 @@
 }
 
 void
-StackHelper::AddRoute (Ptr<Node> node, std::string prefix, uint32_t faceId, int32_t metric)
+StackHelper::AddRoute (Ptr<Node> node, const std::string &prefix, uint32_t faceId, int32_t metric)
 {
   Ptr<L3Protocol>     ndn = node->GetObject<L3Protocol> ();
   NS_ASSERT_MSG (ndn != 0, "Ndn stack should be installed on the node");
@@ -326,7 +326,7 @@
 }
 
 void
-StackHelper::AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric)
+StackHelper::AddRoute (const std::string &nodeName, const std::string &prefix, uint32_t faceId, int32_t metric)
 {
   Ptr<Node> node = Names::Find<Node> (nodeName);
   NS_ASSERT_MSG (node != 0, "Node [" << nodeName << "] does not exist");
@@ -340,5 +340,49 @@
   AddRoute (node, prefix, face, metric);
 }
 
+void
+StackHelper::AddRoute (Ptr<Node> node, const std::string &prefix, Ptr<Node> otherNode, int32_t metric)
+{
+  for (uint32_t deviceId = 0; deviceId < node->GetNDevices (); deviceId ++)
+    {
+      Ptr<PointToPointNetDevice> netDevice = DynamicCast<PointToPointNetDevice> (node->GetDevice (deviceId));
+      if (netDevice == 0)
+        continue;
+
+      Ptr<Channel> channel = netDevice->GetChannel ();
+      if (channel == 0)
+        continue;
+
+      if (channel->GetDevice (0)->GetNode () == otherNode ||
+          channel->GetDevice (1)->GetNode () == otherNode)
+        {
+          Ptr<L3Protocol> ndn = node->GetObject<L3Protocol> ();
+          NS_ASSERT_MSG (ndn != 0, "Ndn stack should be installed on the node");
+
+          Ptr<Face> face = ndn->GetFaceByNetDevice (netDevice);
+          NS_ASSERT_MSG (face != 0, "There is no face associated with the p2p link");
+
+          AddRoute (node, prefix, face, metric);
+
+          return;
+        }
+    }
+
+  NS_FATAL_ERROR ("Cannot add route: Node# " << node->GetId () << " and Node# " << otherNode->GetId () << " are not connected");
+}
+
+void
+StackHelper::AddRoute (const std::string &nodeName, const std::string &prefix, const std::string &otherNodeName, int32_t metric)
+{
+  Ptr<Node> node = Names::Find<Node> (nodeName);
+  NS_ASSERT_MSG (node != 0, "Node [" << nodeName << "] does not exist");
+
+  Ptr<Node> otherNode = Names::Find<Node> (otherNodeName);
+  NS_ASSERT_MSG (otherNode != 0, "Node [" << otherNodeName << "] does not exist");
+
+  AddRoute (node, prefix, otherNode, metric);
+}
+
+
 } // namespace ndn
 } // namespace ns3
diff --git a/helper/ndn-stack-helper.h b/helper/ndn-stack-helper.h
index 3b7e3cf..0c036d4 100644
--- a/helper/ndn-stack-helper.h
+++ b/helper/ndn-stack-helper.h
@@ -151,7 +151,7 @@
    * to NdnFaceContainer object
    */
   Ptr<FaceContainer>
-  Install (std::string nodeName) const;
+  Install (const std::string &nodeName) const;
 
   /**
    * \brief Install Ndn stack on the node
@@ -180,7 +180,7 @@
    * to FaceContainer object
    */
   Ptr<FaceContainer>
-  Install (NodeContainer c) const;
+  Install (const NodeContainer &c) const;
 
   /**
    * \brief Install Ndn stack on all nodes in the simulation
@@ -192,7 +192,7 @@
   InstallAll () const;
 
   /**
-   * \brief Add forwarding entry in FIB
+   * \brief Add forwarding entry to FIB
    *
    * \param nodeName Node name
    * \param prefix Routing prefix
@@ -200,10 +200,10 @@
    * \param metric Routing metric
    */
   static void
-  AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric);
+  AddRoute (const std::string &nodeName, const std::string &prefix, uint32_t faceId, int32_t metric);
 
   /**
-   * \brief Add forwarding entry in FIB
+   * \brief Add forwarding entry to FIB
    *
    * \param nodeName Node
    * \param prefix Routing prefix
@@ -211,10 +211,10 @@
    * \param metric Routing metric
    */
   static void
-  AddRoute (Ptr<Node> node, std::string prefix, uint32_t faceId, int32_t metric);
+  AddRoute (Ptr<Node> node, const std::string &prefix, uint32_t faceId, int32_t metric);
 
   /**
-   * \brief Add forwarding entry in FIB
+   * \brief Add forwarding entry to FIB
    *
    * \param node   Node
    * \param prefix Routing prefix
@@ -222,9 +222,31 @@
    * \param metric Routing metric
    */
   static void
-  AddRoute (Ptr<Node> node, std::string prefix, Ptr<Face> face, int32_t metric);
+  AddRoute (Ptr<Node> node, const std::string &prefix, Ptr<Face> face, int32_t metric);
 
   /**
+   * @brief Add forwarding entry to FIB (work only with point-to-point links)
+   *
+   * \param node Node
+   * \param prefix Routing prefix
+   * \param otherNode The other node, to which interests (will be used to infer face id
+   * \param metric Routing metric
+   */
+  static void
+  AddRoute (Ptr<Node> node, const std::string &prefix, Ptr<Node> otherNode, int32_t metric);
+
+  /**
+   * @brief Add forwarding entry to FIB (work only with point-to-point links)
+   *
+   * \param nodeName Node name (refer to ns3::Names)
+   * \param prefix Routing prefix
+   * \param otherNode The other node name, to which interests (will be used to infer face id (refer to ns3::Names)
+   * \param metric Routing metric
+   */
+  static void
+  AddRoute (const std::string &nodeName, const std::string &prefix, const std::string &otherNodeName, int32_t metric);
+  
+  /**
    * \brief Set flag indicating necessity to install default routes in FIB
    */
   void
@@ -241,11 +263,11 @@
   ObjectFactory m_pitFactory;
   ObjectFactory m_fibFactory;
   
-  bool m_limitsEnabled;
+  bool     m_limitsEnabled;
   Time     m_avgRtt;
   uint32_t m_avgContentObjectSize;
   uint32_t m_avgInterestSize;
-  bool m_needSetDefaultRoutes;  
+  bool     m_needSetDefaultRoutes;  
 };
 
 } // namespace ndn