lsa-info.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "lsa-info.hpp"
23 #include "tlv-nlsr.hpp"
24 
25 #include <ndn-cxx/util/concepts.hpp>
26 #include <ndn-cxx/encoding/block-helpers.hpp>
27 
28 namespace nlsr {
29 namespace tlv {
30 
31 BOOST_CONCEPT_ASSERT((ndn::WireEncodable<LsaInfo>));
32 BOOST_CONCEPT_ASSERT((ndn::WireDecodable<LsaInfo>));
33 static_assert(std::is_base_of<ndn::tlv::Error, LsaInfo::Error>::value,
34  "LsaInfo::Error must inherit from tlv::Error");
35 
36 const ndn::time::milliseconds LsaInfo::INFINITE_EXPIRATION_PERIOD(ndn::time::milliseconds::max());
37 
39  : m_sequenceNumber(0)
40  , m_expirationPeriod(INFINITE_EXPIRATION_PERIOD)
41  , m_hasInfiniteExpirationPeriod(true)
42 {
43 }
44 
45 LsaInfo::LsaInfo(const ndn::Block& block)
46 {
47  wireDecode(block);
48 }
49 
50 template<ndn::encoding::Tag TAG>
51 size_t
52 LsaInfo::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
53 {
54  size_t totalLength = 0;
55 
56  // Absence of an ExpirationPeriod signifies non-expiration
57  if (!m_hasInfiniteExpirationPeriod) {
58  totalLength += prependNonNegativeIntegerBlock(encoder,
60  m_expirationPeriod.count());
61  }
62 
63  totalLength += prependNonNegativeIntegerBlock(encoder,
65  m_sequenceNumber);
66 
67  totalLength += prependNestedBlock(encoder, ndn::tlv::nlsr::OriginRouter, m_originRouter);
68 
69  totalLength += encoder.prependVarNumber(totalLength);
70  totalLength += encoder.prependVarNumber(ndn::tlv::nlsr::LsaInfo);
71 
72  return totalLength;
73 }
74 
75 template size_t
76 LsaInfo::wireEncode<ndn::encoding::EncoderTag>(ndn::EncodingImpl<ndn::encoding::EncoderTag>& block) const;
77 
78 template size_t
79 LsaInfo::wireEncode<ndn::encoding::EstimatorTag>(ndn::EncodingImpl<ndn::encoding::EstimatorTag>& block) const;
80 
81 const ndn::Block&
83 {
84  if (m_wire.hasWire()) {
85  return m_wire;
86  }
87 
88  ndn::EncodingEstimator estimator;
89  size_t estimatedSize = wireEncode(estimator);
90 
91  ndn::EncodingBuffer buffer(estimatedSize, 0);
92  wireEncode(buffer);
93 
94  m_wire = buffer.block();
95 
96  return m_wire;
97 }
98 
99 void
100 LsaInfo::wireDecode(const ndn::Block& wire)
101 {
102  m_originRouter.clear();
103  m_sequenceNumber = 0;
104  m_expirationPeriod = ndn::time::milliseconds::min();
105 
106  m_wire = wire;
107 
108  if (m_wire.type() != ndn::tlv::nlsr::LsaInfo) {
109  std::stringstream error;
110  error << "Expected LsaInfo Block, but Block is of a different type: #"
111  << m_wire.type();
112  BOOST_THROW_EXCEPTION(Error(error.str()));
113  }
114 
115  m_wire.parse();
116 
117  ndn::Block::element_const_iterator val = m_wire.elements_begin();
118 
119  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::OriginRouter) {
120  val->parse();
121  ndn::Block::element_const_iterator it = val->elements_begin();
122 
123  if (it != val->elements_end() && it->type() == ndn::tlv::Name) {
124  m_originRouter.wireDecode(*it);
125  }
126  else {
127  BOOST_THROW_EXCEPTION(Error("OriginRouter: Missing required Name field"));
128  }
129 
130  ++val;
131  }
132  else {
133  BOOST_THROW_EXCEPTION(Error("Missing required OriginRouter field"));
134  }
135 
136  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::SequenceNumber) {
137  m_sequenceNumber = ndn::readNonNegativeInteger(*val);
138  ++val;
139  }
140  else {
141  BOOST_THROW_EXCEPTION(Error("Missing required SequenceNumber field"));
142  }
143 
144  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::ExpirationPeriod) {
145  m_expirationPeriod = ndn::time::milliseconds(ndn::readNonNegativeInteger(*val));
146  m_hasInfiniteExpirationPeriod = false;
147  }
148  else {
149  m_expirationPeriod = INFINITE_EXPIRATION_PERIOD;
150  m_hasInfiniteExpirationPeriod = true;
151  }
152 }
153 
154 std::ostream&
155 operator<<(std::ostream& os, const LsaInfo& lsaInfo)
156 {
157  os << "LsaInfo("
158  << "OriginRouter: " << lsaInfo.getOriginRouter() << ", "
159  << "SequenceNumber: " << lsaInfo.getSequenceNumber() << ", ";
160 
161  if (!lsaInfo.hasInfiniteExpirationPeriod()) {
162  os << "ExpirationPeriod: " << lsaInfo.getExpirationPeriod();
163  }
164  else {
165  os << "ExpirationPeriod: Infinity";
166  }
167 
168  os << ")";
169 
170  return os;
171 }
172 
173 std::shared_ptr<LsaInfo>
174 makeLsaInfo(const Lsa& lsa)
175 {
176  std::shared_ptr<LsaInfo> lsaInfo = std::make_shared<LsaInfo>();
177 
178  lsaInfo->setOriginRouter(lsa.getOrigRouter());
179  lsaInfo->setSequenceNumber(lsa.getLsSeqNo());
180 
181  ndn::time::system_clock::duration duration
182  = lsa.getExpirationTimePoint() - ndn::time::system_clock::now();
183 
184  lsaInfo->setExpirationPeriod(ndn::time::duration_cast<ndn::time::milliseconds>(duration));
185 
186  return lsaInfo;
187 }
188 
189 } // namespace tlv
190 } // namespace nlsr
const ndn::time::system_clock::TimePoint & getExpirationTimePoint() const
Definition: lsa.hpp:88
const ndn::Name & getOrigRouter() const
Definition: lsa.hpp:76
const ndn::time::milliseconds & getExpirationPeriod() const
Definition: lsa-info.hpp:96
uint32_t getLsSeqNo() const
Definition: lsa.hpp:70
std::shared_ptr< LsaInfo > makeLsaInfo(const Lsa &lsa)
Definition: lsa-info.cpp:174
const ndn::Block & wireEncode() const
Create a TLV encoding of this object.
Definition: lsa-info.cpp:82
const ndn::Name & getOriginRouter() const
Definition: lsa-info.hpp:66
Data abstraction for LsaInfo.
Definition: lsa-info.hpp:47
uint64_t getSequenceNumber() const
Definition: lsa-info.hpp:80
Copyright (c) 2014-2017, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
bool hasInfiniteExpirationPeriod() const
Definition: lsa-info.hpp:113
std::ostream & operator<<(std::ostream &os, const AdjacencyLsa &adjacencyLsa)
static const ndn::time::milliseconds INFINITE_EXPIRATION_PERIOD
Definition: lsa-info.hpp:93
void wireDecode(const ndn::Block &wire)
Populate this object by decoding the one contained in the given block.
Definition: lsa-info.cpp:100