[Cyphal/UDP] Architectural issues caused by the dependency between the node's IP address and its identity

This mostly makes sense except:

I understand that this is not formally part of this proposal but in the future I will strongly oppose this because it constitutes a breach of abstraction: the function of the transport layer is to deliver a serialized object from A to B without regard for its contents (things like the SwST flag are exempted because in this case the operation of the transport layer is dependent on the application data). If your application needs to differentiate valid data from invalid data then it has to be explicitly expressed in the data type definition. I think ARINC-825 (along with some related standards) is poorly designed in this respect.

If strongly desired, we could introduce some opaque user-specific flags that one could use to emulate ARINC-825-like behaviors in closed ecosystems.


I would like to revise the CRC definition once again. Could you comment on my suggestion to limit the CRC such that it covers only the header, and the payload is covered by the Transfer-CRC which is always present (even for single-frame transfers)?


Next I would like to bikeshed the field arrangement a little without altering the semantics significantly. The objectives are two: ensure natural alignment of each field to make struct aliasing possible, and harmonize the header format with Cyphal/serial. The latter stems from the fact that the updated Cyphal/UDP header definition is surprisingly close to that of Cyphal/serial and we could reap some benefits from their unification.

Here is basically your header definition with some fields shifted around, expressed in DSDL:

uint4 version           # <- 1
void4                   # Reserved for minor version or optional feature flags.

uint3 priority          # Duplicates QoS for ease of access; 0 -- highest, 7 -- lowest.
void5

@assert _offset_ == {16}
uint16 source_node_id
uint16 destination_node_id
uint16 data_specifier   # Like in Cyphal/serial: subject-ID | (service-ID + request/response discriminator).

@assert _offset_ == {64}
void64
uint64 transfer_id

@assert _offset_ % 32 == {0}
uint32 frame_index_eot  # MSB is set if the current frame is the last frame of the transfer.

bool starts_with_synchronized_time
void7

uint8 user_flags
# Opaque application-specific flags with user-defined semantics. Generic implementations should ignore.

@assert _offset_ % 16 == {0}
uint16 header_crc

@assert _offset_ / 8 == {32}  # Fixed-size 32-byte header with natural alignment for each field ensured.
@sealed

Key changes:

  • The field reserved for the Cyphal Header Length (CHL) is removed because its addition will necessitate changing the version number, which makes it redundant.
  • The data specifier incorporates the service-not-message and request-not-response flags. The subject-ID is 15-bit wide and the service-ID is 14-bit wide. This mirrors Cyphal/serial.
  • Anonymous transfers are indicated by setting the source node-ID to 2^{16}-1.
  • Multicast (i.e., message) transfers are indicated by setting the destination node-ID to 2^{16}-1.
  • The CRC is reduced to 16-bit and covers only the header (Hamming distance of 6 (sic!) is possible). The freed space is allocated for the user-specific flags.
  • TLAs are replaced with spelled-out names!!!1one