blob: 637ea90471d5f5a88e65a5c81f8615264d547861 [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 Pesaventod90338d2021-01-07 17:50:05 -05003 * Copyright (c) 2014-2021, 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
dulalsaurabd0816a32019-07-26 13:11:24 +000029const double Adjacent::DEFAULT_LINK_COST = 10.0;
30const double Adjacent::NON_ADJACENT_COST = -12345;
akmhoque157b0a42014-05-13 00:26:37 -050031
32Adjacent::Adjacent()
Davide Pesaventod90338d2021-01-07 17:50:05 -050033 : m_name()
34 , m_faceUri()
35 , m_linkCost(DEFAULT_LINK_COST)
36 , m_status(STATUS_INACTIVE)
37 , m_interestTimedOutNo(0)
38 , m_faceId(0)
akmhoque157b0a42014-05-13 00:26:37 -050039{
40}
41
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080042Adjacent::Adjacent(const ndn::Block& block)
43{
44 wireDecode(block);
45}
46
akmhoque157b0a42014-05-13 00:26:37 -050047Adjacent::Adjacent(const ndn::Name& an)
Davide Pesaventod90338d2021-01-07 17:50:05 -050048 : m_name(an)
49 , m_faceUri()
50 , m_linkCost(DEFAULT_LINK_COST)
51 , m_status(STATUS_INACTIVE)
52 , m_interestTimedOutNo(0)
53 , m_faceId(0)
54{
55}
akmhoque157b0a42014-05-13 00:26:37 -050056
Ashlesh Gawande41878572019-09-29 00:16:02 -050057Adjacent::Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
Vince Lehmancb76ade2014-08-28 21:24:41 -050058 Status s, uint32_t iton, uint64_t faceId)
Davide Pesaventod90338d2021-01-07 17:50:05 -050059 : m_name(an)
60 , m_faceUri(faceUri)
61 , m_status(s)
62 , m_interestTimedOutNo(iton)
63 , m_faceId(faceId)
64{
65 this->setLinkCost(lc);
66}
akmhoque53353462014-04-22 08:43:45 -050067
dulalsaurabd0816a32019-07-26 13:11:24 +000068void
69Adjacent::setLinkCost(double lc)
70{
71 // NON_ADJACENT_COST is a negative value and is used for nodes that aren't direct neighbors.
72 // But for direct/active neighbors, the cost cannot be negative.
Davide Pesaventod90338d2021-01-07 17:50:05 -050073 if (lc < 0 && lc != NON_ADJACENT_COST) {
dulalsaurabd0816a32019-07-26 13:11:24 +000074 NLSR_LOG_ERROR(" Neighbor's link-cost cannot be negative");
Davide Pesaventod90338d2021-01-07 17:50:05 -050075 NDN_THROW(ndn::tlv::Error("Neighbor's link-cost cannot be negative"));
dulalsaurabd0816a32019-07-26 13:11:24 +000076 }
77
78 m_linkCost = lc;
79}
80
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -080081NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Adjacent);
82
83template<ndn::encoding::Tag TAG>
84size_t
85Adjacent::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
86{
87 size_t totalLength = 0;
88
89 totalLength += prependDoubleBlock(encoder, ndn::tlv::nlsr::Cost, m_linkCost);
90
91 totalLength += prependStringBlock(encoder, ndn::tlv::nlsr::Uri, m_faceUri.toString());
92
93 totalLength += m_name.wireEncode(encoder);
94
95 totalLength += encoder.prependVarNumber(totalLength);
96 totalLength += encoder.prependVarNumber(ndn::tlv::nlsr::Adjacency);
97
98 return totalLength;
99}
100
101const ndn::Block&
102Adjacent::wireEncode() const
103{
104 if (m_wire.hasWire()) {
105 return m_wire;
106 }
107
108 ndn::EncodingEstimator estimator;
109 size_t estimatedSize = wireEncode(estimator);
110
111 ndn::EncodingBuffer buffer(estimatedSize, 0);
112 wireEncode(buffer);
113
114 m_wire = buffer.block();
115
116 return m_wire;
117}
118
119void
120Adjacent::wireDecode(const ndn::Block& wire)
121{
122 m_name.clear();
123 m_faceUri = ndn::FaceUri();
124 m_linkCost = 0;
125
126 m_wire = wire;
127
128 if (m_wire.type() != ndn::tlv::nlsr::Adjacency) {
Davide Pesaventod90338d2021-01-07 17:50:05 -0500129 NDN_THROW(Error("Adjacency", m_wire.type()));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800130 }
131
132 m_wire.parse();
133
Davide Pesaventod90338d2021-01-07 17:50:05 -0500134 auto val = m_wire.elements_begin();
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800135
136 if (val != m_wire.elements_end() && val->type() == ndn::tlv::Name) {
137 m_name.wireDecode(*val);
138 ++val;
139 }
140 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -0500141 NDN_THROW(Error("Missing required Name field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800142 }
143
144 if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Uri) {
145 m_faceUri = ndn::FaceUri(readString(*val));
146 ++val;
147 }
148 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -0500149 NDN_THROW(Error("Missing required Uri field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800150 }
151
152 if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Cost) {
153 m_linkCost = ndn::encoding::readDouble(*val);
154 ++val;
155 }
156 else {
Davide Pesaventod90338d2021-01-07 17:50:05 -0500157 NDN_THROW(Error("Missing required Cost field"));
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800158 }
159}
160
akmhoque53353462014-04-22 08:43:45 -0500161bool
akmhoquefdbddb12014-05-02 18:35:19 -0500162Adjacent::operator==(const Adjacent& adjacent) const
akmhoque53353462014-04-22 08:43:45 -0500163{
akmhoquefdbddb12014-05-02 18:35:19 -0500164 return (m_name == adjacent.getName()) &&
Nick Gordone9733ed2017-04-26 10:48:39 -0500165 (m_faceUri == adjacent.getFaceUri()) &&
akmhoquefdbddb12014-05-02 18:35:19 -0500166 (std::abs(m_linkCost - adjacent.getLinkCost()) <
Nick Gordone9733ed2017-04-26 10:48:39 -0500167 std::numeric_limits<double>::epsilon());
akmhoque53353462014-04-22 08:43:45 -0500168}
169
Nick Gordon2a1ac612017-10-06 15:36:49 -0500170bool
171Adjacent::operator<(const Adjacent& adjacent) const
172{
Ashlesh Gawandee8d8bd52018-08-09 17:18:51 -0500173 auto linkCost = adjacent.getLinkCost();
174 return std::tie(m_name, m_linkCost) <
175 std::tie(adjacent.getName(), linkCost);
Nick Gordon2a1ac612017-10-06 15:36:49 -0500176}
177
178std::ostream&
179operator<<(std::ostream& os, const Adjacent& adjacent)
180{
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800181 os << "Adjacent: " << adjacent.m_name
182 << "\n\t\tConnecting FaceUri: " << adjacent.m_faceUri
183 << "\n\t\tLink cost: " << adjacent.m_linkCost
184 << "\n\t\tStatus: " << adjacent.m_status
185 << "\n\t\tInterest Timed Out: " << adjacent.m_interestTimedOutNo << std::endl;
Nick Gordon2a1ac612017-10-06 15:36:49 -0500186 return os;
187}
188
Nick Gordonfad8e252016-08-11 14:21:38 -0500189} // namespace nlsr