fw: forward Interest/Data to ad hoc incoming face

Change-Id: Ia2eacf2a54d65ea4bffb607a709e1d1263547fd7
Refs: #3968
diff --git a/tests/daemon/fw/topology-tester.cpp b/tests/daemon/fw/topology-tester.cpp
index ad68447..fef3080 100644
--- a/tests/daemon/fw/topology-tester.cpp
+++ b/tests/daemon/fw/topology-tester.cpp
@@ -36,36 +36,43 @@
 using face::InternalClientTransport;
 using face::GenericLinkService;
 
-TopologyLink::TopologyLink(const time::nanoseconds& delay)
+TopologyLink::TopologyLink(time::nanoseconds delay)
   : m_isUp(true)
 {
   this->setDelay(delay);
 }
 
 void
-TopologyLink::setDelay(const time::nanoseconds& delay)
+TopologyLink::block(TopologyNode i, TopologyNode j)
 {
-  BOOST_ASSERT(delay > time::nanoseconds::zero());
-  // zero delay does not work on OSX
+  m_transports.at(i).blockedDestinations.insert(j);
+}
 
+void
+TopologyLink::unblock(TopologyNode i, TopologyNode j)
+{
+  m_transports.at(i).blockedDestinations.erase(j);
+}
+
+void
+TopologyLink::setDelay(time::nanoseconds delay)
+{
+  BOOST_ASSERT(delay > time::nanoseconds::zero()); // zero delay does not work on macOS
   m_delay = delay;
 }
 
 void
 TopologyLink::addFace(TopologyNode i, shared_ptr<Face> face)
 {
-  this->attachTransport(i, dynamic_cast<InternalTransportBase*>(face->getTransport()));
-  m_faces[i] = face;
-}
-
-void
-TopologyLink::attachTransport(TopologyNode i, InternalTransportBase* transport)
-{
-  BOOST_ASSERT(transport != nullptr);
   BOOST_ASSERT(m_transports.count(i) == 0);
+  auto& nodeTransport = m_transports[i];
 
-  m_transports[i] = transport;
-  transport->afterSend.connect([this, i] (const Block& packet) { this->transmit(i, packet); });
+  nodeTransport.face = face;
+
+  nodeTransport.transport = dynamic_cast<InternalTransportBase*>(face->getTransport());
+  BOOST_ASSERT(nodeTransport.transport != nullptr);
+  nodeTransport.transport->afterSend.connect(
+    [this, i] (const Block& packet) { this->transmit(i, packet); });
 }
 
 void
@@ -75,12 +82,14 @@
     return;
   }
 
+  const auto& blockedDestinations = m_transports.at(i).blockedDestinations;
+
   for (const auto& p : m_transports) {
-    if (p.first == i) {
+    if (p.first == i || blockedDestinations.count(p.first) > 0) {
       continue;
     }
 
-    InternalTransportBase* recipient = p.second;
+    InternalTransportBase* recipient = p.second.transport;
     this->scheduleReceive(recipient, packet);
   }
 }
@@ -156,15 +165,17 @@
 }
 
 shared_ptr<TopologyLink>
-TopologyTester::addLink(const std::string& label, const time::nanoseconds& delay,
+TopologyTester::addLink(const std::string& label, time::nanoseconds delay,
                         std::initializer_list<TopologyNode> forwarders,
-                        bool forceMultiAccessFace)
+                        ndn::nfd::LinkType linkType)
 {
   auto link = std::make_shared<TopologyLink>(delay);
   FaceUri remoteUri("topology://link/" + label);
-  ndn::nfd::LinkType linkType = (forceMultiAccessFace || forwarders.size() > 2) ?
-                                ndn::nfd::LINK_TYPE_MULTI_ACCESS :
-                                ndn::nfd::LINK_TYPE_POINT_TO_POINT;
+  if (linkType == ndn::nfd::LINK_TYPE_NONE) {
+    linkType = forwarders.size() > 2 ? ndn::nfd::LINK_TYPE_MULTI_ACCESS :
+                                       ndn::nfd::LINK_TYPE_POINT_TO_POINT;
+  }
+  BOOST_ASSERT(forwarders.size() <= 2 || linkType != ndn::nfd::LINK_TYPE_POINT_TO_POINT);
 
   for (TopologyNode i : forwarders) {
     Forwarder& forwarder = this->getForwarder(i);
@@ -244,16 +255,23 @@
 
 void
 TopologyTester::addIntervalConsumer(ndn::Face& face, const Name& prefix,
-                                    const time::nanoseconds& interval, size_t n)
+                                    time::nanoseconds interval, size_t n, int seq)
 {
   Name name(prefix);
-  name.appendTimestamp();
+  if (seq >= 0) {
+    name.appendSequenceNumber(seq);
+    ++seq;
+  }
+  else {
+    name.appendTimestamp();
+  }
+
   shared_ptr<Interest> interest = makeInterest(name);
   face.expressInterest(*interest, nullptr, nullptr, nullptr);
 
   if (n > 1) {
     scheduler::schedule(interval, bind(&TopologyTester::addIntervalConsumer, this,
-                                       ref(face), prefix, interval, n - 1));
+                                       ref(face), prefix, interval, n - 1, seq));
   }
 }