blob: f99223181080e809dc496645c914b96ba9fe774d [file] [log] [blame]
Alexander Afanasyevbd220a02014-02-20 00:29:56 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -07003 * Copyright (c) 2014 Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology
9 *
10 * This file is part of NFD (Named Data Networking Forwarding Daemon).
11 * See AUTHORS.md for complete list of NFD authors and contributors.
12 *
13 * NFD is free software: you can redistribute it and/or modify it under the terms
14 * of the GNU General Public License as published by the Free Software Foundation,
15 * either version 3 of the License, or (at your option) any later version.
16 *
17 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 * PURPOSE. See the GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
23 **/
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080024
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070025#ifndef NFD_DAEMON_FACE_LOCAL_FACE_HPP
26#define NFD_DAEMON_FACE_LOCAL_FACE_HPP
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080027
28#include "face.hpp"
Steve DiBenedetto7564d972014-03-24 14:28:46 -060029#include <ndn-cpp-dev/management/nfd-control-parameters.hpp>
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080030
31namespace nfd {
32
Steve DiBenedetto7564d972014-03-24 14:28:46 -060033using ndn::nfd::LocalControlFeature;
34using ndn::nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID;
35using ndn::nfd::LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID;
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080036
37/** \brief represents a face
38 */
39class LocalFace : public Face
40{
41public:
Junxiao Shi79494162014-04-02 18:25:11 -070042 LocalFace(const FaceUri& remoteUri, const FaceUri& localUri);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080043
Steve DiBenedetto7564d972014-03-24 14:28:46 -060044 /** \brief get whether any LocalControlHeader feature is enabled
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080045 *
Steve DiBenedetto7564d972014-03-24 14:28:46 -060046 * \returns true if any feature is enabled.
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080047 */
48 bool
Steve DiBenedetto7564d972014-03-24 14:28:46 -060049 isLocalControlHeaderEnabled() const;
50
51 /** \brief get whether a specific LocalControlHeader feature is enabled
52 *
53 * \param feature The feature.
54 * \returns true if the specified feature is enabled.
55 */
56 bool
57 isLocalControlHeaderEnabled(LocalControlFeature feature) const;
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080058
59 /** \brief enable or disable a LocalControlHeader feature
60 *
Steve DiBenedetto7564d972014-03-24 14:28:46 -060061 * \param feature The feature. Cannot be LOCAL_CONTROL_FEATURE_ANY
62 * or LOCAL_CONTROL_FEATURE_MAX
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080063 */
64 void
Steve DiBenedetto7564d972014-03-24 14:28:46 -060065 setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled = true);
66
67public:
68
69 static const size_t LOCAL_CONTROL_FEATURE_MAX = 3; /// upper bound of LocalControlFeature enum
70 static const size_t LOCAL_CONTROL_FEATURE_ANY = 0; /// any feature
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080071
72protected:
73 // statically overridden from Face
74
75 /** \brief Decode block into Interest/Data, considering potential LocalControlHeader
76 *
77 * If LocalControlHeader is present, the encoded data is filtered out, based
78 * on enabled features on the face.
79 */
80 bool
81 decodeAndDispatchInput(const Block& element);
82
83 // LocalFace-specific methods
84
85 /** \brief Check if LocalControlHeader needs to be included, taking into account
86 * both set parameters in supplied LocalControlHeader and features
87 * enabled on the local face.
88 */
89 bool
90 isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const;
91
92 /** \brief Create LocalControlHeader, considering enabled features
93 */
94 template<class Packet>
95 Block
96 filterAndEncodeLocalControlHeader(const Packet& packet);
97
98private:
99 std::vector<bool> m_localControlHeaderFeatures;
100};
101
102inline
Junxiao Shi79494162014-04-02 18:25:11 -0700103LocalFace::LocalFace(const FaceUri& remoteUri, const FaceUri& localUri)
104 : Face(remoteUri, localUri, true)
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600105 , m_localControlHeaderFeatures(LocalFace::LOCAL_CONTROL_FEATURE_MAX)
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800106{
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800107}
108
109inline bool
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600110LocalFace::isLocalControlHeaderEnabled() const
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800111{
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600112 return m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY];
113}
114
115inline bool
116LocalFace::isLocalControlHeaderEnabled(LocalControlFeature feature) const
117{
118 BOOST_ASSERT(0 < feature && feature < m_localControlHeaderFeatures.size());
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800119 return m_localControlHeaderFeatures[feature];
120}
121
122inline void
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600123LocalFace::setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled/* = true*/)
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800124{
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600125 BOOST_ASSERT(0 < feature && feature < m_localControlHeaderFeatures.size());
126
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800127 m_localControlHeaderFeatures[feature] = enabled;
128
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600129 m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY] =
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800130 std::find(m_localControlHeaderFeatures.begin() + 1,
131 m_localControlHeaderFeatures.end(), true) <
132 m_localControlHeaderFeatures.end();
133 // 'find(..) < .end()' instead of 'find(..) != .end()' due to LLVM Bug 16816
134}
135
136inline bool
137LocalFace::decodeAndDispatchInput(const Block& element)
138{
139 const Block& payload = ndn::nfd::LocalControlHeader::getPayload(element);
140
141 // If received LocalControlHeader, but it is not enabled on the face
142 if ((&payload != &element) && !this->isLocalControlHeaderEnabled())
143 return false;
144
145 if (payload.type() == tlv::Interest)
146 {
147 shared_ptr<Interest> i = make_shared<Interest>();
148 i->wireDecode(payload);
149 if (&payload != &element)
150 {
151 i->getLocalControlHeader().wireDecode(element,
152 false,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600153 this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800154 }
155
156 this->onReceiveInterest(*i);
157 }
158 else if (payload.type() == tlv::Data)
159 {
160 shared_ptr<Data> d = make_shared<Data>();
161 d->wireDecode(payload);
162
163 /// \todo Uncomment and correct the following when we have more
164 /// options in LocalControlHeader that apply for incoming
165 /// Data packets (if ever)
166 // if (&payload != &element)
167 // {
168 //
169 // d->getLocalControlHeader().wireDecode(element,
170 // false,
171 // false);
172 // }
173
174 this->onReceiveData(*d);
175 }
176 else
177 return false;
178
179 return true;
180}
181
182inline bool
183LocalFace::isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const
184{
185 if (!this->isLocalControlHeaderEnabled())
186 return true;
187
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600188 return header.empty(this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800189 false);
190}
191
192template<class Packet>
193inline Block
194LocalFace::filterAndEncodeLocalControlHeader(const Packet& packet)
195{
196 return packet.getLocalControlHeader().wireEncode(packet,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600197 this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800198 false);
199}
200
201} // namespace nfd
202
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700203#endif // NFD_DAEMON_FACE_LOCAL_FACE_HPP