blob: b3ccc435660002399972d3c12a5ed9c91b4bc93a [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:
Junxiao Shi79494162014-04-02 18:25:11 -070024 LocalFace(const FaceUri& remoteUri, const FaceUri& localUri);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080025
Steve DiBenedetto7564d972014-03-24 14:28:46 -060026 /** \brief get whether any LocalControlHeader feature is enabled
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080027 *
Steve DiBenedetto7564d972014-03-24 14:28:46 -060028 * \returns true if any feature is enabled.
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080029 */
30 bool
Steve DiBenedetto7564d972014-03-24 14:28:46 -060031 isLocalControlHeaderEnabled() const;
32
33 /** \brief get whether a specific LocalControlHeader feature is enabled
34 *
35 * \param feature The feature.
36 * \returns true if the specified feature is enabled.
37 */
38 bool
39 isLocalControlHeaderEnabled(LocalControlFeature feature) const;
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080040
41 /** \brief enable or disable a LocalControlHeader feature
42 *
Steve DiBenedetto7564d972014-03-24 14:28:46 -060043 * \param feature The feature. Cannot be LOCAL_CONTROL_FEATURE_ANY
44 * or LOCAL_CONTROL_FEATURE_MAX
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080045 */
46 void
Steve DiBenedetto7564d972014-03-24 14:28:46 -060047 setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled = true);
48
49public:
50
51 static const size_t LOCAL_CONTROL_FEATURE_MAX = 3; /// upper bound of LocalControlFeature enum
52 static const size_t LOCAL_CONTROL_FEATURE_ANY = 0; /// any feature
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080053
54protected:
55 // statically overridden from Face
56
57 /** \brief Decode block into Interest/Data, considering potential LocalControlHeader
58 *
59 * If LocalControlHeader is present, the encoded data is filtered out, based
60 * on enabled features on the face.
61 */
62 bool
63 decodeAndDispatchInput(const Block& element);
64
65 // LocalFace-specific methods
66
67 /** \brief Check if LocalControlHeader needs to be included, taking into account
68 * both set parameters in supplied LocalControlHeader and features
69 * enabled on the local face.
70 */
71 bool
72 isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const;
73
74 /** \brief Create LocalControlHeader, considering enabled features
75 */
76 template<class Packet>
77 Block
78 filterAndEncodeLocalControlHeader(const Packet& packet);
79
80private:
81 std::vector<bool> m_localControlHeaderFeatures;
82};
83
84inline
Junxiao Shi79494162014-04-02 18:25:11 -070085LocalFace::LocalFace(const FaceUri& remoteUri, const FaceUri& localUri)
86 : Face(remoteUri, localUri, true)
Steve DiBenedetto7564d972014-03-24 14:28:46 -060087 , m_localControlHeaderFeatures(LocalFace::LOCAL_CONTROL_FEATURE_MAX)
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080088{
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080089}
90
91inline bool
Steve DiBenedetto7564d972014-03-24 14:28:46 -060092LocalFace::isLocalControlHeaderEnabled() const
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080093{
Steve DiBenedetto7564d972014-03-24 14:28:46 -060094 return m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY];
95}
96
97inline bool
98LocalFace::isLocalControlHeaderEnabled(LocalControlFeature feature) const
99{
100 BOOST_ASSERT(0 < feature && feature < m_localControlHeaderFeatures.size());
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800101 return m_localControlHeaderFeatures[feature];
102}
103
104inline void
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600105LocalFace::setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled/* = true*/)
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800106{
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600107 BOOST_ASSERT(0 < feature && feature < m_localControlHeaderFeatures.size());
108
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800109 m_localControlHeaderFeatures[feature] = enabled;
110
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600111 m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY] =
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800112 std::find(m_localControlHeaderFeatures.begin() + 1,
113 m_localControlHeaderFeatures.end(), true) <
114 m_localControlHeaderFeatures.end();
115 // 'find(..) < .end()' instead of 'find(..) != .end()' due to LLVM Bug 16816
116}
117
118inline bool
119LocalFace::decodeAndDispatchInput(const Block& element)
120{
121 const Block& payload = ndn::nfd::LocalControlHeader::getPayload(element);
122
123 // If received LocalControlHeader, but it is not enabled on the face
124 if ((&payload != &element) && !this->isLocalControlHeaderEnabled())
125 return false;
126
127 if (payload.type() == tlv::Interest)
128 {
129 shared_ptr<Interest> i = make_shared<Interest>();
130 i->wireDecode(payload);
131 if (&payload != &element)
132 {
133 i->getLocalControlHeader().wireDecode(element,
134 false,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600135 this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800136 }
137
138 this->onReceiveInterest(*i);
139 }
140 else if (payload.type() == tlv::Data)
141 {
142 shared_ptr<Data> d = make_shared<Data>();
143 d->wireDecode(payload);
144
145 /// \todo Uncomment and correct the following when we have more
146 /// options in LocalControlHeader that apply for incoming
147 /// Data packets (if ever)
148 // if (&payload != &element)
149 // {
150 //
151 // d->getLocalControlHeader().wireDecode(element,
152 // false,
153 // false);
154 // }
155
156 this->onReceiveData(*d);
157 }
158 else
159 return false;
160
161 return true;
162}
163
164inline bool
165LocalFace::isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const
166{
167 if (!this->isLocalControlHeaderEnabled())
168 return true;
169
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600170 return header.empty(this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800171 false);
172}
173
174template<class Packet>
175inline Block
176LocalFace::filterAndEncodeLocalControlHeader(const Packet& packet)
177{
178 return packet.getLocalControlHeader().wireEncode(packet,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600179 this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800180 false);
181}
182
183} // namespace nfd
184
185#endif // NFD_FACE_LOCAL_FACE_HPP