NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: NDN, CCN, CCNx, content centric networks
API Documentation
packet.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "packet.hpp"
23 #include "detail/field-info.hpp"
24 
25 #include <boost/range/adaptor/reversed.hpp>
26 
27 namespace ndn {
28 namespace lp {
29 
31  : m_wire(Block(tlv::LpPacket))
32 {
33 }
34 
35 Packet::Packet(const Block& wire)
36 {
37  wireDecode(wire);
38 }
39 
40 template<encoding::Tag TAG>
41 size_t
43 {
44  if (m_wire.hasWire()) {
45  return m_wire.size();
46  }
47 
48  size_t length = 0;
49 
50  for (const Block& element : boost::adaptors::reverse(m_wire.elements())) {
51  length += encoder.prependBlock(element);
52  }
53 
54  length += encoder.prependVarNumber(length);
55  length += encoder.prependVarNumber(tlv::LpPacket);
56 
57  return length;
58 }
59 
60 template size_t
61 Packet::wireEncode<encoding::EncoderTag>(EncodingImpl<encoding::EncoderTag>& encoder) const;
62 
63 template size_t
64 Packet::wireEncode<encoding::EstimatorTag>(EncodingImpl<encoding::EstimatorTag>& encoder) const;
65 
66 Block
68 {
69  if (m_wire.hasWire()) {
70  return m_wire;
71  }
72 
73  // If no header or trailer, return bare network packet
74  Block::element_container elements = m_wire.elements();
75  if (elements.size() == 1 && elements.front().type() == FragmentField::TlvType::value) {
76  elements.front().parse();
77  elements.front().elements().front().parse();
78  return elements.front().elements().front();
79  }
80 
81  EncodingEstimator estimator;
82  size_t estimatedSize = wireEncode(estimator);
83 
84  EncodingBuffer buffer(estimatedSize, 0);
85  wireEncode(buffer);
86 
87  m_wire = buffer.block();
88  return m_wire;
89 }
90 
91 void
93 {
94  if (wire.type() == ndn::tlv::Interest || wire.type() == ndn::tlv::Data) {
95  m_wire = Block(tlv::LpPacket);
96  add<FragmentField>(make_pair(wire.begin(), wire.end()));
97  return;
98  }
99 
100  if (wire.type() != tlv::LpPacket) {
101  BOOST_THROW_EXCEPTION(Error("unrecognized TLV-TYPE " + to_string(wire.type())));
102  }
103 
104  wire.parse();
105 
106  bool isFirst = true;
107  detail::FieldInfo prev;
108  for (const Block& element : wire.elements()) {
109  detail::FieldInfo info(element.type());
110 
111  if (!info.isRecognized && !info.canIgnore) {
112  BOOST_THROW_EXCEPTION(Error("unrecognized field cannot be ignored"));
113  }
114 
115  if (!isFirst) {
116  if (info.tlvType == prev.tlvType && !info.isRepeatable) {
117  BOOST_THROW_EXCEPTION(Error("non-repeatable field cannot be repeated"));
118  }
119 
120  else if (info.tlvType != prev.tlvType && !detail::compareFieldSortOrder(prev, info)) {
121  BOOST_THROW_EXCEPTION(Error("fields are not in correct sort order"));
122  }
123  }
124 
125  isFirst = false;
126  prev = info;
127  }
128 
129  m_wire = wire;
130 }
131 
132 bool
133 Packet::comparePos(const Block& first, const uint64_t second)
134 {
135  detail::FieldInfo firstInfo(first.type());
136  detail::FieldInfo secondInfo(second);
137  return detail::compareFieldSortOrder(firstInfo, secondInfo);
138 }
139 
140 } // namespace lp
141 } // namespace ndn
bool hasWire() const
Check if the Block has fully encoded wire.
Definition: block.cpp:471
Copyright (c) 2011-2015 Regents of the University of California.
EncodingImpl< EstimatorTag > EncodingEstimator
void parse() const
Parse wire buffer into subblocks.
Definition: block.cpp:322
Class representing a wire element of NDN-TLV packet format.
Definition: block.hpp:43
size_t size() const
Definition: block.cpp:504
bool compareFieldSortOrder(const FieldInfo &first, const FieldInfo &second)
Definition: field-info.hpp:87
void wireDecode(const Block &wire)
decode packet from wire format
Definition: packet.cpp:92
EncodingImpl< EncoderTag > EncodingBuffer
Buffer::const_iterator begin() const
Definition: block.cpp:477
Buffer::const_iterator end() const
Definition: block.cpp:486
std::vector< Block > element_container
Definition: block.hpp:46
const element_container & elements() const
Get all subelements.
Definition: block.hpp:364
Block wireEncode() const
encode packet into wire format
Definition: packet.cpp:67
std::string to_string(const V &v)
Definition: backports.hpp:55
uint32_t type() const
Definition: block.hpp:346
uint64_t tlvType
TLV-TYPE of the field; 0 if field does not exist.
Definition: field-info.hpp:45