Skip to content

Notes on future transport frame headers #143

@pavel-kirienko

Description

@pavel-kirienko

At some point in the future we may want to consider updating the transport frame header definitions for UDP and serial. When that happens, we should consider this:

  1. It is desirable to add the total transfer payload size in the header. Yes, every frame of a transfer will carry the size of that transfer's payload, because in non-CAN transports frames may arrive out of order and even interleave with neighboring transfers. Having the size allows us to allocate not just extent-sized payload buffers but min(extent,size), which saves memory if the extent is large.

  2. Depending on how the named topic design goes, it is likely to be a good idea to add at least a 32-bit field for the topic discriminator. Per the current proposal, the topic discriminator is just a hash of the topic name that is added to every transfer and frame to manage topic allocation collisions. Currently, in the UDP and serial transports we only have space for 16~25 bits of the topic discriminator, depending on how you count.

It is important to attach the hash per frame rather than per transfer because frames may arrive out of order, and the transport should be able to detect a mismatch before an attempt to reassemble the transfer is made.

Cyphal/UDP specific

# All Cyphal/UDP traffic is sent to port 9382.
# All frames of a transfer must share the same field values unless otherwise noted.
# Frames may arrive out-of-order, possibly interleaved with neighboring transfers.

uint5 version                   #= 2
uint3 priority

bool flag_ack_required
void7

void16

@assert _offset_ == {4*8}

uint24 frame_index              # Zero-based index of the payload fragment carried by this frame.
void8
uint32 frame_payload_offset     # The offset of the frame payload relative to the start of the transfer payload.
uint32 transfer_payload_size    # Total for all frames.

@assert _offset_ == {16*8}

uint64 transfer_id              # For multi-frame (out-of-order) reassembly and duplicate rejection.
uint64 sender_uid               # Origin identifier ensures invariance to the source IP address for reassembly.
uint64 topic_hash

uint32 prefix_crc32c            # crc32c(payload[0:(frame_payload_offset+payload_size)])
uint32 header_crc32c            # Covers all fields above. Same as the transfer payload CRC.

@assert _offset_ == {48*8}

Cyphal/serial specific

# Single-frame transfers only; unlimited MTU.

uint5  version               #= 2
uint3  priority

bool   flag_ack_required
bool   flag_p2p
void6  # Reserved for future flags.

uint16 user_data
uint32 transfer_crc32c       # CRC32C of the entire transfer payload.

uint64 source_uid
uint64 topic_hash            # For P2P transfers specifies the destination UID.
uint64 transfer_id

uint32 transfer_payload_size # Capped at 2^32-1 if larger than 4 GiB.

uint32 header_crc32c         # Same CRC function as the transfer payload CRC.

@assert _offset_ == {40*8}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions