blob: d16a64f4aff89a02118c558ee2bf6a3964fa0683 [file] [log] [blame]
Alexander Afanasyevbd220a02014-02-20 00:29:56 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#ifndef NFD_FACE_LOCAL_FACE_HPP
8#define NFD_FACE_LOCAL_FACE_HPP
9
10#include "face.hpp"
Steve DiBenedetto7564d972014-03-24 14:28:46 -060011#include <ndn-cpp-dev/management/nfd-control-parameters.hpp>
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080012
13namespace nfd {
14
Steve DiBenedetto7564d972014-03-24 14:28:46 -060015using ndn::nfd::LocalControlFeature;
16using ndn::nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID;
17using ndn::nfd::LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID;
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080018
19/** \brief represents a face
20 */
21class LocalFace : public Face
22{
23public:
Steve DiBenedetto7564d972014-03-24 14:28:46 -060024
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +000025 explicit
26 LocalFace(const FaceUri& uri);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080027
Steve DiBenedetto7564d972014-03-24 14:28:46 -060028 /** \brief get whether any LocalControlHeader feature is enabled
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080029 *
Steve DiBenedetto7564d972014-03-24 14:28:46 -060030 * \returns true if any feature is enabled.
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080031 */
32 bool
Steve DiBenedetto7564d972014-03-24 14:28:46 -060033 isLocalControlHeaderEnabled() const;
34
35 /** \brief get whether a specific LocalControlHeader feature is enabled
36 *
37 * \param feature The feature.
38 * \returns true if the specified feature is enabled.
39 */
40 bool
41 isLocalControlHeaderEnabled(LocalControlFeature feature) const;
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080042
43 /** \brief enable or disable a LocalControlHeader feature
44 *
Steve DiBenedetto7564d972014-03-24 14:28:46 -060045 * \param feature The feature. Cannot be LOCAL_CONTROL_FEATURE_ANY
46 * or LOCAL_CONTROL_FEATURE_MAX
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080047 */
48 void
Steve DiBenedetto7564d972014-03-24 14:28:46 -060049 setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled = true);
50
51public:
52
53 static const size_t LOCAL_CONTROL_FEATURE_MAX = 3; /// upper bound of LocalControlFeature enum
54 static const size_t LOCAL_CONTROL_FEATURE_ANY = 0; /// any feature
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080055
56protected:
57 // statically overridden from Face
58
59 /** \brief Decode block into Interest/Data, considering potential LocalControlHeader
60 *
61 * If LocalControlHeader is present, the encoded data is filtered out, based
62 * on enabled features on the face.
63 */
64 bool
65 decodeAndDispatchInput(const Block& element);
66
67 // LocalFace-specific methods
68
69 /** \brief Check if LocalControlHeader needs to be included, taking into account
70 * both set parameters in supplied LocalControlHeader and features
71 * enabled on the local face.
72 */
73 bool
74 isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const;
75
76 /** \brief Create LocalControlHeader, considering enabled features
77 */
78 template<class Packet>
79 Block
80 filterAndEncodeLocalControlHeader(const Packet& packet);
81
82private:
83 std::vector<bool> m_localControlHeaderFeatures;
84};
85
86inline
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +000087LocalFace::LocalFace(const FaceUri& uri)
88 : Face(uri, true)
Steve DiBenedetto7564d972014-03-24 14:28:46 -060089 , m_localControlHeaderFeatures(LocalFace::LOCAL_CONTROL_FEATURE_MAX)
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080090{
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080091}
92
93inline bool
Steve DiBenedetto7564d972014-03-24 14:28:46 -060094LocalFace::isLocalControlHeaderEnabled() const
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080095{
Steve DiBenedetto7564d972014-03-24 14:28:46 -060096 return m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY];
97}
98
99inline bool
100LocalFace::isLocalControlHeaderEnabled(LocalControlFeature feature) const
101{
102 BOOST_ASSERT(0 < feature && feature < m_localControlHeaderFeatures.size());
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800103 return m_localControlHeaderFeatures[feature];
104}
105
106inline void
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600107LocalFace::setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled/* = true*/)
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800108{
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600109 BOOST_ASSERT(0 < feature && feature < m_localControlHeaderFeatures.size());
110
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800111 m_localControlHeaderFeatures[feature] = enabled;
112
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600113 m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY] =
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800114 std::find(m_localControlHeaderFeatures.begin() + 1,
115 m_localControlHeaderFeatures.end(), true) <
116 m_localControlHeaderFeatures.end();
117 // 'find(..) < .end()' instead of 'find(..) != .end()' due to LLVM Bug 16816
118}
119
120inline bool
121LocalFace::decodeAndDispatchInput(const Block& element)
122{
123 const Block& payload = ndn::nfd::LocalControlHeader::getPayload(element);
124
125 // If received LocalControlHeader, but it is not enabled on the face
126 if ((&payload != &element) && !this->isLocalControlHeaderEnabled())
127 return false;
128
129 if (payload.type() == tlv::Interest)
130 {
131 shared_ptr<Interest> i = make_shared<Interest>();
132 i->wireDecode(payload);
133 if (&payload != &element)
134 {
135 i->getLocalControlHeader().wireDecode(element,
136 false,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600137 this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800138 }
139
140 this->onReceiveInterest(*i);
141 }
142 else if (payload.type() == tlv::Data)
143 {
144 shared_ptr<Data> d = make_shared<Data>();
145 d->wireDecode(payload);
146
147 /// \todo Uncomment and correct the following when we have more
148 /// options in LocalControlHeader that apply for incoming
149 /// Data packets (if ever)
150 // if (&payload != &element)
151 // {
152 //
153 // d->getLocalControlHeader().wireDecode(element,
154 // false,
155 // false);
156 // }
157
158 this->onReceiveData(*d);
159 }
160 else
161 return false;
162
163 return true;
164}
165
166inline bool
167LocalFace::isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const
168{
169 if (!this->isLocalControlHeaderEnabled())
170 return true;
171
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600172 return header.empty(this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800173 false);
174}
175
176template<class Packet>
177inline Block
178LocalFace::filterAndEncodeLocalControlHeader(const Packet& packet)
179{
180 return packet.getLocalControlHeader().wireEncode(packet,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600181 this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800182 false);
183}
184
185} // namespace nfd
186
187#endif // NFD_FACE_LOCAL_FACE_HPP