lsa.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "lsa.hpp"
23 #include "nlsr.hpp"
24 #include "name-prefix-list.hpp"
25 #include "adjacent.hpp"
26 #include "logger.hpp"
27 
28 #include <string>
29 #include <iostream>
30 #include <sstream>
31 #include <algorithm>
32 #include <cmath>
33 #include <limits>
34 #include <boost/algorithm/string.hpp>
35 
36 namespace nlsr {
37 
38 INIT_LOGGER(Lsa);
39 
40 std::string
41 Lsa::getData() const
42 {
43  std::ostringstream os;
44  os << m_origRouter << "|" << getType() << "|" << m_lsSeqNo << "|"
45  << ndn::time::toIsoString(m_expirationTimePoint) << "|";
46  return os.str();
47 }
48 
49 const ndn::Name
50 Lsa::getKey() const
51 {
52  return ndn::Name(m_origRouter).append(std::to_string(getType()));
53 }
54 
55 bool
56 Lsa::deserializeCommon(boost::tokenizer<boost::char_separator<char>>::iterator& iterator)
57 {
58  m_origRouter = ndn::Name(*iterator++);
59  if (m_origRouter.size() <= 0)
60  return false;
61  if (*iterator++ != std::to_string(getType()))
62  return false;
63  m_lsSeqNo = boost::lexical_cast<uint32_t>(*iterator++);
64  m_expirationTimePoint = ndn::time::fromIsoString(*iterator++);
65  return true;
66 }
67 
68 NameLsa::NameLsa(const ndn::Name& origR, uint32_t lsn,
69  const ndn::time::system_clock::TimePoint& lt,
70  NamePrefixList& npl)
71 {
72  m_origRouter = origR;
73  m_lsSeqNo = lsn;
75  for (const auto& name : npl.getNames()) {
76  addName(name);
77  }
78 }
79 
80 std::string
82 {
83  std::ostringstream os;
84  os << getData() << m_npl.size();
85  for (const auto& name : m_npl.getNames()) {
86  os << "|" << name;
87  }
88  os << "|";
89  return os.str();
90 }
91 
92 bool
93 NameLsa::deserialize(const std::string& content) noexcept
94 {
95  uint32_t numName = 0;
96  boost::char_separator<char> sep("|");
97  boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
98  boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
99  tokens.begin();
100 
101  try {
102  if (!deserializeCommon(tok_iter))
103  return false;
104  numName = boost::lexical_cast<uint32_t>(*tok_iter++);
105  for (uint32_t i = 0; i < numName; i++) {
106  ndn::Name name(*tok_iter++);
107  addName(name);
108  }
109  }
110  catch (const std::exception& e) {
111  NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
112  return false;
113  }
114  return true;
115 }
116 
117 bool
118 NameLsa::isEqualContent(const NameLsa& other) const
119 {
120  return m_npl == other.getNpl();
121 }
122 
123 void
125 {
126  NLSR_LOG_DEBUG(*this);
127 }
128 
129 CoordinateLsa::CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
130  const ndn::time::system_clock::TimePoint& lt,
131  double r, std::vector<double> theta)
132 {
133  m_origRouter = origR;
134  m_lsSeqNo = lsn;
136  m_corRad = r;
137  m_angles = theta;
138 }
139 
140 bool
142 {
143  if (clsa.getCorTheta().size() != m_angles.size()) {
144  return false;
145  }
146 
147  std::vector<double> m_angles2 = clsa.getCorTheta();
148  for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
149  if (std::abs(m_angles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
150  return false;
151  }
152  }
153 
154  return (std::abs(m_corRad - clsa.getCorRadius()) <
155  std::numeric_limits<double>::epsilon());
156 }
157 
158 std::string
160 {
161  std::ostringstream os;
162  os << getData() << m_corRad << "|" << m_angles.size() << "|";
163  for (const auto& angle: m_angles) {
164  os << angle << "|";
165  }
166  return os.str();
167 }
168 
169 bool
170 CoordinateLsa::deserialize(const std::string& content) noexcept
171 {
172  boost::char_separator<char> sep("|");
173  boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
174  boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
175  tokens.begin();
176 
177  try {
178  if (!deserializeCommon(tok_iter))
179  return false;
180  m_corRad = boost::lexical_cast<double>(*tok_iter++);
181  int numAngles = boost::lexical_cast<uint32_t>(*tok_iter++);
182  for (int i = 0; i < numAngles; i++) {
183  m_angles.push_back(boost::lexical_cast<double>(*tok_iter++));
184  }
185  }
186  catch (const std::exception& e) {
187  NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
188  return false;
189  }
190  return true;
191 }
192 
193 void
195 {
196  NLSR_LOG_DEBUG(*this);
197 }
198 
199 AdjLsa::AdjLsa(const ndn::Name& origR, uint32_t lsn,
200  const ndn::time::system_clock::TimePoint& lt,
201  uint32_t nl , AdjacencyList& adl)
202 {
203  m_origRouter = origR;
204  m_lsSeqNo = lsn;
206  m_noLink = nl;
207  std::list<Adjacent> al = adl.getAdjList();
208  for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++) {
209  if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
210  addAdjacent((*it));
211  }
212  }
213 }
214 
215 bool
216 AdjLsa::isEqualContent(const AdjLsa& alsa) const
217 {
218  return m_adl == alsa.getAdl();
219 }
220 
221 std::string
223 {
224  std::ostringstream os;
225  os << getData() << m_adl.size();
226  for (const auto& adjacent : m_adl.getAdjList()) {
227  os << "|" << adjacent.getName() << "|" << adjacent.getFaceUri()
228  << "|" << adjacent.getLinkCost();
229  }
230  os << "|";
231  return os.str();
232 }
233 
234 bool
235 AdjLsa::deserialize(const std::string& content) noexcept
236 {
237  uint32_t numLink = 0;
238  boost::char_separator<char> sep("|");
239  boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
240  boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
241  tokens.begin();
242 
243  try {
244  if (!deserializeCommon(tok_iter))
245  return false;
246  numLink = boost::lexical_cast<uint32_t>(*tok_iter++);
247  for (uint32_t i = 0; i < numLink; i++) {
248  ndn::Name adjName(*tok_iter++);
249  std::string connectingFaceUri(*tok_iter++);
250  double linkCost = boost::lexical_cast<double>(*tok_iter++);
251 
252  Adjacent adjacent(adjName, ndn::FaceUri(connectingFaceUri), linkCost,
254  addAdjacent(adjacent);
255  }
256  }
257  // Ignore neighbors with negative cost received from the Adjacent LSA data.
258  catch (const ndn::tlv::Error& e) {
259  NLSR_LOG_ERROR(e.what());
260  }
261  catch (const std::exception& e) {
262  NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
263  return false;
264  }
265  return true;
266 }
267 
268 void
270 {
271  NLSR_LOG_DEBUG(*this);
272 }
273 
274 std::ostream&
275 operator<<(std::ostream& os, const AdjLsa& lsa)
276 {
277  os << lsa.toString();
278  os << "-Adjacents:";
279 
280  int adjacencyIndex = 1;
281 
282  for (const Adjacent& adjacency : lsa.m_adl) {
283  os << "--Adjacent" << adjacencyIndex++ << ":\n"
284  << "---Adjacent Name: " << adjacency.getName() << "\n"
285  << "---Connecting FaceUri: " << adjacency.getFaceUri() << "\n"
286  << "---Link Cost: " << adjacency.getLinkCost() << "\n";
287  }
288  os << "adj_lsa_end";
289 
290  return os;
291 }
292 
293 std::ostream&
294 operator<<(std::ostream& os, const CoordinateLsa& lsa)
295 {
296  os << lsa.toString();
297  os << "--Hyperbolic Radius: " << lsa.m_corRad << "\n";
298  int i = 0;
299  for (const auto& value : lsa.m_angles) {
300  os << "---Hyperbolic Theta: " << i++ << ": " << value << "\n";
301  }
302  os << "cor_lsa_end";
303 
304  return os;
305 }
306 
307 std::ostream&
308 operator<<(std::ostream& os, const NameLsa& lsa)
309 {
310  os << lsa.toString();
311  os << "--Names:\n";
312  int i = 0;
313  auto names = lsa.m_npl.getNames();
314  for (const auto& name : names) {
315  os << "---Name " << i++ << ": " << name << "\n";
316  }
317  os << "name_lsa_end";
318 
319  return os;
320 }
321 
322 std::ostream&
323 operator<<(std::ostream& os, const Lsa::Type& type)
324 {
325  os << std::to_string(type);
326  return os;
327 }
328 
329 std::istream&
330 operator>>(std::istream& is, Lsa::Type& type)
331 {
332  std::string typeString;
333  is >> typeString;
334  if (typeString == "ADJACENCY") {
335  type = Lsa::Type::ADJACENCY;
336  }
337  else if (typeString == "COORDINATE") {
338  type = Lsa::Type::COORDINATE;
339  }
340  else if (typeString == "NAME") {
341  type = Lsa::Type::NAME;
342  }
343  else {
344  type = Lsa::Type::BASE;
345  }
346  return is;
347 }
348 
349 std::string
351 {
352  std::ostringstream os;
353  os << "LSA of type " << getType() << ":\n-Origin Router: " << getOrigRouter()
354  << "\n-Sequence Number: " << getLsSeqNo() << "\n-Expiration Point: "
355  << getExpirationTimePoint() << "\n";
356  return os.str();
357 }
358 
359 } // namespace nlsr
360 
361 namespace std {
362 std::string
364 {
365  switch (type) {
367  return "ADJACENCY";
369  return "COORDINATE";
371  return "NAME";
373  return "MOCK";
374  default:
375  return "BASE";
376  }
377 }
378 
379 } // namespace std
ndn::time::system_clock::TimePoint m_expirationTimePoint
Definition: lsa.hpp:146
CoordinateLsa()=default
std::string getData() const
Definition: lsa.cpp:41
std::string to_string(const nlsr::Lsa::Type &type)
Definition: lsa.cpp:363
std::ostream & operator<<(std::ostream &os, const Adjacent &adjacent)
Definition: adjacent.cpp:99
const ndn::time::system_clock::TimePoint & getExpirationTimePoint() const
Definition: lsa.hpp:80
const ndn::FaceUri & getFaceUri() const
Definition: adjacent.hpp:69
std::string serialize() const override
Returns the data this adjacency LSA has.
Definition: lsa.cpp:222
std::list< ndn::Name > getNames() const
AdjacencyList & getAdl()
Definition: lsa.hpp:240
ndn::Name m_origRouter
Definition: lsa.hpp:144
double getLinkCost() const
Definition: adjacent.hpp:81
bool deserialize(const std::string &content) noexceptoverride
Initializes this LSA object with content&#39;s data.
Definition: lsa.cpp:93
void writeLog() const override
Definition: lsa.cpp:269
NamePrefixList & getNpl()
Definition: lsa.hpp:166
NameLsa()=default
#define NLSR_LOG_DEBUG(x)
Definition: logger.hpp:38
bool deserializeCommon(boost::tokenizer< boost::char_separator< char >>::iterator &iterator)
Definition: lsa.cpp:56
STL namespace.
void writeLog() const override
Definition: lsa.cpp:194
bool deserialize(const std::string &content) noexceptoverride
Initializes this adj. LSA from the supplied content.
Definition: lsa.cpp:235
std::string toString() const
Definition: lsa.cpp:350
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California.
#define INIT_LOGGER(name)
Definition: logger.hpp:35
const ndn::Name & getOrigRouter() const
Definition: lsa.hpp:68
const ndn::Name & getName() const
Definition: adjacent.hpp:57
uint32_t getLsSeqNo() const
Definition: lsa.hpp:62
void writeLog() const override
Definition: lsa.cpp:124
uint32_t m_lsSeqNo
Definition: lsa.hpp:145
bool isEqualContent(const NameLsa &other) const
Definition: lsa.cpp:118
virtual Type getType() const
Definition: lsa.hpp:50
bool isEqualContent(const AdjLsa &alsa) const
Definition: lsa.cpp:216
std::string serialize() const override
Returns the data that this name LSA has.
Definition: lsa.cpp:81
A neighbor reachable over a Face.
Definition: adjacent.hpp:38
bool isEqualContent(const CoordinateLsa &clsa) const
Definition: lsa.cpp:141
#define NLSR_LOG_ERROR(x)
Definition: logger.hpp:41
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
const std::vector< double > getCorTheta() const
Definition: lsa.hpp:346
std::istream & operator>>(std::istream &is, Lsa::Type &type)
Definition: lsa.cpp:330
const ndn::Name getKey() const
Gets the key for this LSA.
Definition: lsa.cpp:50
bool deserialize(const std::string &content) noexceptoverride
Initializes this coordinate LSA with the data in content.
Definition: lsa.cpp:170
std::string serialize() const override
Returns the data that this coordinate LSA represents.
Definition: lsa.cpp:159
AdjLsa()=default
std::list< Adjacent > & getAdjList()
double getCorRadius() const
Definition: lsa.hpp:334