util: make DummyClientFace public API
refs #2164
Change-Id: I4a21b70faab1fc1f5cde8430ef602f2425150df9
diff --git a/src/util/dummy-client-face.cpp b/src/util/dummy-client-face.cpp
new file mode 100644
index 0000000..a7ab505
--- /dev/null
+++ b/src/util/dummy-client-face.cpp
@@ -0,0 +1,185 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "dummy-client-face.hpp"
+#include "../transport/transport.hpp"
+#include "../management/nfd-controller.hpp"
+#include "../management/nfd-control-response.hpp"
+
+namespace ndn {
+namespace util {
+
+const DummyClientFace::Options DummyClientFace::DEFAULT_OPTIONS { true, false };
+
+class DummyClientFace::Transport : public ndn::Transport
+{
+public:
+ void
+ receive(const Block& block)
+ {
+ if (static_cast<bool>(m_receiveCallback))
+ m_receiveCallback(block);
+ }
+
+ virtual void
+ close()
+ {
+ }
+
+ virtual void
+ pause()
+ {
+ }
+
+ virtual void
+ resume()
+ {
+ }
+
+ virtual void
+ send(const Block& wire)
+ {
+ if (wire.type() == tlv::Interest) {
+ shared_ptr<Interest> interest = make_shared<Interest>(wire);
+ (*m_onInterest)(*interest);
+ }
+ else if (wire.type() == tlv::Data) {
+ shared_ptr<Data> data = make_shared<Data>(wire);
+ (*m_onData)(*data);
+ }
+ }
+
+ virtual void
+ send(const Block& header, const Block& payload)
+ {
+ this->send(payload);
+ }
+
+ boost::asio::io_service&
+ getIoService()
+ {
+ return *m_ioService;
+ }
+
+private:
+ friend class DummyClientFace;
+ EventEmitter<Interest>* m_onInterest;
+ EventEmitter<Data>* m_onData;
+};
+
+DummyClientFace::DummyClientFace(const Options& options, shared_ptr<Transport> transport)
+ : Face(transport)
+ , m_transport(transport)
+{
+ this->construct(options);
+}
+
+DummyClientFace::DummyClientFace(const Options& options, shared_ptr<Transport> transport,
+ boost::asio::io_service& ioService)
+ : Face(transport, ioService)
+ , m_transport(transport)
+{
+ this->construct(options);
+}
+
+void
+DummyClientFace::construct(const Options& options)
+{
+ m_transport->m_onInterest = &onInterest;
+ m_transport->m_onData = &onData;
+
+ if (options.enablePacketLogging)
+ this->enablePacketLogging();
+
+ if (options.enableRegistrationReply)
+ this->enableRegistrationReply();
+}
+
+void
+DummyClientFace::enablePacketLogging()
+{
+ onInterest += [this] (const Interest& interest) { this->sentInterests.push_back(interest); };
+ onData += [this] (const Data& data) { this->sentDatas.push_back(data); };
+}
+
+void
+DummyClientFace::enableRegistrationReply()
+{
+ onInterest += [this] (const Interest& interest) {
+ static const Name localhostRegistration("/localhost/nfd/rib");
+ if (!localhostRegistration.isPrefixOf(interest.getName()))
+ return;
+
+ nfd::ControlParameters params(interest.getName().get(-5).blockFromValue());
+ params.setFaceId(1);
+ params.setOrigin(0);
+ if (interest.getName().get(3) == name::Component("register")) {
+ params.setCost(0);
+ }
+
+ nfd::ControlResponse resp;
+ resp.setCode(200);
+ resp.setBody(params.wireEncode());
+
+ shared_ptr<Data> data = make_shared<Data>(interest.getName());
+ data->setContent(resp.wireEncode());
+
+ KeyChain keyChain;
+ keyChain.signWithSha256(*data);
+
+ this->getIoService().post([this, data] { this->receive(*data); });
+ };
+}
+
+template<typename Packet>
+void
+DummyClientFace::receive(const Packet& packet)
+{
+ m_transport->receive(packet.wireEncode());
+}
+
+template void
+DummyClientFace::receive<Interest>(const Interest& packet);
+
+template void
+DummyClientFace::receive<Data>(const Data& packet);
+
+
+shared_ptr<DummyClientFace>
+makeDummyClientFace(const DummyClientFace::Options& options)
+{
+ // cannot use make_shared<DummyClientFace> before DummyClientFace constructor is private
+ return shared_ptr<DummyClientFace>(
+ new DummyClientFace(options, make_shared<DummyClientFace::Transport>()));
+}
+
+shared_ptr<DummyClientFace>
+makeDummyClientFace(boost::asio::io_service& ioService,
+ const DummyClientFace::Options& options)
+{
+ // cannot use make_shared<DummyClientFace> before DummyClientFace constructor is private
+ return shared_ptr<DummyClientFace>(
+ new DummyClientFace(options, make_shared<DummyClientFace::Transport>(),
+ ref(ioService)));
+}
+
+} // namespace util
+} // namespace ndn