blob: 5f83863a6ec8b61de55e8a803123f755d02c98b6 [file] [log] [blame]
Jiewen Tan7a56d1c2015-01-26 23:26:51 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev67758b12018-03-06 18:36:44 -05002/*
3 * Copyright (c) 2014-2018, The University of Memphis,
Jiewen Tan7a56d1c2015-01-26 23:26:51 -08004 * Regents of the University of California,
5 * Arizona Board of Regents.
6 *
7 * This file is part of NLSR (Named-data Link State Routing).
8 * See AUTHORS.md for complete list of NLSR authors and contributors.
9 *
10 * NLSR is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Alexander Afanasyev67758b12018-03-06 18:36:44 -050020 */
Jiewen Tan7a56d1c2015-01-26 23:26:51 -080021
22#include "lsa-info.hpp"
23#include "tlv-nlsr.hpp"
24
25#include <ndn-cxx/util/concepts.hpp>
26#include <ndn-cxx/encoding/block-helpers.hpp>
27
28namespace nlsr {
dmcoomes9f936662017-03-02 10:33:09 -060029namespace tlv {
Jiewen Tan7a56d1c2015-01-26 23:26:51 -080030
31BOOST_CONCEPT_ASSERT((ndn::WireEncodable<LsaInfo>));
32BOOST_CONCEPT_ASSERT((ndn::WireDecodable<LsaInfo>));
33static_assert(std::is_base_of<ndn::tlv::Error, LsaInfo::Error>::value,
34 "LsaInfo::Error must inherit from tlv::Error");
35
36const ndn::time::milliseconds LsaInfo::INFINITE_EXPIRATION_PERIOD(ndn::time::milliseconds::max());
37
38LsaInfo::LsaInfo()
39 : m_sequenceNumber(0)
40 , m_expirationPeriod(INFINITE_EXPIRATION_PERIOD)
41 , m_hasInfiniteExpirationPeriod(true)
42{
43}
44
45LsaInfo::LsaInfo(const ndn::Block& block)
46{
47 wireDecode(block);
48}
49
Alexander Afanasyevf9f39102015-12-01 17:43:40 -080050template<ndn::encoding::Tag TAG>
Jiewen Tan7a56d1c2015-01-26 23:26:51 -080051size_t
Alexander Afanasyevf9f39102015-12-01 17:43:40 -080052LsaInfo::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
Jiewen Tan7a56d1c2015-01-26 23:26:51 -080053{
54 size_t totalLength = 0;
55
56 // Absence of an ExpirationPeriod signifies non-expiration
57 if (!m_hasInfiniteExpirationPeriod) {
Vince Lehmanf4772d42015-06-29 14:02:22 -050058 totalLength += prependNonNegativeIntegerBlock(encoder,
59 ndn::tlv::nlsr::ExpirationPeriod,
60 m_expirationPeriod.count());
Jiewen Tan7a56d1c2015-01-26 23:26:51 -080061 }
62
Vince Lehmanf4772d42015-06-29 14:02:22 -050063 totalLength += prependNonNegativeIntegerBlock(encoder,
64 ndn::tlv::nlsr::SequenceNumber,
65 m_sequenceNumber);
Jiewen Tan7a56d1c2015-01-26 23:26:51 -080066
Vince Lehmanf4772d42015-06-29 14:02:22 -050067 totalLength += prependNestedBlock(encoder, ndn::tlv::nlsr::OriginRouter, m_originRouter);
Jiewen Tan7a56d1c2015-01-26 23:26:51 -080068
Vince Lehmanf4772d42015-06-29 14:02:22 -050069 totalLength += encoder.prependVarNumber(totalLength);
70 totalLength += encoder.prependVarNumber(ndn::tlv::nlsr::LsaInfo);
Jiewen Tan7a56d1c2015-01-26 23:26:51 -080071
72 return totalLength;
73}
74
Alexander Afanasyev67758b12018-03-06 18:36:44 -050075NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(LsaInfo);
Jiewen Tan7a56d1c2015-01-26 23:26:51 -080076
77const ndn::Block&
78LsaInfo::wireEncode() const
79{
80 if (m_wire.hasWire()) {
81 return m_wire;
82 }
83
84 ndn::EncodingEstimator estimator;
85 size_t estimatedSize = wireEncode(estimator);
86
87 ndn::EncodingBuffer buffer(estimatedSize, 0);
88 wireEncode(buffer);
89
90 m_wire = buffer.block();
91
92 return m_wire;
93}
94
95void
96LsaInfo::wireDecode(const ndn::Block& wire)
97{
98 m_originRouter.clear();
99 m_sequenceNumber = 0;
100 m_expirationPeriod = ndn::time::milliseconds::min();
101
102 m_wire = wire;
103
104 if (m_wire.type() != ndn::tlv::nlsr::LsaInfo) {
105 std::stringstream error;
106 error << "Expected LsaInfo Block, but Block is of a different type: #"
107 << m_wire.type();
dmcoomes9f936662017-03-02 10:33:09 -0600108 BOOST_THROW_EXCEPTION(Error(error.str()));
Jiewen Tan7a56d1c2015-01-26 23:26:51 -0800109 }
110
111 m_wire.parse();
112
113 ndn::Block::element_const_iterator val = m_wire.elements_begin();
114
115 if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::OriginRouter) {
116 val->parse();
117 ndn::Block::element_const_iterator it = val->elements_begin();
118
119 if (it != val->elements_end() && it->type() == ndn::tlv::Name) {
120 m_originRouter.wireDecode(*it);
121 }
122 else {
dmcoomes9f936662017-03-02 10:33:09 -0600123 BOOST_THROW_EXCEPTION(Error("OriginRouter: Missing required Name field"));
Jiewen Tan7a56d1c2015-01-26 23:26:51 -0800124 }
125
126 ++val;
127 }
128 else {
dmcoomes9f936662017-03-02 10:33:09 -0600129 BOOST_THROW_EXCEPTION(Error("Missing required OriginRouter field"));
Jiewen Tan7a56d1c2015-01-26 23:26:51 -0800130 }
131
132 if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::SequenceNumber) {
133 m_sequenceNumber = ndn::readNonNegativeInteger(*val);
134 ++val;
135 }
136 else {
dmcoomes9f936662017-03-02 10:33:09 -0600137 BOOST_THROW_EXCEPTION(Error("Missing required SequenceNumber field"));
Jiewen Tan7a56d1c2015-01-26 23:26:51 -0800138 }
139
140 if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::ExpirationPeriod) {
141 m_expirationPeriod = ndn::time::milliseconds(ndn::readNonNegativeInteger(*val));
142 m_hasInfiniteExpirationPeriod = false;
143 }
144 else {
145 m_expirationPeriod = INFINITE_EXPIRATION_PERIOD;
146 m_hasInfiniteExpirationPeriod = true;
147 }
148}
149
150std::ostream&
151operator<<(std::ostream& os, const LsaInfo& lsaInfo)
152{
153 os << "LsaInfo("
154 << "OriginRouter: " << lsaInfo.getOriginRouter() << ", "
155 << "SequenceNumber: " << lsaInfo.getSequenceNumber() << ", ";
156
157 if (!lsaInfo.hasInfiniteExpirationPeriod()) {
158 os << "ExpirationPeriod: " << lsaInfo.getExpirationPeriod();
159 }
160 else {
161 os << "ExpirationPeriod: Infinity";
162 }
163
164 os << ")";
165
166 return os;
167}
168
Jiewen Tana0497d82015-02-02 21:59:18 -0800169std::shared_ptr<LsaInfo>
170makeLsaInfo(const Lsa& lsa)
171{
172 std::shared_ptr<LsaInfo> lsaInfo = std::make_shared<LsaInfo>();
173
174 lsaInfo->setOriginRouter(lsa.getOrigRouter());
175 lsaInfo->setSequenceNumber(lsa.getLsSeqNo());
176
177 ndn::time::system_clock::duration duration
178 = lsa.getExpirationTimePoint() - ndn::time::system_clock::now();
179
180 lsaInfo->setExpirationPeriod(ndn::time::duration_cast<ndn::time::milliseconds>(duration));
181
182 return lsaInfo;
183}
184
Jiewen Tan7a56d1c2015-01-26 23:26:51 -0800185} // namespace tlv
186} // namespace nlsr