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