blob: 42fc522d3fca06620be746bfe22eb804e6c1ea90 [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
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070027#include "interest.hpp"
28#include "data.hpp"
29#include "security/identity-certificate.hpp"
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080030
31#include "util/time.hpp"
32#include "util/random.hpp"
Jeff Thompsonb982b6d2013-07-15 18:15:45 -070033
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -070034namespace ndn {
Alexander Afanasyevb790d952014-01-24 12:07:53 -080035
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080036Face::Face()
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070037 : m_nfdController(new nfd::Controller(*this))
38 , m_isDirectNfdFibManagementRequested(false)
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070039 , m_impl(make_shared<Impl>(ref(*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),
Alexander Afanasyev505646e2014-02-24 20:13:37 -080043 make_shared<boost::asio::io_service>());
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080044}
45
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080046Face::Face(const shared_ptr<boost::asio::io_service>& ioService)
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070047 : m_nfdController(new nfd::Controller(*this))
48 , m_isDirectNfdFibManagementRequested(false)
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070049 , m_impl(make_shared<Impl>(ref(*this)))
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080050{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070051 const std::string socketName = UnixTransport::getDefaultSocketName(m_impl->m_config);
Alexander Afanasyevf73f0632014-05-12 18:02:37 -070052 construct(make_shared<UnixTransport>(socketName),
Alexander Afanasyev505646e2014-02-24 20:13:37 -080053 ioService);
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080054}
55
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070056class NullIoDeleter
57{
58public:
59 void
60 operator()(boost::asio::io_service*)
61 {
62 }
63};
64
65Face::Face(boost::asio::io_service& ioService)
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070066 : m_nfdController(make_shared<nfd::Controller>(ref(*this)))
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070067 , m_isDirectNfdFibManagementRequested(false)
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070068 , m_impl(make_shared<Impl>(ref(*this)))
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070069{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070070 const std::string socketName = UnixTransport::getDefaultSocketName(m_impl->m_config);
Alexander Afanasyevf73f0632014-05-12 18:02:37 -070071 construct(make_shared<UnixTransport>(socketName),
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070072 shared_ptr<boost::asio::io_service>(&ioService, NullIoDeleter()));
73}
74
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -080075Face::Face(const std::string& host, const std::string& port/* = "6363"*/)
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070076 : m_nfdController(make_shared<nfd::Controller>(ref(*this)))
77 , m_impl(make_shared<Impl>(ref(*this)))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080078{
Alexander Afanasyevf73f0632014-05-12 18:02:37 -070079 construct(make_shared<TcpTransport>(host, port),
Alexander Afanasyev505646e2014-02-24 20:13:37 -080080 make_shared<boost::asio::io_service>());
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080081}
82
Alexander Afanasyevf7ca3202014-02-14 22:28:31 -080083Face::Face(const shared_ptr<Transport>& transport)
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070084 : m_nfdController(make_shared<nfd::Controller>(ref(*this)))
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070085 , m_isDirectNfdFibManagementRequested(false)
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070086 , m_impl(make_shared<Impl>(ref(*this)))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080087{
88 construct(transport,
Alexander Afanasyev505646e2014-02-24 20:13:37 -080089 make_shared<boost::asio::io_service>());
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080090}
91
92Face::Face(const shared_ptr<Transport>& transport,
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070093 boost::asio::io_service& ioService)
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070094 : m_nfdController(make_shared<nfd::Controller>(ref(*this)))
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070095 , m_isDirectNfdFibManagementRequested(false)
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070096 , m_impl(make_shared<Impl>(ref(*this)))
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080097{
Alexander Afanasyev691c3ce2014-04-23 14:28:04 -070098 construct(transport,
99 shared_ptr<boost::asio::io_service>(&ioService, NullIoDeleter()));
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800100}
101
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800102void
103Face::construct(const shared_ptr<Transport>& transport,
Alexander Afanasyev505646e2014-02-24 20:13:37 -0800104 const shared_ptr<boost::asio::io_service>& ioService)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800105{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700106 m_impl->m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyevf39c5372014-02-17 19:42:56 -0800107 m_transport = transport;
108 m_ioService = ioService;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800109
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -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
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800142const PendingInterestId*
143Face::expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout)
144{
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700145 shared_ptr<Interest> interestToExpress = make_shared<Interest>(interest);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800146
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700147 // Use `interestToExpress` to avoid wire format creation for the original Interest
148 if (interestToExpress->wireEncode().size() > MAX_NDN_PACKET_SIZE)
149 throw Error("Interest size exceeds maximum limit");
150
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700151 // If the same ioService thread, dispatch directly calls the method
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700152 m_ioService->dispatch(bind(&Impl::asyncExpressInterest, m_impl,
Alexander Afanasyev4e50b972014-03-25 10:57:50 -0700153 interestToExpress, onData, onTimeout));
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800154
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800155 return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
156}
157
158const PendingInterestId*
159Face::expressInterest(const Name& name,
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800160 const Interest& tmpl,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800161 const OnData& onData, const OnTimeout& onTimeout/* = OnTimeout()*/)
162{
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700163 return expressInterest(Interest(tmpl)
164 .setName(name)
165 .setNonce(0),
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800166 onData, onTimeout);
167}
168
169void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800170Face::put(const Data& data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800171{
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700172 // Use original `data`, since wire format should already exist for the original Data
173 if (data.wireEncode().size() > MAX_NDN_PACKET_SIZE)
174 throw Error("Data size exceeds maximum limit");
175
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700176 shared_ptr<const Data> dataPtr;
177 try {
178 dataPtr = data.shared_from_this();
179 }
180 catch (const bad_weak_ptr& e) {
181 std::cerr << "Face::put WARNING: the supplied Data should be created using make_shared<Data>()"
182 << std::endl;
183 dataPtr = make_shared<Data>(data);
184 }
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800185
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700186 // If the same ioService thread, dispatch directly calls the method
187 m_ioService->dispatch(bind(&Impl::asyncPutData, m_impl, dataPtr));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800188}
189
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800190void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800191Face::removePendingInterest(const PendingInterestId* pendingInterestId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800192{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700193 m_ioService->post(bind(&Impl::asyncRemovePendingInterest, m_impl, pendingInterestId));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800194}
195
Alexander Afanasyev6fcdde22014-08-22 19:03:36 -0700196size_t
197Face::getNPendingInterests() const
198{
199 return m_impl->m_pendingInterestTable.size();
200}
201
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800202const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000203Face::setInterestFilter(const InterestFilter& interestFilter,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800204 const OnInterest& onInterest,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700205 const RegisterPrefixSuccessCallback& onSuccess,
206 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700207 const IdentityCertificate& certificate,
208 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700209{
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700210 shared_ptr<InterestFilterRecord> filter =
211 make_shared<InterestFilterRecord>(interestFilter, onInterest);
212
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700213 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
214 onSuccess, onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700215 flags,
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700216 certificate);
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700217}
218
219const RegisteredPrefixId*
Alexander Afanasyev90164962014-03-06 08:29:59 +0000220Face::setInterestFilter(const InterestFilter& interestFilter,
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700221 const OnInterest& onInterest,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700222 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700223 const IdentityCertificate& certificate,
224 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700225{
226 shared_ptr<InterestFilterRecord> filter =
227 make_shared<InterestFilterRecord>(interestFilter, onInterest);
228
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700229 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
230 RegisterPrefixSuccessCallback(), onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700231 flags,
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700232 certificate);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700233}
234
235const RegisteredPrefixId*
236Face::setInterestFilter(const InterestFilter& interestFilter,
237 const OnInterest& onInterest,
238 const RegisterPrefixSuccessCallback& onSuccess,
239 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700240 const Name& identity,
241 uint64_t flags)
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700242{
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700243 shared_ptr<InterestFilterRecord> filter =
244 make_shared<InterestFilterRecord>(interestFilter, onInterest);
245
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700246 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
247 onSuccess, onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700248 flags,
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700249 identity);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700250}
251
252const RegisteredPrefixId*
253Face::setInterestFilter(const InterestFilter& interestFilter,
254 const OnInterest& onInterest,
255 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700256 const Name& identity,
257 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700258{
259 shared_ptr<InterestFilterRecord> filter =
260 make_shared<InterestFilterRecord>(interestFilter, onInterest);
261
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700262 return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
263 RegisterPrefixSuccessCallback(), onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700264 flags,
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700265 identity);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700266}
267
268
269const InterestFilterId*
270Face::setInterestFilter(const InterestFilter& interestFilter,
271 const OnInterest& onInterest)
272{
273 shared_ptr<InterestFilterRecord> filter =
274 make_shared<InterestFilterRecord>(interestFilter, onInterest);
275
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700276 getIoService().post(bind(&Impl::asyncSetInterestFilter, m_impl, filter));
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700277
278 return reinterpret_cast<const InterestFilterId*>(filter.get());
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700279}
280
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700281const RegisteredPrefixId*
282Face::registerPrefix(const Name& prefix,
283 const RegisterPrefixSuccessCallback& onSuccess,
284 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700285 const IdentityCertificate& certificate,
286 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700287{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700288 return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
289 onSuccess, onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700290 flags,
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700291 certificate);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700292}
293
294const RegisteredPrefixId*
295Face::registerPrefix(const Name& prefix,
296 const RegisterPrefixSuccessCallback& onSuccess,
297 const RegisterPrefixFailureCallback& onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700298 const Name& identity,
299 uint64_t flags)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700300{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700301 return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
302 onSuccess, onFailure,
Alexander Afanasyev0866f512014-08-11 13:25:09 -0700303 flags,
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700304 identity);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700305}
306
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700307void
Alexander Afanasyev7682ccb2014-02-20 10:29:35 -0800308Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800309{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700310 m_ioService->post(bind(&Impl::asyncUnregisterPrefix, m_impl, registeredPrefixId,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700311 UnregisterPrefixSuccessCallback(), UnregisterPrefixFailureCallback()));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800312}
313
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700314void
315Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
316{
317 m_ioService->post(bind(&Impl::asyncUnsetInterestFilter, m_impl, interestFilterId));
318}
Yingdi Yue66bf2a2014-04-28 17:07:36 -0700319
320void
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700321Face::unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
322 const UnregisterPrefixSuccessCallback& onSuccess,
323 const UnregisterPrefixFailureCallback& onFailure)
324{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700325 m_ioService->post(bind(&Impl::asyncUnregisterPrefix, m_impl, registeredPrefixId,
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700326 onSuccess, onFailure));
327}
328
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800329void
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700330Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
331 bool keepThread/* = false*/)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800332{
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700333 try {
334 if (timeout < time::milliseconds::zero())
335 {
336 // do not block if timeout is negative, but process pending events
337 m_ioService->poll();
338 return;
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800339 }
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800340
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700341 if (timeout > time::milliseconds::zero())
342 {
343 m_impl->m_processEventsTimeoutTimer->expires_from_now(time::milliseconds(timeout));
344 m_impl->m_processEventsTimeoutTimer->async_wait(&fireProcessEventsTimeout);
345 }
346
347 if (keepThread) {
348 // work will ensure that m_ioService is running until work object exists
349 m_impl->m_ioServiceWork = make_shared<boost::asio::io_service::work>(ref(*m_ioService));
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800350 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -0700351
352 m_ioService->run();
353 m_ioService->reset(); // so it is possible to run processEvents again (if necessary)
354 }
355 catch (Face::ProcessEventsTimeout&) {
356 // break
357 m_impl->m_ioServiceWork.reset();
358 m_ioService->reset();
359 }
360 catch (...) {
361 m_impl->m_ioServiceWork.reset();
362 m_ioService->reset();
363 m_impl->m_pendingInterestTable.clear();
364 m_impl->m_registeredPrefixTable.clear();
365 throw;
366 }
Jeff Thompsonfb29cda2013-08-24 10:26:54 -0700367}
368
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800369void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700370Face::shutdown()
Jeff Thompson517ffa82013-08-05 16:04:34 -0700371{
Alexander Afanasyev7dced462014-03-19 15:12:32 -0700372 m_ioService->post(bind(&Face::asyncShutdown, this));
373}
374
375void
376Face::asyncShutdown()
377{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700378 m_impl->m_pendingInterestTable.clear();
379 m_impl->m_registeredPrefixTable.clear();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800380
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700381 if (m_transport->isConnected())
382 m_transport->close();
383
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700384 m_impl->m_pitTimeoutCheckTimer->cancel();
385 m_impl->m_processEventsTimeoutTimer->cancel();
386 m_impl->m_pitTimeoutCheckTimerActive = false;
Alexander Afanasyev1f5486e2014-07-10 17:45:49 -0700387
388 m_impl->m_ioServiceWork.reset();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700389}
390
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800391void
392Face::fireProcessEventsTimeout(const boost::system::error_code& error)
393{
394 if (!error) // can fire for some other reason, e.g., cancelled
395 throw Face::ProcessEventsTimeout();
Jeff Thompsonaa4e6db2013-07-15 17:25:23 -0700396}
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800397
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800398
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800399void
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800400Face::onReceiveElement(const Block& blockFromDaemon)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800401{
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800402 const Block& block = nfd::LocalControlHeader::getPayload(blockFromDaemon);
403
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600404 if (block.type() == tlv::Interest)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800405 {
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700406 shared_ptr<Interest> interest = make_shared<Interest>();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800407 interest->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800408 if (&block != &blockFromDaemon)
409 interest->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyeva68aa7f2014-02-11 15:42:33 -0800410
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700411 m_impl->processInterestFilters(*interest);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800412 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600413 else if (block.type() == tlv::Data)
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800414 {
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700415 shared_ptr<Data> data = make_shared<Data>();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800416 data->wireDecode(block);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800417 if (&block != &blockFromDaemon)
418 data->getLocalControlHeader().wireDecode(blockFromDaemon);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800419
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700420 m_impl->satisfyPendingInterests(*data);
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800421
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700422 if (m_impl->m_pendingInterestTable.empty()) {
423 m_impl->m_pitTimeoutCheckTimer->cancel(); // this will cause checkPitExpire invocation
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800424 }
425 }
Yingdi Yuf9fa52f2014-02-06 12:27:32 -0800426 // ignore any other type
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800427}
428
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800429
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800430
431} // namespace ndn