blob: 38d7f7070be7b8abf512bef39280c56648ffdf6f [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +00002/*
3 * Copyright (c) 2013-2017 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 Afanasyevc8823bc2014-02-09 19:33:33 -080020 */
21
22#ifndef NDN_DETAIL_PENDING_INTEREST_HPP
23#define NDN_DETAIL_PENDING_INTEREST_HPP
24
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080025#include "../data.hpp"
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +000026#include "../interest.hpp"
Eric Newberry83872fd2015-08-06 17:01:24 -070027#include "../lp/nack.hpp"
Junxiao Shi103d8ed2016-08-07 20:34:10 +000028#include "../util/scheduler-scoped-event-id.hpp"
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080029
30namespace ndn {
31
Junxiao Shi103d8ed2016-08-07 20:34:10 +000032/**
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +000033 * @brief Indicates where a pending Interest came from
34 */
35enum class PendingInterestOrigin
36{
37 APP, ///< Interest was received from this app via Face::expressInterest API
38 FORWARDER ///< Interest was received from the forwarder via Transport
39};
40
41std::ostream&
42operator<<(std::ostream& os, PendingInterestOrigin origin)
43{
44 switch (origin) {
45 case PendingInterestOrigin::APP:
46 return os << "app";
47 case PendingInterestOrigin::FORWARDER:
48 return os << "forwarder";
49 }
50 BOOST_ASSERT(false);
51 return os;
52}
53
54/**
55 * @brief Stores a pending Interest and associated callbacks
Junxiao Shi103d8ed2016-08-07 20:34:10 +000056 */
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070057class PendingInterest : noncopyable
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070058{
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080059public:
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080060 /**
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +000061 * @brief Construct a pending Interest record for an Interest from Face::expressInterest
Junxiao Shi103d8ed2016-08-07 20:34:10 +000062 *
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +000063 * The timeout is set based on the current time and InterestLifetime.
Junxiao Shi103d8ed2016-08-07 20:34:10 +000064 * This class will invoke the timeout callback unless the record is deleted before timeout.
65 *
66 * @param interest the Interest
67 * @param dataCallback invoked when matching Data packet is received
68 * @param nackCallback invoked when Nack matching Interest is received
69 * @param timeoutCallback invoked when Interest times out
70 * @param scheduler Scheduler for scheduling the timeout event
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080071 */
Eric Newberry83872fd2015-08-06 17:01:24 -070072 PendingInterest(shared_ptr<const Interest> interest,
73 const DataCallback& dataCallback,
74 const NackCallback& nackCallback,
75 const TimeoutCallback& timeoutCallback,
76 Scheduler& scheduler)
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +000077 : m_interest(std::move(interest))
78 , m_origin(PendingInterestOrigin::APP)
Eric Newberry83872fd2015-08-06 17:01:24 -070079 , m_dataCallback(dataCallback)
80 , m_nackCallback(nackCallback)
81 , m_timeoutCallback(timeoutCallback)
Alexander Afanasyev9d158f02015-02-17 21:30:19 -080082 , m_timeoutEvent(scheduler)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080083 {
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +000084 scheduleTimeoutEvent(scheduler);
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -080085 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070086
Alexander Afanasyev9d158f02015-02-17 21:30:19 -080087 /**
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +000088 * @brief Construct a pending Interest record for an Interest from NFD
89 *
90 * @param interest the Interest
91 * @param scheduler Scheduler for scheduling the timeout event
92 */
93 PendingInterest(shared_ptr<const Interest> interest, Scheduler& scheduler)
94 : m_interest(std::move(interest))
95 , m_origin(PendingInterestOrigin::FORWARDER)
96 , m_timeoutEvent(scheduler)
97 {
98 scheduleTimeoutEvent(scheduler);
99 }
100
101 /**
102 * @brief Get the Interest
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800103 */
Eric Newberry83872fd2015-08-06 17:01:24 -0700104 shared_ptr<const Interest>
Alexander Afanasyev6fcdde22014-08-22 19:03:36 -0700105 getInterest() const
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800106 {
Eric Newberry83872fd2015-08-06 17:01:24 -0700107 return m_interest;
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800108 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700109
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000110 PendingInterestOrigin
111 getOrigin() const
112 {
113 return m_origin;
114 }
115
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800116 /**
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000117 * @brief Invoke the Data callback
Junxiao Shi76e0eb22016-08-08 05:54:10 +0000118 * @note This method does nothing if the Data callback is empty
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800119 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700120 void
Eric Newberry83872fd2015-08-06 17:01:24 -0700121 invokeDataCallback(const Data& data)
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800122 {
Junxiao Shi76e0eb22016-08-08 05:54:10 +0000123 if (m_dataCallback != nullptr) {
124 m_dataCallback(*m_interest, data);
125 }
Eric Newberry83872fd2015-08-06 17:01:24 -0700126 }
127
128 /**
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000129 * @brief Invoke the Nack callback
Junxiao Shi76e0eb22016-08-08 05:54:10 +0000130 * @note This method does nothing if the Nack callback is empty
Eric Newberry83872fd2015-08-06 17:01:24 -0700131 */
132 void
133 invokeNackCallback(const lp::Nack& nack)
134 {
Junxiao Shi76e0eb22016-08-08 05:54:10 +0000135 if (m_nackCallback != nullptr) {
136 m_nackCallback(*m_interest, nack);
137 }
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800138 }
139
140 /**
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000141 * @brief Set cleanup function to be invoked when Interest times out
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800142 */
143 void
144 setDeleter(const std::function<void()>& deleter)
145 {
146 m_deleter = deleter;
147 }
148
149private:
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000150 void
151 scheduleTimeoutEvent(Scheduler& scheduler)
152 {
153 m_timeoutEvent = scheduler.scheduleEvent(m_interest->getInterestLifetime(),
154 [=] { this->invokeTimeoutCallback(); });
155 }
156
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800157 /**
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000158 * @brief Invoke the timeout callback (if non-empty) and the deleter
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800159 */
160 void
161 invokeTimeoutCallback()
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800162 {
Eric Newberry83872fd2015-08-06 17:01:24 -0700163 if (m_timeoutCallback) {
164 m_timeoutCallback(*m_interest);
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800165 }
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800166
167 BOOST_ASSERT(m_deleter);
168 m_deleter();
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800169 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700170
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800171private:
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700172 shared_ptr<const Interest> m_interest;
Junxiao Shi1ad0b4b2017-08-18 14:19:14 +0000173 PendingInterestOrigin m_origin;
Eric Newberry83872fd2015-08-06 17:01:24 -0700174 DataCallback m_dataCallback;
175 NackCallback m_nackCallback;
176 TimeoutCallback m_timeoutCallback;
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800177 util::scheduler::ScopedEventId m_timeoutEvent;
178 std::function<void()> m_deleter;
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800179};
180
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000181/**
182 * @brief Opaque type to identify a PendingInterest
183 */
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700184class PendingInterestId;
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800185
186/**
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000187 * @brief Functor to match PendingInterestId
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800188 */
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700189class MatchPendingInterestId
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800190{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700191public:
192 explicit
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700193 MatchPendingInterestId(const PendingInterestId* pendingInterestId)
194 : m_id(pendingInterestId)
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800195 {
196 }
197
198 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700199 operator()(const shared_ptr<const PendingInterest>& pendingInterest) const
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800200 {
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000201 return reinterpret_cast<const PendingInterestId*>(pendingInterest->getInterest().get()) == m_id;
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800202 }
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000203
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800204private:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700205 const PendingInterestId* m_id;
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800206};
207
Alexander Afanasyevc8823bc2014-02-09 19:33:33 -0800208} // namespace ndn
209
210#endif // NDN_DETAIL_PENDING_INTEREST_HPP