blob: f5e117224377fe6545bfb27a6b2428a78e9ff20f [file] [log] [blame]
Junxiao Shia60d9362014-11-12 09:38:21 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyevaf99f462015-01-19 21:43:09 -08003 * Copyright (c) 2013-2015 Regents of the University of California.
Junxiao Shia60d9362014-11-12 09:38:21 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "dummy-client-face.hpp"
23#include "../transport/transport.hpp"
24#include "../management/nfd-controller.hpp"
25#include "../management/nfd-control-response.hpp"
26
27namespace ndn {
28namespace util {
29
30const DummyClientFace::Options DummyClientFace::DEFAULT_OPTIONS { true, false };
31
32class DummyClientFace::Transport : public ndn::Transport
33{
34public:
35 void
36 receive(const Block& block)
37 {
38 if (static_cast<bool>(m_receiveCallback))
39 m_receiveCallback(block);
40 }
41
42 virtual void
43 close()
44 {
45 }
46
47 virtual void
48 pause()
49 {
50 }
51
52 virtual void
53 resume()
54 {
55 }
56
57 virtual void
58 send(const Block& wire)
59 {
Junxiao Shi27913b42014-12-23 14:49:38 -070060 onSendBlock(wire);
Junxiao Shia60d9362014-11-12 09:38:21 -070061 }
62
63 virtual void
64 send(const Block& header, const Block& payload)
65 {
Alexander Afanasyevea719672015-02-10 20:25:23 -080066 EncodingBuffer encoder(header.size() + payload.size(), header.size() + payload.size());
67 encoder.appendByteArray(header.wire(), header.size());
68 encoder.appendByteArray(payload.wire(), payload.size());
69
70 this->send(encoder.block());
Junxiao Shia60d9362014-11-12 09:38:21 -070071 }
72
73 boost::asio::io_service&
74 getIoService()
75 {
76 return *m_ioService;
77 }
78
Junxiao Shi27913b42014-12-23 14:49:38 -070079public:
80 Signal<Transport, Block> onSendBlock;
Junxiao Shia60d9362014-11-12 09:38:21 -070081};
82
83DummyClientFace::DummyClientFace(const Options& options, shared_ptr<Transport> transport)
84 : Face(transport)
85 , m_transport(transport)
86{
87 this->construct(options);
88}
89
90DummyClientFace::DummyClientFace(const Options& options, shared_ptr<Transport> transport,
91 boost::asio::io_service& ioService)
92 : Face(transport, ioService)
93 , m_transport(transport)
94{
95 this->construct(options);
96}
97
98void
99DummyClientFace::construct(const Options& options)
100{
Alexander Afanasyevea719672015-02-10 20:25:23 -0800101 m_transport->onSendBlock.connect([this] (const Block& blockFromDaemon) {
102 const Block& block = nfd::LocalControlHeader::getPayload(blockFromDaemon);
103
104 if (block.type() == tlv::Interest) {
105 shared_ptr<Interest> interest = make_shared<Interest>(block);
106 if (&block != &blockFromDaemon)
107 interest->getLocalControlHeader().wireDecode(blockFromDaemon);
108
Junxiao Shi27913b42014-12-23 14:49:38 -0700109 onSendInterest(*interest);
110 }
Alexander Afanasyevea719672015-02-10 20:25:23 -0800111 else if (block.type() == tlv::Data) {
112 shared_ptr<Data> data = make_shared<Data>(block);
113 if (&block != &blockFromDaemon)
114 data->getLocalControlHeader().wireDecode(blockFromDaemon);
115
Junxiao Shi27913b42014-12-23 14:49:38 -0700116 onSendData(*data);
117 }
118 });
119
Junxiao Shia60d9362014-11-12 09:38:21 -0700120 if (options.enablePacketLogging)
121 this->enablePacketLogging();
122
123 if (options.enableRegistrationReply)
124 this->enableRegistrationReply();
125}
126
127void
128DummyClientFace::enablePacketLogging()
129{
Junxiao Shi27913b42014-12-23 14:49:38 -0700130 onSendInterest.connect([this] (const Interest& interest) {
131 this->sentInterests.push_back(interest);
132 });
133 onSendData.connect([this] (const Data& data) {
134 this->sentDatas.push_back(data);
135 });
Junxiao Shia60d9362014-11-12 09:38:21 -0700136}
137
138void
139DummyClientFace::enableRegistrationReply()
140{
Junxiao Shi27913b42014-12-23 14:49:38 -0700141 onSendInterest.connect([this] (const Interest& interest) {
Junxiao Shia60d9362014-11-12 09:38:21 -0700142 static const Name localhostRegistration("/localhost/nfd/rib");
143 if (!localhostRegistration.isPrefixOf(interest.getName()))
144 return;
145
146 nfd::ControlParameters params(interest.getName().get(-5).blockFromValue());
147 params.setFaceId(1);
148 params.setOrigin(0);
149 if (interest.getName().get(3) == name::Component("register")) {
150 params.setCost(0);
151 }
152
153 nfd::ControlResponse resp;
154 resp.setCode(200);
155 resp.setBody(params.wireEncode());
156
157 shared_ptr<Data> data = make_shared<Data>(interest.getName());
158 data->setContent(resp.wireEncode());
159
160 KeyChain keyChain;
161 keyChain.signWithSha256(*data);
162
163 this->getIoService().post([this, data] { this->receive(*data); });
Junxiao Shi27913b42014-12-23 14:49:38 -0700164 });
Junxiao Shia60d9362014-11-12 09:38:21 -0700165}
166
167template<typename Packet>
168void
169DummyClientFace::receive(const Packet& packet)
170{
Alexander Afanasyevea719672015-02-10 20:25:23 -0800171 // do not restrict what injected control header can contain
172 if (!packet.getLocalControlHeader().empty(true, true)) {
173
174 Block header = packet.getLocalControlHeader().wireEncode(packet, true, true);
175 Block payload = packet.wireEncode();
176
177 EncodingBuffer encoder(header.size() + payload.size(), header.size() + payload.size());
178 encoder.appendByteArray(header.wire(), header.size());
179 encoder.appendByteArray(payload.wire(), payload.size());
180
181 m_transport->receive(encoder.block());
182 }
183 else {
184 m_transport->receive(packet.wireEncode());
185 }
Junxiao Shia60d9362014-11-12 09:38:21 -0700186}
187
188template void
189DummyClientFace::receive<Interest>(const Interest& packet);
190
191template void
192DummyClientFace::receive<Data>(const Data& packet);
193
194
195shared_ptr<DummyClientFace>
196makeDummyClientFace(const DummyClientFace::Options& options)
197{
Junxiao Shia1ea5062014-12-27 22:33:39 -0700198 // cannot use make_shared<DummyClientFace> because DummyClientFace constructor is private
Junxiao Shia60d9362014-11-12 09:38:21 -0700199 return shared_ptr<DummyClientFace>(
200 new DummyClientFace(options, make_shared<DummyClientFace::Transport>()));
201}
202
203shared_ptr<DummyClientFace>
204makeDummyClientFace(boost::asio::io_service& ioService,
205 const DummyClientFace::Options& options)
206{
Junxiao Shia1ea5062014-12-27 22:33:39 -0700207 // cannot use make_shared<DummyClientFace> because DummyClientFace constructor is private
Junxiao Shia60d9362014-11-12 09:38:21 -0700208 return shared_ptr<DummyClientFace>(
209 new DummyClientFace(options, make_shared<DummyClientFace::Transport>(),
210 ref(ioService)));
211}
212
213} // namespace util
214} // namespace ndn