blob: 6175b5d1889e138ba7f81c02b0d5617df5b07d46 [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:
34 LocalFace();
35
36 /** \brief get whether a LocalControlHeader feature is enabled
37 *
38 * \param feature The feature. Cannot be LOCAL_CONTROL_HEADER_FEATURE_MAX
39 * LOCAL_CONTROL_HEADER_FEATURE_ANY returns true if any feature is enabled.
40 */
41 bool
42 isLocalControlHeaderEnabled(LocalControlHeaderFeature feature =
43 LOCAL_CONTROL_HEADER_FEATURE_ANY) const;
44
45 /** \brief enable or disable a LocalControlHeader feature
46 *
47 * \param feature The feature. Cannot be LOCAL_CONTROL_HEADER_FEATURE_ANY
48 * or LOCAL_CONTROL_HEADER_FEATURE_MAX
49 */
50 void
51 setLocalControlHeaderFeature(LocalControlHeaderFeature feature, bool enabled = true);
52
53protected:
54 // statically overridden from Face
55
56 /** \brief Decode block into Interest/Data, considering potential LocalControlHeader
57 *
58 * If LocalControlHeader is present, the encoded data is filtered out, based
59 * on enabled features on the face.
60 */
61 bool
62 decodeAndDispatchInput(const Block& element);
63
64 // LocalFace-specific methods
65
66 /** \brief Check if LocalControlHeader needs to be included, taking into account
67 * both set parameters in supplied LocalControlHeader and features
68 * enabled on the local face.
69 */
70 bool
71 isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const;
72
73 /** \brief Create LocalControlHeader, considering enabled features
74 */
75 template<class Packet>
76 Block
77 filterAndEncodeLocalControlHeader(const Packet& packet);
78
79private:
80 std::vector<bool> m_localControlHeaderFeatures;
81};
82
83inline
84LocalFace::LocalFace()
85 : m_localControlHeaderFeatures(LOCAL_CONTROL_HEADER_FEATURE_MAX)
86{
87 setLocal(true);
88}
89
90inline bool
91LocalFace::isLocalControlHeaderEnabled(LocalControlHeaderFeature feature) const
92{
93 BOOST_ASSERT(feature < m_localControlHeaderFeatures.size());
94 return m_localControlHeaderFeatures[feature];
95}
96
97inline void
98LocalFace::setLocalControlHeaderFeature(LocalControlHeaderFeature feature, bool enabled/* = true*/)
99{
100 BOOST_ASSERT(feature > LOCAL_CONTROL_HEADER_FEATURE_ANY &&
101 feature < m_localControlHeaderFeatures.size());
102 m_localControlHeaderFeatures[feature] = enabled;
103
104 BOOST_STATIC_ASSERT(LOCAL_CONTROL_HEADER_FEATURE_ANY == 0);
105 m_localControlHeaderFeatures[LOCAL_CONTROL_HEADER_FEATURE_ANY] =
106 std::find(m_localControlHeaderFeatures.begin() + 1,
107 m_localControlHeaderFeatures.end(), true) <
108 m_localControlHeaderFeatures.end();
109 // 'find(..) < .end()' instead of 'find(..) != .end()' due to LLVM Bug 16816
110}
111
112inline bool
113LocalFace::decodeAndDispatchInput(const Block& element)
114{
115 const Block& payload = ndn::nfd::LocalControlHeader::getPayload(element);
116
117 // If received LocalControlHeader, but it is not enabled on the face
118 if ((&payload != &element) && !this->isLocalControlHeaderEnabled())
119 return false;
120
121 if (payload.type() == tlv::Interest)
122 {
123 shared_ptr<Interest> i = make_shared<Interest>();
124 i->wireDecode(payload);
125 if (&payload != &element)
126 {
127 i->getLocalControlHeader().wireDecode(element,
128 false,
129 this->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID));
130 }
131
132 this->onReceiveInterest(*i);
133 }
134 else if (payload.type() == tlv::Data)
135 {
136 shared_ptr<Data> d = make_shared<Data>();
137 d->wireDecode(payload);
138
139 /// \todo Uncomment and correct the following when we have more
140 /// options in LocalControlHeader that apply for incoming
141 /// Data packets (if ever)
142 // if (&payload != &element)
143 // {
144 //
145 // d->getLocalControlHeader().wireDecode(element,
146 // false,
147 // false);
148 // }
149
150 this->onReceiveData(*d);
151 }
152 else
153 return false;
154
155 return true;
156}
157
158inline bool
159LocalFace::isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const
160{
161 if (!this->isLocalControlHeaderEnabled())
162 return true;
163
164 return header.empty(this->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID),
165 false);
166}
167
168template<class Packet>
169inline Block
170LocalFace::filterAndEncodeLocalControlHeader(const Packet& packet)
171{
172 return packet.getLocalControlHeader().wireEncode(packet,
173 this->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID),
174 false);
175}
176
177} // namespace nfd
178
179#endif // NFD_FACE_LOCAL_FACE_HPP