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 "lsa.hpp"
23 #include "tlv-nlsr.hpp"
24 
25 namespace nlsr {
26 
27 Lsa::Lsa(const ndn::Name& originRouter, uint64_t seqNo,
28  ndn::time::system_clock::time_point expirationTimePoint)
29  : m_originRouter(originRouter)
30  , m_seqNo(seqNo)
31  , m_expirationTimePoint(expirationTimePoint)
32 {
33 }
34 
35 Lsa::Lsa(const Lsa& lsa)
36  : m_originRouter(lsa.getOriginRouter())
37  , m_seqNo(lsa.getSeqNo())
38  , m_expirationTimePoint(lsa.getExpirationTimePoint())
39 {
40 }
41 
42 template<ndn::encoding::Tag TAG>
43 size_t
44 Lsa::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
45 {
46  size_t totalLength = 0;
47 
48  totalLength += prependStringBlock(encoder,
50  ndn::time::toString(m_expirationTimePoint));
51 
52  totalLength += prependNonNegativeIntegerBlock(encoder, nlsr::tlv::SequenceNumber, m_seqNo);
53 
54  totalLength += m_originRouter.wireEncode(encoder);
55 
56  totalLength += encoder.prependVarNumber(totalLength);
57  totalLength += encoder.prependVarNumber(nlsr::tlv::Lsa);
58 
59  return totalLength;
60 }
61 
63 
64 void
65 Lsa::wireDecode(const ndn::Block& wire)
66 {
67  m_originRouter.clear();
68  m_seqNo = 0;
69 
70  ndn::Block baseWire = wire;
71  baseWire.parse();
72 
73  auto val = baseWire.elements_begin();
74 
75  if (val != baseWire.elements_end() && val->type() == ndn::tlv::Name) {
76  m_originRouter.wireDecode(*val);
77  }
78  else {
79  NDN_THROW(Error("OriginRouter: Missing required Name field"));
80  }
81 
82  ++val;
83 
84  if (val != baseWire.elements_end() && val->type() == nlsr::tlv::SequenceNumber) {
85  m_seqNo = ndn::readNonNegativeInteger(*val);
86  ++val;
87  }
88  else {
89  NDN_THROW(Error("Missing required SequenceNumber field"));
90  }
91 
92  if (val != baseWire.elements_end() && val->type() == nlsr::tlv::ExpirationTime) {
93  m_expirationTimePoint = ndn::time::fromString(readString(*val));
94  }
95  else {
96  NDN_THROW(Error("Missing required ExpirationTime field"));
97  }
98 }
99 
100 std::ostream&
101 operator<<(std::ostream& os, const Lsa& lsa)
102 {
103  auto duration = lsa.m_expirationTimePoint - ndn::time::system_clock::now();
104  os << " " << lsa.getType() << " LSA:\n"
105  << " Origin Router : " << lsa.m_originRouter << "\n"
106  << " Sequence Number : " << lsa.m_seqNo << "\n"
107  << " Expires in : " << ndn::time::duration_cast<ndn::time::milliseconds>(duration)
108  << "\n";
109  lsa.print(os);
110  return os;
111 }
112 
113 std::ostream&
114 operator<<(std::ostream& os, const Lsa::Type& type)
115 {
116  switch (type) {
118  os << "ADJACENCY";
119  break;
121  os << "COORDINATE";
122  break;
123  case Lsa::Type::NAME:
124  os << "NAME";
125  break;
126  default:
127  os << "BASE";
128  break;
129  }
130  return os;
131 }
132 
133 std::istream&
134 operator>>(std::istream& is, Lsa::Type& type)
135 {
136  std::string typeString;
137  is >> typeString;
138  if (typeString == "ADJACENCY") {
139  type = Lsa::Type::ADJACENCY;
140  }
141  else if (typeString == "COORDINATE") {
142  type = Lsa::Type::COORDINATE;
143  }
144  else if (typeString == "NAME") {
145  type = Lsa::Type::NAME;
146  }
147  else {
148  type = Lsa::Type::BASE;
149  }
150  return is;
151 }
152 
153 } // namespace nlsr
Represents a Link State Announcement (LSA).
Definition: lsa.hpp:46
virtual const ndn::Block & wireEncode() const =0
virtual Type getType() const =0
Lsa()=default
uint64_t m_seqNo
Definition: lsa.hpp:138
ndn::time::system_clock::time_point m_expirationTimePoint
Definition: lsa.hpp:139
void wireDecode(const ndn::Block &wire)
Definition: lsa.cpp:65
ndn::Name m_originRouter
Definition: lsa.hpp:137
@ SequenceNumber
Definition: tlv-nlsr.hpp:34
@ ExpirationTime
Definition: tlv-nlsr.hpp:43
Copyright (c) 2014-2020, The University of Memphis, Regents of the University of California.
std::istream & operator>>(std::istream &is, Lsa::Type &type)
Definition: lsa.cpp:134
std::ostream & operator<<(std::ostream &os, const Adjacent &adjacent)
Definition: adjacent.cpp:176
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Adjacent)