poke: code modernization and cleanup
Change-Id: Ia0d5f0b1bc495636f8fac127bec735cc35af66a7
diff --git a/manpages/ndnpeek.rst b/manpages/ndnpeek.rst
index 9468889..0b6683e 100644
--- a/manpages/ndnpeek.rst
+++ b/manpages/ndnpeek.rst
@@ -63,4 +63,4 @@
Send Interest for ``/app1/video`` and print the received payload only::
- ndnpeek -p ndn:/app1/video
+ ndnpeek -p /app1/video
diff --git a/manpages/ndnpoke.rst b/manpages/ndnpoke.rst
index c4c0a47..caa7753 100644
--- a/manpages/ndnpoke.rst
+++ b/manpages/ndnpoke.rst
@@ -1,54 +1,59 @@
ndnpoke
=======
-Usage
------
+Synopsis
+--------
-::
-
- ndnpoke [-h] [-f] [-D] [-i identity] [-F] [-x freshness] [-w timeout] name
+**ndnpoke** [-h] [-f] [-F] [-x *freshness*] [-i *identity*\|\ -D] [-w *timeout*] [-V] *name*
Description
-----------
-``ndnpoke`` is a simple producer program that reads payload from stdin and publishes it
-as a single NDN Data packet. The Data packet is published either as a response to the
-incoming Interest for the given ``name``, or forcefully pushed to the local NDN
-forwarder's cache if ``-f`` flag is specified.
-
-The program terminates with return code 0 if Data is sent and with return code 1 when
-timeout occurs.
+:program:`ndnpoke` is a simple producer program that reads a payload from the standard
+input and publishes it as a single Data packet. The Data packet is either sent as a
+response to an incoming Interest matching *name*, or immediately pushed to the local
+NDN forwarder as "unsolicited Data" if the **-f** flag is specified.
Options
-------
-``-h``
- Print usage and exit.
+``-h, --help``
+ Print help and exit.
-``-f``
- If specified, send Data without waiting for Interest.
+``-f, --force``
+ Send the Data packet without waiting for an incoming Interest.
-``-D``
- If specified, use ``DigestSha256`` signature instead of default ``SignatureSha256WithRsa``.
+``-F, --final``
+ Set the ``FinalBlockId`` to the last component of *name*.
-``-i``
- Use ``identity`` to sign the created Data packet.
+``-x, --freshness <freshness>``
+ Set ``freshness`` (in milliseconds) as the ``FreshnessPeriod``.
-``-F``
- Set ``FinalBlockId`` to the last component of specified name.
+``-i, --identity <identity>``
+ Use ``identity`` to sign the Data packet.
-``-x``
- Set ``FreshnessPeriod`` in milliseconds.
+``-D, --digest``
+ Use ``DigestSha256`` signature type instead of the default ``SignatureSha256WithRsa``.
-``-w``
- Wait at most ``timeout`` milliseconds for the incoming Interest. If no Interest arrives
- within the ``timeout``, the Data packet will not be published.
+``-w, --timeout <timeout>``
+ Quit the program after ``timeout`` milliseconds, even if no Interest has been received.
+``-V, --version``
+ Print version and exit.
-Examples
---------
+Exit Status
+-----------
-Create Data packet with content ``hello`` with the name ``ndn:/app/video`` and wait at
-most 3 seconds for the incoming Interest for it::
+0: Success
- echo "Hello" | build/bin/ndnpoke -w 3000 ndn:/app/video
+1: An unspecified error occurred
+
+2: Malformed command line
+
+Example
+-------
+
+Create a Data packet with content ``hello`` and name ``/app/video`` and wait at
+most 3 seconds for a matching Interest to arrive::
+
+ echo "hello" | ndnpoke -w 3000 /app/video
diff --git a/tests/peek/ndnpoke.t.cpp b/tests/peek/ndnpoke.t.cpp
index f569f03..3f9a59b 100644
--- a/tests/peek/ndnpoke.t.cpp
+++ b/tests/peek/ndnpoke.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2018, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,6 +26,7 @@
#include "tools/peek/ndnpoke/ndnpoke.hpp"
#include "tests/test-common.hpp"
+#include "tests/identity-management-fixture.hpp"
#include <ndn-cxx/util/dummy-client-face.hpp>
@@ -35,37 +36,33 @@
using namespace ndn::tests;
-class NdnPokeFixture : public UnitTestTimeFixture
+class NdnPokeFixture : public IdentityManagementTimeFixture
{
protected:
NdnPokeFixture()
- : face(io, keyChain, {true, true})
{
- keyChain.createIdentity("/test-id");
-
- inData << "Hello world!";
+ m_keyChain.createIdentity("/test-id");
}
void
- initialize(const PokeOptions& opts)
+ initialize(const PokeOptions& opts = makeDefaultOptions())
{
- poke = make_unique<NdnPoke>(face, keyChain, inData, opts);
+ poke = make_unique<NdnPoke>(face, m_keyChain, payload, opts);
}
static PokeOptions
makeDefaultOptions()
{
PokeOptions opt;
- opt.prefixName = "/poke/test";
+ opt.name = "/poke/test";
return opt;
}
protected:
boost::asio::io_service io;
- ndn::util::DummyClientFace face;
- KeyChain keyChain;
+ ndn::util::DummyClientFace face{io, m_keyChain, {true, true}};
+ std::stringstream payload{"Hello, world!\n"};
unique_ptr<NdnPoke> poke;
- std::stringstream inData;
};
BOOST_AUTO_TEST_SUITE(Peek)
@@ -73,11 +70,9 @@
BOOST_AUTO_TEST_CASE(Basic)
{
- auto options = makeDefaultOptions();
- initialize(options);
+ initialize();
poke->start();
-
this->advanceClocks(io, 1_ms, 10);
// Check for prefix registration
@@ -88,11 +83,13 @@
this->advanceClocks(io, 1_ms, 10);
io.run();
- BOOST_CHECK(poke->wasDataSent());
+ BOOST_CHECK(poke->didSendData());
BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
BOOST_CHECK_EQUAL(face.sentData.back().getName(), "/poke/test");
BOOST_CHECK(!face.sentData.back().getFinalBlock());
BOOST_CHECK_EQUAL(face.sentData.back().getFreshnessPeriod(), 0_ms);
+ BOOST_CHECK_EQUAL(face.sentData.back().getContentType(), tlv::ContentType_Blob);
+ BOOST_CHECK_EQUAL(face.sentData.back().getContent(), "150E48656C6C6F2C20776F726C64210A"_block);
BOOST_CHECK_EQUAL(face.sentData.back().getSignature().getType(), tlv::SignatureSha256WithEcdsa);
// Check for prefix unregistration
@@ -100,45 +97,20 @@
BOOST_CHECK_EQUAL(face.sentInterests.back().getName().getPrefix(4), "/localhost/nfd/rib/unregister");
}
-BOOST_AUTO_TEST_CASE(FinalBlockId)
-{
- auto options = makeDefaultOptions();
- options.prefixName = "/poke/test/123";
- options.wantLastAsFinalBlockId = true;
- initialize(options);
-
- poke->start();
-
- this->advanceClocks(io, 1_ms, 10);
-
- face.receive(*makeInterest("/poke/test/123"));
- this->advanceClocks(io, 1_ms, 10);
- io.run();
-
- BOOST_CHECK(poke->wasDataSent());
- BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
- BOOST_CHECK_EQUAL(face.sentData.back().getName(), "/poke/test/123");
- BOOST_REQUIRE(face.sentData.back().getFinalBlock());
- BOOST_CHECK_EQUAL(*(face.sentData.back().getFinalBlock()), name::Component("123"));
- BOOST_CHECK_EQUAL(face.sentData.back().getFreshnessPeriod(), 0_ms);
- BOOST_CHECK_EQUAL(face.sentData.back().getSignature().getType(), tlv::SignatureSha256WithEcdsa);
-}
-
BOOST_AUTO_TEST_CASE(FreshnessPeriod)
{
auto options = makeDefaultOptions();
- options.freshnessPeriod = make_optional<time::milliseconds>(1_s);
+ options.freshnessPeriod = 1_s;
initialize(options);
poke->start();
-
this->advanceClocks(io, 1_ms, 10);
face.receive(*makeInterest("/poke/test"));
this->advanceClocks(io, 1_ms, 10);
io.run();
- BOOST_CHECK(poke->wasDataSent());
+ BOOST_CHECK(poke->didSendData());
BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
BOOST_CHECK_EQUAL(face.sentData.back().getName(), "/poke/test");
BOOST_CHECK(!face.sentData.back().getFinalBlock());
@@ -146,6 +118,29 @@
BOOST_CHECK_EQUAL(face.sentData.back().getSignature().getType(), tlv::SignatureSha256WithEcdsa);
}
+BOOST_AUTO_TEST_CASE(FinalBlockId)
+{
+ auto options = makeDefaultOptions();
+ options.name = "/poke/test/123";
+ options.wantFinalBlockId = true;
+ initialize(options);
+
+ poke->start();
+ this->advanceClocks(io, 1_ms, 10);
+
+ face.receive(*makeInterest(options.name));
+ this->advanceClocks(io, 1_ms, 10);
+ io.run();
+
+ BOOST_CHECK(poke->didSendData());
+ BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
+ BOOST_CHECK_EQUAL(face.sentData.back().getName(), options.name);
+ BOOST_REQUIRE(face.sentData.back().getFinalBlock());
+ BOOST_CHECK_EQUAL(*(face.sentData.back().getFinalBlock()), name::Component("123"));
+ BOOST_CHECK_EQUAL(face.sentData.back().getFreshnessPeriod(), 0_ms);
+ BOOST_CHECK_EQUAL(face.sentData.back().getSignature().getType(), tlv::SignatureSha256WithEcdsa);
+}
+
BOOST_AUTO_TEST_CASE(DigestSha256)
{
auto options = makeDefaultOptions();
@@ -153,14 +148,13 @@
initialize(options);
poke->start();
-
this->advanceClocks(io, 1_ms, 10);
face.receive(*makeInterest("/poke/test"));
this->advanceClocks(io, 1_ms, 10);
io.run();
- BOOST_CHECK(poke->wasDataSent());
+ BOOST_CHECK(poke->didSendData());
BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
BOOST_CHECK_EQUAL(face.sentData.back().getName(), "/poke/test");
BOOST_CHECK(!face.sentData.back().getFinalBlock());
@@ -175,10 +169,9 @@
initialize(options);
poke->start();
-
this->advanceClocks(io, 1_ms, 10);
- BOOST_CHECK(poke->wasDataSent());
+ BOOST_CHECK(poke->didSendData());
BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
BOOST_CHECK_EQUAL(face.sentData.back().getName(), "/poke/test");
BOOST_CHECK(!face.sentData.back().getFinalBlock());
@@ -186,24 +179,42 @@
BOOST_CHECK_EQUAL(face.sentData.back().getSignature().getType(), tlv::SignatureSha256WithEcdsa);
}
-BOOST_AUTO_TEST_CASE(ExceedMaxPacketSize)
+BOOST_AUTO_TEST_CASE(Timeout)
{
- for (size_t i = 0; i < MAX_NDN_PACKET_SIZE; i++) {
- inData << "A";
- }
-
auto options = makeDefaultOptions();
+ options.timeout = 4_s;
initialize(options);
poke->start();
+ this->advanceClocks(io, 1_ms, 10);
+ // Check for prefix registration
+ BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
+ BOOST_CHECK_EQUAL(face.sentInterests.front().getName().getPrefix(4), "/localhost/nfd/rib/register");
+
+ this->advanceClocks(io, 1_s, 4);
+
+ BOOST_CHECK(!poke->didSendData());
+ BOOST_CHECK_EQUAL(face.sentData.size(), 0);
+
+ // Check for prefix unregistration
+ BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 2); // One for registration, one for unregistration
+ BOOST_CHECK_EQUAL(face.sentInterests.back().getName().getPrefix(4), "/localhost/nfd/rib/unregister");
+}
+
+BOOST_AUTO_TEST_CASE(OversizedPacket)
+{
+ payload << std::string(MAX_NDN_PACKET_SIZE, 'A');
+ initialize();
+
+ poke->start();
this->advanceClocks(io, 1_ms, 10);
face.receive(*makeInterest("/poke/test"));
BOOST_CHECK_THROW(face.processEvents(), Face::OversizedPacketError);
- // We can't check wasDataSent() correctly here because it will be set to true, even if put failed
- // due to the packet being oversized.
+ // No point in checking didSendData() here. The exception is thrown from processEvents(),
+ // not from put(), so didSendData() is still set to true even though no packets are sent.
BOOST_CHECK_EQUAL(face.sentData.size(), 0);
}
diff --git a/tools/peek/README.md b/tools/peek/README.md
index 5c6fb35..79e9832 100644
--- a/tools/peek/README.md
+++ b/tools/peek/README.md
@@ -1,14 +1,14 @@
# ndnpeek and ndnpoke
-**ndnpeek** and **ndnpoke** are a pair of programs to request and make available for retrieval of a single Data packet.
+**ndnpeek** and **ndnpoke** are a pair of programs to respectively request and serve a single Data packet.
* **ndnpeek** is a consumer program that sends one Interest and expects one Data.
* **ndnpoke** is a producer program that serves one Data in response to an Interest.
Usage example:
-1. start NFD on local machine
-2. execute `echo 'HELLO WORLD' | ndnpoke ndn:/localhost/demo/hello`
-3. on another console, execute `ndnpeek -p ndn:/localhost/demo/hello`
+1. start NFD
+2. execute `echo 'HELLO WORLD' | ndnpoke /localhost/demo/hello`
+3. in another terminal, execute `ndnpeek -p /localhost/demo/hello`
-For more information, consult manpages of these programs.
+For more information, consult the manpages of these programs.
diff --git a/tools/peek/ndnpeek/main.cpp b/tools/peek/ndnpeek/main.cpp
index 1586387..f763b96 100644
--- a/tools/peek/ndnpeek/main.cpp
+++ b/tools/peek/ndnpeek/main.cpp
@@ -39,7 +39,7 @@
static void
usage(std::ostream& os, const std::string& program, const po::options_description& options)
{
- os << "Usage: " << program << " [options] ndn:/name\n"
+ os << "Usage: " << program << " [options] /name\n"
<< "\n"
<< "Fetch one data item matching the specified name and write it to the standard output.\n"
<< options;
diff --git a/tools/peek/ndnpoke/main.cpp b/tools/peek/ndnpoke/main.cpp
index 2086a2b..33d91ea 100644
--- a/tools/peek/ndnpoke/main.cpp
+++ b/tools/peek/ndnpoke/main.cpp
@@ -28,47 +28,40 @@
#include "ndnpoke.hpp"
#include "core/version.hpp"
-#include <ndn-cxx/util/io.hpp>
-
-#include <sstream>
-
namespace ndn {
namespace peek {
namespace po = boost::program_options;
static void
-usage(std::ostream& os, const po::options_description& options)
+usage(std::ostream& os, const std::string& program, const po::options_description& options)
{
- os << "Usage: ndnpoke [options] ndn:/name\n"
- "\n"
- "Reads payload from stdin and sends it to the local NDN forwarder as a single Data packet\n"
- "\n"
+ os << "Usage: " << program << " [options] /name\n"
+ << "\n"
+ << "Reads a payload from the standard input and sends it as a single Data packet.\n"
<< options;
}
static int
main(int argc, char* argv[])
{
+ std::string progName(argv[0]);
PokeOptions options;
- bool wantDigestSha256;
+ bool wantDigestSha256 = false;
po::options_description visibleOptDesc;
visibleOptDesc.add_options()
- ("help,h", "print help and exit")
- ("version,V", "print version and exit")
- ("force,f", po::bool_switch(&options.wantForceData),
- "for, send Data without waiting for Interest")
- ("digest,D", po::bool_switch(&wantDigestSha256),
- "use DigestSha256 signing method instead of SignatureSha256WithRsa")
- ("identity,i", po::value<std::string>(),
- "set identity to be used for signing")
- ("final,F", po::bool_switch(&options.wantLastAsFinalBlockId),
- "set FinalBlockId to the last component of Name")
- ("freshness,x", po::value<int>(),
- "set FreshnessPeriod in milliseconds")
- ("timeout,w", po::value<int>(),
- "set Timeout in milliseconds")
+ ("help,h", "print help and exit")
+ ("force,f", po::bool_switch(&options.wantForceData),
+ "send the Data packet without waiting for an incoming Interest")
+ ("final,F", po::bool_switch(&options.wantFinalBlockId),
+ "set FinalBlockId to the last component of the Data name")
+ ("freshness,x", po::value<int>(), "set FreshnessPeriod (in milliseconds)")
+ ("identity,i", po::value<std::string>(), "use the specified identity for signing")
+ ("digest,D", po::bool_switch(&wantDigestSha256),
+ "use DigestSha256 signing method instead of SignatureSha256WithRsa")
+ ("timeout,w", po::value<int>(), "set timeout (in milliseconds)")
+ ("version,V", "print version and exit")
;
po::options_description hiddenOptDesc;
@@ -91,11 +84,8 @@
return 2;
}
- // We store timeout here, instead of PokeOptions, because processEvents is called outside the NdnPoke class
- time::milliseconds timeout = 10_s;
-
if (vm.count("help") > 0) {
- usage(std::cout, visibleOptDesc);
+ usage(std::cout, progName, visibleOptDesc);
return 0;
}
@@ -104,78 +94,75 @@
return 0;
}
- if (vm.count("name") > 0) {
- options.prefixName = vm["name"].as<std::string>();
- }
- else {
- std::cerr << "ERROR: Data name is missing" << std::endl;
- usage(std::cerr, visibleOptDesc);
+ if (vm.count("name") == 0) {
+ std::cerr << "ERROR: missing name\n\n";
+ usage(std::cerr, progName, visibleOptDesc);
return 2;
}
+ try {
+ options.name = vm["name"].as<std::string>();
+ }
+ catch (const Name::Error& e) {
+ std::cerr << "ERROR: invalid name: " << e.what() << std::endl;
+ return 2;
+ }
+
+ if (options.name.empty()) {
+ std::cerr << "ERROR: name cannot have zero components" << std::endl;
+ return 2;
+ }
+
+ if (vm.count("freshness") > 0) {
+ if (vm["freshness"].as<int>() < 0) {
+ std::cerr << "ERROR: freshness cannot be negative" << std::endl;
+ return 2;
+ }
+ options.freshnessPeriod = time::milliseconds(vm["freshness"].as<int>());
+ }
+
+ if (vm.count("identity") > 0) {
+ if (wantDigestSha256) {
+ std::cerr << "ERROR: conflicting '--digest' and '--identity' options specified" << std::endl;
+ return 2;
+ }
+ try {
+ options.signingInfo.setSigningIdentity(vm["identity"].as<std::string>());
+ }
+ catch (const Name::Error& e) {
+ std::cerr << "ERROR: invalid identity name: " << e.what() << std::endl;
+ return 2;
+ }
+ }
+
if (wantDigestSha256) {
options.signingInfo.setSha256Signing();
}
- if (vm.count("identity") > 0) {
- if (wantDigestSha256) {
- std::cerr << "ERROR: Signing identity cannot be specified when using DigestSha256 signing method" << std::endl;
- usage(std::cerr, visibleOptDesc);
- return 2;
- }
- options.signingInfo.setSigningIdentity(vm["identity"].as<std::string>());
- }
-
- if (vm.count("final") > 0) {
- if (!options.prefixName.empty()) {
- options.wantLastAsFinalBlockId = true;
- }
- else {
- std::cerr << "The provided Name must have 1 or more components to be used with FinalBlockId option" << std::endl;
- usage(std::cerr, visibleOptDesc);
- return 1;
- }
- }
-
- if (vm.count("freshness") > 0) {
- if (vm["freshness"].as<int>() >= 0) {
- options.freshnessPeriod = time::milliseconds(vm["freshness"].as<int>());
- }
- else {
- std::cerr << "ERROR: FreshnessPeriod must be a non-negative integer" << std::endl;
- usage(std::cerr, visibleOptDesc);
- return 2;
- }
- }
-
if (vm.count("timeout") > 0) {
- if (vm["timeout"].as<int>() > 0) {
- timeout = time::milliseconds(vm["timeout"].as<int>());
- }
- else {
- std::cerr << "ERROR: Timeout must a positive integer" << std::endl;
- usage(std::cerr, visibleOptDesc);
+ if (options.wantForceData) {
+ std::cerr << "ERROR: conflicting '--force' and '--timeout' options specified" << std::endl;
return 2;
}
+ if (vm["timeout"].as<int>() < 0) {
+ std::cerr << "ERROR: timeout cannot be negative" << std::endl;
+ return 2;
+ }
+ options.timeout = time::milliseconds(vm["timeout"].as<int>());
}
- boost::asio::io_service io;
- Face face(io);
- KeyChain keyChain;
- NdnPoke program(face, keyChain, std::cin, options);
try {
+ Face face;
+ KeyChain keyChain;
+ NdnPoke program(face, keyChain, std::cin, options);
+
program.start();
- face.processEvents(timeout);
+ face.processEvents();
+
+ return program.didSendData() ? 0 : 1;
}
catch (const std::exception& e) {
- std::cerr << "ERROR: " << e.what() << "\n" << std::endl;
- return 1;
- }
-
- if (program.wasDataSent()) {
- return 0;
- }
- else {
+ std::cerr << "ERROR: " << e.what() << std::endl;
return 1;
}
}
diff --git a/tools/peek/ndnpoke/ndnpoke.cpp b/tools/peek/ndnpoke/ndnpoke.cpp
index 40ec247..2934404 100644
--- a/tools/peek/ndnpoke/ndnpoke.cpp
+++ b/tools/peek/ndnpoke/ndnpoke.cpp
@@ -27,79 +27,66 @@
#include "ndnpoke.hpp"
-#include <ndn-cxx/security/signing-helpers.hpp>
-
-#include <sstream>
+#include <ndn-cxx/encoding/buffer-stream.hpp>
namespace ndn {
namespace peek {
-NdnPoke::NdnPoke(Face& face, KeyChain& keyChain, std::istream& inStream, const PokeOptions& options)
- : m_face(face)
+NdnPoke::NdnPoke(Face& face, KeyChain& keyChain, std::istream& input, const PokeOptions& options)
+ : m_options(options)
+ , m_face(face)
, m_keyChain(keyChain)
- , m_inStream(inStream)
- , m_options(options)
- , m_wasDataSent(false)
+ , m_input(input)
+ , m_scheduler(m_face.getIoService())
{
}
void
NdnPoke::start()
{
- shared_ptr<Data> dataPacket = createDataPacket();
+ auto data = createData();
+
if (m_options.wantForceData) {
- m_face.put(*dataPacket);
- m_wasDataSent = true;
+ m_face.put(*data);
+ m_didSendData = true;
+ return;
}
- else {
- m_registeredPrefix = m_face.setInterestFilter(m_options.prefixName,
- bind(&NdnPoke::onInterest, this, _1, _2, dataPacket),
- nullptr,
- bind(&NdnPoke::onRegisterFailed, this, _1, _2));
- }
+
+ m_registeredPrefix = m_face.setInterestFilter(m_options.name,
+ [this, data] (auto&&...) {
+ m_timeoutEvent.cancel();
+ m_face.put(*data);
+ m_didSendData = true;
+ m_registeredPrefix.cancel();
+ },
+ [this] (auto&&) {
+ m_timeoutEvent = m_scheduler.schedule(m_options.timeout, [this] {
+ m_registeredPrefix.cancel();
+ });
+ },
+ [] (auto&&, const auto& reason) {
+ std::cerr << "Prefix registration failure (" << reason << ")\n";
+ });
}
shared_ptr<Data>
-NdnPoke::createDataPacket()
+NdnPoke::createData() const
{
- auto dataPacket = make_shared<Data>(m_options.prefixName);
-
- std::stringstream payloadStream;
- payloadStream << m_inStream.rdbuf();
- std::string payload = payloadStream.str();
- dataPacket->setContent(reinterpret_cast<const uint8_t*>(payload.c_str()), payload.length());
-
+ auto data = make_shared<Data>(m_options.name);
if (m_options.freshnessPeriod) {
- dataPacket->setFreshnessPeriod(*m_options.freshnessPeriod);
+ data->setFreshnessPeriod(*m_options.freshnessPeriod);
+ }
+ if (m_options.wantFinalBlockId) {
+ data->setFinalBlock(m_options.name.at(-1));
}
- if (m_options.wantLastAsFinalBlockId) {
- dataPacket->setFinalBlock(m_options.prefixName.get(-1));
- }
+ OBufferStream os;
+ os << m_input.rdbuf();
+ data->setContent(os.buf());
- m_keyChain.sign(*dataPacket, m_options.signingInfo);
+ m_keyChain.sign(*data, m_options.signingInfo);
- return dataPacket;
-}
-
-void
-NdnPoke::onInterest(const Name& name, const Interest& interest, const shared_ptr<Data>& data)
-{
- try {
- m_face.put(*data);
- m_wasDataSent = true;
- }
- catch (const Face::OversizedPacketError& e) {
- std::cerr << "Data exceeded maximum packet size" << std::endl;
- }
-
- m_registeredPrefix.cancel();
-}
-
-void
-NdnPoke::onRegisterFailed(const Name& prefix, const std::string& reason)
-{
- std::cerr << "Prefix Registration Failure. Reason = " << reason << std::endl;
+ return data;
}
} // namespace peek
diff --git a/tools/peek/ndnpoke/ndnpoke.hpp b/tools/peek/ndnpoke/ndnpoke.hpp
index fdad5bb..af5ad34 100644
--- a/tools/peek/ndnpoke/ndnpoke.hpp
+++ b/tools/peek/ndnpoke/ndnpoke.hpp
@@ -30,6 +30,8 @@
#include "core/common.hpp"
+#include <ndn-cxx/util/scheduler.hpp>
+
namespace ndn {
namespace peek {
@@ -38,45 +40,44 @@
*/
struct PokeOptions
{
- Name prefixName;
- bool wantForceData = false;
+ // Data construction options
+ Name name;
+ optional<time::milliseconds> freshnessPeriod;
+ bool wantFinalBlockId = false;
security::SigningInfo signingInfo;
- bool wantLastAsFinalBlockId = false;
- optional<time::milliseconds> freshnessPeriod = {};
+
+ // program behavior options
+ bool wantForceData = false;
+ time::milliseconds timeout = 10_s;
};
class NdnPoke : boost::noncopyable
{
public:
- NdnPoke(Face& face, KeyChain& keyChain, std::istream& inStream, const PokeOptions& options);
+ NdnPoke(Face& face, KeyChain& keyChain, std::istream& input, const PokeOptions& options);
void
start();
bool
- wasDataSent() const
+ didSendData() const
{
- return m_wasDataSent;
+ return m_didSendData;
}
private:
shared_ptr<Data>
- createDataPacket();
-
- void
- onInterest(const Name& name, const Interest& interest, const shared_ptr<Data>& data);
-
- void
- onRegisterFailed(const Name& prefix, const std::string& reason);
+ createData() const;
private:
+ const PokeOptions m_options;
Face& m_face;
KeyChain& m_keyChain;
- std::istream& m_inStream;
- const PokeOptions& m_options;
-
- RegisteredPrefixHandle m_registeredPrefix;
- bool m_wasDataSent;
+ std::istream& m_input;
+ Scheduler m_scheduler;
+ ScopedRegisteredPrefixHandle m_registeredPrefix;
+ scheduler::ScopedEventId m_timeoutEvent;
+ bool m_didSendData = false;
};
} // namespace peek