28 construct(shared_ptr<Transport>(
new UnixTransport(socketName)),
29 make_shared<boost::asio::io_service>());
32 Face::Face(
const shared_ptr<boost::asio::io_service>& ioService)
35 construct(shared_ptr<Transport>(
new UnixTransport(socketName)),
51 construct(shared_ptr<Transport>(
new UnixTransport(socketName)),
52 shared_ptr<boost::asio::io_service>(&ioService,
NullIoDeleter()));
55 Face::Face(
const std::string& host,
const std::string& port)
57 construct(shared_ptr<Transport>(
new TcpTransport(host, port)),
58 make_shared<boost::asio::io_service>());
64 make_shared<boost::asio::io_service>());
68 boost::asio::io_service& ioService)
71 shared_ptr<boost::asio::io_service>(&ioService,
NullIoDeleter()));
77 m_fwController = controller;
81 Face::construct(
const shared_ptr<Transport>& transport,
82 const shared_ptr<boost::asio::io_service>& ioService)
84 m_pitTimeoutCheckTimerActive =
false;
85 m_transport = transport;
88 m_pitTimeoutCheckTimer = make_shared<monotonic_deadline_timer>(boost::ref(*m_ioService));
89 m_processEventsTimeoutTimer = make_shared<monotonic_deadline_timer>(boost::ref(*m_ioService));
91 std::string protocol =
"nrd-0.1";
97 catch (boost::property_tree::ptree_bad_path& error)
101 catch (boost::property_tree::ptree_bad_data& error)
103 throw ConfigFile::Error(error.what());
106 if (isSupportedNrdProtocol(protocol))
108 m_fwController = make_shared<nrd::Controller>(boost::ref(*
this));
110 else if (isSupportedNfdProtocol(protocol))
112 m_fwController = make_shared<nfd::Controller>(boost::ref(*
this));
114 else if (isSupportedNdndProtocol(protocol))
116 m_fwController = make_shared<ndnd::Controller>(boost::ref(*
this));
120 throw Face::Error(
"Cannot create controller for unsupported protocol \"" + protocol +
"\"");
124 const PendingInterestId*
127 if (!m_transport->isConnected())
128 m_transport->connect(*m_ioService,
129 bind(&Face::onReceiveElement,
this, _1));
131 shared_ptr<const Interest> interestToExpress(
new Interest(interest));
134 m_ioService->dispatch(bind(&Face::asyncExpressInterest,
this,
135 interestToExpress, onData, onTimeout));
137 return reinterpret_cast<const PendingInterestId*
>(interestToExpress.get());
140 const PendingInterestId*
157 Face::asyncExpressInterest(
const shared_ptr<const Interest>& interest,
160 if (!m_transport->isExpectingData())
161 m_transport->resume();
163 m_pendingInterestTable.push_back(shared_ptr<PendingInterest>(
new PendingInterest
164 (interest, onData, onTimeout)));
166 if (!interest->getLocalControlHeader().empty(
false,
true))
169 m_transport->send(interest->getLocalControlHeader().wireEncode(*interest,
false,
true),
170 interest->wireEncode());
174 m_transport->send(interest->wireEncode());
177 if (!m_pitTimeoutCheckTimerActive) {
178 m_pitTimeoutCheckTimerActive =
true;
179 m_pitTimeoutCheckTimer->expires_from_now(time::milliseconds(100));
180 m_pitTimeoutCheckTimer->async_wait(bind(&Face::checkPitExpire,
this));
187 if (!m_transport->isConnected())
188 m_transport->connect(*m_ioService,
189 bind(&Face::onReceiveElement,
this, _1));
205 m_ioService->post(bind(&Face::asyncRemovePendingInterest,
this, pendingInterestId));
210 Face::asyncRemovePendingInterest(
const PendingInterestId* pendingInterestId)
215 const RegisteredPrefixId*
220 shared_ptr<RegisteredPrefix> prefixToRegister(
new RegisteredPrefix(prefix, onInterest));
222 m_fwController->selfRegisterPrefix(prefixToRegister->getPrefix(),
223 bind(&RegisteredPrefixTable::push_back,
224 &m_registeredPrefixTable, prefixToRegister),
225 bind(onSetInterestFilterFailed,
226 prefixToRegister->getPrefix(), _1));
228 return reinterpret_cast<const RegisteredPrefixId*
>(prefixToRegister.get());
234 m_ioService->post(bind(&Face::asyncUnsetInterestFilter,
this, registeredPrefixId));
238 Face::asyncUnsetInterestFilter(
const RegisteredPrefixId* registeredPrefixId)
240 RegisteredPrefixTable::iterator i = std::find_if(m_registeredPrefixTable.begin(),
241 m_registeredPrefixTable.end(),
243 if (i != m_registeredPrefixTable.end())
245 m_fwController->selfDeregisterPrefix((*i)->getPrefix(),
246 bind(&Face::finalizeUnsetInterestFilter,
this, i),
254 Face::finalizeUnsetInterestFilter(RegisteredPrefixTable::iterator item)
256 m_registeredPrefixTable.erase(item);
258 if (!m_pitTimeoutCheckTimerActive && m_registeredPrefixTable.empty())
260 m_transport->pause();
261 if (!m_ioServiceWork) {
262 m_processEventsTimeoutTimer->cancel();
273 if (timeout < time::milliseconds::zero())
280 if (timeout > time::milliseconds::zero())
282 m_processEventsTimeoutTimer->expires_from_now(time::milliseconds(timeout));
283 m_processEventsTimeoutTimer->async_wait(&fireProcessEventsTimeout);
288 m_ioServiceWork = make_shared<boost::asio::io_service::work>(boost::ref(*m_ioService));
292 m_ioService->reset();
294 catch (Face::ProcessEventsTimeout&)
297 m_ioService->reset();
299 catch (std::exception&)
301 m_ioService->reset();
302 m_pendingInterestTable.clear();
303 m_registeredPrefixTable.clear();
311 m_ioService->post(bind(&Face::asyncShutdown,
this));
315 Face::asyncShutdown()
317 m_pendingInterestTable.clear();
318 m_registeredPrefixTable.clear();
320 m_transport->close();
321 m_pitTimeoutCheckTimer->cancel();
322 m_processEventsTimeoutTimer->cancel();
323 m_pitTimeoutCheckTimerActive =
false;
327 Face::fireProcessEventsTimeout(
const boost::system::error_code& error)
330 throw Face::ProcessEventsTimeout();
334 Face::checkPitExpire()
339 PendingInterestTable::iterator i = m_pendingInterestTable.begin();
340 while (i != m_pendingInterestTable.end())
342 if ((*i)->isTimedOut(now))
345 shared_ptr<PendingInterest> pendingInterest = *i;
347 i = m_pendingInterestTable.erase(i);
349 pendingInterest->callTimeout();
355 if (!m_pendingInterestTable.empty()) {
356 m_pitTimeoutCheckTimerActive =
true;
358 m_pitTimeoutCheckTimer->expires_from_now(time::milliseconds(100));
359 m_pitTimeoutCheckTimer->async_wait(bind(&Face::checkPitExpire,
this));
362 m_pitTimeoutCheckTimerActive =
false;
364 if (m_registeredPrefixTable.empty()) {
365 m_transport->pause();
366 if (!m_ioServiceWork) {
367 m_processEventsTimeoutTimer->cancel();
375 Face::onReceiveElement(
const Block& blockFromDaemon)
381 shared_ptr<Interest> interest(
new Interest());
382 interest->wireDecode(block);
383 if (&block != &blockFromDaemon)
384 interest->getLocalControlHeader().wireDecode(blockFromDaemon);
386 processInterestFilters(*interest);
390 shared_ptr<Data> data(
new Data());
391 data->wireDecode(block);
392 if (&block != &blockFromDaemon)
393 data->getLocalControlHeader().wireDecode(blockFromDaemon);
395 satisfyPendingInterests(*data);
397 if (m_pendingInterestTable.empty()) {
398 m_pitTimeoutCheckTimer->cancel();
405 Face::satisfyPendingInterests(
Data& data)
407 for (PendingInterestTable::iterator i = m_pendingInterestTable.begin ();
408 i != m_pendingInterestTable.end();
411 if ((*i)->getInterest()->matchesData(data))
414 OnData onData = (*i)->getOnData();
415 shared_ptr<const Interest> interest = (*i)->getInterest();
417 PendingInterestTable::iterator next = i;
419 m_pendingInterestTable.erase(i);
422 if (static_cast<bool>(onData)) {
423 onData(*interest, data);
432 Face::processInterestFilters(
Interest& interest)
434 for (RegisteredPrefixTable::iterator i = m_registeredPrefixTable.begin();
435 i != m_registeredPrefixTable.end();
438 if ((*i)->getPrefix().isPrefixOf(interest.getName()))
440 (*i)->getOnInterest()((*i)->getPrefix(), interest);
int getMinSuffixComponents() const
int getMaxSuffixComponents() const
static std::string getDefaultSocketName(const ConfigFile &config)
Determine the default NFD unix socket.
const Parsed & getParsedConfiguration() const
An Interest holds a Name and other fields for an interest.
function< void(const Interest &)> OnTimeout
An OnTimeout function object is used to pass a callback to expressInterest.
function< void(const Name &, const Interest &)> OnInterest
An OnInterest function object is used to pass a callback to registerPrefix.
const time::milliseconds & getInterestLifetime() const
int getChildSelector() const
size_t wireEncode(EncodingImpl< T > &block, bool unsignedPortion=false) const
Fast encoding or block size estimation.
Face()
Create a new Face using the default transport (UnixTransport)
void operator()(boost::asio::io_service *)
void setController(const shared_ptr< Controller > &controller)
Set controller used for prefix registration.
int getMustBeFresh() const
function< void(const std::string &)> FailCallback
const RegisteredPrefixId * setInterestFilter(const Name &prefix, const OnInterest &onInterest, const OnSetInterestFilterFailed &onSetInterestFilterFailed)
Register prefix with the connected NDN hub and call onInterest when a matching interest is received...
shared_ptr< boost::asio::io_service > ioService()
Get shared_ptr of the IO service object.
void shutdown()
Shutdown face operations.
function< void(const Name &, const std::string &)> OnSetInterestFilterFailed
An OnRegisterFailed function object is used to report when registerPrefix fails.
const Exclude & getExclude() const
Functor to match pending interests against PendingInterestId.
A Name holds an array of Name::Component and represents an NDN name.
const PendingInterestId * expressInterest(const Interest &interest, const OnData &onData, const OnTimeout &onTimeout=OnTimeout())
Express Interest.
void unsetInterestFilter(const RegisteredPrefixId *registeredPrefixId)
Remove the registered prefix entry with the registeredPrefixId from the pending interest table...
function< void(const Interest &, Data &)> OnData
An OnData function object is used to pass a callback to expressInterest.
Functor to match pending interests against PendingInterestId.
void processEvents(const time::milliseconds &timeout=time::milliseconds::zero(), bool keepThread=false)
Process any data to receive or call timeout callbacks.
nfd::LocalControlHeader & getLocalControlHeader()
void removePendingInterest(const PendingInterestId *pendingInterestId)
Remove the pending interest entry with the pendingInterestId from the pending interest table...
void put(const Data &data)
Publish data packet.