blob: 57f9605e480e05bedcb0870bea65c026781090ba [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -07002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * 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.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * Based on code originally written by Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070022 */
23
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080024#include "face.hpp"
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070025#include "detail/face-impl.hpp"
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070026
Junxiao Shi468abc32014-11-04 09:12:47 -070027#include "encoding/tlv.hpp"
Junxiao Shiedd834e2014-10-28 20:28:58 -070028#include "security/key-chain.hpp"
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080029#include "util/time.hpp"
30#include "util/random.hpp"
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070031#include "util/face-uri.hpp"
Jeff Thompsonb982b6d2013-07-15 18:15:45 -070032
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070033namespace ndn {
Alexander Afanasyevb790d952014-01-24 12:07:53 -080034
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080035Face::Face()
Junxiao Shi2cced062014-11-02 21:27:38 -070036 : m_internalIoService(new boost::asio::io_service())
37 , m_ioService(*m_internalIoService)
38 , m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070039 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070040 , m_impl(new Impl(*this))
Jeff Thompsonfb29cda2013-08-24 10:26:54 -070041{
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070042 construct(m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080043}
44
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070045Face::Face(boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070046 : m_ioService(ioService)
47 , m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070048 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070049 , m_impl(new Impl(*this))
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070050{
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070051 construct(m_internalKeyChain);
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070052}
53
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080054Face::Face(const std::string& host, const std::string& port/* = "6363"*/)
Junxiao Shi2cced062014-11-02 21:27:38 -070055 : m_internalIoService(new boost::asio::io_service())
56 , m_ioService(*m_internalIoService)
57 , m_internalKeyChain(new KeyChain())
Junxiao Shiedd834e2014-10-28 20:28:58 -070058 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080059{
Alexander Afanasyevf73f0632014-05-12 18:02:37 -070060 construct(make_shared<TcpTransport>(host, port),
Junxiao Shiedd834e2014-10-28 20:28:58 -070061 m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080062}
63
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080064Face::Face(const shared_ptr<Transport>& transport)
Junxiao Shi2cced062014-11-02 21:27:38 -070065 : m_internalIoService(new boost::asio::io_service())
66 , m_ioService(*m_internalIoService)
67 , m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070068 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070069 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080070{
71 construct(transport,
Junxiao Shiedd834e2014-10-28 20:28:58 -070072 m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080073}
74
75Face::Face(const shared_ptr<Transport>& transport,
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070076 boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070077 : m_ioService(ioService)
78 , m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070079 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070080 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080081{
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070082 construct(transport,
Junxiao Shiedd834e2014-10-28 20:28:58 -070083 m_internalKeyChain);
84}
85
86Face::Face(shared_ptr<Transport> transport,
87 boost::asio::io_service& ioService,
88 KeyChain& keyChain)
Junxiao Shi2cced062014-11-02 21:27:38 -070089 : m_ioService(ioService)
90 , m_internalKeyChain(nullptr)
Junxiao Shiedd834e2014-10-28 20:28:58 -070091 , m_isDirectNfdFibManagementRequested(false)
92 , m_impl(new Impl(*this))
93{
94 construct(transport,
Junxiao Shiedd834e2014-10-28 20:28:58 -070095 &keyChain);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080096}
97
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080098void
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -070099Face::construct(KeyChain* keyChain)
100{
101 // transport=unix:///var/run/nfd.sock
102 // transport=tcp://localhost:6363
103
104 const ConfigFile::Parsed& parsed = m_impl->m_config.getParsedConfiguration();
105
106 const auto transportType = parsed.get_optional<std::string>("transport");
107 if (!transportType)
108 {
109 // transport not specified, use default Unix transport.
110 construct(UnixTransport::create(m_impl->m_config), keyChain);
111 return;
112 }
113
114 unique_ptr<util::FaceUri> uri;
115 try
116 {
117 uri.reset(new util::FaceUri(*transportType));
118 }
119 catch (const util::FaceUri::Error& error)
120 {
121 throw ConfigFile::Error(error.what());
122 }
123
124 shared_ptr<Transport> transport;
125 const std::string protocol = uri->getScheme();
126
127 if (protocol == "unix")
128 {
129 construct(UnixTransport::create(m_impl->m_config), keyChain);
130
131 }
132 else if (protocol == "tcp" || protocol == "tcp4" || protocol == "tcp6")
133 {
134 construct(TcpTransport::create(m_impl->m_config), keyChain);
135 }
136 else
137 {
138 throw ConfigFile::Error("Unsupported transport protocol \"" + protocol + "\"");
139 }
140}
141
142void
Junxiao Shiedd834e2014-10-28 20:28:58 -0700143Face::construct(shared_ptr<Transport> transport,
Junxiao Shiedd834e2014-10-28 20:28:58 -0700144 KeyChain* keyChain)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800145{
Junxiao Shiedd834e2014-10-28 20:28:58 -0700146 m_nfdController = new nfd::Controller(*this, *keyChain);
147
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700148 m_impl->m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800149 m_transport = transport;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800150
Junxiao Shi2cced062014-11-02 21:27:38 -0700151 m_impl->m_pitTimeoutCheckTimer = make_shared<monotonic_deadline_timer>(ref(m_ioService));
152 m_impl->m_processEventsTimeoutTimer = make_shared<monotonic_deadline_timer>(ref(m_ioService));
Junxiao Shia1ea5062014-12-27 22:33:39 -0700153 m_impl->ensureConnected(false);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800154
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600155 std::string protocol = "nrd-0.1";
156
157 try
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -0800158 {
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700159 protocol = m_impl->m_config.getParsedConfiguration().get<std::string>("protocol");
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600160 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700161 catch (boost::property_tree::ptree_bad_path& error)
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600162 {
163 // protocol not specified
164 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700165 catch (boost::property_tree::ptree_bad_data& error)
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600166 {
167 throw ConfigFile::Error(error.what());
168 }
169
170 if (isSupportedNrdProtocol(protocol))
171 {
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700172 // do nothing
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600173 }
Steve DiBenedettoacab8802014-03-24 11:15:57 -0600174 else if (isSupportedNfdProtocol(protocol))
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600175 {
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700176 m_isDirectNfdFibManagementRequested = true;
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -0800177 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700178 else
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600179 {
180 throw Face::Error("Cannot create controller for unsupported protocol \"" + protocol + "\"");
181 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800182}
183
Junxiao Shiedd834e2014-10-28 20:28:58 -0700184Face::~Face()
185{
186 if (m_internalKeyChain != nullptr) {
187 delete m_internalKeyChain;
188 }
189
190 delete m_nfdController;
191 delete m_impl;
192}
193
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800194const PendingInterestId*
195Face::expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout)
196{
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700197 shared_ptr<Interest> interestToExpress = make_shared<Interest>(interest);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800198
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700199 // Use `interestToExpress` to avoid wire format creation for the original Interest
200 if (interestToExpress->wireEncode().size() > MAX_NDN_PACKET_SIZE)
201 throw Error("Interest size exceeds maximum limit");
202
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700203 // If the same ioService thread, dispatch directly calls the method
Junxiao Shi2cced062014-11-02 21:27:38 -0700204 m_ioService.dispatch(bind(&Impl::asyncExpressInterest, m_impl,
205 interestToExpress, onData, onTimeout));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800206
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800207 return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
208}
209
210const PendingInterestId*
211Face::expressInterest(const Name& name,
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800212 const Interest& tmpl,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800213 const OnData& onData, const OnTimeout& onTimeout/* = OnTimeout()*/)
214{
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700215 return expressInterest(Interest(tmpl)
Steve DiBenedettoa8659ff2014-12-04 14:50:28 -0700216 .setName(name)
217 .setNonce(0),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800218 onData, onTimeout);
219}
220
221void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800222Face::put(const Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800223{
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700224 // Use original `data`, since wire format should already exist for the original Data
225 if (data.wireEncode().size() > MAX_NDN_PACKET_SIZE)
226 throw Error("Data size exceeds maximum limit");
227
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700228 shared_ptr<const Data> dataPtr;
229 try {
230 dataPtr = data.shared_from_this();
231 }
232 catch (const bad_weak_ptr& e) {
233 std::cerr << "Face::put WARNING: the supplied Data should be created using make_shared<Data>()"
234 << std::endl;
235 dataPtr = make_shared<Data>(data);
236 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800237
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700238 // If the same ioService thread, dispatch directly calls the method
Junxiao Shi2cced062014-11-02 21:27:38 -0700239 m_ioService.dispatch(bind(&Impl::asyncPutData, m_impl, dataPtr));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800240}
241
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800242void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800243Face::removePendingInterest(const PendingInterestId* pendingInterestId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800244{
Junxiao Shi2cced062014-11-02 21:27:38 -0700245 m_ioService.post(bind(&Impl::asyncRemovePendingInterest, m_impl, pendingInterestId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800246}
247
Alexander Afanasyev6fcdde22014-08-22 19:03:36 -0700248size_t
249Face::getNPendingInterests() const
250{
251 return m_impl->m_pendingInterestTable.size();
252}
253
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800254const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000255Face::setInterestFilter(const InterestFilter& interestFilter,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800256 const OnInterest& onInterest,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700257 const RegisterPrefixSuccessCallback& onSuccess,
258 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700259 const IdentityCertificate& certificate,
260 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700261{
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700262 shared_ptr<InterestFilterRecord> filter =
263 make_shared<InterestFilterRecord>(interestFilter, onInterest);
264
Junxiao Shi388ec252014-11-02 15:19:57 -0700265 nfd::CommandOptions options;
266 if (certificate.getName().empty()) {
267 options.setSigningDefault();
268 }
269 else {
270 options.setSigningCertificate(certificate);
271 }
272
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700273 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
274 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700275 flags, options);
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700276}
277
278const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000279Face::setInterestFilter(const InterestFilter& interestFilter,
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700280 const OnInterest& onInterest,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700281 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700282 const IdentityCertificate& certificate,
283 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700284{
285 shared_ptr<InterestFilterRecord> filter =
286 make_shared<InterestFilterRecord>(interestFilter, onInterest);
287
Junxiao Shi388ec252014-11-02 15:19:57 -0700288 nfd::CommandOptions options;
289 if (certificate.getName().empty()) {
290 options.setSigningDefault();
291 }
292 else {
293 options.setSigningCertificate(certificate);
294 }
295
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700296 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
297 RegisterPrefixSuccessCallback(), onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700298 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700299}
300
301const RegisteredPrefixId*
302Face::setInterestFilter(const InterestFilter& interestFilter,
303 const OnInterest& onInterest,
304 const RegisterPrefixSuccessCallback& onSuccess,
305 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700306 const Name& identity,
307 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700308{
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700309 shared_ptr<InterestFilterRecord> filter =
310 make_shared<InterestFilterRecord>(interestFilter, onInterest);
311
Junxiao Shi388ec252014-11-02 15:19:57 -0700312 nfd::CommandOptions options;
313 options.setSigningIdentity(identity);
314
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700315 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
316 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700317 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700318}
319
320const RegisteredPrefixId*
321Face::setInterestFilter(const InterestFilter& interestFilter,
322 const OnInterest& onInterest,
323 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700324 const Name& identity,
325 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700326{
327 shared_ptr<InterestFilterRecord> filter =
328 make_shared<InterestFilterRecord>(interestFilter, onInterest);
329
Junxiao Shi388ec252014-11-02 15:19:57 -0700330 nfd::CommandOptions options;
331 options.setSigningIdentity(identity);
332
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700333 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
334 RegisterPrefixSuccessCallback(), onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700335 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700336}
337
338
339const InterestFilterId*
340Face::setInterestFilter(const InterestFilter& interestFilter,
341 const OnInterest& onInterest)
342{
343 shared_ptr<InterestFilterRecord> filter =
344 make_shared<InterestFilterRecord>(interestFilter, onInterest);
345
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700346 getIoService().post(bind(&Impl::asyncSetInterestFilter, m_impl, filter));
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700347
348 return reinterpret_cast<const InterestFilterId*>(filter.get());
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700349}
350
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700351const RegisteredPrefixId*
352Face::registerPrefix(const Name& prefix,
353 const RegisterPrefixSuccessCallback& onSuccess,
354 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700355 const IdentityCertificate& certificate,
356 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700357{
Junxiao Shi388ec252014-11-02 15:19:57 -0700358 nfd::CommandOptions options;
359 if (certificate.getName().empty()) {
360 options.setSigningDefault();
361 }
362 else {
363 options.setSigningCertificate(certificate);
364 }
365
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700366 return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
367 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700368 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700369}
370
371const RegisteredPrefixId*
372Face::registerPrefix(const Name& prefix,
373 const RegisterPrefixSuccessCallback& onSuccess,
374 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700375 const Name& identity,
376 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700377{
Junxiao Shi388ec252014-11-02 15:19:57 -0700378 nfd::CommandOptions options;
379 options.setSigningIdentity(identity);
380
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700381 return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
382 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700383 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700384}
385
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700386void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800387Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800388{
Junxiao Shi2cced062014-11-02 21:27:38 -0700389 m_ioService.post(bind(&Impl::asyncUnregisterPrefix, m_impl, registeredPrefixId,
390 UnregisterPrefixSuccessCallback(), UnregisterPrefixFailureCallback()));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800391}
392
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700393void
394Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
395{
Junxiao Shi2cced062014-11-02 21:27:38 -0700396 m_ioService.post(bind(&Impl::asyncUnsetInterestFilter, m_impl, interestFilterId));
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700397}
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700398
399void
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700400Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
401 const UnregisterPrefixSuccessCallback& onSuccess,
402 const UnregisterPrefixFailureCallback& onFailure)
403{
Junxiao Shi2cced062014-11-02 21:27:38 -0700404 m_ioService.post(bind(&Impl::asyncUnregisterPrefix, m_impl, registeredPrefixId,
405 onSuccess, onFailure));
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700406}
407
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800408void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700409Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
410 bool keepThread/* = false*/)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800411{
Alexander Afanasyev8e158542014-11-18 00:47:18 -0500412 if (m_ioService.stopped()) {
413 m_ioService.reset(); // ensure that run()/poll() will do some work
414 }
415
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700416 try {
417 if (timeout < time::milliseconds::zero())
418 {
419 // do not block if timeout is negative, but process pending events
Junxiao Shi2cced062014-11-02 21:27:38 -0700420 m_ioService.poll();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700421 return;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800422 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800423
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700424 if (timeout > time::milliseconds::zero())
425 {
426 m_impl->m_processEventsTimeoutTimer->expires_from_now(time::milliseconds(timeout));
427 m_impl->m_processEventsTimeoutTimer->async_wait(&fireProcessEventsTimeout);
428 }
429
430 if (keepThread) {
431 // work will ensure that m_ioService is running until work object exists
Junxiao Shi2cced062014-11-02 21:27:38 -0700432 m_impl->m_ioServiceWork = make_shared<boost::asio::io_service::work>(ref(m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800433 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700434
Junxiao Shi2cced062014-11-02 21:27:38 -0700435 m_ioService.run();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700436 }
437 catch (Face::ProcessEventsTimeout&) {
438 // break
439 m_impl->m_ioServiceWork.reset();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700440 }
441 catch (...) {
442 m_impl->m_ioServiceWork.reset();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700443 m_impl->m_pendingInterestTable.clear();
444 m_impl->m_registeredPrefixTable.clear();
445 throw;
446 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700447}
448
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800449void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700450Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700451{
Junxiao Shi2cced062014-11-02 21:27:38 -0700452 m_ioService.post(bind(&Face::asyncShutdown, this));
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700453}
454
455void
456Face::asyncShutdown()
457{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700458 m_impl->m_pendingInterestTable.clear();
459 m_impl->m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800460
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700461 if (m_transport->isConnected())
462 m_transport->close();
463
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700464 m_impl->m_pitTimeoutCheckTimer->cancel();
465 m_impl->m_processEventsTimeoutTimer->cancel();
466 m_impl->m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyev1f5486e2014-07-10 17:45:49 -0700467
468 m_impl->m_ioServiceWork.reset();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700469}
470
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800471void
472Face::fireProcessEventsTimeout(const boost::system::error_code& error)
473{
474 if (!error) // can fire for some other reason, e.g., cancelled
475 throw Face::ProcessEventsTimeout();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700476}
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800477
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800478
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800479void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800480Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800481{
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800482 const Block& block = nfd::LocalControlHeader::getPayload(blockFromDaemon);
483
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600484 if (block.type() == tlv::Interest)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800485 {
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700486 shared_ptr<Interest> interest = make_shared<Interest>();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800487 interest->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800488 if (&block != &blockFromDaemon)
489 interest->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800490
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700491 m_impl->processInterestFilters(*interest);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800492 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600493 else if (block.type() == tlv::Data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800494 {
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700495 shared_ptr<Data> data = make_shared<Data>();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800496 data->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800497 if (&block != &blockFromDaemon)
498 data->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800499
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700500 m_impl->satisfyPendingInterests(*data);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800501
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700502 if (m_impl->m_pendingInterestTable.empty()) {
503 m_impl->m_pitTimeoutCheckTimer->cancel(); // this will cause checkPitExpire invocation
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800504 }
505 }
Yingdi Yuf9fa52f2014-02-06 12:27:32 -0800506 // ignore any other type
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800507}
508
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800509
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800510
511} // namespace ndn