blob: 8a088250923ac22b08f1ceff8249e90e4052166d [file] [log] [blame]
Junxiao Shi13e637f2014-07-16 19:20:40 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2014 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "nfd-face-status.hpp"
Junxiao Shi65f1a712014-11-20 14:59:36 -070023#include "encoding/tlv-nfd.hpp"
24#include "encoding/block-helpers.hpp"
25#include "util/concepts.hpp"
Junxiao Shi13e637f2014-07-16 19:20:40 -070026
27namespace ndn {
28namespace nfd {
29
Junxiao Shi65f1a712014-11-20 14:59:36 -070030//BOOST_CONCEPT_ASSERT((boost::EqualityComparable<FaceStatus>));
31BOOST_CONCEPT_ASSERT((WireEncodable<FaceStatus>));
32BOOST_CONCEPT_ASSERT((WireDecodable<FaceStatus>));
33static_assert(std::is_base_of<tlv::Error, FaceStatus::Error>::value,
34 "FaceStatus::Error must inherit from tlv::Error");
35
Junxiao Shi13e637f2014-07-16 19:20:40 -070036FaceStatus::FaceStatus()
Junxiao Shi65f1a712014-11-20 14:59:36 -070037 : m_hasExpirationPeriod(false)
Junxiao Shi13e637f2014-07-16 19:20:40 -070038 , m_nInInterests(0)
39 , m_nInDatas(0)
40 , m_nOutInterests(0)
41 , m_nOutDatas(0)
42 , m_nInBytes(0)
43 , m_nOutBytes(0)
44{
45}
46
Chengyu Fan36dca992014-09-25 13:42:03 -060047FaceStatus::FaceStatus(const Block& block)
48{
49 this->wireDecode(block);
50}
51
Junxiao Shi13e637f2014-07-16 19:20:40 -070052template<bool T>
53size_t
54FaceStatus::wireEncode(EncodingImpl<T>& encoder) const
55{
56 size_t totalLength = 0;
57
58 totalLength += prependNonNegativeIntegerBlock(encoder,
59 tlv::nfd::NOutBytes, m_nOutBytes);
60 totalLength += prependNonNegativeIntegerBlock(encoder,
61 tlv::nfd::NInBytes, m_nInBytes);
62 totalLength += prependNonNegativeIntegerBlock(encoder,
63 tlv::nfd::NOutDatas, m_nOutDatas);
64 totalLength += prependNonNegativeIntegerBlock(encoder,
65 tlv::nfd::NOutInterests, m_nOutInterests);
66 totalLength += prependNonNegativeIntegerBlock(encoder,
67 tlv::nfd::NInDatas, m_nInDatas);
68 totalLength += prependNonNegativeIntegerBlock(encoder,
69 tlv::nfd::NInInterests, m_nInInterests);
70 totalLength += prependNonNegativeIntegerBlock(encoder,
Chengyu Fan36dca992014-09-25 13:42:03 -060071 tlv::nfd::LinkType, m_linkType);
72 totalLength += prependNonNegativeIntegerBlock(encoder,
73 tlv::nfd::FacePersistency, m_facePersistency);
74 totalLength += prependNonNegativeIntegerBlock(encoder,
75 tlv::nfd::FaceScope, m_faceScope);
Junxiao Shi13e637f2014-07-16 19:20:40 -070076 if (m_hasExpirationPeriod) {
77 totalLength += prependNonNegativeIntegerBlock(encoder,
78 tlv::nfd::ExpirationPeriod, m_expirationPeriod.count());
79 }
80 totalLength += prependByteArrayBlock(encoder, tlv::nfd::LocalUri,
81 reinterpret_cast<const uint8_t*>(m_localUri.c_str()), m_localUri.size());
82 totalLength += prependByteArrayBlock(encoder, tlv::nfd::Uri,
83 reinterpret_cast<const uint8_t*>(m_remoteUri.c_str()), m_remoteUri.size());
84 totalLength += prependNonNegativeIntegerBlock(encoder,
85 tlv::nfd::FaceId, m_faceId);
86
87 totalLength += encoder.prependVarNumber(totalLength);
88 totalLength += encoder.prependVarNumber(tlv::nfd::FaceStatus);
89 return totalLength;
90}
91
92template size_t
93FaceStatus::wireEncode<true>(EncodingImpl<true>& block) const;
94
95template size_t
96FaceStatus::wireEncode<false>(EncodingImpl<false>& block) const;
97
98const Block&
99FaceStatus::wireEncode() const
100{
101 if (m_wire.hasWire())
102 return m_wire;
103
104 EncodingEstimator estimator;
105 size_t estimatedSize = wireEncode(estimator);
106
107 EncodingBuffer buffer(estimatedSize, 0);
108 wireEncode(buffer);
109
110 m_wire = buffer.block();
111 return m_wire;
112}
113
114void
115FaceStatus::wireDecode(const Block& block)
116{
117 if (block.type() != tlv::nfd::FaceStatus) {
118 throw Error("expecting FaceStatus block");
119 }
120 m_wire = block;
121 m_wire.parse();
122 Block::element_const_iterator val = m_wire.elements_begin();
123
124 if (val != m_wire.elements_end() && val->type() == tlv::nfd::FaceId) {
125 m_faceId = readNonNegativeInteger(*val);
126 ++val;
127 }
128 else {
129 throw Error("missing required FaceId field");
130 }
131
132 if (val != m_wire.elements_end() && val->type() == tlv::nfd::Uri) {
133 m_remoteUri.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
134 ++val;
135 }
136 else {
137 throw Error("missing required Uri field");
138 }
139
140 if (val != m_wire.elements_end() && val->type() == tlv::nfd::LocalUri) {
141 m_localUri.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
142 ++val;
143 }
144 else {
145 throw Error("missing required LocalUri field");
146 }
147
148 if (val != m_wire.elements_end() && val->type() == tlv::nfd::ExpirationPeriod) {
149 m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
150 m_hasExpirationPeriod = true;
151 ++val;
152 }
153 else {
154 m_hasExpirationPeriod = false;
155 // ExpirationPeriod is optional
156 }
157
Chengyu Fan36dca992014-09-25 13:42:03 -0600158 if (val != m_wire.elements_end() && val->type() == tlv::nfd::FaceScope) {
159 m_faceScope = static_cast<FaceScope>(readNonNegativeInteger(*val));
Junxiao Shi13e637f2014-07-16 19:20:40 -0700160 ++val;
161 }
162 else {
Chengyu Fan36dca992014-09-25 13:42:03 -0600163 throw Error("missing required FaceScope field");
164 }
165
166 if (val != m_wire.elements_end() && val->type() == tlv::nfd::FacePersistency) {
167 m_facePersistency = static_cast<FacePersistency>(readNonNegativeInteger(*val));
168 ++val;
169 }
170 else {
171 throw Error("missing required FacePersistency field");
172 }
173
174 if (val != m_wire.elements_end() && val->type() == tlv::nfd::LinkType) {
175 m_linkType = static_cast<LinkType>(readNonNegativeInteger(*val));
176 ++val;
177 }
178 else {
179 throw Error("missing required LinkType field");
Junxiao Shi13e637f2014-07-16 19:20:40 -0700180 }
181
182 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInInterests) {
183 m_nInInterests = readNonNegativeInteger(*val);
184 ++val;
185 }
186 else {
187 throw Error("missing required NInInterests field");
188 }
189
190 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInDatas) {
191 m_nInDatas = readNonNegativeInteger(*val);
192 ++val;
193 }
194 else {
195 throw Error("missing required NInDatas field");
196 }
197
198 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutInterests) {
199 m_nOutInterests = readNonNegativeInteger(*val);
200 ++val;
201 }
202 else {
203 throw Error("missing required NOutInterests field");
204 }
205
206 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutDatas) {
207 m_nOutDatas = readNonNegativeInteger(*val);
208 ++val;
209 }
210 else {
211 throw Error("missing required NOutDatas field");
212 }
213
214 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInBytes) {
215 m_nInBytes = readNonNegativeInteger(*val);
216 ++val;
217 }
218 else {
219 throw Error("missing required NInBytes field");
220 }
221
222 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutBytes) {
223 m_nOutBytes = readNonNegativeInteger(*val);
224 ++val;
225 }
226 else {
227 throw Error("missing required NOutBytes field");
228 }
229}
230
Chengyu Fan36dca992014-09-25 13:42:03 -0600231FaceStatus&
232FaceStatus::setExpirationPeriod(const time::milliseconds& expirationPeriod)
233{
234 m_wire.reset();
235 m_expirationPeriod = expirationPeriod;
236 m_hasExpirationPeriod = true;
237 return *this;
238}
239
240FaceStatus&
241FaceStatus::setNInInterests(uint64_t nInInterests)
242{
243 m_wire.reset();
244 m_nInInterests = nInInterests;
245 return *this;
246}
247
248FaceStatus&
249FaceStatus::setNInDatas(uint64_t nInDatas)
250{
251 m_wire.reset();
252 m_nInDatas = nInDatas;
253 return *this;
254}
255
256FaceStatus&
257FaceStatus::setNOutInterests(uint64_t nOutInterests)
258{
259 m_wire.reset();
260 m_nOutInterests = nOutInterests;
261 return *this;
262}
263
264FaceStatus&
265FaceStatus::setNOutDatas(uint64_t nOutDatas)
266{
267 m_wire.reset();
268 m_nOutDatas = nOutDatas;
269 return *this;
270}
271
272FaceStatus&
273FaceStatus::setNInBytes(uint64_t nInBytes)
274{
275 m_wire.reset();
276 m_nInBytes = nInBytes;
277 return *this;
278}
279
280FaceStatus&
281FaceStatus::setNOutBytes(uint64_t nOutBytes)
282{
283 m_wire.reset();
284 m_nOutBytes = nOutBytes;
285 return *this;
286}
287
288void
289FaceStatus::wireReset() const
290{
291 m_wire.reset();
292}
293
Junxiao Shi13e637f2014-07-16 19:20:40 -0700294std::ostream&
295operator<<(std::ostream& os, const FaceStatus& status)
296{
297 os << "FaceStatus("
298 << "FaceID: " << status.getFaceId() << ",\n"
299 << "RemoteUri: " << status.getRemoteUri() << ",\n"
300 << "LocalUri: " << status.getLocalUri() << ",\n";
301
302 if (status.hasExpirationPeriod()) {
303 os << "ExpirationPeriod: " << status.getExpirationPeriod() << ",\n";
304 }
305 else {
306 os << "ExpirationPeriod: infinite,\n";
307 }
308
Chengyu Fan36dca992014-09-25 13:42:03 -0600309 os << "FaceScope: " << status.getFaceScope() << ",\n"
310 << "FacePersistency: " << status.getFacePersistency() << ",\n"
311 << "LinkType: " << status.getLinkType() << ",\n"
Junxiao Shi13e637f2014-07-16 19:20:40 -0700312 << "Counters: { Interests: {in: " << status.getNInInterests() << ", "
313 << "out: " << status.getNOutInterests() << "},\n"
314 << " Data: {in: " << status.getNInDatas() << ", "
315 << "out: " << status.getNOutDatas() << "},\n"
316 << " bytes: {in: " << status.getNInBytes() << ", "
317 << "out: " << status.getNOutBytes() << "} }\n"
318 << ")";
319 return os;
320}
321
322} // namespace nfd
323} // namespace ndn
324