Add Congestion Mark scenario

refs #4327

Change-Id: Iabbbe241585378e77d792c74d005a22b0d1440c5
diff --git a/install_helpers/tools/Makefile b/install_helpers/tools/Makefile
index 6a41305..dd395bd 100644
--- a/install_helpers/tools/Makefile
+++ b/install_helpers/tools/Makefile
@@ -3,7 +3,8 @@
 LIBS = `pkg-config --libs libndn-cxx`
 DESTDIR ?= /usr/local
 
-PROGRAMS = test-nack-consumer test-nexthopfaceid-consumer generate-link-object
+PROGRAMS = test-congestionmark-consumer test-congestionmark-producer test-nack-consumer \
+	test-nexthopfaceid-consumer generate-link-object
 
 all: $(PROGRAMS)
 
diff --git a/install_helpers/tools/test-congestionmark-consumer.cpp b/install_helpers/tools/test-congestionmark-consumer.cpp
new file mode 100644
index 0000000..fb78312
--- /dev/null
+++ b/install_helpers/tools/test-congestionmark-consumer.cpp
@@ -0,0 +1,61 @@
+/*
+ * Consumer for CongestionMark test (test_congestionmark)
+ *
+ * Sends an Interest for a specified prefix and prints the returned congestion mark (or whether
+ * there was a Nack or Timeout).
+ *
+ * Author: Eric Newberry <enewberry@cs.arizona.edu>
+ *
+ * Based on ndn-cxx example consumer
+ */
+
+#include <ndn-cxx/data.hpp>
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/interest.hpp>
+#include <ndn-cxx/lp/nack.hpp>
+
+using namespace ndn;
+
+class TestCongestionMarkConsumer
+{
+public:
+  void
+  run(Name name)
+  {
+    Interest interest(name);
+
+    m_face.expressInterest(interest,
+                           [] (const Interest& interest, const Data& data) {
+                             std::cout << "CongestionMark=" << data.getCongestionMark() << std::endl;
+                           },
+                           [] (const Interest& interest, const lp::Nack& nack) {
+                             std::cout << "Nack" << std::endl;
+                           },
+                           [] (const Interest& interest) {
+                             std::cout << "Timeout" << std::endl;
+                           });
+    m_face.processEvents();
+  }
+
+private:
+  Face m_face;
+};
+
+int
+main(int argc, char** argv)
+{
+  if (argc != 2) {
+    return 2;
+  }
+
+  try {
+    TestCongestionMarkConsumer consumer;
+    consumer.run(Name(argv[1]));
+  }
+  catch (const std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    return 1;
+  }
+
+  return 0;
+}
diff --git a/install_helpers/tools/test-congestionmark-producer.cpp b/install_helpers/tools/test-congestionmark-producer.cpp
new file mode 100644
index 0000000..c83d15d
--- /dev/null
+++ b/install_helpers/tools/test-congestionmark-producer.cpp
@@ -0,0 +1,76 @@
+/*
+ * Producer for CongestionMark test (test_congestionmark)
+ *
+ * Receives Interests for a specified prefix and returns a Data packet with the same congestion mark
+ * as the corresponding Interest.
+ *
+ * Author: Eric Newberry <enewberry@cs.arizona.edu>
+ *
+ * Based on ndn-cxx example producer
+ */
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/interest.hpp>
+#include <ndn-cxx/interest-filter.hpp>
+#include <ndn-cxx/lp/tags.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+
+using namespace ndn;
+
+class TestCongestionMarkProducer
+{
+public:
+  void
+  run(std::string prefix)
+  {
+    m_face.setInterestFilter(prefix,
+                             bind(&TestCongestionMarkProducer::onInterest, this, _1, _2),
+                             RegisterPrefixSuccessCallback(),
+                             bind(&TestCongestionMarkProducer::onRegisterFailed, this, _1, _2));
+    m_face.processEvents();
+  }
+
+private:
+  void
+  onInterest(const InterestFilter& filter, const Interest& i)
+  {
+    static const std::string content = "0123456789";
+    shared_ptr<Data> data = make_shared<Data>();
+    data->setName(i.getName());
+    data->setFreshnessPeriod(time::seconds(10));
+    data->setContent(reinterpret_cast<const uint8_t*>(content.c_str()), content.size());
+    data->setCongestionMark(i.getCongestionMark());
+    m_keyChain.sign(*data);
+    m_face.put(*data);
+  }
+
+  void
+  onRegisterFailed(const Name& prefix, const std::string& reason)
+  {
+    std::cerr << "Failed to register prefix " << prefix << " (reason: " + reason + ")" << std::endl;
+    m_face.shutdown();
+  }
+
+private:
+  Face m_face;
+  KeyChain m_keyChain;
+};
+
+int
+main(int argc, char** argv)
+{
+  if (argc != 2) {
+    return 2;
+  }
+
+  try {
+    TestCongestionMarkProducer producer;
+    producer.run(argv[1]);
+  }
+  catch (const std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    return 1;
+  }
+
+  return 0;
+}