1 #ifndef NDNPH_PACKET_LP_HPP
2 #define NDNPH_PACKET_LP_HPP
15 using MaxSize = std::integral_constant<size_t, 1 + 1 + 8 + 1 + 1 + 1 + 1 + 1 + 1>;
47 explicit operator bool()
const {
56 return m_value.begin();
60 uint32_t
to4()
const {
66 if (
length > m_value.size()) {
76 if (room ==
nullptr) {
79 std::copy_n(m_value.begin(), m_length, room);
88 return lhs.m_length == rhs.m_length &&
89 std::equal(lhs.m_value.begin(), lhs.m_value.begin() + lhs.m_length, rhs.m_value.begin());
107 std::integral_constant<size_t, 1 + 1 + NDNPH_PITTOKEN_MAX + NackHeader::MaxSize::value>;
138 template<
typename Payload>
142 : payload(std::move(payload)) {}
153 if (frag.fragCount <= 1 && l3h.
size() == 0) {
160 if (frag.fragCount > 1) {
161 encoder.prepend(frag);
176 template<
typename L3,
typename R = Encodable<L3>>
180 encodable.pitToken = pitToken;
188 inline Encodable<Interest>
215 , m_room(static_cast<int>(mtu) - FragmentOverhead) {
230 template<
typename L3>
233 size_t sizeofHeader = 0;
240 sizeofHeader = l3h.
size();
244 packet.
payload.encodeTo(payload);
251 return fragmentImpl(packet, sizeofHeader,
tlv::Value(payload));
256 int sizeofFirstFragment = m_room - sizeofHeader;
257 if (sizeofFirstFragment >
static_cast<int>(payload.
size())) {
258 auto frag = region.make<
Fragment>(payload);
259 if (frag ==
nullptr) {
262 frag->copyL3HeaderFrom(
input);
265 if (sizeofFirstFragment <= 0) {
269 auto first = region.make<Fragment>(tlv::Value(payload.
begin(), sizeofFirstFragment));
270 if (first ==
nullptr) {
273 first->copyL3HeaderFrom(
input);
276 uint8_t fragCount = 1;
277 for (
size_t nextOffset, offset = sizeofFirstFragment; offset < payload.
size();
278 offset = nextOffset) {
279 nextOffset = std::min(offset + m_room, payload.
size());
281 region.make<Fragment>(tlv::Value(payload.
begin() + offset, payload.
begin() + nextOffset));
282 if (frag ==
nullptr) {
291 for (uint8_t fragIndex = 0; fragIndex < fragCount; ++fragIndex) {
292 frag->frag.seqNum = m_nextSeqNum++;
293 frag->frag.fragIndex = fragIndex;
294 frag->frag.fragCount = fragCount;
295 frag =
const_cast<Fragment*
>(frag->next);
302 FragmentOverhead = 1 + 3 +
309 uint64_t m_nextSeqNum = 0;
320 return std::make_tuple(
true, copy);
322 copy.
nack = nack.clone(region);
323 return std::make_tuple(!!copy.
nack, copy);
352 : m_l3header(l3header)
353 , m_payload(payload) {
354 m_type = classifyType();
362 switch (
input.type) {
366 m_type = classifyType();
367 return m_type != Type::None;
376 [](uint32_t type) {
return type < 800 || type > 959 || (type & 0x03) != 0x00; },
377 EvDecoder::defNni<TT::LpSeqNum, tlv::NNI8>(&m_frag.seqNum),
378 EvDecoder::defNni<TT::FragIndex>(&m_frag.fragIndex),
379 EvDecoder::defNni<TT::FragCount>(&m_frag.fragCount),
380 EvDecoder::def<TT::PitToken>(&m_l3header.pitToken),
381 EvDecoder::def<TT::Nack>([
this](
const Decoder::Tlv& d) {
385 EvDecoder::def<TT::LpPayload>(&m_payload));
390 m_type = classifyType();
391 return m_type != Type::None;
401 return m_l3header.pitToken;
421 return m_type ==
Type::Interest && m_payload.makeDecoder().decode(interest);
429 return m_type ==
Type::Data && m_payload.makeDecoder().decode(data);
439 return m_type ==
Type::Nack && m_l3header.nack.makeDecoder().decode(nackHeader) &&
440 m_payload.makeDecoder().decode(interest);
444 Type classifyType()
const {
445 if (m_frag.fragCount > 1) {
446 return Type::Fragment;
448 for (
auto l3 : m_payload.makeDecoder()) {
462 Type m_type = Type::None;
463 FragmentHeader m_frag;
465 tlv::Value m_payload;
521 if (m_nextFragIndex != m_fragCount) {
534 m_capacity = region.available();
535 m_buffer = region.alloc(m_capacity);
536 if (!ok || m_buffer ==
nullptr) {
547 bool append(
const Fragment& frag) {
548 if (m_buffer ==
nullptr || frag.getSeqNumBase() != m_seqNumBase ||
549 frag.fragIndex != m_nextFragIndex || frag.fragCount != m_fragCount ||
550 frag.payload.size() > m_capacity - m_size) {
554 std::copy(frag.payload.begin(), frag.payload.end(), &m_buffer[m_size]);
555 m_size += frag.payload.size();
562 uint8_t* m_buffer =
nullptr;
563 size_t m_capacity = 0;
565 uint64_t m_seqNumBase = 0;
566 uint8_t m_nextFragIndex = 0;
567 uint8_t m_fragCount = 0;
static bool generate(uint8_t *output, size_t count)
Data packet.
Definition: data.hpp:136
Decoded TLV.
Definition: decoder.hpp:13
const uint8_t * tlv
Definition: decoder.hpp:42
size_t length
Definition: decoder.hpp:39
size_t size
Definition: decoder.hpp:43
const uint8_t * value
Definition: decoder.hpp:40
TLV encoder that accepts items in reverse order.
Definition: encoder.hpp:10
bool prepend(const First &first, const Arg &... arg)
Prepend a sequence of values.
Definition: encoder.hpp:123
void trim() const
Release unused space to the Region.
Definition: encoder.hpp:58
bool prependTypeLength(uint32_t type, size_t length)
Prepend TLV-TYPE and TLV-LENGTH.
Definition: encoder.hpp:103
void discard()
Release all space to the Region.
Definition: encoder.hpp:72
uint8_t * prependRoom(size_t size)
Make room to prepend an object.
Definition: encoder.hpp:90
bool prependTlv(uint32_t type, OmitEmptyTag omitEmpty, const Arg &... arg)
Prepend TLV, measuring TLV-LENGTH automatically.
Definition: encoder.hpp:143
void setError()
Indicate an error has occurred.
Definition: encoder.hpp:166
size_t size() const
Get output size.
Definition: encoder.hpp:44
Definition: ev-decoder.hpp:95
static bool decodeEx(const Decoder::Tlv &input, std::initializer_list< uint32_t > topTypes, const UnknownCallback &unknownCb, const IsCritical &isCritical, const E &... defs)
Decode input TLV with a sequence of element definitions.
Definition: ev-decoder.hpp:145
Interest packet.
Definition: interest.hpp:284
Nack packet.
Definition: nack.hpp:73
Interest getInterest() const
Access the Interest.
Definition: nack.hpp:87
NackHeader getHeader() const
Access the Nack header.
Definition: nack.hpp:78
Region-based memory allocator thats owns memory of NDNph objects.
Definition: region.hpp:9
Encoder that auto-discards upon destruction.
Definition: encoder.hpp:198
Region with statically allocated memory.
Definition: region.hpp:143
Base class of an object associated with a Region.
Definition: region.hpp:182
Common fields during encoding.
Definition: lp.hpp:103
void encodeL3Header(Encoder &encoder) const
Definition: lp.hpp:109
FragmentHeader frag
Definition: lp.hpp:129
NackHeader nack
Definition: lp.hpp:131
std::integral_constant< size_t, 1+1+NDNPH_PITTOKEN_MAX+NackHeader::MaxSize::value > L3MaxSize
Maximum encoded size of L3 headers.
Definition: lp.hpp:107
PitToken pitToken
Definition: lp.hpp:130
void copyL3HeaderFrom(const EncodableBase &src)
Definition: lp.hpp:123
Encodable type of an LpPacket.
Definition: lp.hpp:139
Encodable(Payload payload)
Definition: lp.hpp:141
Payload payload
Definition: lp.hpp:168
void encodeTo(Encoder &encoder) const
Definition: lp.hpp:144
Decoded fragment.
Definition: lp.hpp:332
tlv::Value payload
Definition: lp.hpp:335
L3Header l3header
Definition: lp.hpp:334
Singly linked list of encodable fragments.
Definition: lp.hpp:199
NDNLPv2 fragmenter.
Definition: lp.hpp:196
Fragmenter(Region ®ion, uint16_t mtu)
Constructor.
Definition: lp.hpp:213
const Fragment * fragment(Encodable< L3 > packet)
Fragment an LP packet.
Definition: lp.hpp:231
Decode NDNLPv2 packet for classification.
Definition: lp.hpp:339
Type getType() const
Determine L3 packet type.
Definition: lp.hpp:395
Fragment getFragment() const
Retrieve fragment.
Definition: lp.hpp:408
bool decodeFrom(const Decoder::Tlv &input)
Definition: lp.hpp:357
bool decodeNack(Nack nack) const
Decode Nack.
Definition: lp.hpp:436
bool decodeData(Data data) const
Decode payload as Data.
Definition: lp.hpp:428
Type
Definition: lp.hpp:341
const PitToken & getPitToken() const
Retrieve PIT token.
Definition: lp.hpp:400
PacketClassify(L3Header l3header, tlv::Value payload)
Definition: lp.hpp:351
bool decodeInterest(Interest interest) const
Decode payload as Interest.
Definition: lp.hpp:420
PIT token field.
Definition: lp.hpp:35
bool decodeFrom(const Decoder::Tlv &d)
Definition: lp.hpp:83
const uint8_t * value() const
Definition: lp.hpp:55
static PitToken from4(uint32_t n)
Construct 4-octet PIT token from uint32.
Definition: lp.hpp:38
uint32_t to4() const
Interpret 4-octet PIT token as uint32.
Definition: lp.hpp:60
bool set(size_t length, const uint8_t *value)
Assign PIT token length and value.
Definition: lp.hpp:65
void encodeTo(Encoder &encoder) const
Definition: lp.hpp:74
size_t length() const
Definition: lp.hpp:51
friend bool operator==(const PitToken &lhs, const PitToken &rhs)
Definition: lp.hpp:87
NDNLPv2 fragmenter.
Definition: lp.hpp:471
PacketClassify reassemble() const
Reassemble the packet if it's complete.
Definition: lp.hpp:520
void discard()
Discard the reassembly buffer.
Definition: lp.hpp:488
bool add(const Fragment &frag)
Add a fragment.
Definition: lp.hpp:507
Reassembler(Region ®ion)
Constructor.
Definition: lp.hpp:478
NonNegativeInteger encoding.
Definition: nni.hpp:118
A sequence of bytes, usually TLV-VALUE.
Definition: value.hpp:11
const uint8_t * begin() const
Definition: value.hpp:38
size_t size() const
Definition: value.hpp:46
static void writeValue(uint8_t *room, T n)
static T readValue(const uint8_t *input)
#define NDNPH_PITTOKEN_MAX
Maximum length of PIT token.
Definition: common.hpp:45
@ Interest
Definition: an.hpp:30
@ LpSeqNum
Definition: an.hpp:11
@ LpPacket
Definition: an.hpp:9
@ LpPayload
Definition: an.hpp:10
@ Nack
Definition: an.hpp:15
@ Data
Definition: an.hpp:41
@ FragCount
Definition: an.hpp:13
@ PitToken
Definition: an.hpp:14
@ FragIndex
Definition: an.hpp:12
bool input(Region ®ion, T &target, std::istream &is=std::cin)
Read and decode from input stream.
Definition: io.hpp:15
R encode(L3 l3, PitToken pitToken={})
Encode Interest or Data as LpPacket, optionally with PIT token.
Definition: lp.hpp:178
#define NDNPH_DECLARE_NE(T, specifier)
Declare operator!= in terms of operator==.
Definition: operators.hpp:7