blob: 7023efbb230366de0fc9eea6736db812e4f937fd [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"
11
12namespace nfd {
13
14/* \brief indicates a feature in LocalControlHeader
15 */
16enum LocalControlHeaderFeature
17{
18 /// any feature
19 LOCAL_CONTROL_HEADER_FEATURE_ANY,
20 /// in-faceid
21 LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID,
22 /// out-faceid
23 LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID,
24 /// upper bound of enum
25 LOCAL_CONTROL_HEADER_FEATURE_MAX
26};
27
28
29/** \brief represents a face
30 */
31class LocalFace : public Face
32{
33public:
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +000034 explicit
35 LocalFace(const FaceUri& uri);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080036
37 /** \brief get whether a LocalControlHeader feature is enabled
38 *
39 * \param feature The feature. Cannot be LOCAL_CONTROL_HEADER_FEATURE_MAX
40 * LOCAL_CONTROL_HEADER_FEATURE_ANY returns true if any feature is enabled.
41 */
42 bool
43 isLocalControlHeaderEnabled(LocalControlHeaderFeature feature =
44 LOCAL_CONTROL_HEADER_FEATURE_ANY) const;
45
46 /** \brief enable or disable a LocalControlHeader feature
47 *
48 * \param feature The feature. Cannot be LOCAL_CONTROL_HEADER_FEATURE_ANY
49 * or LOCAL_CONTROL_HEADER_FEATURE_MAX
50 */
51 void
52 setLocalControlHeaderFeature(LocalControlHeaderFeature feature, bool enabled = true);
53
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
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +000085LocalFace::LocalFace(const FaceUri& uri)
86 : Face(uri, true)
Davide Pesavento0ff10db2014-02-28 03:12:27 +010087 , m_localControlHeaderFeatures(LOCAL_CONTROL_HEADER_FEATURE_MAX)
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080088{
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080089}
90
91inline bool
92LocalFace::isLocalControlHeaderEnabled(LocalControlHeaderFeature feature) const
93{
94 BOOST_ASSERT(feature < m_localControlHeaderFeatures.size());
95 return m_localControlHeaderFeatures[feature];
96}
97
98inline void
99LocalFace::setLocalControlHeaderFeature(LocalControlHeaderFeature feature, bool enabled/* = true*/)
100{
101 BOOST_ASSERT(feature > LOCAL_CONTROL_HEADER_FEATURE_ANY &&
102 feature < m_localControlHeaderFeatures.size());
103 m_localControlHeaderFeatures[feature] = enabled;
104
105 BOOST_STATIC_ASSERT(LOCAL_CONTROL_HEADER_FEATURE_ANY == 0);
106 m_localControlHeaderFeatures[LOCAL_CONTROL_HEADER_FEATURE_ANY] =
107 std::find(m_localControlHeaderFeatures.begin() + 1,
108 m_localControlHeaderFeatures.end(), true) <
109 m_localControlHeaderFeatures.end();
110 // 'find(..) < .end()' instead of 'find(..) != .end()' due to LLVM Bug 16816
111}
112
113inline bool
114LocalFace::decodeAndDispatchInput(const Block& element)
115{
116 const Block& payload = ndn::nfd::LocalControlHeader::getPayload(element);
117
118 // If received LocalControlHeader, but it is not enabled on the face
119 if ((&payload != &element) && !this->isLocalControlHeaderEnabled())
120 return false;
121
122 if (payload.type() == tlv::Interest)
123 {
124 shared_ptr<Interest> i = make_shared<Interest>();
125 i->wireDecode(payload);
126 if (&payload != &element)
127 {
128 i->getLocalControlHeader().wireDecode(element,
129 false,
130 this->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID));
131 }
132
133 this->onReceiveInterest(*i);
134 }
135 else if (payload.type() == tlv::Data)
136 {
137 shared_ptr<Data> d = make_shared<Data>();
138 d->wireDecode(payload);
139
140 /// \todo Uncomment and correct the following when we have more
141 /// options in LocalControlHeader that apply for incoming
142 /// Data packets (if ever)
143 // if (&payload != &element)
144 // {
145 //
146 // d->getLocalControlHeader().wireDecode(element,
147 // false,
148 // false);
149 // }
150
151 this->onReceiveData(*d);
152 }
153 else
154 return false;
155
156 return true;
157}
158
159inline bool
160LocalFace::isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const
161{
162 if (!this->isLocalControlHeaderEnabled())
163 return true;
164
165 return header.empty(this->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID),
166 false);
167}
168
169template<class Packet>
170inline Block
171LocalFace::filterAndEncodeLocalControlHeader(const Packet& packet)
172{
173 return packet.getLocalControlHeader().wireEncode(packet,
174 this->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID),
175 false);
176}
177
178} // namespace nfd
179
180#endif // NFD_FACE_LOCAL_FACE_HPP