@@ -99,6 +99,14 @@ static const uint16_t UPDARD_DATA_SPECIFIER_MESSAGE = 0x7FFFU; // SNM (0) + Subj
9999static const uint16_t UDPARD_DATA_SPECIFIER_SERVICE_RESPONSE = 0x8000 ; // (2U << UDPARD_IRNR_DATA_SPECIFIER_OFFSET) // Set SNM in Cyphal data specifier - SNM (1) + IRNR (0) + ServiceID
100100static const uint16_t UDPARD_DATA_SPECIFIER_SERVICE_REQUEST = 0xC000 ; // (3U << UDPARD_IRNR_DATA_SPECIFIER_OFFSET) // Set SNM and IRNR in Cyphal data specifier - SNM (1) + IRNR (1) + ServiceID
101101
102+ /// Ports align with subject and service ids
103+ /// Subjects use multicast and always use port 16383
104+ /// Services use unicast and start with port 16384
105+ /// Unique service id request / response are identified by initial port + (service * 2) (+1 for response)
106+ /// A service response will always be > 16384 and will always be odd (port > initial && port % 2 == 1)
107+ static const uint16_t UDPARD_SUBJECT_ID_PORT = 16383U ;
108+ static const uint16_t UDPARD_SERVICE_ID_INITIAL_PORT = 16384U ;
109+
102110static const uint16_t UDPARD_UDP_PORT = 9382U ;
103111
104112/// Used for inserting new items into AVL trees.
@@ -350,7 +358,7 @@ UDPARD_PRIVATE void txMakeFrameHeader(UdpardFrameHeader* const header,
350358 header -> cyphal_header_checksum = cyphalHeaderCrcAdd (CYPHAL_HEADER_CRC_INITIAL , cyphal_header_size_without_crc , header );
351359 if (transfer_kind == UdpardTransferKindMessage )
352360 {
353- header -> data_specifier = ( uint16_t )( port_id & UDPARD_SUBJECT_ID_MASK ) & UPDARD_DATA_SPECIFIER_MESSAGE ; // SNM (0) + Subject ID
361+ header -> data_specifier = port_id & UDPARD_SUBJECT_ID_MASK & UPDARD_DATA_SPECIFIER_MESSAGE ; // SNM (0) + Subject ID
354362 }
355363 else
356364 {
@@ -450,15 +458,17 @@ UDPARD_PRIVATE int32_t txPushSingleFrame(UdpardTxQueue* const que
450458 txMakeFrameHeader (& tqi -> base .frame .udp_cyphal_header , src_node_id , dst_node_id , port_id , transfer_kind , priority , transfer_id , true, 1 );
451459 // Clang-Tidy raises an error recommending the use of memcpy_s() instead.
452460 // We ignore it because the safe functions are poorly supported; reliance on them may limit the portability.
453- (void ) memcpy (& tqi -> payload_buffer [0 ], & tqi -> base .frame .udp_cyphal_header , sizeof (UdpardFrameHeader )); // NOLINT
461+ (void ) memcpy (& tqi -> payload_buffer [0 ],
462+ & tqi -> base .frame .udp_cyphal_header ,
463+ sizeof (UdpardFrameHeader )); // NOLINT
454464
455465 // Insert CRC
456466 size_t frame_offset = payload_size + sizeof (UdpardFrameHeader );
457467 TransferCRC crc = crcValue (crcAdd (CRC_INITIAL , payload_size , payload ));
458468 uint8_t crc_as_byte [] = {(uint8_t )(crc & BYTE_MAX & CRC_BYTE_MASK ),
459- (uint8_t )(crc >> (BITS_PER_BYTE * 1U ) & CRC_BYTE_MASK ),
460- (uint8_t )(crc >> (BITS_PER_BYTE * 2U ) & CRC_BYTE_MASK ),
461- (uint8_t )(crc >> (BITS_PER_BYTE * 3U ) & CRC_BYTE_MASK )};
469+ (uint8_t )(crc >> (BITS_PER_BYTE * 1 ) & CRC_BYTE_MASK ),
470+ (uint8_t )(crc >> (BITS_PER_BYTE * 2 ) & CRC_BYTE_MASK ),
471+ (uint8_t )(crc >> (BITS_PER_BYTE * 3 ) & CRC_BYTE_MASK )};
462472 for (unsigned int i = 0 ; i < sizeof (crc_as_byte ); i ++ )
463473 {
464474 tqi -> payload_buffer [frame_offset ++ ] = crc_as_byte [i ];
@@ -509,9 +519,9 @@ UDPARD_PRIVATE TxChain txGenerateMultiFrameChain(UdpardInstance* const in
509519 const uint8_t * payload_ptr = (const uint8_t * ) payload ;
510520 uint32_t frame_index = 0U ;
511521 uint8_t crc_as_byte [] = {(uint8_t )(crc & BYTE_MAX & CRC_BYTE_MASK ),
512- (uint8_t )(crc >> (BITS_PER_BYTE * 1U ) & CRC_BYTE_MASK ),
513- (uint8_t )(crc >> (BITS_PER_BYTE * 2U ) & CRC_BYTE_MASK ),
514- (uint8_t )(crc >> (BITS_PER_BYTE * 3U ) & CRC_BYTE_MASK )};
522+ (uint8_t )(crc >> (BITS_PER_BYTE * 1 ) & CRC_BYTE_MASK ),
523+ (uint8_t )(crc >> (BITS_PER_BYTE * 2 ) & CRC_BYTE_MASK ),
524+ (uint8_t )(crc >> (BITS_PER_BYTE * 3 ) & CRC_BYTE_MASK )};
515525 size_t last_crc_index = 0U ;
516526 size_t inserted_crc_amount = 0 ;
517527 while (offset < payload_size_with_crc )
@@ -723,6 +733,35 @@ typedef struct
723733 uint32_t frame_index ;
724734} RxFrameModel ;
725735
736+ UDPARD_PRIVATE UdpardNodeID getNodeIdFromRouteSpecifier (UdpardIPv4Addr src_ip_addr )
737+ {
738+ UdpardNodeID out = (UdpardNodeID ) (src_ip_addr & UDPARD_NODE_ID_MASK );
739+ return out ;
740+ }
741+
742+ UDPARD_PRIVATE UdpardNodeID getNodeIdFromRouteAndDataSpecifiers (UdpardIPv4Addr route_specifier ,
743+ UdpardUdpPortID data_specifier )
744+ {
745+ UdpardNodeID out = UDPARD_NODE_ID_UNSET ;
746+ if (data_specifier > UDPARD_SUBJECT_ID_PORT )
747+ {
748+ out = getNodeIdFromRouteSpecifier (route_specifier );
749+ }
750+ return out ;
751+ }
752+
753+ UDPARD_PRIVATE UdpardPortID getPortIdFromRouteAndDataSpecifiers (UdpardIPv4Addr route_specifier ,
754+ UdpardUdpPortID data_specifier )
755+ {
756+ UDPARD_ASSERT (data_specifier >= UDPARD_SUBJECT_ID_PORT );
757+ if (data_specifier == UDPARD_SUBJECT_ID_PORT )
758+ {
759+ return (UdpardPortID ) (route_specifier & UDPARD_SUBJECT_ID_MASK );
760+ }
761+ return (data_specifier % 2 == 1 ) ? (UdpardPortID ) ((data_specifier - UDPARD_SERVICE_ID_INITIAL_PORT - 1 ) / 2 )
762+ : (UdpardPortID ) ((data_specifier - UDPARD_SERVICE_ID_INITIAL_PORT ) / 2 );
763+ }
764+
726765UDPARD_PRIVATE UdpardPortID getPortIdFromDataSpecifiers (UdpardUdpPortID data_specifier )
727766{
728767 if ((uint16_t )(data_specifier >> UDPARD_SERVICE_NOT_MESSAGE_DATA_SPECIFIER_OFFSET ) & 1U )
0 commit comments