7777#define UDPARD_SUBJECT_ID_MASK 32767U /// 0x7FFF
7878#define UDPARD_SUBNET_OFFSET 17U
7979#define UDPARD_SUBNET_MASK (31U << UDPARD_SUBNET_OFFSET)
80+ #define UDPARD_TRANSMIT_SUBNET_VALUE 0U
8081#define UDPARD_RESERVED_1BIT_OFFSET 15U
8182#define UDPARD_RESERVED_1BIT_MASK (1U << UDPARD_RESERVED_1BIT_OFFSET)
8283#define UDPARD_SERVICE_NOT_MESSAGE_OFFSET 16U
@@ -97,7 +98,7 @@ IRNR - Is Request, Not Response
9798#define UDPARD_SERVICE_ID_MASK 16383U /// 0x3FFF
9899#define UPDARD_DATA_SPECIFIER_MESSAGE (0xFFFF >> 1) // SNM (0) + SubjectID
99100#define UDPARD_DATA_SPECIFIER_SERVICE_RESPONSE (2U << UDPARD_IRNR_DATA_SPECIFIER_OFFSET) // Set SNM in Cyphal data specifier - SNM (1) + IRNR (0) + ServiceID
100- #define UDPARD_DATA_SPECIFIER_SERVICE_REQUEST (3U << UDPARD_IRNR_DATA_SPECIFIER_OFFSET) // Set SNM and IRNR in Cyphal data specifier - SNM (1) + IRNR (1) + ServiceID
101+ #define UDPARD_DATA_SPECIFIER_SERVICE_REQUEST (3U << UDPARD_IRNR_DATA_SPECIFIER_OFFSET) // Set SNM and IRNR in Cyphal data specifier - SNM (1) + IRNR (1) + ServiceID
101102
102103/// Ports align with subject and service ids
103104/// Subjects use multicast and always use port 16383
@@ -255,7 +256,7 @@ UDPARD_PRIVATE int32_t txMakeMessageSessionSpecifier(const UdpardPortID
255256 (local_node_addr & ~(UdpardIPv4Addr ) UDPARD_NODE_ID_MASK ) |
256257 (UdpardIPv4Addr ) src_node_id ;
257258 out_spec -> destination_route_specifier =
258- ((local_node_addr & (UdpardIPv4Addr ) UDPARD_SUBNET_MASK ) |
259+ ((UDPARD_TRANSMIT_SUBNET_VALUE & (UdpardIPv4Addr ) UDPARD_SUBNET_MASK ) |
259260 (UdpardIPv4Addr ) UDPARD_MULTICAST_PREFIX |
260261 ((UdpardIPv4Addr ) UDPARD_SUBJECT_ID_MASK & (UdpardIPv4Addr ) subject_id )) &
261262 ~(UdpardIPv4Addr ) UDPARD_SERVICE_NOT_MESSAGE_MASK &
@@ -265,9 +266,7 @@ UDPARD_PRIVATE int32_t txMakeMessageSessionSpecifier(const UdpardPortID
265266}
266267
267268UDPARD_PRIVATE int32_t txMakeServiceSessionSpecifier (const UdpardPortID service_id ,
268- const bool request_not_response ,
269269 const UdpardNodeID src_node_id ,
270- const UdpardNodeID dst_node_id ,
271270 const UdpardIPv4Addr local_node_addr ,
272271 UdpardSessionSpecifier * const out_spec )
273272{
@@ -278,9 +277,9 @@ UDPARD_PRIVATE int32_t txMakeServiceSessionSpecifier(const UdpardPortID
278277 (local_node_addr & ~(UdpardIPv4Addr ) UDPARD_NODE_ID_MASK ) |
279278 (UdpardIPv4Addr ) src_node_id ;
280279 out_spec -> destination_route_specifier =
281- ((local_node_addr & (UdpardIPv4Addr ) UDPARD_SUBNET_MASK ) |
280+ ((UDPARD_TRANSMIT_SUBNET_VALUE & (UdpardIPv4Addr ) UDPARD_SUBNET_MASK ) |
282281 (UdpardIPv4Addr ) UDPARD_MULTICAST_PREFIX |
283- ((UdpardIPv4Addr ) UDPARD_NODE_ID_MASK & (UdpardIPv4Addr ) dst_node_id )) |
282+ ((UdpardIPv4Addr ) UDPARD_NODE_ID_MASK & (UdpardIPv4Addr ) service_id )) |
284283 (UdpardIPv4Addr ) UDPARD_SERVICE_NOT_MESSAGE_MASK ;
285284 out_spec -> data_specifier = (UdpardUdpPortID ) UDPARD_UDP_PORT ;
286285 return UDPARD_SUCCESS ;
@@ -323,9 +322,7 @@ UDPARD_PRIVATE int32_t txMakeSessionSpecifier(const UdpardTransferMetadata* cons
323322 if (local_node_id != UDPARD_NODE_ID_UNSET )
324323 {
325324 out = txMakeServiceSessionSpecifier (tr -> port_id ,
326- tr -> transfer_kind == UdpardTransferKindRequest ,
327325 local_node_id ,
328- tr -> remote_node_id ,
329326 local_node_addr ,
330327 spec );
331328 UDPARD_ASSERT (out >= 0 );
@@ -365,20 +362,20 @@ UDPARD_PRIVATE void txMakeFrameHeader(UdpardFrameHeader* const header,
365362 uint32_t end_of_transfer_mask = (uint32_t ) (end_of_transfer ? 1 : 0 ) << (uint32_t ) UDPARD_END_OF_TRANSFER_OFFSET ;
366363 size_t cyphal_header_size_without_crc = sizeof (UdpardFrameHeader ) - CYPHAL_HEADER_CRC_SIZE_BYTES ;
367364 header -> transfer_id = transfer_id ;
365+ header -> version = (uint8_t ) UDPARD_CYPHAL_HEADER_VERSION ;
368366 header -> priority = (uint8_t ) priority ;
369367 header -> frame_index_eot = end_of_transfer_mask | frame_index ;
370368 header -> source_node_id = src_node_id ;
371369 header -> destination_node_id = dst_node_id ;
372370 header -> cyphal_header_checksum = cyphalHeaderCrcAdd (CYPHAL_HEADER_CRC_INITIAL , cyphal_header_size_without_crc , header );
373371 if (transfer_kind == UdpardTransferKindMessage )
374372 {
375- header -> data_specifier = (uint16_t ) UPDARD_DATA_SPECIFIER_MESSAGE & port_id ; // SNM (0) + Subject ID
373+ header -> data_specifier = (uint16_t ) UPDARD_DATA_SPECIFIER_MESSAGE & port_id & UDPARD_SUBJECT_ID_MASK ; // SNM (0) + Subject ID
376374 }
377375 else
378376 {
379377 header -> data_specifier =
380- (transfer_kind == UdpardTransferKindRequest ) ? UDPARD_DATA_SPECIFIER_SERVICE_REQUEST | port_id
381- : UDPARD_DATA_SPECIFIER_SERVICE_RESPONSE | port_id ; // SNM (1) + IRNR + ServiceID
378+ ((transfer_kind == UdpardTransferKindRequest ) ? UDPARD_DATA_SPECIFIER_SERVICE_REQUEST : UDPARD_DATA_SPECIFIER_SERVICE_RESPONSE ) | port_id ; // SNM (1) + IRNR + ServiceID
382379 }
383380}
384381
@@ -435,10 +432,10 @@ UDPARD_PRIVATE int32_t txPushSingleFrame(UdpardTxQueue* const que
435432 UdpardInstance * const ins ,
436433 const UdpardMicrosecond deadline_usec ,
437434 const UdpardSessionSpecifier * const specifier ,
438- const UdpardNodeID src_node_id ,
439- const UdpardNodeID dst_node_id ,
440- const UdpardPortID port_id ,
441- const UdpardTransferKind transfer_kind ,
435+ const UdpardNodeID src_node_id ,
436+ const UdpardNodeID dst_node_id ,
437+ const UdpardPortID port_id ,
438+ const UdpardTransferKind transfer_kind ,
442439 const UdpardPriority priority ,
443440 const UdpardTransferID transfer_id ,
444441 const size_t payload_size ,
@@ -477,7 +474,7 @@ UDPARD_PRIVATE int32_t txPushSingleFrame(UdpardTxQueue* const que
477474 (uint8_t )(crc >> 8U & CRC_BYTE_MASK ),
478475 (uint8_t )(crc >> 16U & CRC_BYTE_MASK ),
479476 (uint8_t )(crc >> 24U & CRC_BYTE_MASK )};
480- for (int i = 0 ; i < sizeof (crc_as_byte ); i ++ )
477+ for (unsigned int i = 0 ; i < sizeof (crc_as_byte ); i ++ )
481478 {
482479 tqi -> payload_buffer [frame_offset ++ ] = crc_as_byte [i ];
483480 }
@@ -590,9 +587,9 @@ UDPARD_PRIVATE TxChain txGenerateMultiFrameChain(UdpardInstance* const in
590587 (void ) memcpy (& out .tail -> payload_buffer [sizeof (UdpardFrameHeader )], payload_ptr , payload_move_size ); // NOLINT
591588 frame_offset += sizeof (UdpardFrameHeader ) + payload_move_size ;
592589 // Insert crc into same frame
593- for (int i = 0 ; i < overrun_amount ; i ++ )
590+ for (unsigned int i = 0 ; i < overrun_amount ; i ++ )
594591 {
595- out .tail -> payload_buffer [frame_offset ++ ] = crc_as_byte [i + last_crc_index ];
592+ out .tail -> payload_buffer [frame_offset ++ ] = crc_as_byte [i + last_crc_index ];
596593 }
597594 last_crc_index += overrun_amount ;
598595 }
@@ -727,6 +724,7 @@ typedef struct UdpardInternalRxSession
727724typedef struct
728725{
729726 UdpardMicrosecond timestamp_usec ;
727+ UdpardHeaderVersion version ;
730728 UdpardPriority priority ;
731729 UdpardTransferKind transfer_kind ;
732730 UdpardPortID port_id ;
@@ -810,19 +808,22 @@ UDPARD_PRIVATE bool rxTryParseFrame(const UdpardMicrosecond timestam
810808 (void ) memcpy (& frame -> udp_cyphal_header , frame -> payload , sizeof (frame -> udp_cyphal_header )); // NOLINT
811809 out -> timestamp_usec = timestamp_usec ;
812810
813- out -> priority = (UdpardPriority ) frame -> udp_cyphal_header .priority ;
814- out -> source_node_id = frame -> udp_cyphal_header .source_node_id ;
815- out -> transfer_kind = getTransferKindFromDataSpecifier (frame -> udp_cyphal_header .data_specifier );
816- out -> port_id = getPortIdFromDataSpecifiers (frame -> udp_cyphal_header .data_specifier );
817- out -> destination_node_id = frame -> udp_cyphal_header .destination_node_id ;
811+ out -> version = frame -> udp_cyphal_header .version ;
812+ out -> priority = (UdpardPriority ) frame -> udp_cyphal_header .priority ;
813+ out -> source_node_id = frame -> udp_cyphal_header .source_node_id ;
814+ out -> transfer_kind = getTransferKindFromDataSpecifier (frame -> udp_cyphal_header .data_specifier );
815+ out -> port_id = getPortIdFromDataSpecifiers (frame -> udp_cyphal_header .data_specifier );
816+ out -> destination_node_id = frame -> udp_cyphal_header .destination_node_id ;
818817 // Payload parsing.
819- out -> payload_size = frame -> payload_size - sizeof (frame -> udp_cyphal_header ); // Cut off the header size.
820- out -> payload = (void * ) ((uint8_t * ) frame -> payload + sizeof (frame -> udp_cyphal_header ));
821-
822- out -> transfer_id = frame -> udp_cyphal_header .transfer_id ;
823- out -> start_of_transfer = (((frame -> udp_cyphal_header .frame_index_eot ) & (UDPARD_MAX_FRAME_INDEX )) == 1 );
824- out -> end_of_transfer = ((frame -> udp_cyphal_header .frame_index_eot >> UDPARD_END_OF_TRANSFER_OFFSET ) == 1 );
825- out -> frame_index = frame -> udp_cyphal_header .frame_index_eot ;
818+ out -> payload_size = frame -> payload_size - sizeof (frame -> udp_cyphal_header ); // Cut off the header size.
819+ out -> payload = (void * ) ((uint8_t * ) frame -> payload + sizeof (frame -> udp_cyphal_header ));
820+
821+ out -> transfer_id = frame -> udp_cyphal_header .transfer_id ;
822+ out -> start_of_transfer = (((frame -> udp_cyphal_header .frame_index_eot ) & (UDPARD_MAX_FRAME_INDEX )) == 1 );
823+ out -> end_of_transfer = ((frame -> udp_cyphal_header .frame_index_eot >> UDPARD_END_OF_TRANSFER_OFFSET ) == 1 );
824+ out -> frame_index = frame -> udp_cyphal_header .frame_index_eot ;
825+ // Make sure header version is supported
826+ valid = valid && (out -> version >= UDPARD_CYPHAL_HEADER_VERSION );
826827 if (out -> transfer_kind != UdpardTransferKindMessage )
827828 {
828829 valid = valid && (out -> source_node_id != out -> destination_node_id );
0 commit comments