ndn_packet/lp/
mod.rs

1//! NDNLPv2 Link Protocol Packet framing.
2//!
3//! An `LpPacket` (TLV 0x64) wraps a network-layer packet (Interest or Data)
4//! with optional link-layer header fields:
5//!
6//! - **Nack** (0x0320): carries a NackReason; the fragment is the nacked Interest
7//! - **CongestionMark** (0x0340): hop-by-hop congestion signal
8//! - **Sequence / FragIndex / FragCount**: fragmentation (decode only)
9//!
10//! Bare Interest/Data packets (not wrapped in LpPacket) are still valid on the
11//! wire — LpPacket framing is only required when link-layer fields are present.
12
13mod decode;
14mod encode;
15mod fragment;
16
17pub use decode::LpPacket;
18pub use encode::{
19    encode_lp_acks, encode_lp_nack, encode_lp_packet, encode_lp_reliable, encode_lp_with_headers,
20};
21pub use fragment::{FragmentHeader, extract_acks, extract_fragment};
22
23/// Cache policy type for NDNLPv2 CachePolicy header field.
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub enum CachePolicyType {
26    NoCache,
27    Other(u64),
28}
29
30/// Optional LP header fields for encoding.
31pub struct LpHeaders {
32    pub pit_token: Option<bytes::Bytes>,
33    pub congestion_mark: Option<u64>,
34    pub incoming_face_id: Option<u64>,
35    pub cache_policy: Option<CachePolicyType>,
36}
37
38/// Check if raw bytes start with an LpPacket TLV type (0x64).
39pub fn is_lp_packet(raw: &[u8]) -> bool {
40    raw.first() == Some(&0x64)
41}
42
43/// Encode a u64 as a NonNegativeInteger (minimal big-endian, 1/2/4/8 bytes).
44/// Returns the buffer and the number of bytes written.
45pub(super) fn nni(val: u64) -> ([u8; 8], usize) {
46    let be = val.to_be_bytes();
47    if val <= 0xFF {
48        ([be[7], 0, 0, 0, 0, 0, 0, 0], 1)
49    } else if val <= 0xFFFF {
50        ([be[6], be[7], 0, 0, 0, 0, 0, 0], 2)
51    } else if val <= 0xFFFF_FFFF {
52        ([be[4], be[5], be[6], be[7], 0, 0, 0, 0], 4)
53    } else {
54        (be, 8)
55    }
56}
57
58/// Decode a big-endian unsigned integer from variable-length bytes.
59pub(super) fn decode_be_u64(bytes: &[u8]) -> u64 {
60    let mut val = 0u64;
61    for &b in bytes {
62        val = (val << 8) | b as u64;
63    }
64    val
65}