blob: fe8635e3137a43e4b956ae106a8c5aabaaae02bd [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/*
Junxiao Shib5734842024-01-09 21:14:53 +00003 * Copyright (c) 2014-2024, 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"
Junxiao Shib5734842024-01-09 21:14:53 +000024#include "utility/numeric.hpp"
akmhoquec8a10f72014-04-25 18:42:55 -050025
akmhoque53353462014-04-22 08:43:45 -050026namespace nlsr {
27
dmcoomescf8d0ed2017-02-21 11:39:01 -060028INIT_LOGGER(Adjacent);
akmhoque674b0b12014-05-20 14:33:28 -050029
akmhoque157b0a42014-05-13 00:26:37 -050030Adjacent::Adjacent()
Davide Pesaventod90338d2021-01-07 17:50:05 -050031 : m_name()
32 , m_faceUri()
33 , m_linkCost(DEFAULT_LINK_COST)
34 , m_status(STATUS_INACTIVE)
35 , m_interestTimedOutNo(0)
36 , m_faceId(0)
akmhoque157b0a42014-05-13 00:26:37 -050037{
38}
39
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080040Adjacent::Adjacent(const ndn::Block& block)
41{
42 wireDecode(block);
43}
44
akmhoque157b0a42014-05-13 00:26:37 -050045Adjacent::Adjacent(const ndn::Name& an)
Davide Pesaventod90338d2021-01-07 17:50:05 -050046 : m_name(an)
47 , m_faceUri()
48 , m_linkCost(DEFAULT_LINK_COST)
49 , m_status(STATUS_INACTIVE)
50 , m_interestTimedOutNo(0)
51 , m_faceId(0)
52{
53}
akmhoque157b0a42014-05-13 00:26:37 -050054
Ashlesh Gawande41878572019-09-29 00:16:02 -050055Adjacent::Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
Vince Lehmancb76ade2014-08-28 21:24:41 -050056 Status s, uint32_t iton, uint64_t faceId)
Davide Pesaventod90338d2021-01-07 17:50:05 -050057 : m_name(an)
58 , m_faceUri(faceUri)
59 , m_status(s)
60 , m_interestTimedOutNo(iton)
61 , m_faceId(faceId)
62{
63 this->setLinkCost(lc);
64}
akmhoque53353462014-04-22 08:43:45 -050065
dulalsaurabd0816a32019-07-26 13:11:24 +000066void
67Adjacent::setLinkCost(double lc)
68{
69 // NON_ADJACENT_COST is a negative value and is used for nodes that aren't direct neighbors.
70 // But for direct/active neighbors, the cost cannot be negative.
Davide Pesaventod90338d2021-01-07 17:50:05 -050071 if (lc < 0 && lc != NON_ADJACENT_COST) {
dulalsaurabd0816a32019-07-26 13:11:24 +000072 NLSR_LOG_ERROR(" Neighbor's link-cost cannot be negative");
Davide Pesaventod90338d2021-01-07 17:50:05 -050073 NDN_THROW(ndn::tlv::Error("Neighbor's link-cost cannot be negative"));
dulalsaurabd0816a32019-07-26 13:11:24 +000074 }
75
76 m_linkCost = lc;
77}
78
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080079NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Adjacent);
80
81template<ndn::encoding::Tag TAG>
82size_t
83Adjacent::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
84{
85 size_t totalLength = 0;
86
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -040087 totalLength += prependDoubleBlock(encoder, nlsr::tlv::Cost, m_linkCost);
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080088
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -040089 totalLength += prependStringBlock(encoder, nlsr::tlv::Uri, m_faceUri.toString());
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080090
91 totalLength += m_name.wireEncode(encoder);
92
93 totalLength += encoder.prependVarNumber(totalLength);
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -040094 totalLength += encoder.prependVarNumber(nlsr::tlv::Adjacency);
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080095
96 return totalLength;
97}
98
99const ndn::Block&
100Adjacent::wireEncode() const
101{
102 if (m_wire.hasWire()) {
103 return m_wire;
104 }
105
106 ndn::EncodingEstimator estimator;
107 size_t estimatedSize = wireEncode(estimator);
108
109 ndn::EncodingBuffer buffer(estimatedSize, 0);
110 wireEncode(buffer);
111
112 m_wire = buffer.block();
113
114 return m_wire;
115}
116
117void
118Adjacent::wireDecode(const ndn::Block& wire)
119{
120 m_name.clear();
121 m_faceUri = ndn::FaceUri();
122 m_linkCost = 0;
123
124 m_wire = wire;
125
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -0400126 if (m_wire.type() != nlsr::tlv::Adjacency) {
Davide Pesaventod90338d2021-01-07 17:50:05 -0500127 NDN_THROW(Error("Adjacency", m_wire.type()));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800128 }
129
130 m_wire.parse();
131
Davide Pesaventod90338d2021-01-07 17:50:05 -0500132 auto val = m_wire.elements_begin();
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800133
134 if (val != m_wire.elements_end() && val->type() == ndn::tlv::Name) {
135 m_name.wireDecode(*val);
136 ++val;
137 }
138 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -0500139 NDN_THROW(Error("Missing required Name field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800140 }
141
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -0400142 if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Uri) {
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800143 m_faceUri = ndn::FaceUri(readString(*val));
144 ++val;
145 }
146 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -0500147 NDN_THROW(Error("Missing required Uri field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800148 }
149
Davide Pesaventoc1d0e8e2022-06-15 14:26:02 -0400150 if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Cost) {
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800151 m_linkCost = ndn::encoding::readDouble(*val);
152 ++val;
153 }
154 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -0500155 NDN_THROW(Error("Missing required Cost field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800156 }
157}
158
akmhoque53353462014-04-22 08:43:45 -0500159bool
akmhoquefdbddb12014-05-02 18:35:19 -0500160Adjacent::operator==(const Adjacent& adjacent) const
akmhoque53353462014-04-22 08:43:45 -0500161{
Junxiao Shib5734842024-01-09 21:14:53 +0000162 return m_name == adjacent.getName() &&
163 m_faceUri == adjacent.getFaceUri() &&
164 util::diffInEpsilon(m_linkCost, adjacent.getLinkCost());
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