diff --git a/tools/ndn-tlv-poke.cpp b/tools/ndn-tlv-poke.cpp new file mode 100644 index 00000000..51a12d9e --- /dev/null +++ b/tools/ndn-tlv-poke.cpp @@ -0,0 +1,254 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */ +/** + * Copyright (C) 2014 University of Arizona. + * + * Author: Jerald Paul Abraham + */ + +#include + +#include +#include + +namespace ndntlvpoke { + +class NdnTlvPoke : boost::noncopyable +{ + +public: + + explicit + NdnTlvPoke(char* programName) + : m_programName(programName) + , m_isForceDataSet(false) + , m_isUseDigestSha256Set(false) + , m_isLastAsFinalBlockIdSet(false) + , m_freshnessPeriod(-1) + , m_timeout(-1) + , m_isDataSent(false) + { + } + + void + usage() + { + std::cout << "\n Usage:\n " << m_programName << " " + "[-f] [-D] [-i identity] [-F] [-x freshness] [-w timeout] ndn:/name\n" + " Reads payload from stdin and sends it to local NDN forwarder as a " + "single Data packet\n" + " [-f] - force, send Data without waiting for Interest\n" + " [-D] - use DigestSha256 signing method instead of " + "SignatureSha256WithRsa\n" + " [-i identity] - set identity to be used for signing\n" + " [-F] - set FinalBlockId to the last component of Name\n" + " [-x] - set FreshnessPeriod in milliseconds\n" + " [-w timeout] - set Timeout in milliseconds\n" + " [-h] - print help and exit\n\n"; + exit(1); + } + + void + setForceData() + { + m_isForceDataSet = true; + } + + void + setUseDigestSha256() + { + m_isUseDigestSha256Set = true; + } + + void + setIdentityName(char* identityName) + { + m_identityName = ndn::make_shared(identityName); + } + + void + setLastAsFinalBlockId() + { + m_isLastAsFinalBlockIdSet = true; + } + + void + setFreshnessPeriod(int freshnessPeriod) + { + if (freshnessPeriod < 0) + usage(); + m_freshnessPeriod = freshnessPeriod; + } + + void + setTimeout(int timeout) + { + if (timeout < 0) + usage(); + m_timeout = timeout; + } + + void + setPrefixName(char* prefixName) + { + m_prefixName = ndn::Name(prefixName); + } + + ndn::Milliseconds + getDefaultTimeout() + { + return 10000; + } + + ndn::Data + createDataPacket() + { + ndn::Data dataPacket(m_prefixName); + std::stringstream payloadStream; + payloadStream << std::cin.rdbuf(); + std::string payload = payloadStream.str(); + dataPacket.setContent(reinterpret_cast(payload.c_str()), payload.length()); + if (m_freshnessPeriod >= 0) + dataPacket.setFreshnessPeriod(m_freshnessPeriod); + if (m_isLastAsFinalBlockIdSet) + { + if (!m_prefixName.empty()) + dataPacket.setFinalBlockId(m_prefixName.get(-1)); + else + { + std::cerr << "Name Provided Has 0 Components" << std::endl; + exit(1); + } + } + if (m_isUseDigestSha256Set) + m_keyChain.signWithSha256(dataPacket); + else + { + if (!static_cast(m_identityName)) + m_keyChain.sign(dataPacket); + else + m_keyChain.signByIdentity(dataPacket, *m_identityName); + } + return dataPacket; + } + + void + onInterest(const ndn::Name& name, + const ndn::Interest& interest, + const ndn::Data& dataPacket) + { + m_face.put(dataPacket); + m_isDataSent = true; + m_face.shutdown(); + } + + void + onRegisterFailed(const ndn::Name& prefix, const std::string& reason) + { + std::cerr << "Prefix Registration Failure." << std::endl; + std::cerr << "Reason = " << reason << std::endl; + } + + void + run() + { + try + { + ndn::Data dataPacket = createDataPacket(); + if (m_isForceDataSet) + { + m_face.put(dataPacket); + m_isDataSent = true; + } + else + { + m_face.setInterestFilter(m_prefixName, + ndn::func_lib::bind(&NdnTlvPoke::onInterest, + this, _1, _2, dataPacket), + ndn::func_lib::bind(&NdnTlvPoke::onRegisterFailed, + this, _1, _2)); + } + if (m_timeout < 0) + m_face.processEvents(getDefaultTimeout()); + else + m_face.processEvents(m_timeout); + } + catch (std::exception& e) + { + std::cerr << "ERROR: " << e.what() << "\n" << std::endl; + exit(1); + } + } + + bool + isDataSent() const + { + return m_isDataSent; + } + +private: + + ndn::KeyChain m_keyChain; + std::string m_programName; + bool m_isForceDataSet; + bool m_isUseDigestSha256Set; + ndn::shared_ptr m_identityName; + bool m_isLastAsFinalBlockIdSet; + ndn::Milliseconds m_freshnessPeriod; + ndn::Milliseconds m_timeout; + ndn::Name m_prefixName; + bool m_isDataSent; + ndn::Face m_face; + +}; + +} + +int +main(int argc, char* argv[]) +{ + int option; + ndntlvpoke::NdnTlvPoke ndnTlvPoke(argv[0]); + while ((option = getopt(argc, argv, "hfDi:Fx:w:")) != -1) + { + switch (option) { + case 'h': + ndnTlvPoke.usage(); + break; + case 'f': + ndnTlvPoke.setForceData(); + break; + case 'D': + ndnTlvPoke.setUseDigestSha256(); + break; + case 'i': + ndnTlvPoke.setIdentityName(optarg); + break; + case 'F': + ndnTlvPoke.setLastAsFinalBlockId(); + break; + case 'x': + ndnTlvPoke.setFreshnessPeriod(atoi(optarg)); + break; + case 'w': + ndnTlvPoke.setTimeout(atoi(optarg)); + break; + default: + ndnTlvPoke.usage(); + break; + } + } + + argc -= optind; + argv += optind; + + if (argv[0] == 0) + ndnTlvPoke.usage(); + + ndnTlvPoke.setPrefixName(argv[0]); + ndnTlvPoke.run(); + + if (ndnTlvPoke.isDataSent()) + return 0; + else + return 1; +}