blob: 30af9fbbb7fdd144629d763fc01c77129ea5f7b3 [file] [log] [blame]
Junxiao Shi13e637f2014-07-16 19:20:40 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev74633892015-02-08 18:08:46 -08003 * Copyright (c) 2013-2015 Regents of the University of California.
Junxiao Shi13e637f2014-07-16 19:20:40 -07004 *
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
Alexander Afanasyev74633892015-02-08 18:08:46 -080052template<encoding::Tag TAG>
Junxiao Shi13e637f2014-07-16 19:20:40 -070053size_t
Alexander Afanasyev74633892015-02-08 18:08:46 -080054FaceStatus::wireEncode(EncodingImpl<TAG>& encoder) const
Junxiao Shi13e637f2014-07-16 19:20:40 -070055{
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 }
Alexander Afanasyev74633892015-02-08 18:08:46 -080080 totalLength += encoder.prependByteArrayBlock(tlv::nfd::LocalUri,
Junxiao Shi13e637f2014-07-16 19:20:40 -070081 reinterpret_cast<const uint8_t*>(m_localUri.c_str()), m_localUri.size());
Alexander Afanasyev74633892015-02-08 18:08:46 -080082 totalLength += encoder.prependByteArrayBlock(tlv::nfd::Uri,
Junxiao Shi13e637f2014-07-16 19:20:40 -070083 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
Alexander Afanasyev74633892015-02-08 18:08:46 -080093FaceStatus::wireEncode<encoding::EncoderTag>(EncodingImpl<encoding::EncoderTag>& block) const;
Junxiao Shi13e637f2014-07-16 19:20:40 -070094
95template size_t
Alexander Afanasyev74633892015-02-08 18:08:46 -080096FaceStatus::wireEncode<encoding::EstimatorTag>(EncodingImpl<encoding::EstimatorTag>& block) const;
Junxiao Shi13e637f2014-07-16 19:20:40 -070097
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) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700118 BOOST_THROW_EXCEPTION(Error("expecting FaceStatus block"));
Junxiao Shi13e637f2014-07-16 19:20:40 -0700119 }
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 {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700129 BOOST_THROW_EXCEPTION(Error("missing required FaceId field"));
Junxiao Shi13e637f2014-07-16 19:20:40 -0700130 }
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 {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700137 BOOST_THROW_EXCEPTION(Error("missing required Uri field"));
Junxiao Shi13e637f2014-07-16 19:20:40 -0700138 }
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 {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700145 BOOST_THROW_EXCEPTION(Error("missing required LocalUri field"));
Junxiao Shi13e637f2014-07-16 19:20:40 -0700146 }
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 {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700163 BOOST_THROW_EXCEPTION(Error("missing required FaceScope field"));
Chengyu Fan36dca992014-09-25 13:42:03 -0600164 }
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 {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700171 BOOST_THROW_EXCEPTION(Error("missing required FacePersistency field"));
Chengyu Fan36dca992014-09-25 13:42:03 -0600172 }
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 {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700179 BOOST_THROW_EXCEPTION(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 {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700187 BOOST_THROW_EXCEPTION(Error("missing required NInInterests field"));
Junxiao Shi13e637f2014-07-16 19:20:40 -0700188 }
189
190 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInDatas) {
191 m_nInDatas = readNonNegativeInteger(*val);
192 ++val;
193 }
194 else {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700195 BOOST_THROW_EXCEPTION(Error("missing required NInDatas field"));
Junxiao Shi13e637f2014-07-16 19:20:40 -0700196 }
197
198 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutInterests) {
199 m_nOutInterests = readNonNegativeInteger(*val);
200 ++val;
201 }
202 else {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700203 BOOST_THROW_EXCEPTION(Error("missing required NOutInterests field"));
Junxiao Shi13e637f2014-07-16 19:20:40 -0700204 }
205
206 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutDatas) {
207 m_nOutDatas = readNonNegativeInteger(*val);
208 ++val;
209 }
210 else {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700211 BOOST_THROW_EXCEPTION(Error("missing required NOutDatas field"));
Junxiao Shi13e637f2014-07-16 19:20:40 -0700212 }
213
214 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInBytes) {
215 m_nInBytes = readNonNegativeInteger(*val);
216 ++val;
217 }
218 else {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700219 BOOST_THROW_EXCEPTION(Error("missing required NInBytes field"));
Junxiao Shi13e637f2014-07-16 19:20:40 -0700220 }
221
222 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutBytes) {
223 m_nOutBytes = readNonNegativeInteger(*val);
224 ++val;
225 }
226 else {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700227 BOOST_THROW_EXCEPTION(Error("missing required NOutBytes field"));
Junxiao Shi13e637f2014-07-16 19:20:40 -0700228 }
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