coordinate-lsa.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014-2024, The University of Memphis,
4  * 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/>.
20  */
21 
22 #include "coordinate-lsa.hpp"
23 #include "tlv-nlsr.hpp"
24 
25 namespace nlsr {
26 
27 CoordinateLsa::CoordinateLsa(const ndn::Name& originRouter, uint64_t seqNo,
28  const ndn::time::system_clock::time_point& timepoint,
29  double radius, std::vector<double> angles)
30  : Lsa(originRouter, seqNo, timepoint)
31  , m_hyperbolicRadius(radius)
32  , m_hyperbolicAngles(angles)
33 {
34 }
35 
36 CoordinateLsa::CoordinateLsa(const ndn::Block& block)
37 {
38  wireDecode(block);
39 }
40 
41 template<ndn::encoding::Tag TAG>
42 size_t
43 CoordinateLsa::wireEncode(ndn::EncodingImpl<TAG>& block) const
44 {
45  size_t totalLength = 0;
46 
47  for (auto it = m_hyperbolicAngles.rbegin(); it != m_hyperbolicAngles.rend(); ++it) {
48  totalLength += ndn::encoding::prependDoubleBlock(block, nlsr::tlv::HyperbolicAngle, *it);
49  }
50 
51  totalLength += ndn::encoding::prependDoubleBlock(block, nlsr::tlv::HyperbolicRadius, m_hyperbolicRadius);
52 
53  totalLength += Lsa::wireEncode(block);
54 
55  totalLength += block.prependVarNumber(totalLength);
56  totalLength += block.prependVarNumber(nlsr::tlv::CoordinateLsa);
57 
58  return totalLength;
59 }
60 
62 
63 const ndn::Block&
65 {
66  if (m_wire.hasWire()) {
67  return m_wire;
68  }
69 
70  ndn::EncodingEstimator estimator;
71  size_t estimatedSize = wireEncode(estimator);
72 
73  ndn::EncodingBuffer buffer(estimatedSize, 0);
74  wireEncode(buffer);
75 
76  m_wire = buffer.block();
77 
78  return m_wire;
79 }
80 
81 void
82 CoordinateLsa::wireDecode(const ndn::Block& wire)
83 {
84  m_wire = wire;
85 
86  if (m_wire.type() != nlsr::tlv::CoordinateLsa) {
87  NDN_THROW(Error("CoordinateLsa", m_wire.type()));
88  }
89 
90  m_wire.parse();
91 
92  auto val = m_wire.elements_begin();
93 
94  if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Lsa) {
95  Lsa::wireDecode(*val);
96  ++val;
97  }
98  else {
99  NDN_THROW(Error("Missing required Lsa field"));
100  }
101 
102  if (val != m_wire.elements_end() && val->type() == nlsr::tlv::HyperbolicRadius) {
103  m_hyperbolicRadius = ndn::encoding::readDouble(*val);
104  ++val;
105  }
106  else {
107  NDN_THROW(Error("Missing required HyperbolicRadius field"));
108  }
109 
110  std::vector<double> angles;
111  for (; val != m_wire.elements_end(); ++val) {
112  if (val->type() == nlsr::tlv::HyperbolicAngle) {
113  angles.push_back(ndn::encoding::readDouble(*val));
114  }
115  else {
116  NDN_THROW(Error("Missing required HyperbolicAngle field"));
117  }
118  }
119  m_hyperbolicAngles = angles;
120 }
121 
122 void
123 CoordinateLsa::print(std::ostream& os) const
124 {
125  os << " Hyperbolic Radius : " << m_hyperbolicRadius << "\n";
126  int i = 0;
127  for (const auto& value : m_hyperbolicAngles) {
128  os << " Hyperbolic Theta " << i++ << " : " << value << "\n";
129  }
130 }
131 
132 std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
133 CoordinateLsa::update(const std::shared_ptr<Lsa>& lsa)
134 {
135  auto clsa = std::static_pointer_cast<CoordinateLsa>(lsa);
136  if (*this != *clsa) {
137  m_hyperbolicRadius = clsa->getRadius();
138  m_hyperbolicAngles.clear();
139  for (const auto& angle : clsa->getTheta()) {
140  m_hyperbolicAngles.push_back(angle);
141  }
142  return {true, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
143  }
144  return {false, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
145 }
146 
147 } // namespace nlsr
Represents an LSA of hyperbolic coordinates of the origin router.
const ndn::Block & wireEncode() const override
void wireDecode(const ndn::Block &wire)
CoordinateLsa()=default
std::tuple< bool, std::list< ndn::Name >, std::list< ndn::Name > > update(const std::shared_ptr< Lsa > &lsa) override
Represents a Link State Announcement (LSA).
Definition: lsa.hpp:46
virtual const ndn::Block & wireEncode() const =0
ndn::Block m_wire
Definition: lsa.hpp:142
void wireDecode(const ndn::Block &wire)
Definition: lsa.cpp:65
@ HyperbolicAngle
Definition: tlv-nlsr.hpp:40
@ CoordinateLsa
Definition: tlv-nlsr.hpp:37
@ HyperbolicRadius
Definition: tlv-nlsr.hpp:39
Copyright (c) 2014-2020, The University of Memphis, Regents of the University of California.
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Adjacent)