diff --git a/src/lsa/adj-lsa.cpp b/src/lsa/adj-lsa.cpp
new file mode 100644
index 0000000..e2d0a2b
--- /dev/null
+++ b/src/lsa/adj-lsa.cpp
@@ -0,0 +1,144 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2020,  The University of Memphis,
+ *                           Regents of the University of California,
+ *                           Arizona Board of Regents.
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "adj-lsa.hpp"
+#include "tlv/tlv-nlsr.hpp"
+
+namespace nlsr {
+
+AdjLsa::AdjLsa(const ndn::Name& originRouter, uint32_t seqNo,
+               const ndn::time::system_clock::TimePoint& timepoint,
+               uint32_t noLink, AdjacencyList& adl)
+  : Lsa(originRouter, seqNo, timepoint)
+  , m_noLink(noLink)
+{
+  for (const auto& adjacent : adl.getAdjList()) {
+    if (adjacent.getStatus() == Adjacent::STATUS_ACTIVE) {
+      addAdjacent(adjacent);
+    }
+  }
+}
+
+AdjLsa::AdjLsa(const ndn::Block& block)
+{
+  wireDecode(block);
+}
+
+bool
+AdjLsa::isEqualContent(const AdjLsa& alsa) const
+{
+  return m_adl == alsa.getAdl();
+}
+
+template<ndn::encoding::Tag TAG>
+size_t
+AdjLsa::wireEncode(ndn::EncodingImpl<TAG>& block) const
+{
+  size_t totalLength = 0;
+
+  auto list = m_adl.getAdjList();
+  for (auto it = list.rbegin(); it != list.rend(); ++it) {
+    totalLength += it->wireEncode(block);
+  }
+
+  totalLength += Lsa::wireEncode(block);
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(ndn::tlv::nlsr::AdjacencyLsa);
+
+  return totalLength;
+}
+
+NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(AdjLsa);
+
+const ndn::Block&
+AdjLsa::wireEncode() const
+{
+  if (m_wire.hasWire() && m_baseWire.hasWire()) {
+    return m_wire;
+  }
+
+  ndn::EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  ndn::EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+
+  return m_wire;
+}
+
+void
+AdjLsa::wireDecode(const ndn::Block& wire)
+{
+  m_wire = wire;
+
+  if (m_wire.type() != ndn::tlv::nlsr::AdjacencyLsa) {
+    BOOST_THROW_EXCEPTION(Error("Expected AdjacencyLsa Block, but Block is of a different type: #" +
+                                ndn::to_string(m_wire.type())));
+  }
+
+  m_wire.parse();
+
+  ndn::Block::element_const_iterator val = m_wire.elements_begin();
+
+  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Lsa) {
+    Lsa::wireDecode(*val);
+    ++val;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Missing required Lsa field"));
+  }
+
+  AdjacencyList adl;
+  for (; val != m_wire.elements_end(); ++val) {
+    if (val->type() == ndn::tlv::nlsr::Adjacency) {
+      Adjacent adj = Adjacent(*val);
+      adl.insert(adj);
+    }
+    else {
+      BOOST_THROW_EXCEPTION(Error("Expected Adjacency Block, but Block is of a different type: #" +
+                                  ndn::to_string(m_wire.type())));
+    }
+  }
+  m_adl = adl;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const AdjLsa& lsa)
+{
+  os << lsa.toString();
+  os << "      Adjacents:\n";
+
+  int adjacencyIndex = 0;
+
+  for (const Adjacent& adjacency : lsa.getAdl()) {
+  os << "        Adjacent " << adjacencyIndex++
+     << ": (name=" << adjacency.getName()
+     << ", uri="   << adjacency.getFaceUri()
+     << ", cost="  << adjacency.getLinkCost() << ")\n";
+  }
+
+  return os;
+}
+
+} // namespace nlsr
\ No newline at end of file
diff --git a/src/lsa/adj-lsa.hpp b/src/lsa/adj-lsa.hpp
new file mode 100644
index 0000000..12e9346
--- /dev/null
+++ b/src/lsa/adj-lsa.hpp
@@ -0,0 +1,123 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2020,  The University of Memphis,
+ *                           Regents of the University of California,
+ *                           Arizona Board of Regents.
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef NLSR_LSA_ADJ_LSA_HPP
+#define NLSR_LSA_ADJ_LSA_HPP
+
+#include "lsa.hpp"
+#include "test-access-control.hpp"
+
+namespace nlsr {
+
+/*!
+   \brief Data abstraction for AdjLsa
+   AdjacencyLsa := ADJACENCY-LSA-TYPE TLV-LENGTH
+                     Lsa
+                     Adjacency*
+
+ */
+class AdjLsa : public Lsa
+{
+public:
+  typedef AdjacencyList::const_iterator const_iterator;
+
+  AdjLsa() = default;
+
+  AdjLsa(const ndn::Name& originR, uint32_t seqNo,
+         const ndn::time::system_clock::TimePoint& timepoint,
+         uint32_t noLink, AdjacencyList& adl);
+
+  AdjLsa(const ndn::Block& block);
+
+  Lsa::Type
+  getType() const override
+  {
+    return Lsa::Type::ADJACENCY;
+  }
+
+  const AdjacencyList&
+  getAdl() const
+  {
+    return m_adl;
+  }
+
+  void
+  resetAdl()
+  {
+    m_wire.reset();
+    m_adl.reset();
+  }
+
+  void
+  addAdjacent(Adjacent adj)
+  {
+    m_wire.reset();
+    m_adl.insert(adj);
+  }
+
+  uint32_t
+  getNoLink()
+  {
+    return m_noLink;
+  }
+
+  bool
+  isEqualContent(const AdjLsa& alsa) const;
+
+  const_iterator
+  begin() const
+  {
+    return m_adl.begin();
+  }
+
+  const_iterator
+  end() const
+  {
+    return m_adl.end();
+  }
+
+  template<ndn::encoding::Tag TAG>
+  size_t
+  wireEncode(ndn::EncodingImpl<TAG>& block) const;
+
+  const ndn::Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const ndn::Block& wire);
+
+private:
+  uint32_t m_noLink;
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  AdjacencyList m_adl;
+
+  mutable ndn::Block m_wire;
+};
+
+NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(AdjLsa);
+
+std::ostream&
+operator<<(std::ostream& os, const AdjLsa& lsa);
+
+} // namespace nlsr
+
+#endif // NLSR_LSA_ADJ_LSA_HPP
diff --git a/src/lsa/coordinate-lsa.cpp b/src/lsa/coordinate-lsa.cpp
new file mode 100644
index 0000000..a73ab76
--- /dev/null
+++ b/src/lsa/coordinate-lsa.cpp
@@ -0,0 +1,159 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2020,  The University of Memphis,
+ *                           Regents of the University of California,
+ *                           Arizona Board of Regents.
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "coordinate-lsa.hpp"
+#include "tlv/tlv-nlsr.hpp"
+
+#include <boost/lexical_cast.hpp>
+
+namespace nlsr {
+
+CoordinateLsa::CoordinateLsa(const ndn::Name& originRouter, uint32_t seqNo,
+                             const ndn::time::system_clock::TimePoint& timepoint,
+                             double radius, std::vector<double> angles)
+  : Lsa(originRouter, seqNo, timepoint)
+  , m_hyperbolicRadius(radius)
+  , m_hyperbolicAngles(angles)
+{
+}
+
+CoordinateLsa::CoordinateLsa(const ndn::Block& block)
+{
+  wireDecode(block);
+}
+
+bool
+CoordinateLsa::isEqualContent(const CoordinateLsa& clsa) const
+{
+  if (clsa.getCorTheta().size() != m_hyperbolicAngles.size()) {
+    return false;
+  }
+
+  std::vector<double> m_angles2 = clsa.getCorTheta();
+  for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
+    if (std::abs(m_hyperbolicAngles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
+      return false;
+    }
+  }
+
+  return (std::abs(m_hyperbolicRadius - clsa.getCorRadius()) <
+          std::numeric_limits<double>::epsilon());
+}
+
+template<ndn::encoding::Tag TAG>
+size_t
+CoordinateLsa::wireEncode(ndn::EncodingImpl<TAG>& block) const
+{
+  size_t totalLength = 0;
+
+  for (auto it = m_hyperbolicAngles.rbegin(); it != m_hyperbolicAngles.rend(); ++it) {
+    totalLength += ndn::encoding::prependDoubleBlock(block, ndn::tlv::nlsr::HyperbolicAngle, *it);
+  }
+
+  totalLength += ndn::encoding::prependDoubleBlock(block, ndn::tlv::nlsr::HyperbolicRadius,
+                                                   m_hyperbolicRadius);
+
+  totalLength += Lsa::wireEncode(block);
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(ndn::tlv::nlsr::CoordinateLsa);
+
+  return totalLength;
+}
+
+NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(CoordinateLsa);
+
+const ndn::Block&
+CoordinateLsa::wireEncode() const
+{
+  if (m_wire.hasWire() && m_baseWire.hasWire()) {
+    return m_wire;
+  }
+
+  ndn::EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  ndn::EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+
+  return m_wire;
+}
+
+void
+CoordinateLsa::wireDecode(const ndn::Block& wire)
+{
+  m_wire = wire;
+
+  if (m_wire.type() != ndn::tlv::nlsr::CoordinateLsa) {
+    std::stringstream error;
+    error << "Expected CoordinateLsa Block, but Block is of a different type: #"
+          << m_wire.type();
+    BOOST_THROW_EXCEPTION(Error(error.str()));
+  }
+
+  m_wire.parse();
+
+  ndn::Block::element_const_iterator val = m_wire.elements_begin();
+
+  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Lsa) {
+    Lsa::wireDecode(*val);
+    ++val;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Missing required Lsa field"));
+  }
+
+  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::HyperbolicRadius) {
+    m_hyperbolicRadius = ndn::encoding::readDouble(*val);
+    ++val;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Missing required HyperbolicRadius field"));
+  }
+
+  std::vector<double> angles;
+  for (; val != m_wire.elements_end(); ++val) {
+    if (val->type() == ndn::tlv::nlsr::HyperbolicAngle) {
+      angles.push_back(ndn::encoding::readDouble(*val));
+    }
+    else {
+      BOOST_THROW_EXCEPTION(Error("Missing required HyperbolicAngle field"));
+    }
+  }
+  m_hyperbolicAngles = angles;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const CoordinateLsa& lsa)
+{
+  os << lsa.toString();
+  os << "      Hyperbolic Radius  : " << lsa.getCorRadius() << "\n";
+  int i = 0;
+  for (const auto& value : lsa.getCorTheta()) {
+    os << "      Hyperbolic Theta " << i++ << " : " << value << "\n";
+  }
+
+  return os;
+}
+
+} // namespace nlsr
\ No newline at end of file
diff --git a/src/lsa/coordinate-lsa.hpp b/src/lsa/coordinate-lsa.hpp
new file mode 100644
index 0000000..abeea2c
--- /dev/null
+++ b/src/lsa/coordinate-lsa.hpp
@@ -0,0 +1,106 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2020,  The University of Memphis,
+ *                           Regents of the University of California,
+ *                           Arizona Board of Regents.
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef NLSR_LSA_COORDINATE_LSA_HPP
+#define NLSR_LSA_COORDINATE_LSA_HPP
+
+#include "lsa.hpp"
+
+namespace nlsr {
+
+/*!
+   \brief Data abstraction for CoordinateLsa
+   CoordinateLsa := COORDINATE-LSA-TYPE TLV-LENGTH
+                      Lsa
+                      HyperbolicRadius
+                      HyperbolicAngle+
+ */
+class CoordinateLsa : public Lsa
+{
+public:
+  CoordinateLsa() = default;
+
+  CoordinateLsa(const ndn::Name& originRouter, uint32_t seqNo,
+                const ndn::time::system_clock::TimePoint& timepoint,
+                double radius, std::vector<double> angles);
+
+  CoordinateLsa(const ndn::Block& block);
+
+  Lsa::Type
+  getType() const override
+  {
+    return Lsa::Type::COORDINATE;
+  }
+
+  double
+  getCorRadius() const
+  {
+    return m_hyperbolicRadius;
+  }
+
+  void
+  setCorRadius(double cr)
+  {
+    m_wire.reset();
+    m_hyperbolicRadius = cr;
+  }
+
+  const std::vector<double>
+  getCorTheta() const
+  {
+    return m_hyperbolicAngles;
+  }
+
+  void
+  setCorTheta(std::vector<double> ct)
+  {
+    m_wire.reset();
+    m_hyperbolicAngles = ct;
+  }
+
+  bool
+  isEqualContent(const CoordinateLsa& clsa) const;
+
+  template<ndn::encoding::Tag TAG>
+  size_t
+  wireEncode(ndn::EncodingImpl<TAG>& block) const;
+
+  const ndn::Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const ndn::Block& wire);
+
+private:
+  double m_hyperbolicRadius = 0.0;
+  std::vector<double> m_hyperbolicAngles;
+
+  mutable ndn::Block m_wire;
+};
+
+NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(CoordinateLsa);
+
+std::ostream&
+operator<<(std::ostream& os, const CoordinateLsa& lsa);
+
+} // namespace nlsr
+
+#endif // NLSR_LSA_COORDINATE_LSA_HPP
diff --git a/src/lsa/lsa.cpp b/src/lsa/lsa.cpp
new file mode 100644
index 0000000..c0d6435
--- /dev/null
+++ b/src/lsa/lsa.cpp
@@ -0,0 +1,167 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2020,  The University of Memphis,
+ *                           Regents of the University of California,
+ *                           Arizona Board of Regents.
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "lsa.hpp"
+#include "nlsr.hpp"
+#include "name-prefix-list.hpp"
+#include "adjacent.hpp"
+#include "tlv/tlv-nlsr.hpp"
+
+namespace nlsr {
+
+Lsa::Lsa(const ndn::Name& originRouter, uint32_t seqNo,
+         ndn::time::system_clock::TimePoint expirationTimePoint)
+  : m_originRouter(originRouter)
+  , m_seqNo(seqNo)
+  , m_expirationTimePoint(expirationTimePoint)
+{
+}
+
+ndn::Name
+Lsa::getKey() const
+{
+  return ndn::Name(m_originRouter).append(boost::lexical_cast<std::string>((getType())));
+}
+
+template<ndn::encoding::Tag TAG>
+size_t
+Lsa::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
+{
+  size_t totalLength = 0;
+
+  totalLength += prependStringBlock(encoder,
+                                    ndn::tlv::nlsr::ExpirationTime,
+                                    ndn::time::toString(m_expirationTimePoint));
+
+  totalLength += prependNonNegativeIntegerBlock(encoder, ndn::tlv::nlsr::SequenceNumber,
+                                                m_seqNo);
+
+  totalLength += m_originRouter.wireEncode(encoder);
+
+  totalLength += encoder.prependVarNumber(totalLength);
+  totalLength += encoder.prependVarNumber(ndn::tlv::nlsr::Lsa);
+
+  return totalLength;
+}
+
+NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Lsa);
+
+void
+Lsa::wireDecode(const ndn::Block& wire)
+{
+  m_originRouter.clear();
+  m_seqNo = 0;
+
+  m_baseWire = wire;
+
+  if (m_baseWire.type() != ndn::tlv::nlsr::Lsa) {
+    std::stringstream error;
+    error << "Expected Lsa Block, but Block is of a different type: #"
+          << m_baseWire.type();
+    BOOST_THROW_EXCEPTION(Error(error.str()));
+  }
+
+  m_baseWire.parse();
+
+  ndn::Block::element_const_iterator val = m_baseWire.elements_begin();
+
+  if (val != m_baseWire.elements_end() && val->type() == ndn::tlv::Name) {
+    m_originRouter.wireDecode(*val);
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("OriginRouter: Missing required Name field"));
+  }
+
+  ++val;
+
+  if (val != m_baseWire.elements_end() && val->type() == ndn::tlv::nlsr::SequenceNumber) {
+    m_seqNo = ndn::readNonNegativeInteger(*val);
+    ++val;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Missing required SequenceNumber field"));
+  }
+
+  if (val != m_baseWire.elements_end() && val->type() == ndn::tlv::nlsr::ExpirationTime) {
+    m_expirationTimePoint = ndn::time::fromString(readString(*val));
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Missing required ExpirationTimePoint field"));
+  }
+}
+
+std::ostream&
+operator<<(std::ostream& os, const Lsa::Type& type)
+{
+  switch (type) {
+  case nlsr::Lsa::Type::ADJACENCY:
+    os << "ADJACENCY";
+    break;
+
+  case nlsr::Lsa::Type::COORDINATE:
+    os << "COORDINATE";
+    break;
+
+  case nlsr::Lsa::Type::NAME:
+    os << "NAME";
+    break;
+
+  default:
+    os << "BASE";
+    break;
+  }
+  return os;
+}
+
+std::istream&
+operator>>(std::istream& is, Lsa::Type& type)
+{
+  std::string typeString;
+  is >> typeString;
+  if (typeString == "ADJACENCY") {
+    type = Lsa::Type::ADJACENCY;
+  }
+  else if (typeString == "COORDINATE") {
+    type = Lsa::Type::COORDINATE;
+  }
+  else if (typeString == "NAME") {
+    type = Lsa::Type::NAME;
+  }
+  else {
+    type = Lsa::Type::BASE;
+  }
+  return is;
+}
+
+std::string
+Lsa::toString() const
+{
+  std::ostringstream os;
+  auto duration = getExpirationTimePoint() - ndn::time::system_clock::now();
+  os << "    " << getType() << " LSA:\n"
+     << "      Origin Router      : " << getOriginRouter() << "\n"
+     << "      Sequence Number    : " << getSeqNo() << "\n"
+     << "      Expires in         : " << ndn::time::duration_cast<ndn::time::milliseconds>(duration)
+     << "\n";
+  return os.str();
+}
+
+} // namespace nlsr
diff --git a/src/lsa/lsa.hpp b/src/lsa/lsa.hpp
new file mode 100644
index 0000000..1bd4382
--- /dev/null
+++ b/src/lsa/lsa.hpp
@@ -0,0 +1,160 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2020,  The University of Memphis,
+ *                           Regents of the University of California,
+ *                           Arizona Board of Regents.
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NLSR_LSA_LSA_HPP
+#define NLSR_LSA_LSA_HPP
+
+#include "name-prefix-list.hpp"
+#include "adjacent.hpp"
+#include "adjacency-list.hpp"
+#include "test-access-control.hpp"
+
+#include <ndn-cxx/util/scheduler.hpp>
+#include <ndn-cxx/util/time.hpp>
+
+namespace nlsr {
+
+/*!
+   \brief Data abstraction for Lsa
+   Lsa := LSA-TYPE TLV-LENGTH
+            Name
+            SequenceNumber
+            ExpirationTimePoint
+ */
+class Lsa
+{
+public:
+  class Error : public ndn::tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : ndn::tlv::Error(what)
+    {
+    }
+  };
+
+  enum class Type {
+    ADJACENCY,
+    COORDINATE,
+    NAME,
+    BASE
+  };
+
+protected:
+  Lsa(const ndn::Name& originRouter, uint32_t seqNo,
+      ndn::time::system_clock::TimePoint expirationTimePoint);
+
+  Lsa() = default;
+
+public:
+  virtual
+  ~Lsa() = default;
+
+  virtual Type
+  getType() const
+  {
+    return Type::BASE;
+  }
+
+  void
+  setSeqNo(uint64_t seqNo)
+  {
+    m_seqNo = seqNo;
+    m_baseWire.reset();
+  }
+
+  uint64_t
+  getSeqNo() const
+  {
+    return m_seqNo;
+  }
+
+  const ndn::Name&
+  getOriginRouter() const
+  {
+    return m_originRouter;
+  }
+
+  const ndn::time::system_clock::TimePoint&
+  getExpirationTimePoint() const
+  {
+    return m_expirationTimePoint;
+  }
+
+  void
+  setExpirationTimePoint(const ndn::time::system_clock::TimePoint& lt)
+  {
+    m_expirationTimePoint = lt;
+    m_baseWire.reset();
+  }
+
+  void
+  setExpiringEventId(ndn::scheduler::EventId eid)
+  {
+    m_expiringEventId = std::move(eid);
+  }
+
+  ndn::scheduler::EventId
+  getExpiringEventId() const
+  {
+    return m_expiringEventId;
+  }
+
+  /*! \brief Gets the key for this LSA.
+
+    Format is: \<router name\>/\<LSA type>\
+   */
+  ndn::Name
+  getKey() const;
+
+  /*! Get data common to all LSA types.
+   */
+  std::string
+  toString() const;
+
+  template<ndn::encoding::Tag TAG>
+  size_t
+  wireEncode(ndn::EncodingImpl<TAG>& block) const;
+
+  void
+  wireDecode(const ndn::Block& wire);
+
+PUBLIC_WITH_TESTS_ELSE_PROTECTED:
+  ndn::Name m_originRouter;
+  uint64_t m_seqNo = 0;
+  ndn::time::system_clock::TimePoint m_expirationTimePoint;
+  ndn::scheduler::EventId m_expiringEventId;
+
+  mutable ndn::Block m_baseWire;
+};
+
+NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Lsa);
+
+std::ostream&
+operator<<(std::ostream& os, const Lsa::Type& type);
+
+std::istream&
+operator>>(std::istream& is, Lsa::Type& type);
+
+} // namespace nlsr
+
+#endif // NLSR_LSA_LSA_HPP
diff --git a/src/lsa/name-lsa.cpp b/src/lsa/name-lsa.cpp
new file mode 100644
index 0000000..37b7408
--- /dev/null
+++ b/src/lsa/name-lsa.cpp
@@ -0,0 +1,138 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2020,  The University of Memphis,
+ *                           Regents of the University of California,
+ *                           Arizona Board of Regents.
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "name-lsa.hpp"
+#include "tlv/tlv-nlsr.hpp"
+
+namespace nlsr {
+
+NameLsa::NameLsa(const ndn::Name& originRouter, uint32_t seqNo,
+                 const ndn::time::system_clock::TimePoint& timepoint,
+                 NamePrefixList& npl)
+  : Lsa(originRouter, seqNo, timepoint)
+{
+  for (const auto& name : npl.getNames()) {
+    addName(name);
+  }
+}
+
+NameLsa::NameLsa(const ndn::Block& block)
+{
+  wireDecode(block);
+}
+
+template<ndn::encoding::Tag TAG>
+size_t
+NameLsa::wireEncode(ndn::EncodingImpl<TAG>& block) const
+{
+  size_t totalLength = 0;
+
+  auto names = m_npl.getNames();
+
+  for (auto it = names.rbegin();  it != names.rend(); ++it) {
+    totalLength += it->wireEncode(block);
+  }
+
+  totalLength += Lsa::wireEncode(block);
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(ndn::tlv::nlsr::NameLsa);
+
+  return totalLength;
+}
+
+NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(NameLsa);
+
+const ndn::Block&
+NameLsa::wireEncode() const
+{
+  if (m_wire.hasWire() && m_baseWire.hasWire()) {
+    return m_wire;
+  }
+
+  ndn::EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  ndn::EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+
+  return m_wire;
+}
+
+void
+NameLsa::wireDecode(const ndn::Block& wire)
+{
+  m_wire = wire;
+
+  if (m_wire.type() != ndn::tlv::nlsr::NameLsa) {
+    BOOST_THROW_EXCEPTION(Error("Expected NameLsa Block, but Block is of a different type: #" +
+                                ndn::to_string(m_wire.type())));
+  }
+
+  m_wire.parse();
+
+  ndn::Block::element_const_iterator val = m_wire.elements_begin();
+
+  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Lsa) {
+    Lsa::wireDecode(*val);
+    ++val;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Missing required Lsa field"));
+  }
+
+  NamePrefixList npl;
+  for (; val != m_wire.elements_end(); ++val) {
+    if (val->type() == ndn::tlv::Name) {
+      npl.insert(ndn::Name(*val));
+    }
+    else {
+      BOOST_THROW_EXCEPTION(Error("Expected Name Block, but Block is of a different type: #" +
+                                  ndn::to_string(m_wire.type())));
+    }
+  }
+
+  m_npl = npl;
+}
+
+bool
+NameLsa::isEqualContent(const NameLsa& other) const
+{
+  return m_npl == other.getNpl();
+}
+
+std::ostream&
+operator<<(std::ostream& os, const NameLsa& lsa)
+{
+  os << lsa.toString();
+  os << "      Names:\n";
+  int i = 0;
+  auto names = lsa.getNpl().getNames();
+  for (const auto& name : names) {
+    os << "        Name " << i++ << ": " << name << "\n";
+  }
+
+  return os;
+}
+
+} // namespace nlsr
diff --git a/src/lsa/name-lsa.hpp b/src/lsa/name-lsa.hpp
new file mode 100644
index 0000000..3223839
--- /dev/null
+++ b/src/lsa/name-lsa.hpp
@@ -0,0 +1,103 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2020,  The University of Memphis,
+ *                           Regents of the University of California,
+ *                           Arizona Board of Regents.
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef NLSR_LSA_NAME_LSA_HPP
+#define NLSR_LSA_NAME_LSA_HPP
+
+#include "lsa.hpp"
+
+namespace nlsr {
+
+/*!
+   \brief Data abstraction for NameLsa
+   NameLsa := NAME-LSA-TYPE TLV-LENGTH
+                Lsa
+                Name+
+ */
+class NameLsa : public Lsa
+{
+public:
+  NameLsa() = default;
+
+  NameLsa(const ndn::Name& originRouter, uint32_t seqNo,
+          const ndn::time::system_clock::TimePoint& timepoint,
+          NamePrefixList& npl);
+
+  NameLsa(const ndn::Block& block);
+
+  Lsa::Type
+  getType() const override
+  {
+    return Lsa::Type::NAME;
+  }
+
+  NamePrefixList&
+  getNpl()
+  {
+    return m_npl;
+  }
+
+  const NamePrefixList&
+  getNpl() const
+  {
+    return m_npl;
+  }
+
+  void
+  addName(const ndn::Name& name)
+  {
+    m_wire.reset();
+    m_npl.insert(name);
+  }
+
+  void
+  removeName(const ndn::Name& name)
+  {
+    m_wire.reset();
+    m_npl.remove(name);
+  }
+
+  bool
+  isEqualContent(const NameLsa& other) const;
+
+  template<ndn::encoding::Tag TAG>
+  size_t
+  wireEncode(ndn::EncodingImpl<TAG>& block) const;
+
+  const ndn::Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const ndn::Block& wire);
+
+private:
+  NamePrefixList m_npl;
+  mutable ndn::Block m_wire;
+};
+
+NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(NameLsa);
+
+std::ostream&
+operator<<(std::ostream& os, const NameLsa& lsa);
+
+} // namespace nlsr
+
+#endif // NLSR_LSA_NAME_LSA_HPP
