ndn-tlv-peek: simple consumer program that sends one interest and expects one response
refs: #1349
Change-Id: I5b98baf63ffdea5ec1c9bf1e98953e2035339e41
diff --git a/tools/ndn-tlv-peek.cpp b/tools/ndn-tlv-peek.cpp
new file mode 100644
index 0000000..8ed429d
--- /dev/null
+++ b/tools/ndn-tlv-peek.cpp
@@ -0,0 +1,257 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2014 University of Arizona.
+ *
+ * Author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
+ */
+
+#include <boost/asio.hpp>
+
+#include <ndn-cpp-dev/face.hpp>
+
+namespace ndntlvpeek {
+
+class NdnTlvPeek
+{
+public:
+ NdnTlvPeek(char* programName)
+ : m_programName(programName)
+ , m_mustBeFresh(false)
+ , m_isChildSelectorRightmost(false)
+ , m_minSuffixComponents(-1)
+ , m_maxSuffixComponents(-1)
+ , m_interestLifetime(-1)
+ , m_isPayloadOnlySet(false)
+ , m_timeout(-1)
+ , m_prefixName("")
+ , m_isDataReceived(false)
+ , m_ioService(new boost::asio::io_service)
+ , m_face(m_ioService)
+ {
+ }
+
+ void
+ usage()
+ {
+ std::cout << "\n Usage:\n " << m_programName << " "
+ "[-f] [-r] [-m min] [-M max] [-l lifetime] [-p] [-w timeout] ndn:/name\n"
+ " Get one data item matching the name prefix and write it to stdout\n"
+ " [-f] - set MustBeFresh\n"
+ " [-r] - set ChildSelector to select rightmost child\n"
+ " [-m min] - set MinSuffixComponents\n"
+ " [-M max] - set MaxSuffixComponents\n"
+ " [-l lifetime] - set InterestLifetime in milliseconds\n"
+ " [-p] - print payload only, not full packet\n"
+ " [-w timeout] - set Timeout in milliseconds\n"
+ " [-h] - print help and exit\n\n";
+ exit(1);
+ }
+
+ void
+ setMustBeFresh()
+ {
+ m_mustBeFresh = true;
+ }
+
+ void
+ setRightmostChildSelector()
+ {
+ m_isChildSelectorRightmost = true;
+ }
+
+ void
+ setMinSuffixComponents(int minSuffixComponents)
+ {
+ if (minSuffixComponents < 0)
+ usage();
+ m_minSuffixComponents = minSuffixComponents;
+ }
+
+ void
+ setMaxSuffixComponents(int maxSuffixComponents)
+ {
+ if (maxSuffixComponents < 0)
+ usage();
+ m_maxSuffixComponents = maxSuffixComponents;
+ }
+
+ void
+ setInterestLifetime(int interestLifetime)
+ {
+ if (interestLifetime < 0)
+ usage();
+ m_interestLifetime = interestLifetime;
+ }
+
+ void
+ setPayloadOnly()
+ {
+ m_isPayloadOnlySet = true;
+ }
+
+ void
+ setTimeout(int timeout)
+ {
+ if (timeout < 0)
+ usage();
+ m_timeout = timeout;
+ }
+
+ void
+ setPrefixName(char* prefixName)
+ {
+ m_prefixName = prefixName;
+ if (m_prefixName.length() == 0)
+ usage();
+ }
+
+ int
+ getDefaultInterestLifetime()
+ {
+ return 4000;
+ }
+
+ ndn::Interest
+ createInterestPacket()
+ {
+ ndn::Name interestName(m_prefixName);
+ ndn::Interest interestPacket(interestName);
+ if (m_mustBeFresh)
+ interestPacket.setMustBeFresh(true);
+ if (m_isChildSelectorRightmost)
+ interestPacket.setChildSelector(1);
+ if (m_minSuffixComponents >= 0)
+ interestPacket.setMinSuffixComponents(m_minSuffixComponents);
+ if (m_maxSuffixComponents >= 0)
+ interestPacket.setMaxSuffixComponents(m_maxSuffixComponents);
+ if (m_interestLifetime < 0)
+ interestPacket.setInterestLifetime(getDefaultInterestLifetime());
+ else
+ interestPacket.setInterestLifetime(m_interestLifetime);
+ return interestPacket;
+ }
+
+ void
+ onData(const ndn::Interest& interest, ndn::Data& data)
+ {
+ int returnValue;
+ m_isDataReceived = true;
+ if (m_isPayloadOnlySet)
+ {
+ ndn::Block block = data.getContent();
+ returnValue = write(1, block.value(), block.value_size());
+ }
+ else
+ {
+ ndn::Block block = data.wireEncode();
+ returnValue = write(1, block.wire(), block.size());
+ }
+ }
+
+ void
+ onTimeout(const ndn::Interest& interest)
+ {
+ }
+
+ void
+ run()
+ {
+ try
+ {
+ m_face.expressInterest(createInterestPacket(),
+ ndn::func_lib::bind(&NdnTlvPeek::onData,
+ this, _1, _2),
+ ndn::func_lib::bind(&NdnTlvPeek::onTimeout,
+ this, _1));
+ if (m_timeout < 0)
+ {
+ if (m_interestLifetime < 0)
+ m_face.processEvents(getDefaultInterestLifetime());
+ else
+ m_face.processEvents(m_interestLifetime);
+ }
+ else
+ m_face.processEvents(m_timeout);
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "ERROR: " << e.what() << "\n" << std::endl;
+ exit(1);
+ }
+ }
+
+ bool
+ isDataReceived() const
+ {
+ return m_isDataReceived;
+ }
+
+private:
+
+ std::string m_programName;
+ bool m_mustBeFresh;
+ bool m_isChildSelectorRightmost;
+ int m_minSuffixComponents;
+ int m_maxSuffixComponents;
+ int m_interestLifetime;
+ bool m_isPayloadOnlySet;
+ int m_timeout;
+ std::string m_prefixName;
+ bool m_isDataReceived;
+ ndn::ptr_lib::shared_ptr<boost::asio::io_service> m_ioService;
+ ndn::Face m_face;
+};
+
+}
+
+int
+main(int argc, char* argv[])
+{
+ int option;
+ ndntlvpeek::NdnTlvPeek ndnTlvPeek (argv[0]);
+ while ((option = getopt(argc, argv, "hfrm:M:l:pw:")) != -1)
+ {
+ switch (option) {
+ case 'h':
+ ndnTlvPeek.usage();
+ break;
+ case 'f':
+ ndnTlvPeek.setMustBeFresh();
+ break;
+ case 'r':
+ ndnTlvPeek.setRightmostChildSelector();
+ break;
+ case 'm':
+ ndnTlvPeek.setMinSuffixComponents(atoi(optarg));
+ break;
+ case 'M':
+ ndnTlvPeek.setMaxSuffixComponents(atoi(optarg));
+ break;
+ case 'l':
+ ndnTlvPeek.setInterestLifetime(atoi(optarg));
+ break;
+ case 'p':
+ ndnTlvPeek.setPayloadOnly();
+ break;
+ case 'w':
+ ndnTlvPeek.setTimeout(atoi(optarg));
+ break;
+ default:
+ ndnTlvPeek.usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argv[0] == 0)
+ ndnTlvPeek.usage();
+
+ ndnTlvPeek.setPrefixName(argv[0]);
+ ndnTlvPeek.run();
+
+ if (ndnTlvPeek.isDataReceived())
+ return 0;
+ else
+ return 1;
+}