blob: 1b5e8046aa030977a0f5564b12e0e8aa0f8bd7f2 [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Nick Gordonfeae5572017-01-13 12:06:26 -06003 * Copyright (c) 2014-2017, The University of Memphis,
Vince Lehmanc2e51f62015-01-20 15:03:11 -06004 * Regents of the University of California,
5 * Arizona Board of Regents.
akmhoque3d06e792014-05-27 16:23:20 -05006 *
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/>.
akmhoque3d06e792014-05-27 16:23:20 -050020 **/
Vince Lehmanc2e51f62015-01-20 15:03:11 -060021
Nick Gordonf14ec352017-07-24 16:09:58 -050022#include "lsa.hpp"
23#include "nlsr.hpp"
24#include "name-prefix-list.hpp"
25#include "adjacent.hpp"
26#include "logger.hpp"
27
akmhoque53353462014-04-22 08:43:45 -050028#include <string>
29#include <iostream>
30#include <sstream>
31#include <algorithm>
32#include <cmath>
33#include <limits>
akmhoque31d1d4b2014-05-05 22:08:14 -050034#include <boost/tokenizer.hpp>
35#include <boost/algorithm/string.hpp>
akmhoque53353462014-04-22 08:43:45 -050036
akmhoque53353462014-04-22 08:43:45 -050037namespace nlsr {
38
akmhoque674b0b12014-05-20 14:33:28 -050039INIT_LOGGER("Lsa");
40
akmhoque31d1d4b2014-05-05 22:08:14 -050041const ndn::Name
akmhoqueb6450b12014-04-24 00:01:03 -050042NameLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -050043{
akmhoque31d1d4b2014-05-05 22:08:14 -050044 ndn::Name key = m_origRouter;
Nick Gordon727d4832017-10-13 18:04:25 -050045 key.append(std::to_string(Lsa::Type::NAME));
akmhoque53353462014-04-22 08:43:45 -050046 return key;
47}
48
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060049NameLsa::NameLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -050050 const ndn::time::system_clock::TimePoint& lt,
akmhoquefdbddb12014-05-02 18:35:19 -050051 NamePrefixList& npl)
akmhoque53353462014-04-22 08:43:45 -050052{
53 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -050054 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -050055 m_expirationTimePoint = lt;
Nick Gordonf14ec352017-07-24 16:09:58 -050056 for (const auto& name : npl.getNames()) {
57 addName(name);
akmhoque53353462014-04-22 08:43:45 -050058 }
59}
60
Nick Gordone98480b2017-05-24 11:23:03 -050061std::string
akmhoque53353462014-04-22 08:43:45 -050062NameLsa::getData()
63{
Nick Gordonadad2492017-05-25 10:53:07 -050064 std::ostringstream os;
Nick Gordon727d4832017-10-13 18:04:25 -050065 os << m_origRouter << "|" << Lsa::Type::NAME << "|" << m_lsSeqNo << "|"
Nick Gordonff9a6272017-10-12 13:38:29 -050066 << ndn::time::toIsoString(m_expirationTimePoint) << "|" << m_npl.size();
Nick Gordonf14ec352017-07-24 16:09:58 -050067 for (const auto& name : m_npl.getNames()) {
Nick Gordonadad2492017-05-25 10:53:07 -050068 os << "|" << name;
akmhoque53353462014-04-22 08:43:45 -050069 }
Nick Gordonadad2492017-05-25 10:53:07 -050070 os << "|";
71 return os.str();
akmhoque53353462014-04-22 08:43:45 -050072}
73
74bool
akmhoque31d1d4b2014-05-05 22:08:14 -050075NameLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -050076{
77 uint32_t numName = 0;
akmhoque31d1d4b2014-05-05 22:08:14 -050078 boost::char_separator<char> sep("|");
79 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
80 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
81 tokens.begin();
82 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -050083 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -050084 return false;
85 }
akmhoque31d1d4b2014-05-05 22:08:14 -050086 try {
Nick Gordon727d4832017-10-13 18:04:25 -050087 if (*tok_iter++ != std::to_string(Lsa::Type::NAME)) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060088 return false;
89 }
90
akmhoque31d1d4b2014-05-05 22:08:14 -050091 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -050092 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -050093 numName = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -050094 }
Nick Gordonadad2492017-05-25 10:53:07 -050095 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060096 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -050097 return false;
98 }
akmhoque157b0a42014-05-13 00:26:37 -050099 for (uint32_t i = 0; i < numName; i++) {
akmhoque778f81b2014-06-27 10:07:56 -0500100 ndn::Name name(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500101 addName(name);
102 }
103 return true;
104}
105
Nick Gordon56d1fae2017-05-26 16:39:25 -0500106bool
107NameLsa::isEqualContent(const NameLsa& other) const
108{
109 return m_npl == other.getNpl();
110}
111
akmhoque53353462014-04-22 08:43:45 -0500112void
113NameLsa::writeLog()
114{
akmhoque674b0b12014-05-20 14:33:28 -0500115 _LOG_DEBUG("Name Lsa: ");
116 _LOG_DEBUG(" Origination Router: " << m_origRouter);
Nick Gordon727d4832017-10-13 18:04:25 -0500117 _LOG_DEBUG(" Ls Type: " << getType());
akmhoque674b0b12014-05-20 14:33:28 -0500118 _LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
akmhoquec7a79b22014-05-26 08:06:19 -0500119 _LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
akmhoque674b0b12014-05-20 14:33:28 -0500120 _LOG_DEBUG(" Names: ");
121 int i = 1;
Nick Gordonf14ec352017-07-24 16:09:58 -0500122 std::list<ndn::Name> nl = m_npl.getNames();
akmhoque674b0b12014-05-20 14:33:28 -0500123 for (std::list<ndn::Name>::iterator it = nl.begin(); it != nl.end(); it++)
124 {
125 _LOG_DEBUG(" Name " << i << ": " << (*it));
126 }
akmhoque2f423352014-06-03 11:49:35 -0500127 _LOG_DEBUG("name_lsa_end");
akmhoque53353462014-04-22 08:43:45 -0500128}
129
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600130CoordinateLsa::CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -0500131 const ndn::time::system_clock::TimePoint& lt,
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600132 double r, std::vector<double> theta)
akmhoque53353462014-04-22 08:43:45 -0500133{
134 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -0500135 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -0500136 m_expirationTimePoint = lt;
akmhoque53353462014-04-22 08:43:45 -0500137 m_corRad = r;
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600138 m_angles = theta;
akmhoque53353462014-04-22 08:43:45 -0500139}
140
akmhoque31d1d4b2014-05-05 22:08:14 -0500141const ndn::Name
akmhoqueb6450b12014-04-24 00:01:03 -0500142CoordinateLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -0500143{
akmhoque31d1d4b2014-05-05 22:08:14 -0500144 ndn::Name key = m_origRouter;
Nick Gordon727d4832017-10-13 18:04:25 -0500145 key.append(std::to_string(Lsa::Type::COORDINATE));
akmhoque53353462014-04-22 08:43:45 -0500146 return key;
147}
148
149bool
akmhoquefdbddb12014-05-02 18:35:19 -0500150CoordinateLsa::isEqualContent(const CoordinateLsa& clsa)
akmhoque53353462014-04-22 08:43:45 -0500151{
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600152 if (clsa.getCorTheta().size() != m_angles.size()) {
153 return false;
154 }
155
156 std::vector<double> m_angles2 = clsa.getCorTheta();
157 for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
158 if (std::abs(m_angles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
159 return false;
160 }
161 }
162
akmhoque53353462014-04-22 08:43:45 -0500163 return (std::abs(m_corRad - clsa.getCorRadius()) <
akmhoque53353462014-04-22 08:43:45 -0500164 std::numeric_limits<double>::epsilon());
165}
166
Nick Gordone98480b2017-05-24 11:23:03 -0500167std::string
akmhoqueb6450b12014-04-24 00:01:03 -0500168CoordinateLsa::getData()
akmhoque53353462014-04-22 08:43:45 -0500169{
Nick Gordonadad2492017-05-25 10:53:07 -0500170 std::ostringstream os;
Nick Gordon727d4832017-10-13 18:04:25 -0500171 os << m_origRouter << "|" << Lsa::Type::COORDINATE << "|" << m_lsSeqNo << "|"
Nick Gordonadad2492017-05-25 10:53:07 -0500172 << ndn::time::toIsoString(m_expirationTimePoint) << "|" << m_corRad << "|"
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600173 << m_angles.size() << "|";
174
175 for (const auto& angle: m_angles) {
176 os << angle << "|";
177 }
178
Nick Gordonadad2492017-05-25 10:53:07 -0500179 return os.str();
akmhoque53353462014-04-22 08:43:45 -0500180}
181
182bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500183CoordinateLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -0500184{
akmhoque31d1d4b2014-05-05 22:08:14 -0500185 boost::char_separator<char> sep("|");
186 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
187 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
188 tokens.begin();
189 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500190 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -0500191 return false;
192 }
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600193
akmhoque31d1d4b2014-05-05 22:08:14 -0500194 try {
Nick Gordon727d4832017-10-13 18:04:25 -0500195 if (*tok_iter++ != std::to_string(Lsa::Type::COORDINATE)) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600196 return false;
197 }
198
akmhoque31d1d4b2014-05-05 22:08:14 -0500199 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -0500200 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500201 m_corRad = boost::lexical_cast<double>(*tok_iter++);
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600202 int numAngles = boost::lexical_cast<uint32_t>(*tok_iter++);
203
204 for (int i = 0; i < numAngles; i++) {
205 m_angles.push_back(boost::lexical_cast<double>(*tok_iter++));
206 }
akmhoque53353462014-04-22 08:43:45 -0500207 }
Nick Gordonadad2492017-05-25 10:53:07 -0500208 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600209 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500210 return false;
211 }
212 return true;
213}
214
akmhoque674b0b12014-05-20 14:33:28 -0500215void
216CoordinateLsa::writeLog()
217{
218 _LOG_DEBUG("Cor Lsa: ");
219 _LOG_DEBUG(" Origination Router: " << m_origRouter);
Nick Gordon727d4832017-10-13 18:04:25 -0500220 _LOG_DEBUG(" Ls Type: " << getType());
akmhoque674b0b12014-05-20 14:33:28 -0500221 _LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
akmhoquec7a79b22014-05-26 08:06:19 -0500222 _LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
akmhoque674b0b12014-05-20 14:33:28 -0500223 _LOG_DEBUG(" Hyperbolic Radius: " << m_corRad);
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600224 int i = 0;
225 for(auto const& value: m_angles) {
226 _LOG_DEBUG(" Hyperbolic Theta " << i++ << ": "<< value);
227 }
akmhoque674b0b12014-05-20 14:33:28 -0500228}
229
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600230AdjLsa::AdjLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -0500231 const ndn::time::system_clock::TimePoint& lt,
akmhoquefdbddb12014-05-02 18:35:19 -0500232 uint32_t nl , AdjacencyList& adl)
akmhoque53353462014-04-22 08:43:45 -0500233{
234 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -0500235 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -0500236 m_expirationTimePoint = lt;
akmhoque53353462014-04-22 08:43:45 -0500237 m_noLink = nl;
akmhoquec8a10f72014-04-25 18:42:55 -0500238 std::list<Adjacent> al = adl.getAdjList();
akmhoque157b0a42014-05-13 00:26:37 -0500239 for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++) {
Vince Lehmancb76ade2014-08-28 21:24:41 -0500240 if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
akmhoque53353462014-04-22 08:43:45 -0500241 addAdjacent((*it));
242 }
243 }
244}
245
akmhoque31d1d4b2014-05-05 22:08:14 -0500246const ndn::Name
247AdjLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -0500248{
akmhoque31d1d4b2014-05-05 22:08:14 -0500249 ndn::Name key = m_origRouter;
Nick Gordon727d4832017-10-13 18:04:25 -0500250 key.append(std::to_string(Lsa::Type::ADJACENCY));
akmhoque53353462014-04-22 08:43:45 -0500251 return key;
252}
253
254bool
akmhoquefdbddb12014-05-02 18:35:19 -0500255AdjLsa::isEqualContent(AdjLsa& alsa)
akmhoque53353462014-04-22 08:43:45 -0500256{
akmhoquefdbddb12014-05-02 18:35:19 -0500257 return m_adl == alsa.getAdl();
akmhoque53353462014-04-22 08:43:45 -0500258}
259
Nick Gordone98480b2017-05-24 11:23:03 -0500260std::string
akmhoque53353462014-04-22 08:43:45 -0500261AdjLsa::getData()
262{
Nick Gordonadad2492017-05-25 10:53:07 -0500263 std::ostringstream os;
Nick Gordon727d4832017-10-13 18:04:25 -0500264 os << m_origRouter << "|" << Lsa::Type::ADJACENCY << "|" << m_lsSeqNo << "|"
Nick Gordonff9a6272017-10-12 13:38:29 -0500265 << ndn::time::toIsoString(m_expirationTimePoint) << "|" << m_adl.size();
Nick Gordonadad2492017-05-25 10:53:07 -0500266 for (const auto& adjacent : m_adl.getAdjList()) {
Nick Gordone9733ed2017-04-26 10:48:39 -0500267 os << "|" << adjacent.getName() << "|" << adjacent.getFaceUri()
Nick Gordonadad2492017-05-25 10:53:07 -0500268 << "|" << adjacent.getLinkCost();
akmhoque53353462014-04-22 08:43:45 -0500269 }
Nick Gordonadad2492017-05-25 10:53:07 -0500270 os << "|";
271 return os.str();
akmhoque53353462014-04-22 08:43:45 -0500272}
273
274bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500275AdjLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -0500276{
277 uint32_t numLink = 0;
akmhoque31d1d4b2014-05-05 22:08:14 -0500278 boost::char_separator<char> sep("|");
279 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
280 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
281 tokens.begin();
282 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500283 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -0500284 return false;
285 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500286 try {
Nick Gordon727d4832017-10-13 18:04:25 -0500287 if (*tok_iter++ != std::to_string(Lsa::Type::ADJACENCY)) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600288 return false;
289 }
290
akmhoque31d1d4b2014-05-05 22:08:14 -0500291 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -0500292 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500293 numLink = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500294 }
Nick Gordonadad2492017-05-25 10:53:07 -0500295 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600296 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500297 return false;
298 }
akmhoque157b0a42014-05-13 00:26:37 -0500299 for (uint32_t i = 0; i < numLink; i++) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500300 try {
akmhoque778f81b2014-06-27 10:07:56 -0500301 ndn::Name adjName(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500302 std::string connectingFaceUri(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500303 double linkCost = boost::lexical_cast<double>(*tok_iter++);
Nick Gordone9733ed2017-04-26 10:48:39 -0500304 Adjacent adjacent(adjName, ndn::util::FaceUri(connectingFaceUri), linkCost,
305 Adjacent::STATUS_INACTIVE, 0, 0);
akmhoque53353462014-04-22 08:43:45 -0500306 addAdjacent(adjacent);
307 }
Nick Gordonadad2492017-05-25 10:53:07 -0500308 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600309 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500310 return false;
311 }
312 }
313 return true;
314}
315
akmhoque53353462014-04-22 08:43:45 -0500316void
317AdjLsa::addNptEntries(Nlsr& pnlsr)
318{
Nick G97e34942016-07-11 14:46:27 -0500319 // Only add NPT entries if this is an adj LSA from another router.
akmhoque157b0a42014-05-13 00:26:37 -0500320 if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
Nick G97e34942016-07-11 14:46:27 -0500321 // Pass the originating router as both the name to register and
322 // where it came from.
akmhoque31d1d4b2014-05-05 22:08:14 -0500323 pnlsr.getNamePrefixTable().addEntry(getOrigRouter(), getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500324 }
325}
326
327
328void
329AdjLsa::removeNptEntries(Nlsr& pnlsr)
330{
akmhoque157b0a42014-05-13 00:26:37 -0500331 if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500332 pnlsr.getNamePrefixTable().removeEntry(getOrigRouter(), getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500333 }
334}
335
akmhoque674b0b12014-05-20 14:33:28 -0500336void
337AdjLsa::writeLog()
338{
alvydce3f182015-04-09 11:23:30 -0500339 _LOG_DEBUG(*this);
akmhoque53353462014-04-22 08:43:45 -0500340}
341
alvydce3f182015-04-09 11:23:30 -0500342std::ostream&
343operator<<(std::ostream& os, const AdjLsa& adjLsa)
344{
345 os << "Adj Lsa:\n"
346 << " Origination Router: " << adjLsa.getOrigRouter() << "\n"
Nick Gordon727d4832017-10-13 18:04:25 -0500347 << " Ls Type: " << adjLsa.getType() << "\n"
alvydce3f182015-04-09 11:23:30 -0500348 << " Ls Seq No: " << adjLsa.getLsSeqNo() << "\n"
349 << " Ls Lifetime: " << adjLsa.getExpirationTimePoint() << "\n"
350 << " Adjacents: \n";
351
352 int adjacencyIndex = 1;
353
354 for (const Adjacent& adjacency : adjLsa) {
355 os << " Adjacent " << adjacencyIndex++ << ":\n"
356 << " Adjacent Name: " << adjacency.getName() << "\n"
Nick Gordone9733ed2017-04-26 10:48:39 -0500357 << " Connecting FaceUri: " << adjacency.getFaceUri() << "\n"
alvydce3f182015-04-09 11:23:30 -0500358 << " Link Cost: " << adjacency.getLinkCost() << "\n";
359 }
360 os << "adj_lsa_end";
361
362 return os;
363}
364
Nick Gordon727d4832017-10-13 18:04:25 -0500365std::ostream&
366operator<<(std::ostream& os, const Lsa::Type& type)
367{
368 os << std::to_string(type);
369 return os;
370}
371
372std::istream&
373operator>>(std::istream& is, Lsa::Type& type)
374{
375 std::string typeString;
376 is >> typeString;
377 if (typeString == "ADJACENCY") {
378 type = Lsa::Type::ADJACENCY;
379 }
380 else if (typeString == "COORDINATE") {
381 type = Lsa::Type::COORDINATE;
382 }
383 else if (typeString == "NAME") {
384 type = Lsa::Type::NAME;
385 }
386 else {
387 type = Lsa::Type::BASE;
388 }
389 return is;
390}
391
alvydce3f182015-04-09 11:23:30 -0500392} // namespace nlsr
Nick Gordon727d4832017-10-13 18:04:25 -0500393
394namespace std {
395std::string
396to_string(const nlsr::Lsa::Type& type)
397{
398 switch (type) {
399 case nlsr::Lsa::Type::ADJACENCY:
400 return "ADJACENCY";
401 case nlsr::Lsa::Type::COORDINATE:
402 return "COORDINATE";
403 case nlsr::Lsa::Type::NAME:
404 return "NAME";
405 default:
406 return "BASE";
407 }
408}
409
410} // namespace std