blob: afb76a101700df41a36b53f6ef53a154f202eced [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
Nick Gordonfaf49f42017-10-23 12:36:28 -050041std::string
42Lsa::getData() const
43{
44 std::ostringstream os;
45 os << m_origRouter << "|" << getType() << "|" << m_lsSeqNo << "|"
46 << ndn::time::toIsoString(m_expirationTimePoint) << "|";
47 return os.str();
48}
49
akmhoque31d1d4b2014-05-05 22:08:14 -050050const ndn::Name
akmhoqueb6450b12014-04-24 00:01:03 -050051NameLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -050052{
akmhoque31d1d4b2014-05-05 22:08:14 -050053 ndn::Name key = m_origRouter;
Nick Gordon727d4832017-10-13 18:04:25 -050054 key.append(std::to_string(Lsa::Type::NAME));
akmhoque53353462014-04-22 08:43:45 -050055 return key;
56}
57
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060058NameLsa::NameLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -050059 const ndn::time::system_clock::TimePoint& lt,
akmhoquefdbddb12014-05-02 18:35:19 -050060 NamePrefixList& npl)
akmhoque53353462014-04-22 08:43:45 -050061{
62 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -050063 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -050064 m_expirationTimePoint = lt;
Nick Gordonf14ec352017-07-24 16:09:58 -050065 for (const auto& name : npl.getNames()) {
66 addName(name);
akmhoque53353462014-04-22 08:43:45 -050067 }
68}
69
Nick Gordone98480b2017-05-24 11:23:03 -050070std::string
Nick Gordonfaf49f42017-10-23 12:36:28 -050071NameLsa::serialize() const
akmhoque53353462014-04-22 08:43:45 -050072{
Nick Gordonadad2492017-05-25 10:53:07 -050073 std::ostringstream os;
Nick Gordonfaf49f42017-10-23 12:36:28 -050074 os << getData() << m_npl.size();
Nick Gordonf14ec352017-07-24 16:09:58 -050075 for (const auto& name : m_npl.getNames()) {
Nick Gordonadad2492017-05-25 10:53:07 -050076 os << "|" << name;
akmhoque53353462014-04-22 08:43:45 -050077 }
Nick Gordonadad2492017-05-25 10:53:07 -050078 os << "|";
79 return os.str();
akmhoque53353462014-04-22 08:43:45 -050080}
81
82bool
akmhoque31d1d4b2014-05-05 22:08:14 -050083NameLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -050084{
85 uint32_t numName = 0;
akmhoque31d1d4b2014-05-05 22:08:14 -050086 boost::char_separator<char> sep("|");
87 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
88 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
89 tokens.begin();
90 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -050091 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -050092 return false;
93 }
akmhoque31d1d4b2014-05-05 22:08:14 -050094 try {
Nick Gordon727d4832017-10-13 18:04:25 -050095 if (*tok_iter++ != std::to_string(Lsa::Type::NAME)) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -060096 return false;
97 }
98
akmhoque31d1d4b2014-05-05 22:08:14 -050099 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -0500100 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500101 numName = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500102 }
Nick Gordonadad2492017-05-25 10:53:07 -0500103 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600104 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500105 return false;
106 }
akmhoque157b0a42014-05-13 00:26:37 -0500107 for (uint32_t i = 0; i < numName; i++) {
akmhoque778f81b2014-06-27 10:07:56 -0500108 ndn::Name name(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500109 addName(name);
110 }
111 return true;
112}
113
Nick Gordon56d1fae2017-05-26 16:39:25 -0500114bool
115NameLsa::isEqualContent(const NameLsa& other) const
116{
117 return m_npl == other.getNpl();
118}
119
akmhoque53353462014-04-22 08:43:45 -0500120void
121NameLsa::writeLog()
122{
akmhoque674b0b12014-05-20 14:33:28 -0500123 _LOG_DEBUG("Name Lsa: ");
124 _LOG_DEBUG(" Origination Router: " << m_origRouter);
Nick Gordon727d4832017-10-13 18:04:25 -0500125 _LOG_DEBUG(" Ls Type: " << getType());
akmhoque674b0b12014-05-20 14:33:28 -0500126 _LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
akmhoquec7a79b22014-05-26 08:06:19 -0500127 _LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
akmhoque674b0b12014-05-20 14:33:28 -0500128 _LOG_DEBUG(" Names: ");
129 int i = 1;
Nick Gordonf14ec352017-07-24 16:09:58 -0500130 std::list<ndn::Name> nl = m_npl.getNames();
akmhoque674b0b12014-05-20 14:33:28 -0500131 for (std::list<ndn::Name>::iterator it = nl.begin(); it != nl.end(); it++)
132 {
133 _LOG_DEBUG(" Name " << i << ": " << (*it));
134 }
akmhoque2f423352014-06-03 11:49:35 -0500135 _LOG_DEBUG("name_lsa_end");
akmhoque53353462014-04-22 08:43:45 -0500136}
137
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600138CoordinateLsa::CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -0500139 const ndn::time::system_clock::TimePoint& lt,
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600140 double r, std::vector<double> theta)
akmhoque53353462014-04-22 08:43:45 -0500141{
142 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -0500143 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -0500144 m_expirationTimePoint = lt;
akmhoque53353462014-04-22 08:43:45 -0500145 m_corRad = r;
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600146 m_angles = theta;
akmhoque53353462014-04-22 08:43:45 -0500147}
148
akmhoque31d1d4b2014-05-05 22:08:14 -0500149const ndn::Name
akmhoqueb6450b12014-04-24 00:01:03 -0500150CoordinateLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -0500151{
akmhoque31d1d4b2014-05-05 22:08:14 -0500152 ndn::Name key = m_origRouter;
Nick Gordon727d4832017-10-13 18:04:25 -0500153 key.append(std::to_string(Lsa::Type::COORDINATE));
akmhoque53353462014-04-22 08:43:45 -0500154 return key;
155}
156
157bool
akmhoquefdbddb12014-05-02 18:35:19 -0500158CoordinateLsa::isEqualContent(const CoordinateLsa& clsa)
akmhoque53353462014-04-22 08:43:45 -0500159{
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600160 if (clsa.getCorTheta().size() != m_angles.size()) {
161 return false;
162 }
163
164 std::vector<double> m_angles2 = clsa.getCorTheta();
165 for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
166 if (std::abs(m_angles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
167 return false;
168 }
169 }
170
akmhoque53353462014-04-22 08:43:45 -0500171 return (std::abs(m_corRad - clsa.getCorRadius()) <
akmhoque53353462014-04-22 08:43:45 -0500172 std::numeric_limits<double>::epsilon());
173}
174
Nick Gordone98480b2017-05-24 11:23:03 -0500175std::string
Nick Gordonfaf49f42017-10-23 12:36:28 -0500176CoordinateLsa::serialize() const
akmhoque53353462014-04-22 08:43:45 -0500177{
Nick Gordonadad2492017-05-25 10:53:07 -0500178 std::ostringstream os;
Nick Gordonfaf49f42017-10-23 12:36:28 -0500179 os << getData() << m_corRad << "|" << m_angles.size() << "|";
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600180 for (const auto& angle: m_angles) {
181 os << angle << "|";
182 }
Nick Gordonadad2492017-05-25 10:53:07 -0500183 return os.str();
akmhoque53353462014-04-22 08:43:45 -0500184}
185
186bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500187CoordinateLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -0500188{
akmhoque31d1d4b2014-05-05 22:08:14 -0500189 boost::char_separator<char> sep("|");
190 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
191 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
192 tokens.begin();
193 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500194 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -0500195 return false;
196 }
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600197
akmhoque31d1d4b2014-05-05 22:08:14 -0500198 try {
Nick Gordon727d4832017-10-13 18:04:25 -0500199 if (*tok_iter++ != std::to_string(Lsa::Type::COORDINATE)) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600200 return false;
201 }
202
akmhoque31d1d4b2014-05-05 22:08:14 -0500203 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -0500204 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500205 m_corRad = boost::lexical_cast<double>(*tok_iter++);
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600206 int numAngles = boost::lexical_cast<uint32_t>(*tok_iter++);
207
208 for (int i = 0; i < numAngles; i++) {
209 m_angles.push_back(boost::lexical_cast<double>(*tok_iter++));
210 }
akmhoque53353462014-04-22 08:43:45 -0500211 }
Nick Gordonadad2492017-05-25 10:53:07 -0500212 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600213 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500214 return false;
215 }
216 return true;
217}
218
akmhoque674b0b12014-05-20 14:33:28 -0500219void
220CoordinateLsa::writeLog()
221{
222 _LOG_DEBUG("Cor Lsa: ");
223 _LOG_DEBUG(" Origination Router: " << m_origRouter);
Nick Gordon727d4832017-10-13 18:04:25 -0500224 _LOG_DEBUG(" Ls Type: " << getType());
akmhoque674b0b12014-05-20 14:33:28 -0500225 _LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
akmhoquec7a79b22014-05-26 08:06:19 -0500226 _LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
akmhoque674b0b12014-05-20 14:33:28 -0500227 _LOG_DEBUG(" Hyperbolic Radius: " << m_corRad);
Muktadir R Chowdhuryb00dc2a2016-11-05 10:48:58 -0600228 int i = 0;
229 for(auto const& value: m_angles) {
230 _LOG_DEBUG(" Hyperbolic Theta " << i++ << ": "<< value);
231 }
akmhoque674b0b12014-05-20 14:33:28 -0500232}
233
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600234AdjLsa::AdjLsa(const ndn::Name& origR, uint32_t lsn,
akmhoquec7a79b22014-05-26 08:06:19 -0500235 const ndn::time::system_clock::TimePoint& lt,
akmhoquefdbddb12014-05-02 18:35:19 -0500236 uint32_t nl , AdjacencyList& adl)
akmhoque53353462014-04-22 08:43:45 -0500237{
238 m_origRouter = origR;
akmhoque53353462014-04-22 08:43:45 -0500239 m_lsSeqNo = lsn;
akmhoquec7a79b22014-05-26 08:06:19 -0500240 m_expirationTimePoint = lt;
akmhoque53353462014-04-22 08:43:45 -0500241 m_noLink = nl;
akmhoquec8a10f72014-04-25 18:42:55 -0500242 std::list<Adjacent> al = adl.getAdjList();
akmhoque157b0a42014-05-13 00:26:37 -0500243 for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++) {
Vince Lehmancb76ade2014-08-28 21:24:41 -0500244 if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
akmhoque53353462014-04-22 08:43:45 -0500245 addAdjacent((*it));
246 }
247 }
248}
249
akmhoque31d1d4b2014-05-05 22:08:14 -0500250const ndn::Name
251AdjLsa::getKey() const
akmhoque53353462014-04-22 08:43:45 -0500252{
akmhoque31d1d4b2014-05-05 22:08:14 -0500253 ndn::Name key = m_origRouter;
Nick Gordon727d4832017-10-13 18:04:25 -0500254 key.append(std::to_string(Lsa::Type::ADJACENCY));
akmhoque53353462014-04-22 08:43:45 -0500255 return key;
256}
257
258bool
akmhoquefdbddb12014-05-02 18:35:19 -0500259AdjLsa::isEqualContent(AdjLsa& alsa)
akmhoque53353462014-04-22 08:43:45 -0500260{
akmhoquefdbddb12014-05-02 18:35:19 -0500261 return m_adl == alsa.getAdl();
akmhoque53353462014-04-22 08:43:45 -0500262}
263
Nick Gordone98480b2017-05-24 11:23:03 -0500264std::string
Nick Gordonfaf49f42017-10-23 12:36:28 -0500265AdjLsa::serialize() const
akmhoque53353462014-04-22 08:43:45 -0500266{
Nick Gordonadad2492017-05-25 10:53:07 -0500267 std::ostringstream os;
Nick Gordonfaf49f42017-10-23 12:36:28 -0500268 os << getData() << m_adl.size();
Nick Gordonadad2492017-05-25 10:53:07 -0500269 for (const auto& adjacent : m_adl.getAdjList()) {
Nick Gordone9733ed2017-04-26 10:48:39 -0500270 os << "|" << adjacent.getName() << "|" << adjacent.getFaceUri()
Nick Gordonadad2492017-05-25 10:53:07 -0500271 << "|" << adjacent.getLinkCost();
akmhoque53353462014-04-22 08:43:45 -0500272 }
Nick Gordonadad2492017-05-25 10:53:07 -0500273 os << "|";
274 return os.str();
akmhoque53353462014-04-22 08:43:45 -0500275}
276
277bool
akmhoque31d1d4b2014-05-05 22:08:14 -0500278AdjLsa::initializeFromContent(const std::string& content)
akmhoque53353462014-04-22 08:43:45 -0500279{
280 uint32_t numLink = 0;
akmhoque31d1d4b2014-05-05 22:08:14 -0500281 boost::char_separator<char> sep("|");
282 boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
283 boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
284 tokens.begin();
285 m_origRouter = ndn::Name(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500286 if (!(m_origRouter.size() > 0)) {
akmhoque53353462014-04-22 08:43:45 -0500287 return false;
288 }
akmhoque31d1d4b2014-05-05 22:08:14 -0500289 try {
Nick Gordon727d4832017-10-13 18:04:25 -0500290 if (*tok_iter++ != std::to_string(Lsa::Type::ADJACENCY)) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600291 return false;
292 }
293
akmhoque31d1d4b2014-05-05 22:08:14 -0500294 m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoquec7a79b22014-05-26 08:06:19 -0500295 m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500296 numLink = boost::lexical_cast<uint32_t>(*tok_iter++);
akmhoque53353462014-04-22 08:43:45 -0500297 }
Nick Gordonadad2492017-05-25 10:53:07 -0500298 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600299 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500300 return false;
301 }
akmhoque157b0a42014-05-13 00:26:37 -0500302 for (uint32_t i = 0; i < numLink; i++) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500303 try {
akmhoque778f81b2014-06-27 10:07:56 -0500304 ndn::Name adjName(*tok_iter++);
akmhoque157b0a42014-05-13 00:26:37 -0500305 std::string connectingFaceUri(*tok_iter++);
akmhoque31d1d4b2014-05-05 22:08:14 -0500306 double linkCost = boost::lexical_cast<double>(*tok_iter++);
Nick Gordone9733ed2017-04-26 10:48:39 -0500307 Adjacent adjacent(adjName, ndn::util::FaceUri(connectingFaceUri), linkCost,
308 Adjacent::STATUS_INACTIVE, 0, 0);
akmhoque53353462014-04-22 08:43:45 -0500309 addAdjacent(adjacent);
310 }
Nick Gordonadad2492017-05-25 10:53:07 -0500311 catch (const std::exception& e) {
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600312 _LOG_ERROR(e.what());
akmhoque53353462014-04-22 08:43:45 -0500313 return false;
314 }
315 }
316 return true;
317}
318
akmhoque53353462014-04-22 08:43:45 -0500319void
320AdjLsa::addNptEntries(Nlsr& pnlsr)
321{
Nick G97e34942016-07-11 14:46:27 -0500322 // Only add NPT entries if this is an adj LSA from another router.
akmhoque157b0a42014-05-13 00:26:37 -0500323 if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
Nick G97e34942016-07-11 14:46:27 -0500324 // Pass the originating router as both the name to register and
325 // where it came from.
akmhoque31d1d4b2014-05-05 22:08:14 -0500326 pnlsr.getNamePrefixTable().addEntry(getOrigRouter(), getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500327 }
328}
329
330
331void
332AdjLsa::removeNptEntries(Nlsr& pnlsr)
333{
akmhoque157b0a42014-05-13 00:26:37 -0500334 if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500335 pnlsr.getNamePrefixTable().removeEntry(getOrigRouter(), getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -0500336 }
337}
338
akmhoque674b0b12014-05-20 14:33:28 -0500339void
340AdjLsa::writeLog()
341{
alvydce3f182015-04-09 11:23:30 -0500342 _LOG_DEBUG(*this);
akmhoque53353462014-04-22 08:43:45 -0500343}
344
alvydce3f182015-04-09 11:23:30 -0500345std::ostream&
346operator<<(std::ostream& os, const AdjLsa& adjLsa)
347{
348 os << "Adj Lsa:\n"
349 << " Origination Router: " << adjLsa.getOrigRouter() << "\n"
Nick Gordon727d4832017-10-13 18:04:25 -0500350 << " Ls Type: " << adjLsa.getType() << "\n"
alvydce3f182015-04-09 11:23:30 -0500351 << " Ls Seq No: " << adjLsa.getLsSeqNo() << "\n"
352 << " Ls Lifetime: " << adjLsa.getExpirationTimePoint() << "\n"
353 << " Adjacents: \n";
354
355 int adjacencyIndex = 1;
356
357 for (const Adjacent& adjacency : adjLsa) {
358 os << " Adjacent " << adjacencyIndex++ << ":\n"
359 << " Adjacent Name: " << adjacency.getName() << "\n"
Nick Gordone9733ed2017-04-26 10:48:39 -0500360 << " Connecting FaceUri: " << adjacency.getFaceUri() << "\n"
alvydce3f182015-04-09 11:23:30 -0500361 << " Link Cost: " << adjacency.getLinkCost() << "\n";
362 }
363 os << "adj_lsa_end";
364
365 return os;
366}
367
Nick Gordon727d4832017-10-13 18:04:25 -0500368std::ostream&
369operator<<(std::ostream& os, const Lsa::Type& type)
370{
371 os << std::to_string(type);
372 return os;
373}
374
375std::istream&
376operator>>(std::istream& is, Lsa::Type& type)
377{
378 std::string typeString;
379 is >> typeString;
380 if (typeString == "ADJACENCY") {
381 type = Lsa::Type::ADJACENCY;
382 }
383 else if (typeString == "COORDINATE") {
384 type = Lsa::Type::COORDINATE;
385 }
386 else if (typeString == "NAME") {
387 type = Lsa::Type::NAME;
388 }
389 else {
390 type = Lsa::Type::BASE;
391 }
392 return is;
393}
394
alvydce3f182015-04-09 11:23:30 -0500395} // namespace nlsr
Nick Gordon727d4832017-10-13 18:04:25 -0500396
397namespace std {
398std::string
399to_string(const nlsr::Lsa::Type& type)
400{
401 switch (type) {
402 case nlsr::Lsa::Type::ADJACENCY:
403 return "ADJACENCY";
404 case nlsr::Lsa::Type::COORDINATE:
405 return "COORDINATE";
406 case nlsr::Lsa::Type::NAME:
407 return "NAME";
Nick Gordon9212bd42017-10-23 10:59:38 -0500408 case nlsr::Lsa::Type::MOCK:
409 return "MOCK";
Nick Gordon727d4832017-10-13 18:04:25 -0500410 default:
411 return "BASE";
412 }
413}
414
415} // namespace std