blob: dece82857989fe84601b79c97f9efe81722ac9ce [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"
Jeff Thompsonb982b6d2013-07-15 18:15:45 -070031
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070032namespace ndn {
Alexander Afanasyevb790d952014-01-24 12:07:53 -080033
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080034Face::Face()
Junxiao Shi2cced062014-11-02 21:27:38 -070035 : m_internalIoService(new boost::asio::io_service())
36 , m_ioService(*m_internalIoService)
37 , m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070038 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070039 , m_impl(new Impl(*this))
Jeff Thompsonfb29cda2013-08-24 10:26:54 -070040{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070041 const std::string socketName = UnixTransport::getDefaultSocketName(m_impl->m_config);
Alexander Afanasyevf73f0632014-05-12 18:02:37 -070042 construct(make_shared<UnixTransport>(socketName),
Junxiao Shiedd834e2014-10-28 20:28:58 -070043 m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080044}
45
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070046Face::Face(boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070047 : m_ioService(ioService)
48 , m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070049 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070050 , m_impl(new Impl(*this))
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070051{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070052 const std::string socketName = UnixTransport::getDefaultSocketName(m_impl->m_config);
Alexander Afanasyevf73f0632014-05-12 18:02:37 -070053 construct(make_shared<UnixTransport>(socketName),
Junxiao Shiedd834e2014-10-28 20:28:58 -070054 m_internalKeyChain);
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070055}
56
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080057Face::Face(const std::string& host, const std::string& port/* = "6363"*/)
Junxiao Shi2cced062014-11-02 21:27:38 -070058 : m_internalIoService(new boost::asio::io_service())
59 , m_ioService(*m_internalIoService)
60 , m_internalKeyChain(new KeyChain())
Junxiao Shiedd834e2014-10-28 20:28:58 -070061 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080062{
Alexander Afanasyevf73f0632014-05-12 18:02:37 -070063 construct(make_shared<TcpTransport>(host, port),
Junxiao Shiedd834e2014-10-28 20:28:58 -070064 m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080065}
66
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080067Face::Face(const shared_ptr<Transport>& transport)
Junxiao Shi2cced062014-11-02 21:27:38 -070068 : m_internalIoService(new boost::asio::io_service())
69 , m_ioService(*m_internalIoService)
70 , m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070071 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070072 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080073{
74 construct(transport,
Junxiao Shiedd834e2014-10-28 20:28:58 -070075 m_internalKeyChain);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080076}
77
78Face::Face(const shared_ptr<Transport>& transport,
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070079 boost::asio::io_service& ioService)
Junxiao Shi2cced062014-11-02 21:27:38 -070080 : m_ioService(ioService)
81 , m_internalKeyChain(new KeyChain())
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070082 , m_isDirectNfdFibManagementRequested(false)
Junxiao Shiedd834e2014-10-28 20:28:58 -070083 , m_impl(new Impl(*this))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080084{
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070085 construct(transport,
Junxiao Shiedd834e2014-10-28 20:28:58 -070086 m_internalKeyChain);
87}
88
89Face::Face(shared_ptr<Transport> transport,
90 boost::asio::io_service& ioService,
91 KeyChain& keyChain)
Junxiao Shi2cced062014-11-02 21:27:38 -070092 : m_ioService(ioService)
93 , m_internalKeyChain(nullptr)
Junxiao Shiedd834e2014-10-28 20:28:58 -070094 , m_isDirectNfdFibManagementRequested(false)
95 , m_impl(new Impl(*this))
96{
97 construct(transport,
Junxiao Shiedd834e2014-10-28 20:28:58 -070098 &keyChain);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080099}
100
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800101void
Junxiao Shiedd834e2014-10-28 20:28:58 -0700102Face::construct(shared_ptr<Transport> transport,
Junxiao Shiedd834e2014-10-28 20:28:58 -0700103 KeyChain* keyChain)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800104{
Junxiao Shiedd834e2014-10-28 20:28:58 -0700105 m_nfdController = new nfd::Controller(*this, *keyChain);
106
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700107 m_impl->m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800108 m_transport = transport;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800109
Junxiao Shi2cced062014-11-02 21:27:38 -0700110 m_impl->m_pitTimeoutCheckTimer = make_shared<monotonic_deadline_timer>(ref(m_ioService));
111 m_impl->m_processEventsTimeoutTimer = make_shared<monotonic_deadline_timer>(ref(m_ioService));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800112
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600113 std::string protocol = "nrd-0.1";
114
115 try
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -0800116 {
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700117 protocol = m_impl->m_config.getParsedConfiguration().get<std::string>("protocol");
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600118 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700119 catch (boost::property_tree::ptree_bad_path& error)
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600120 {
121 // protocol not specified
122 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700123 catch (boost::property_tree::ptree_bad_data& error)
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600124 {
125 throw ConfigFile::Error(error.what());
126 }
127
128 if (isSupportedNrdProtocol(protocol))
129 {
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700130 // do nothing
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600131 }
Steve DiBenedettoacab8802014-03-24 11:15:57 -0600132 else if (isSupportedNfdProtocol(protocol))
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600133 {
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700134 m_isDirectNfdFibManagementRequested = true;
Alexander Afanasyevefe3ab22014-02-19 14:57:50 -0800135 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700136 else
Steve DiBenedettoc07b3a22014-03-19 12:32:52 -0600137 {
138 throw Face::Error("Cannot create controller for unsupported protocol \"" + protocol + "\"");
139 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800140}
141
Junxiao Shiedd834e2014-10-28 20:28:58 -0700142Face::~Face()
143{
144 if (m_internalKeyChain != nullptr) {
145 delete m_internalKeyChain;
146 }
147
148 delete m_nfdController;
149 delete m_impl;
150}
151
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800152const PendingInterestId*
153Face::expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout)
154{
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700155 shared_ptr<Interest> interestToExpress = make_shared<Interest>(interest);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800156
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700157 // Use `interestToExpress` to avoid wire format creation for the original Interest
158 if (interestToExpress->wireEncode().size() > MAX_NDN_PACKET_SIZE)
159 throw Error("Interest size exceeds maximum limit");
160
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700161 // If the same ioService thread, dispatch directly calls the method
Junxiao Shi2cced062014-11-02 21:27:38 -0700162 m_ioService.dispatch(bind(&Impl::asyncExpressInterest, m_impl,
163 interestToExpress, onData, onTimeout));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800164
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800165 return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
166}
167
168const PendingInterestId*
169Face::expressInterest(const Name& name,
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800170 const Interest& tmpl,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800171 const OnData& onData, const OnTimeout& onTimeout/* = OnTimeout()*/)
172{
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700173 return expressInterest(Interest(tmpl)
174 .setName(name)
175 .setNonce(0),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800176 onData, onTimeout);
177}
178
179void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800180Face::put(const Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800181{
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700182 // Use original `data`, since wire format should already exist for the original Data
183 if (data.wireEncode().size() > MAX_NDN_PACKET_SIZE)
184 throw Error("Data size exceeds maximum limit");
185
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700186 shared_ptr<const Data> dataPtr;
187 try {
188 dataPtr = data.shared_from_this();
189 }
190 catch (const bad_weak_ptr& e) {
191 std::cerr << "Face::put WARNING: the supplied Data should be created using make_shared<Data>()"
192 << std::endl;
193 dataPtr = make_shared<Data>(data);
194 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800195
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700196 // If the same ioService thread, dispatch directly calls the method
Junxiao Shi2cced062014-11-02 21:27:38 -0700197 m_ioService.dispatch(bind(&Impl::asyncPutData, m_impl, dataPtr));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800198}
199
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800200void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800201Face::removePendingInterest(const PendingInterestId* pendingInterestId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800202{
Junxiao Shi2cced062014-11-02 21:27:38 -0700203 m_ioService.post(bind(&Impl::asyncRemovePendingInterest, m_impl, pendingInterestId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800204}
205
Alexander Afanasyev6fcdde22014-08-22 19:03:36 -0700206size_t
207Face::getNPendingInterests() const
208{
209 return m_impl->m_pendingInterestTable.size();
210}
211
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800212const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000213Face::setInterestFilter(const InterestFilter& interestFilter,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800214 const OnInterest& onInterest,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700215 const RegisterPrefixSuccessCallback& onSuccess,
216 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700217 const IdentityCertificate& certificate,
218 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700219{
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700220 shared_ptr<InterestFilterRecord> filter =
221 make_shared<InterestFilterRecord>(interestFilter, onInterest);
222
Junxiao Shi388ec252014-11-02 15:19:57 -0700223 nfd::CommandOptions options;
224 if (certificate.getName().empty()) {
225 options.setSigningDefault();
226 }
227 else {
228 options.setSigningCertificate(certificate);
229 }
230
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700231 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
232 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700233 flags, options);
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700234}
235
236const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000237Face::setInterestFilter(const InterestFilter& interestFilter,
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700238 const OnInterest& onInterest,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700239 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700240 const IdentityCertificate& certificate,
241 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700242{
243 shared_ptr<InterestFilterRecord> filter =
244 make_shared<InterestFilterRecord>(interestFilter, onInterest);
245
Junxiao Shi388ec252014-11-02 15:19:57 -0700246 nfd::CommandOptions options;
247 if (certificate.getName().empty()) {
248 options.setSigningDefault();
249 }
250 else {
251 options.setSigningCertificate(certificate);
252 }
253
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700254 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
255 RegisterPrefixSuccessCallback(), onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700256 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700257}
258
259const RegisteredPrefixId*
260Face::setInterestFilter(const InterestFilter& interestFilter,
261 const OnInterest& onInterest,
262 const RegisterPrefixSuccessCallback& onSuccess,
263 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700264 const Name& identity,
265 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700266{
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700267 shared_ptr<InterestFilterRecord> filter =
268 make_shared<InterestFilterRecord>(interestFilter, onInterest);
269
Junxiao Shi388ec252014-11-02 15:19:57 -0700270 nfd::CommandOptions options;
271 options.setSigningIdentity(identity);
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);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700276}
277
278const RegisteredPrefixId*
279Face::setInterestFilter(const InterestFilter& interestFilter,
280 const OnInterest& onInterest,
281 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700282 const Name& identity,
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 options.setSigningIdentity(identity);
290
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700291 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
292 RegisterPrefixSuccessCallback(), onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700293 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700294}
295
296
297const InterestFilterId*
298Face::setInterestFilter(const InterestFilter& interestFilter,
299 const OnInterest& onInterest)
300{
301 shared_ptr<InterestFilterRecord> filter =
302 make_shared<InterestFilterRecord>(interestFilter, onInterest);
303
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700304 getIoService().post(bind(&Impl::asyncSetInterestFilter, m_impl, filter));
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700305
306 return reinterpret_cast<const InterestFilterId*>(filter.get());
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700307}
308
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700309const RegisteredPrefixId*
310Face::registerPrefix(const Name& prefix,
311 const RegisterPrefixSuccessCallback& onSuccess,
312 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700313 const IdentityCertificate& certificate,
314 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700315{
Junxiao Shi388ec252014-11-02 15:19:57 -0700316 nfd::CommandOptions options;
317 if (certificate.getName().empty()) {
318 options.setSigningDefault();
319 }
320 else {
321 options.setSigningCertificate(certificate);
322 }
323
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700324 return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
325 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700326 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700327}
328
329const RegisteredPrefixId*
330Face::registerPrefix(const Name& prefix,
331 const RegisterPrefixSuccessCallback& onSuccess,
332 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700333 const Name& identity,
334 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700335{
Junxiao Shi388ec252014-11-02 15:19:57 -0700336 nfd::CommandOptions options;
337 options.setSigningIdentity(identity);
338
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700339 return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
340 onSuccess, onFailure,
Junxiao Shi388ec252014-11-02 15:19:57 -0700341 flags, options);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700342}
343
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700344void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800345Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800346{
Junxiao Shi2cced062014-11-02 21:27:38 -0700347 m_ioService.post(bind(&Impl::asyncUnregisterPrefix, m_impl, registeredPrefixId,
348 UnregisterPrefixSuccessCallback(), UnregisterPrefixFailureCallback()));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800349}
350
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700351void
352Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
353{
Junxiao Shi2cced062014-11-02 21:27:38 -0700354 m_ioService.post(bind(&Impl::asyncUnsetInterestFilter, m_impl, interestFilterId));
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700355}
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700356
357void
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700358Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
359 const UnregisterPrefixSuccessCallback& onSuccess,
360 const UnregisterPrefixFailureCallback& onFailure)
361{
Junxiao Shi2cced062014-11-02 21:27:38 -0700362 m_ioService.post(bind(&Impl::asyncUnregisterPrefix, m_impl, registeredPrefixId,
363 onSuccess, onFailure));
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700364}
365
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800366void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700367Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
368 bool keepThread/* = false*/)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800369{
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700370 try {
371 if (timeout < time::milliseconds::zero())
372 {
373 // do not block if timeout is negative, but process pending events
Junxiao Shi2cced062014-11-02 21:27:38 -0700374 m_ioService.poll();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700375 return;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800376 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800377
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700378 if (timeout > time::milliseconds::zero())
379 {
380 m_impl->m_processEventsTimeoutTimer->expires_from_now(time::milliseconds(timeout));
381 m_impl->m_processEventsTimeoutTimer->async_wait(&fireProcessEventsTimeout);
382 }
383
384 if (keepThread) {
385 // work will ensure that m_ioService is running until work object exists
Junxiao Shi2cced062014-11-02 21:27:38 -0700386 m_impl->m_ioServiceWork = make_shared<boost::asio::io_service::work>(ref(m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800387 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700388
Junxiao Shi2cced062014-11-02 21:27:38 -0700389 m_ioService.run();
390 m_ioService.reset(); // so it is possible to run processEvents again (if necessary)
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700391 }
392 catch (Face::ProcessEventsTimeout&) {
393 // break
394 m_impl->m_ioServiceWork.reset();
Junxiao Shi2cced062014-11-02 21:27:38 -0700395 m_ioService.reset();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700396 }
397 catch (...) {
398 m_impl->m_ioServiceWork.reset();
Junxiao Shi2cced062014-11-02 21:27:38 -0700399 m_ioService.reset();
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700400 m_impl->m_pendingInterestTable.clear();
401 m_impl->m_registeredPrefixTable.clear();
402 throw;
403 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700404}
405
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800406void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700407Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700408{
Junxiao Shi2cced062014-11-02 21:27:38 -0700409 m_ioService.post(bind(&Face::asyncShutdown, this));
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700410}
411
412void
413Face::asyncShutdown()
414{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700415 m_impl->m_pendingInterestTable.clear();
416 m_impl->m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800417
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700418 if (m_transport->isConnected())
419 m_transport->close();
420
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700421 m_impl->m_pitTimeoutCheckTimer->cancel();
422 m_impl->m_processEventsTimeoutTimer->cancel();
423 m_impl->m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyev1f5486e2014-07-10 17:45:49 -0700424
425 m_impl->m_ioServiceWork.reset();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700426}
427
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800428void
429Face::fireProcessEventsTimeout(const boost::system::error_code& error)
430{
431 if (!error) // can fire for some other reason, e.g., cancelled
432 throw Face::ProcessEventsTimeout();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700433}
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800434
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800435
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800436void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800437Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800438{
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800439 const Block& block = nfd::LocalControlHeader::getPayload(blockFromDaemon);
440
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600441 if (block.type() == tlv::Interest)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800442 {
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700443 shared_ptr<Interest> interest = make_shared<Interest>();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800444 interest->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800445 if (&block != &blockFromDaemon)
446 interest->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800447
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700448 m_impl->processInterestFilters(*interest);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800449 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600450 else if (block.type() == tlv::Data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800451 {
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700452 shared_ptr<Data> data = make_shared<Data>();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800453 data->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800454 if (&block != &blockFromDaemon)
455 data->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800456
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700457 m_impl->satisfyPendingInterests(*data);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800458
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700459 if (m_impl->m_pendingInterestTable.empty()) {
460 m_impl->m_pitTimeoutCheckTimer->cancel(); // this will cause checkPitExpire invocation
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800461 }
462 }
Yingdi Yuf9fa52f2014-02-06 12:27:32 -0800463 // ignore any other type
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800464}
465
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800466
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800467
468} // namespace ndn