blob: 5a6177fafb0624e8ce3825fa02abd4bc6743cc8b [file] [log] [blame]
Spyridon Mastorakis5ea33222016-12-07 14:33:53 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2011-2015 Regents of the University of California.
4 *
5 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
7 *
8 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
19
20#include "ndn-block-header.hpp"
21
22#include <iosfwd>
23#include <boost/iostreams/concepts.hpp>
24#include <boost/iostreams/stream.hpp>
25
26#include <ndn-cxx/encoding/tlv.hpp>
27#include <ndn-cxx/interest.hpp>
28#include <ndn-cxx/data.hpp>
29#include <ndn-cxx/lp/packet.hpp>
30
31namespace io = boost::iostreams;
32namespace nfdFace = nfd::face;
33
34namespace ns3 {
35namespace ndn {
36
37ns3::TypeId
38BlockHeader::GetTypeId()
39{
40 static ns3::TypeId tid =
41 ns3::TypeId("ns3::ndn::Packet")
42 .SetGroupName("Ndn")
43 .SetParent<Header>()
44 .AddConstructor<BlockHeader>()
45 ;
46 return tid;
47}
48
49TypeId
50BlockHeader::GetInstanceTypeId(void) const
51{
52 return GetTypeId();
53}
54
55BlockHeader::BlockHeader()
56{
57}
58
Alexander Afanasyev59090db2020-02-21 16:37:43 -050059BlockHeader::BlockHeader(const Block& packet)
60 : m_block(packet)
Spyridon Mastorakis5ea33222016-12-07 14:33:53 -080061{
62}
63
64uint32_t
65BlockHeader::GetSerializedSize(void) const
66{
67 return m_block.size();
68}
69
70void
71BlockHeader::Serialize(ns3::Buffer::Iterator start) const
72{
73 start.Write(m_block.wire(), m_block.size());
74}
75
76class Ns3BufferIteratorSource : public io::source {
77public:
78 Ns3BufferIteratorSource(ns3::Buffer::Iterator& is)
79 : m_is(is)
80 {
81 }
82
83 std::streamsize
84 read(char* buf, std::streamsize nMaxRead)
85 {
86 std::streamsize i = 0;
87 for (; i < nMaxRead && !m_is.IsEnd(); ++i) {
88 buf[i] = m_is.ReadU8();
89 }
90 if (i == 0) {
91 return -1;
92 }
93 else {
94 return i;
95 }
96 }
97
98private:
99 ns3::Buffer::Iterator& m_is;
100};
101
102uint32_t
103BlockHeader::Deserialize(ns3::Buffer::Iterator start)
104{
105 io::stream<Ns3BufferIteratorSource> is(start);
106 m_block = ::ndn::Block::fromStream(is);
107 return m_block.size();
108}
109
110void
111BlockHeader::Print(std::ostream& os) const
112{
113 namespace tlv = ::ndn::tlv;
114 namespace lp = ::ndn::lp;
115
116 std::function<void(const Block& block)> decodeAndPrint = [&os, &decodeAndPrint] (const Block& block) {
117 switch (block.type()) {
118 case tlv::Interest: {
119 Interest i(block);
120 os << "Interest: " << i;
121 break;
122 }
123 case tlv::Data: {
124 Data d(block);
125 os << "Data: " << d.getName();
126 break;
127 }
128 case lp::tlv::LpPacket: {
129 os << "NDNLP(";
130 lp::Packet p(block);
131 if (p.has<lp::FragCountField>() && p.get<lp::FragCountField>() != 1) {
132 os << "fragment " << (p.get<lp::FragIndexField>() + 1) << " out of " << p.get<lp::FragCountField>();
133 }
134 else {
135 if (p.has<lp::NackField>()) {
136 lp::NackHeader nack = p.get<lp::NackField>();
137 os << "NACK(" << nack.getReason() << ") for ";
138 }
139
140 ::ndn::Buffer::const_iterator first, last;
141 std::tie(first, last) = p.get<lp::FragmentField>(0);
Alexander Afanasyev25e4d8f2019-07-29 13:44:04 -0400142 try {
Alexander Afanasyevf007a992022-05-05 15:57:08 -0400143 Block fragmentBlock(::ndn::make_span(&*first, std::distance(first, last)));
Alexander Afanasyev25e4d8f2019-07-29 13:44:04 -0400144 decodeAndPrint(fragmentBlock);
145 }
146 catch (const tlv::Error& error) {
147 os << "Non-TLV bytes (size: " << std::distance(first, last) << ")";
148 }
Spyridon Mastorakis5ea33222016-12-07 14:33:53 -0800149 }
150 os << ")";
151 break;
152 }
153 default: {
154 os << "Unrecognized";
155 break;
156 }
157 }
158 };
159
160 decodeAndPrint(m_block);
161}
162
163Block&
164BlockHeader::getBlock()
165{
166 return m_block;
167}
168
169const Block&
170BlockHeader::getBlock() const
171{
172 return m_block;
173}
174
175} // namespace ndn
176} // namespace ns3