blob: 508832a2ce03ef8be7e833afef10cc7526d3a1eb [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Ashlesh Gawande0421bc62020-05-08 20:42:19 -07002/*
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -04003 * Copyright (c) 2014-2022, The University of Memphis,
Nick Gordonf8b5bcd2016-08-11 15:06:50 -05004 * Regents of the University of California
akmhoque3d06e792014-05-27 16:23:20 -05005 *
6 * This file is part of NLSR (Named-data Link State Routing).
7 * See AUTHORS.md for complete list of NLSR authors and contributors.
8 *
9 * NLSR is free software: you can redistribute it and/or modify it under the terms
10 * of the GNU General Public License as published by the Free Software Foundation,
11 * either version 3 of the License, or (at your option) any later version.
12 *
13 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070019 */
Nick Gordond0a7df32017-05-30 16:44:34 -050020
21#include "adjacent.hpp"
22#include "logger.hpp"
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070023#include "tlv-nlsr.hpp"
akmhoquec8a10f72014-04-25 18:42:55 -050024
akmhoque53353462014-04-22 08:43:45 -050025namespace nlsr {
26
dmcoomescf8d0ed2017-02-21 11:39:01 -060027INIT_LOGGER(Adjacent);
akmhoque674b0b12014-05-20 14:33:28 -050028
akmhoque157b0a42014-05-13 00:26:37 -050029Adjacent::Adjacent()
Davide Pesaventod90338d2021-01-07 17:50:05 -050030 : m_name()
31 , m_faceUri()
32 , m_linkCost(DEFAULT_LINK_COST)
33 , m_status(STATUS_INACTIVE)
34 , m_interestTimedOutNo(0)
35 , m_faceId(0)
akmhoque157b0a42014-05-13 00:26:37 -050036{
37}
38
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080039Adjacent::Adjacent(const ndn::Block& block)
40{
41 wireDecode(block);
42}
43
akmhoque157b0a42014-05-13 00:26:37 -050044Adjacent::Adjacent(const ndn::Name& an)
Davide Pesaventod90338d2021-01-07 17:50:05 -050045 : m_name(an)
46 , m_faceUri()
47 , m_linkCost(DEFAULT_LINK_COST)
48 , m_status(STATUS_INACTIVE)
49 , m_interestTimedOutNo(0)
50 , m_faceId(0)
51{
52}
akmhoque157b0a42014-05-13 00:26:37 -050053
Ashlesh Gawande41878572019-09-29 00:16:02 -050054Adjacent::Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
Vince Lehmancb76ade2014-08-28 21:24:41 -050055 Status s, uint32_t iton, uint64_t faceId)
Davide Pesaventod90338d2021-01-07 17:50:05 -050056 : m_name(an)
57 , m_faceUri(faceUri)
58 , m_status(s)
59 , m_interestTimedOutNo(iton)
60 , m_faceId(faceId)
61{
62 this->setLinkCost(lc);
63}
akmhoque53353462014-04-22 08:43:45 -050064
dulalsaurabd0816a32019-07-26 13:11:24 +000065void
66Adjacent::setLinkCost(double lc)
67{
68 // NON_ADJACENT_COST is a negative value and is used for nodes that aren't direct neighbors.
69 // But for direct/active neighbors, the cost cannot be negative.
Davide Pesaventod90338d2021-01-07 17:50:05 -050070 if (lc < 0 && lc != NON_ADJACENT_COST) {
dulalsaurabd0816a32019-07-26 13:11:24 +000071 NLSR_LOG_ERROR(" Neighbor's link-cost cannot be negative");
Davide Pesaventod90338d2021-01-07 17:50:05 -050072 NDN_THROW(ndn::tlv::Error("Neighbor's link-cost cannot be negative"));
dulalsaurabd0816a32019-07-26 13:11:24 +000073 }
74
75 m_linkCost = lc;
76}
77
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080078NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Adjacent);
79
80template<ndn::encoding::Tag TAG>
81size_t
82Adjacent::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
83{
84 size_t totalLength = 0;
85
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -040086 totalLength += prependDoubleBlock(encoder, nlsr::tlv::Cost, m_linkCost);
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080087
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -040088 totalLength += prependStringBlock(encoder, nlsr::tlv::Uri, m_faceUri.toString());
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080089
90 totalLength += m_name.wireEncode(encoder);
91
92 totalLength += encoder.prependVarNumber(totalLength);
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -040093 totalLength += encoder.prependVarNumber(nlsr::tlv::Adjacency);
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080094
95 return totalLength;
96}
97
98const ndn::Block&
99Adjacent::wireEncode() const
100{
101 if (m_wire.hasWire()) {
102 return m_wire;
103 }
104
105 ndn::EncodingEstimator estimator;
106 size_t estimatedSize = wireEncode(estimator);
107
108 ndn::EncodingBuffer buffer(estimatedSize, 0);
109 wireEncode(buffer);
110
111 m_wire = buffer.block();
112
113 return m_wire;
114}
115
116void
117Adjacent::wireDecode(const ndn::Block& wire)
118{
119 m_name.clear();
120 m_faceUri = ndn::FaceUri();
121 m_linkCost = 0;
122
123 m_wire = wire;
124
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -0400125 if (m_wire.type() != nlsr::tlv::Adjacency) {
Davide Pesaventod90338d2021-01-07 17:50:05 -0500126 NDN_THROW(Error("Adjacency", m_wire.type()));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800127 }
128
129 m_wire.parse();
130
Davide Pesaventod90338d2021-01-07 17:50:05 -0500131 auto val = m_wire.elements_begin();
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800132
133 if (val != m_wire.elements_end() && val->type() == ndn::tlv::Name) {
134 m_name.wireDecode(*val);
135 ++val;
136 }
137 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -0500138 NDN_THROW(Error("Missing required Name field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800139 }
140
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -0400141 if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Uri) {
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800142 m_faceUri = ndn::FaceUri(readString(*val));
143 ++val;
144 }
145 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -0500146 NDN_THROW(Error("Missing required Uri field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800147 }
148
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -0400149 if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Cost) {
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800150 m_linkCost = ndn::encoding::readDouble(*val);
151 ++val;
152 }
153 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -0500154 NDN_THROW(Error("Missing required Cost field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800155 }
156}
157
akmhoque53353462014-04-22 08:43:45 -0500158bool
akmhoquefdbddb12014-05-02 18:35:19 -0500159Adjacent::operator==(const Adjacent& adjacent) const
akmhoque53353462014-04-22 08:43:45 -0500160{
akmhoquefdbddb12014-05-02 18:35:19 -0500161 return (m_name == adjacent.getName()) &&
Nick Gordone9733ed2017-04-26 10:48:39 -0500162 (m_faceUri == adjacent.getFaceUri()) &&
akmhoquefdbddb12014-05-02 18:35:19 -0500163 (std::abs(m_linkCost - adjacent.getLinkCost()) <
Nick Gordone9733ed2017-04-26 10:48:39 -0500164 std::numeric_limits<double>::epsilon());
akmhoque53353462014-04-22 08:43:45 -0500165}
166
Nick Gordon2a1ac612017-10-06 15:36:49 -0500167bool
168Adjacent::operator<(const Adjacent& adjacent) const
169{
Ashlesh Gawandee8d8bd52018-08-09 17:18:51 -0500170 auto linkCost = adjacent.getLinkCost();
171 return std::tie(m_name, m_linkCost) <
172 std::tie(adjacent.getName(), linkCost);
Nick Gordon2a1ac612017-10-06 15:36:49 -0500173}
174
175std::ostream&
176operator<<(std::ostream& os, const Adjacent& adjacent)
177{
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800178 os << "Adjacent: " << adjacent.m_name
179 << "\n\t\tConnecting FaceUri: " << adjacent.m_faceUri
180 << "\n\t\tLink cost: " << adjacent.m_linkCost
181 << "\n\t\tStatus: " << adjacent.m_status
182 << "\n\t\tInterest Timed Out: " << adjacent.m_interestTimedOutNo << std::endl;
Nick Gordon2a1ac612017-10-06 15:36:49 -0500183 return os;
184}
185
Nick Gordonfad8e252016-08-11 14:21:38 -0500186} // namespace nlsr