diff --git a/src/struct_frame/boilerplate/c/basic_default.h b/src/struct_frame/boilerplate/c/basic_default.h index 62adde4b..7d7c415d 100644 --- a/src/struct_frame/boilerplate/c/basic_default.h +++ b/src/struct_frame/boilerplate/c/basic_default.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -127,18 +127,10 @@ static inline frame_msg_info_t basic_default_parse_byte(basic_default_parser_t* } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - BASIC_DEFAULT_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 2, msg_length + 1 + 1); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + BASIC_DEFAULT_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + BASIC_DEFAULT_HEADER_SIZE, 1, 2); parser->state = BASIC_DEFAULT_LOOKING_FOR_START1; } break; @@ -160,18 +152,11 @@ static inline size_t basic_default_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = BASIC_DEFAULT_START_BYTE1; buffer[1] = BASIC_DEFAULT_START_BYTE2; - buffer[2] = (uint8_t)msg_size; - buffer[3] = msg_id; - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + BASIC_DEFAULT_HEADER_SIZE, msg, msg_size); - } - - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_size + 1 + 1); - buffer[BASIC_DEFAULT_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_DEFAULT_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 1, buffer + 2); return total_size; } @@ -180,30 +165,19 @@ static inline size_t basic_default_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete BasicDefault packet in a buffer */ static inline frame_msg_info_t basic_default_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < BASIC_DEFAULT_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != BASIC_DEFAULT_START_BYTE1) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[1] != BASIC_DEFAULT_START_BYTE2) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - BASIC_DEFAULT_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + BASIC_DEFAULT_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, BASIC_DEFAULT_HEADER_SIZE, 1, 2); } diff --git a/src/struct_frame/boilerplate/c/basic_extended.h b/src/struct_frame/boilerplate/c/basic_extended.h index 5ac00d94..56136f98 100644 --- a/src/struct_frame/boilerplate/c/basic_extended.h +++ b/src/struct_frame/boilerplate/c/basic_extended.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -133,18 +133,10 @@ static inline frame_msg_info_t basic_extended_parse_byte(basic_extended_parser_t } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - BASIC_EXTENDED_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 2, msg_length + 1 + 2); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + BASIC_EXTENDED_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + BASIC_EXTENDED_HEADER_SIZE, 2, 2); parser->state = BASIC_EXTENDED_LOOKING_FOR_START1; } break; @@ -166,19 +158,11 @@ static inline size_t basic_extended_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = BASIC_EXTENDED_START_BYTE1; buffer[1] = BASIC_EXTENDED_START_BYTE2; - buffer[2] = (uint8_t)(msg_size & 0xFF); - buffer[3] = (uint8_t)((msg_size >> 8) & 0xFF); - buffer[4] = msg_id; - - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + BASIC_EXTENDED_HEADER_SIZE, msg, msg_size); - } - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_size + 1 + 2); - buffer[BASIC_EXTENDED_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_EXTENDED_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 2, buffer + 2); return total_size; } @@ -187,30 +171,19 @@ static inline size_t basic_extended_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete BasicExtended packet in a buffer */ static inline frame_msg_info_t basic_extended_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < BASIC_EXTENDED_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != BASIC_EXTENDED_START_BYTE1) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[1] != BASIC_EXTENDED_START_BYTE2) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - BASIC_EXTENDED_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_length + 1 + 2); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[4]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + BASIC_EXTENDED_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, BASIC_EXTENDED_HEADER_SIZE, 2, 2); } diff --git a/src/struct_frame/boilerplate/c/basic_extended_length.h b/src/struct_frame/boilerplate/c/basic_extended_length.h index 4354a0e2..8022954f 100644 --- a/src/struct_frame/boilerplate/c/basic_extended_length.h +++ b/src/struct_frame/boilerplate/c/basic_extended_length.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -133,18 +133,10 @@ static inline frame_msg_info_t basic_extended_length_parse_byte(basic_extended_l } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - BASIC_EXTENDED_LENGTH_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 2, msg_length + 1 + 2); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + BASIC_EXTENDED_LENGTH_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + BASIC_EXTENDED_LENGTH_HEADER_SIZE, 2, 2); parser->state = BASIC_EXTENDED_LENGTH_LOOKING_FOR_START1; } break; @@ -166,19 +158,11 @@ static inline size_t basic_extended_length_encode(uint8_t* buffer, size_t buffer buffer[0] = BASIC_EXTENDED_LENGTH_START_BYTE1; buffer[1] = BASIC_EXTENDED_LENGTH_START_BYTE2; - buffer[2] = (uint8_t)(msg_size & 0xFF); - buffer[3] = (uint8_t)((msg_size >> 8) & 0xFF); - buffer[4] = msg_id; - - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + BASIC_EXTENDED_LENGTH_HEADER_SIZE, msg, msg_size); - } - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_size + 1 + 2); - buffer[BASIC_EXTENDED_LENGTH_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_EXTENDED_LENGTH_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 2, buffer + 2); return total_size; } @@ -187,30 +171,19 @@ static inline size_t basic_extended_length_encode(uint8_t* buffer, size_t buffer * Validate a complete BasicExtendedLength packet in a buffer */ static inline frame_msg_info_t basic_extended_length_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < BASIC_EXTENDED_LENGTH_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != BASIC_EXTENDED_LENGTH_START_BYTE1) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[1] != BASIC_EXTENDED_LENGTH_START_BYTE2) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - BASIC_EXTENDED_LENGTH_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_length + 1 + 2); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[4]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + BASIC_EXTENDED_LENGTH_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, BASIC_EXTENDED_LENGTH_HEADER_SIZE, 2, 2); } diff --git a/src/struct_frame/boilerplate/c/basic_extended_msg_ids.h b/src/struct_frame/boilerplate/c/basic_extended_msg_ids.h index 129f3deb..cbb223b8 100644 --- a/src/struct_frame/boilerplate/c/basic_extended_msg_ids.h +++ b/src/struct_frame/boilerplate/c/basic_extended_msg_ids.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -127,18 +127,10 @@ static inline frame_msg_info_t basic_extended_msg_ids_parse_byte(basic_extended_ } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - BASIC_EXTENDED_MSG_IDS_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 2, msg_length + 1 + 1); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + BASIC_EXTENDED_MSG_IDS_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + BASIC_EXTENDED_MSG_IDS_HEADER_SIZE, 1, 2); parser->state = BASIC_EXTENDED_MSG_IDS_LOOKING_FOR_START1; } break; @@ -160,18 +152,11 @@ static inline size_t basic_extended_msg_ids_encode(uint8_t* buffer, size_t buffe buffer[0] = BASIC_EXTENDED_MSG_IDS_START_BYTE1; buffer[1] = BASIC_EXTENDED_MSG_IDS_START_BYTE2; - buffer[2] = (uint8_t)msg_size; - buffer[3] = msg_id; - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + BASIC_EXTENDED_MSG_IDS_HEADER_SIZE, msg, msg_size); - } - - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_size + 1 + 1); - buffer[BASIC_EXTENDED_MSG_IDS_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_EXTENDED_MSG_IDS_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 1, buffer + 2); return total_size; } @@ -180,30 +165,19 @@ static inline size_t basic_extended_msg_ids_encode(uint8_t* buffer, size_t buffe * Validate a complete BasicExtendedMsgIds packet in a buffer */ static inline frame_msg_info_t basic_extended_msg_ids_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < BASIC_EXTENDED_MSG_IDS_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != BASIC_EXTENDED_MSG_IDS_START_BYTE1) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[1] != BASIC_EXTENDED_MSG_IDS_START_BYTE2) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - BASIC_EXTENDED_MSG_IDS_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + BASIC_EXTENDED_MSG_IDS_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, BASIC_EXTENDED_MSG_IDS_HEADER_SIZE, 1, 2); } diff --git a/src/struct_frame/boilerplate/c/basic_extended_multi_system_stream.h b/src/struct_frame/boilerplate/c/basic_extended_multi_system_stream.h index f7230a86..14fbc1c9 100644 --- a/src/struct_frame/boilerplate/c/basic_extended_multi_system_stream.h +++ b/src/struct_frame/boilerplate/c/basic_extended_multi_system_stream.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -133,18 +133,10 @@ static inline frame_msg_info_t basic_extended_multi_system_stream_parse_byte(bas } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - BASIC_EXTENDED_MULTI_SYSTEM_STREAM_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 2, msg_length + 1 + 2); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + BASIC_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + BASIC_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE, 2, 2); parser->state = BASIC_EXTENDED_MULTI_SYSTEM_STREAM_LOOKING_FOR_START1; } break; @@ -166,19 +158,11 @@ static inline size_t basic_extended_multi_system_stream_encode(uint8_t* buffer, buffer[0] = BASIC_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE1; buffer[1] = BASIC_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE2; - buffer[2] = (uint8_t)(msg_size & 0xFF); - buffer[3] = (uint8_t)((msg_size >> 8) & 0xFF); - buffer[4] = msg_id; - - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + BASIC_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE, msg, msg_size); - } - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_size + 1 + 2); - buffer[BASIC_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 2, buffer + 2); return total_size; } @@ -187,30 +171,19 @@ static inline size_t basic_extended_multi_system_stream_encode(uint8_t* buffer, * Validate a complete BasicExtendedMultiSystemStream packet in a buffer */ static inline frame_msg_info_t basic_extended_multi_system_stream_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < BASIC_EXTENDED_MULTI_SYSTEM_STREAM_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != BASIC_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE1) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[1] != BASIC_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE2) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - BASIC_EXTENDED_MULTI_SYSTEM_STREAM_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_length + 1 + 2); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[4]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + BASIC_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, BASIC_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE, 2, 2); } diff --git a/src/struct_frame/boilerplate/c/basic_minimal.h b/src/struct_frame/boilerplate/c/basic_minimal.h index 3694785c..abded682 100644 --- a/src/struct_frame/boilerplate/c/basic_minimal.h +++ b/src/struct_frame/boilerplate/c/basic_minimal.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -124,10 +124,9 @@ static inline frame_msg_info_t basic_minimal_parse_byte(basic_minimal_parser_t* } if (parser->buffer_index >= parser->packet_size) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = parser->packet_size - BASIC_MINIMAL_OVERHEAD; - result.msg_data = parser->buffer + BASIC_MINIMAL_HEADER_SIZE; + /* Use shared minimal payload validation */ + result = frame_validate_payload_minimal( + parser->buffer, parser->packet_size, BASIC_MINIMAL_HEADER_SIZE); parser->state = BASIC_MINIMAL_LOOKING_FOR_START1; } break; @@ -149,13 +148,10 @@ static inline size_t basic_minimal_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = BASIC_MINIMAL_START_BYTE1; buffer[1] = BASIC_MINIMAL_START_BYTE2; - buffer[2] = msg_id; - - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + BASIC_MINIMAL_HEADER_SIZE, msg, msg_size); - } + /* Use shared minimal payload encoding */ + frame_encode_payload_minimal( + buffer + 2, msg_id, msg, msg_size); return total_size; } @@ -164,26 +160,19 @@ static inline size_t basic_minimal_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete BasicMinimal packet in a buffer */ static inline frame_msg_info_t basic_minimal_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < BASIC_MINIMAL_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != BASIC_MINIMAL_START_BYTE1) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[1] != BASIC_MINIMAL_START_BYTE2) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - BASIC_MINIMAL_OVERHEAD; - - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + BASIC_MINIMAL_HEADER_SIZE); - - return result; + /* Use shared minimal payload validation */ + return frame_validate_payload_minimal( + buffer, length, BASIC_MINIMAL_HEADER_SIZE); } diff --git a/src/struct_frame/boilerplate/c/basic_multi_system_stream.h b/src/struct_frame/boilerplate/c/basic_multi_system_stream.h index 8f1cb66b..f124f497 100644 --- a/src/struct_frame/boilerplate/c/basic_multi_system_stream.h +++ b/src/struct_frame/boilerplate/c/basic_multi_system_stream.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -127,18 +127,10 @@ static inline frame_msg_info_t basic_multi_system_stream_parse_byte(basic_multi_ } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - BASIC_MULTI_SYSTEM_STREAM_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 2, msg_length + 1 + 1); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + BASIC_MULTI_SYSTEM_STREAM_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + BASIC_MULTI_SYSTEM_STREAM_HEADER_SIZE, 1, 2); parser->state = BASIC_MULTI_SYSTEM_STREAM_LOOKING_FOR_START1; } break; @@ -160,18 +152,11 @@ static inline size_t basic_multi_system_stream_encode(uint8_t* buffer, size_t bu buffer[0] = BASIC_MULTI_SYSTEM_STREAM_START_BYTE1; buffer[1] = BASIC_MULTI_SYSTEM_STREAM_START_BYTE2; - buffer[2] = (uint8_t)msg_size; - buffer[3] = msg_id; - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + BASIC_MULTI_SYSTEM_STREAM_HEADER_SIZE, msg, msg_size); - } - - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_size + 1 + 1); - buffer[BASIC_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 1, buffer + 2); return total_size; } @@ -180,30 +165,19 @@ static inline size_t basic_multi_system_stream_encode(uint8_t* buffer, size_t bu * Validate a complete BasicMultiSystemStream packet in a buffer */ static inline frame_msg_info_t basic_multi_system_stream_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < BASIC_MULTI_SYSTEM_STREAM_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != BASIC_MULTI_SYSTEM_STREAM_START_BYTE1) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[1] != BASIC_MULTI_SYSTEM_STREAM_START_BYTE2) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - BASIC_MULTI_SYSTEM_STREAM_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + BASIC_MULTI_SYSTEM_STREAM_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, BASIC_MULTI_SYSTEM_STREAM_HEADER_SIZE, 1, 2); } diff --git a/src/struct_frame/boilerplate/c/basic_seq.h b/src/struct_frame/boilerplate/c/basic_seq.h index efb5e586..d2cbc063 100644 --- a/src/struct_frame/boilerplate/c/basic_seq.h +++ b/src/struct_frame/boilerplate/c/basic_seq.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -127,18 +127,10 @@ static inline frame_msg_info_t basic_seq_parse_byte(basic_seq_parser_t* parser, } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - BASIC_SEQ_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 2, msg_length + 1 + 1); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + BASIC_SEQ_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + BASIC_SEQ_HEADER_SIZE, 1, 2); parser->state = BASIC_SEQ_LOOKING_FOR_START1; } break; @@ -160,18 +152,11 @@ static inline size_t basic_seq_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = BASIC_SEQ_START_BYTE1; buffer[1] = BASIC_SEQ_START_BYTE2; - buffer[2] = (uint8_t)msg_size; - buffer[3] = msg_id; - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + BASIC_SEQ_HEADER_SIZE, msg, msg_size); - } - - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_size + 1 + 1); - buffer[BASIC_SEQ_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_SEQ_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 1, buffer + 2); return total_size; } @@ -180,30 +165,19 @@ static inline size_t basic_seq_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete BasicSeq packet in a buffer */ static inline frame_msg_info_t basic_seq_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < BASIC_SEQ_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != BASIC_SEQ_START_BYTE1) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[1] != BASIC_SEQ_START_BYTE2) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - BASIC_SEQ_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + BASIC_SEQ_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, BASIC_SEQ_HEADER_SIZE, 1, 2); } diff --git a/src/struct_frame/boilerplate/c/basic_sys_comp.h b/src/struct_frame/boilerplate/c/basic_sys_comp.h index 224cc9b3..c15aa6b4 100644 --- a/src/struct_frame/boilerplate/c/basic_sys_comp.h +++ b/src/struct_frame/boilerplate/c/basic_sys_comp.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -127,18 +127,10 @@ static inline frame_msg_info_t basic_sys_comp_parse_byte(basic_sys_comp_parser_t } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - BASIC_SYS_COMP_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 2, msg_length + 1 + 1); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + BASIC_SYS_COMP_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + BASIC_SYS_COMP_HEADER_SIZE, 1, 2); parser->state = BASIC_SYS_COMP_LOOKING_FOR_START1; } break; @@ -160,18 +152,11 @@ static inline size_t basic_sys_comp_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = BASIC_SYS_COMP_START_BYTE1; buffer[1] = BASIC_SYS_COMP_START_BYTE2; - buffer[2] = (uint8_t)msg_size; - buffer[3] = msg_id; - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + BASIC_SYS_COMP_HEADER_SIZE, msg, msg_size); - } - - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_size + 1 + 1); - buffer[BASIC_SYS_COMP_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_SYS_COMP_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 1, buffer + 2); return total_size; } @@ -180,30 +165,19 @@ static inline size_t basic_sys_comp_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete BasicSysComp packet in a buffer */ static inline frame_msg_info_t basic_sys_comp_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < BASIC_SYS_COMP_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != BASIC_SYS_COMP_START_BYTE1) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[1] != BASIC_SYS_COMP_START_BYTE2) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - BASIC_SYS_COMP_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + BASIC_SYS_COMP_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, BASIC_SYS_COMP_HEADER_SIZE, 1, 2); } diff --git a/src/struct_frame/boilerplate/c/frame_base.h b/src/struct_frame/boilerplate/c/frame_base.h index 909c2551..e72d9620 100644 --- a/src/struct_frame/boilerplate/c/frame_base.h +++ b/src/struct_frame/boilerplate/c/frame_base.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser base utilities */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -62,3 +62,142 @@ typedef struct frame_msg_info { size_t msg_len; uint8_t* msg_data; } frame_msg_info_t; + +/*=========================================================================== + * Shared Payload Parsing Functions + *=========================================================================== + * These functions handle payload validation/encoding independent of framing. + * Frame formats (Tiny/Basic) use these for the common parsing logic. + */ + +/** + * Validate a payload with CRC (shared by Default, Extended, etc. payload types). + * + * @param buffer Complete packet buffer (including any start bytes) + * @param length Total buffer length + * @param header_size Size of header (start_bytes + length + msg_id + extra fields) + * @param length_bytes Number of length bytes (1 or 2) + * @param crc_start_offset Offset from start of buffer where CRC calculation begins + * @return frame_msg_info_t with valid=true if checksum matches + */ +static inline frame_msg_info_t frame_validate_payload_with_crc( + const uint8_t* buffer, size_t length, + size_t header_size, size_t length_bytes, size_t crc_start_offset) { + + frame_msg_info_t result = {false, 0, 0, NULL}; + const size_t footer_size = 2; /* CRC is always 2 bytes */ + const size_t overhead = header_size + footer_size; + + if (length < overhead) { + return result; + } + + size_t msg_length = length - overhead; + + /* Calculate expected CRC range: from crc_start_offset to before the CRC bytes */ + size_t crc_data_len = msg_length + 1 + length_bytes; /* msg_id (1) + length_bytes + payload */ + frame_checksum_t ck = frame_fletcher_checksum(buffer + crc_start_offset, crc_data_len); + + if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { + result.valid = true; + result.msg_id = buffer[header_size - 1]; /* msg_id is last byte of header */ + result.msg_len = msg_length; + result.msg_data = (uint8_t*)(buffer + header_size); + } + + return result; +} + +/** + * Validate a minimal payload (no CRC, no length field). + * + * @param buffer Complete packet buffer (including any start bytes) + * @param length Total buffer length + * @param header_size Size of header (start_bytes + msg_id) + * @return frame_msg_info_t with packet data + */ +static inline frame_msg_info_t frame_validate_payload_minimal( + const uint8_t* buffer, size_t length, size_t header_size) { + + frame_msg_info_t result = {false, 0, 0, NULL}; + + if (length < header_size) { + return result; + } + + result.valid = true; + result.msg_id = buffer[header_size - 1]; /* msg_id is last byte of header */ + result.msg_len = length - header_size; + result.msg_data = (uint8_t*)(buffer + header_size); + + return result; +} + +/** + * Encode payload with length and CRC into output buffer. + * + * @param output Output buffer to write to (after start bytes) + * @param msg_id Message ID + * @param msg Message payload data + * @param msg_size Size of message payload + * @param length_bytes Number of length bytes (1 or 2) + * @param crc_start Pointer to start of CRC calculation (typically after start bytes) + * @return Number of bytes written (length + msg_id + payload + CRC) + */ +static inline size_t frame_encode_payload_with_crc( + uint8_t* output, uint8_t msg_id, const uint8_t* msg, size_t msg_size, + size_t length_bytes, const uint8_t* crc_start) { + + size_t idx = 0; + + /* Add length field */ + if (length_bytes == 1) { + output[idx++] = (uint8_t)(msg_size & 0xFF); + } else { + output[idx++] = (uint8_t)(msg_size & 0xFF); + output[idx++] = (uint8_t)((msg_size >> 8) & 0xFF); + } + + /* Add msg_id */ + output[idx++] = msg_id; + + /* Add payload */ + if (msg_size > 0 && msg != NULL) { + memcpy(output + idx, msg, msg_size); + idx += msg_size; + } + + /* Calculate and add CRC */ + size_t crc_data_len = msg_size + 1 + length_bytes; + frame_checksum_t ck = frame_fletcher_checksum(crc_start, crc_data_len); + output[idx++] = ck.byte1; + output[idx++] = ck.byte2; + + return idx; +} + +/** + * Encode minimal payload (no length, no CRC) into output buffer. + * + * @param output Output buffer to write to (after start bytes) + * @param msg_id Message ID + * @param msg Message payload data + * @param msg_size Size of message payload + * @return Number of bytes written (msg_id + payload) + */ +static inline size_t frame_encode_payload_minimal( + uint8_t* output, uint8_t msg_id, const uint8_t* msg, size_t msg_size) { + + size_t idx = 0; + + /* Add msg_id */ + output[idx++] = msg_id; + + /* Add payload */ + if (msg_size > 0 && msg != NULL) { + memcpy(output + idx, msg, msg_size); + idx += msg_size; + } + + return idx; +} diff --git a/src/struct_frame/boilerplate/c/frame_format_config.h b/src/struct_frame/boilerplate/c/frame_format_config.h index b8980421..170e7b39 100644 --- a/src/struct_frame/boilerplate/c/frame_format_config.h +++ b/src/struct_frame/boilerplate/c/frame_format_config.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -124,18 +124,10 @@ static inline frame_msg_info_t frame_format_config_parse_byte(frame_format_confi } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - FRAME_FORMAT_CONFIG_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 2, msg_length + 1); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + FRAME_FORMAT_CONFIG_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + FRAME_FORMAT_CONFIG_HEADER_SIZE, 0, 2); parser->state = FRAME_FORMAT_CONFIG_LOOKING_FOR_START1; } break; @@ -157,17 +149,11 @@ static inline size_t frame_format_config_encode(uint8_t* buffer, size_t buffer_s buffer[0] = FRAME_FORMAT_CONFIG_START_BYTE1; buffer[1] = FRAME_FORMAT_CONFIG_START_BYTE2; - buffer[2] = msg_id; - - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + FRAME_FORMAT_CONFIG_HEADER_SIZE, msg, msg_size); - } - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_size + 1); - buffer[FRAME_FORMAT_CONFIG_HEADER_SIZE + msg_size] = ck.byte1; - buffer[FRAME_FORMAT_CONFIG_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 0, buffer + 2); return total_size; } @@ -176,30 +162,19 @@ static inline size_t frame_format_config_encode(uint8_t* buffer, size_t buffer_s * Validate a complete FrameFormatConfig packet in a buffer */ static inline frame_msg_info_t frame_format_config_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < FRAME_FORMAT_CONFIG_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != FRAME_FORMAT_CONFIG_START_BYTE1) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[1] != FRAME_FORMAT_CONFIG_START_BYTE2) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - FRAME_FORMAT_CONFIG_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_length + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + FRAME_FORMAT_CONFIG_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, FRAME_FORMAT_CONFIG_HEADER_SIZE, 0, 2); } diff --git a/src/struct_frame/boilerplate/c/frame_parsers.h b/src/struct_frame/boilerplate/c/frame_parsers.h index 755b2684..72057973 100644 --- a/src/struct_frame/boilerplate/c/frame_parsers.h +++ b/src/struct_frame/boilerplate/c/frame_parsers.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser main header */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once diff --git a/src/struct_frame/boilerplate/c/mavlink_v1_frame.h b/src/struct_frame/boilerplate/c/mavlink_v1_frame.h index 30797371..0c9a705c 100644 --- a/src/struct_frame/boilerplate/c/mavlink_v1_frame.h +++ b/src/struct_frame/boilerplate/c/mavlink_v1_frame.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -111,18 +111,10 @@ static inline frame_msg_info_t mavlink_v1_frame_parse_byte(mavlink_v1_frame_pars } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - MAVLINK_V1_FRAME_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 1, msg_length + 1 + 1); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + MAVLINK_V1_FRAME_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + MAVLINK_V1_FRAME_HEADER_SIZE, 1, 1); parser->state = MAVLINK_V1_FRAME_LOOKING_FOR_START; } break; @@ -143,18 +135,11 @@ static inline size_t mavlink_v1_frame_encode(uint8_t* buffer, size_t buffer_size } buffer[0] = MAVLINK_V1_FRAME_START_BYTE; - buffer[1] = (uint8_t)msg_size; - buffer[2] = msg_id; - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + MAVLINK_V1_FRAME_HEADER_SIZE, msg, msg_size); - } - - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_size + 1 + 1); - buffer[MAVLINK_V1_FRAME_HEADER_SIZE + msg_size] = ck.byte1; - buffer[MAVLINK_V1_FRAME_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 1, buffer + 1); return total_size; } @@ -163,27 +148,16 @@ static inline size_t mavlink_v1_frame_encode(uint8_t* buffer, size_t buffer_size * Validate a complete MavlinkV1Frame packet in a buffer */ static inline frame_msg_info_t mavlink_v1_frame_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < MAVLINK_V1_FRAME_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != MAVLINK_V1_FRAME_START_BYTE) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - MAVLINK_V1_FRAME_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + MAVLINK_V1_FRAME_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, MAVLINK_V1_FRAME_HEADER_SIZE, 1, 1); } diff --git a/src/struct_frame/boilerplate/c/mavlink_v2_frame.h b/src/struct_frame/boilerplate/c/mavlink_v2_frame.h index 44ccb177..745ed1f8 100644 --- a/src/struct_frame/boilerplate/c/mavlink_v2_frame.h +++ b/src/struct_frame/boilerplate/c/mavlink_v2_frame.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -111,18 +111,10 @@ static inline frame_msg_info_t mavlink_v2_frame_parse_byte(mavlink_v2_frame_pars } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - MAVLINK_V2_FRAME_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 1, msg_length + 1 + 1); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + MAVLINK_V2_FRAME_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + MAVLINK_V2_FRAME_HEADER_SIZE, 1, 1); parser->state = MAVLINK_V2_FRAME_LOOKING_FOR_START; } break; @@ -143,18 +135,11 @@ static inline size_t mavlink_v2_frame_encode(uint8_t* buffer, size_t buffer_size } buffer[0] = MAVLINK_V2_FRAME_START_BYTE; - buffer[1] = (uint8_t)msg_size; - buffer[2] = msg_id; - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + MAVLINK_V2_FRAME_HEADER_SIZE, msg, msg_size); - } - - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_size + 1 + 1); - buffer[MAVLINK_V2_FRAME_HEADER_SIZE + msg_size] = ck.byte1; - buffer[MAVLINK_V2_FRAME_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 1, buffer + 1); return total_size; } @@ -163,27 +148,16 @@ static inline size_t mavlink_v2_frame_encode(uint8_t* buffer, size_t buffer_size * Validate a complete MavlinkV2Frame packet in a buffer */ static inline frame_msg_info_t mavlink_v2_frame_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < MAVLINK_V2_FRAME_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != MAVLINK_V2_FRAME_START_BYTE) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - MAVLINK_V2_FRAME_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + MAVLINK_V2_FRAME_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, MAVLINK_V2_FRAME_HEADER_SIZE, 1, 1); } diff --git a/src/struct_frame/boilerplate/c/tiny_default.h b/src/struct_frame/boilerplate/c/tiny_default.h index 2a021639..9c285171 100644 --- a/src/struct_frame/boilerplate/c/tiny_default.h +++ b/src/struct_frame/boilerplate/c/tiny_default.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -111,18 +111,10 @@ static inline frame_msg_info_t tiny_default_parse_byte(tiny_default_parser_t* pa } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - TINY_DEFAULT_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 1, msg_length + 1 + 1); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + TINY_DEFAULT_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + TINY_DEFAULT_HEADER_SIZE, 1, 1); parser->state = TINY_DEFAULT_LOOKING_FOR_START; } break; @@ -143,18 +135,11 @@ static inline size_t tiny_default_encode(uint8_t* buffer, size_t buffer_size, } buffer[0] = TINY_DEFAULT_START_BYTE; - buffer[1] = (uint8_t)msg_size; - buffer[2] = msg_id; - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + TINY_DEFAULT_HEADER_SIZE, msg, msg_size); - } - - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_size + 1 + 1); - buffer[TINY_DEFAULT_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_DEFAULT_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 1, buffer + 1); return total_size; } @@ -163,27 +148,16 @@ static inline size_t tiny_default_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete TinyDefault packet in a buffer */ static inline frame_msg_info_t tiny_default_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < TINY_DEFAULT_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != TINY_DEFAULT_START_BYTE) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - TINY_DEFAULT_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + TINY_DEFAULT_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, TINY_DEFAULT_HEADER_SIZE, 1, 1); } diff --git a/src/struct_frame/boilerplate/c/tiny_extended.h b/src/struct_frame/boilerplate/c/tiny_extended.h index 7c82a727..b1031168 100644 --- a/src/struct_frame/boilerplate/c/tiny_extended.h +++ b/src/struct_frame/boilerplate/c/tiny_extended.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -117,18 +117,10 @@ static inline frame_msg_info_t tiny_extended_parse_byte(tiny_extended_parser_t* } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - TINY_EXTENDED_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 1, msg_length + 1 + 2); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + TINY_EXTENDED_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + TINY_EXTENDED_HEADER_SIZE, 2, 1); parser->state = TINY_EXTENDED_LOOKING_FOR_START; } break; @@ -149,19 +141,11 @@ static inline size_t tiny_extended_encode(uint8_t* buffer, size_t buffer_size, } buffer[0] = TINY_EXTENDED_START_BYTE; - buffer[1] = (uint8_t)(msg_size & 0xFF); - buffer[2] = (uint8_t)((msg_size >> 8) & 0xFF); - buffer[3] = msg_id; - - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + TINY_EXTENDED_HEADER_SIZE, msg, msg_size); - } - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_size + 1 + 2); - buffer[TINY_EXTENDED_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_EXTENDED_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 2, buffer + 1); return total_size; } @@ -170,27 +154,16 @@ static inline size_t tiny_extended_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete TinyExtended packet in a buffer */ static inline frame_msg_info_t tiny_extended_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < TINY_EXTENDED_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != TINY_EXTENDED_START_BYTE) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - TINY_EXTENDED_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_length + 1 + 2); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + TINY_EXTENDED_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, TINY_EXTENDED_HEADER_SIZE, 2, 1); } diff --git a/src/struct_frame/boilerplate/c/tiny_extended_length.h b/src/struct_frame/boilerplate/c/tiny_extended_length.h index 616f0bdc..fd3fcd75 100644 --- a/src/struct_frame/boilerplate/c/tiny_extended_length.h +++ b/src/struct_frame/boilerplate/c/tiny_extended_length.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -117,18 +117,10 @@ static inline frame_msg_info_t tiny_extended_length_parse_byte(tiny_extended_len } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - TINY_EXTENDED_LENGTH_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 1, msg_length + 1 + 2); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + TINY_EXTENDED_LENGTH_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + TINY_EXTENDED_LENGTH_HEADER_SIZE, 2, 1); parser->state = TINY_EXTENDED_LENGTH_LOOKING_FOR_START; } break; @@ -149,19 +141,11 @@ static inline size_t tiny_extended_length_encode(uint8_t* buffer, size_t buffer_ } buffer[0] = TINY_EXTENDED_LENGTH_START_BYTE; - buffer[1] = (uint8_t)(msg_size & 0xFF); - buffer[2] = (uint8_t)((msg_size >> 8) & 0xFF); - buffer[3] = msg_id; - - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + TINY_EXTENDED_LENGTH_HEADER_SIZE, msg, msg_size); - } - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_size + 1 + 2); - buffer[TINY_EXTENDED_LENGTH_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_EXTENDED_LENGTH_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 2, buffer + 1); return total_size; } @@ -170,27 +154,16 @@ static inline size_t tiny_extended_length_encode(uint8_t* buffer, size_t buffer_ * Validate a complete TinyExtendedLength packet in a buffer */ static inline frame_msg_info_t tiny_extended_length_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < TINY_EXTENDED_LENGTH_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != TINY_EXTENDED_LENGTH_START_BYTE) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - TINY_EXTENDED_LENGTH_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_length + 1 + 2); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + TINY_EXTENDED_LENGTH_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, TINY_EXTENDED_LENGTH_HEADER_SIZE, 2, 1); } diff --git a/src/struct_frame/boilerplate/c/tiny_extended_msg_ids.h b/src/struct_frame/boilerplate/c/tiny_extended_msg_ids.h index 1f45c76c..3dfb96c4 100644 --- a/src/struct_frame/boilerplate/c/tiny_extended_msg_ids.h +++ b/src/struct_frame/boilerplate/c/tiny_extended_msg_ids.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -111,18 +111,10 @@ static inline frame_msg_info_t tiny_extended_msg_ids_parse_byte(tiny_extended_ms } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - TINY_EXTENDED_MSG_IDS_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 1, msg_length + 1 + 1); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + TINY_EXTENDED_MSG_IDS_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + TINY_EXTENDED_MSG_IDS_HEADER_SIZE, 1, 1); parser->state = TINY_EXTENDED_MSG_IDS_LOOKING_FOR_START; } break; @@ -143,18 +135,11 @@ static inline size_t tiny_extended_msg_ids_encode(uint8_t* buffer, size_t buffer } buffer[0] = TINY_EXTENDED_MSG_IDS_START_BYTE; - buffer[1] = (uint8_t)msg_size; - buffer[2] = msg_id; - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + TINY_EXTENDED_MSG_IDS_HEADER_SIZE, msg, msg_size); - } - - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_size + 1 + 1); - buffer[TINY_EXTENDED_MSG_IDS_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_EXTENDED_MSG_IDS_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 1, buffer + 1); return total_size; } @@ -163,27 +148,16 @@ static inline size_t tiny_extended_msg_ids_encode(uint8_t* buffer, size_t buffer * Validate a complete TinyExtendedMsgIds packet in a buffer */ static inline frame_msg_info_t tiny_extended_msg_ids_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < TINY_EXTENDED_MSG_IDS_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != TINY_EXTENDED_MSG_IDS_START_BYTE) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - TINY_EXTENDED_MSG_IDS_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + TINY_EXTENDED_MSG_IDS_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, TINY_EXTENDED_MSG_IDS_HEADER_SIZE, 1, 1); } diff --git a/src/struct_frame/boilerplate/c/tiny_extended_multi_system_stream.h b/src/struct_frame/boilerplate/c/tiny_extended_multi_system_stream.h index e6e4d0bd..614686aa 100644 --- a/src/struct_frame/boilerplate/c/tiny_extended_multi_system_stream.h +++ b/src/struct_frame/boilerplate/c/tiny_extended_multi_system_stream.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -117,18 +117,10 @@ static inline frame_msg_info_t tiny_extended_multi_system_stream_parse_byte(tiny } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - TINY_EXTENDED_MULTI_SYSTEM_STREAM_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 1, msg_length + 1 + 2); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + TINY_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + TINY_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE, 2, 1); parser->state = TINY_EXTENDED_MULTI_SYSTEM_STREAM_LOOKING_FOR_START; } break; @@ -149,19 +141,11 @@ static inline size_t tiny_extended_multi_system_stream_encode(uint8_t* buffer, s } buffer[0] = TINY_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE; - buffer[1] = (uint8_t)(msg_size & 0xFF); - buffer[2] = (uint8_t)((msg_size >> 8) & 0xFF); - buffer[3] = msg_id; - - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + TINY_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE, msg, msg_size); - } - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_size + 1 + 2); - buffer[TINY_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 2, buffer + 1); return total_size; } @@ -170,27 +154,16 @@ static inline size_t tiny_extended_multi_system_stream_encode(uint8_t* buffer, s * Validate a complete TinyExtendedMultiSystemStream packet in a buffer */ static inline frame_msg_info_t tiny_extended_multi_system_stream_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < TINY_EXTENDED_MULTI_SYSTEM_STREAM_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != TINY_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - TINY_EXTENDED_MULTI_SYSTEM_STREAM_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_length + 1 + 2); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + TINY_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, TINY_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE, 2, 1); } diff --git a/src/struct_frame/boilerplate/c/tiny_minimal.h b/src/struct_frame/boilerplate/c/tiny_minimal.h index d9c5d3e5..87889260 100644 --- a/src/struct_frame/boilerplate/c/tiny_minimal.h +++ b/src/struct_frame/boilerplate/c/tiny_minimal.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -108,10 +108,9 @@ static inline frame_msg_info_t tiny_minimal_parse_byte(tiny_minimal_parser_t* pa } if (parser->buffer_index >= parser->packet_size) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = parser->packet_size - TINY_MINIMAL_OVERHEAD; - result.msg_data = parser->buffer + TINY_MINIMAL_HEADER_SIZE; + /* Use shared minimal payload validation */ + result = frame_validate_payload_minimal( + parser->buffer, parser->packet_size, TINY_MINIMAL_HEADER_SIZE); parser->state = TINY_MINIMAL_LOOKING_FOR_START; } break; @@ -132,13 +131,10 @@ static inline size_t tiny_minimal_encode(uint8_t* buffer, size_t buffer_size, } buffer[0] = TINY_MINIMAL_START_BYTE; - buffer[1] = msg_id; - - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + TINY_MINIMAL_HEADER_SIZE, msg, msg_size); - } + /* Use shared minimal payload encoding */ + frame_encode_payload_minimal( + buffer + 1, msg_id, msg, msg_size); return total_size; } @@ -147,23 +143,16 @@ static inline size_t tiny_minimal_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete TinyMinimal packet in a buffer */ static inline frame_msg_info_t tiny_minimal_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < TINY_MINIMAL_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != TINY_MINIMAL_START_BYTE) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - TINY_MINIMAL_OVERHEAD; - - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + TINY_MINIMAL_HEADER_SIZE); - - return result; + /* Use shared minimal payload validation */ + return frame_validate_payload_minimal( + buffer, length, TINY_MINIMAL_HEADER_SIZE); } diff --git a/src/struct_frame/boilerplate/c/tiny_multi_system_stream.h b/src/struct_frame/boilerplate/c/tiny_multi_system_stream.h index 26cccd16..9a062559 100644 --- a/src/struct_frame/boilerplate/c/tiny_multi_system_stream.h +++ b/src/struct_frame/boilerplate/c/tiny_multi_system_stream.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -111,18 +111,10 @@ static inline frame_msg_info_t tiny_multi_system_stream_parse_byte(tiny_multi_sy } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - TINY_MULTI_SYSTEM_STREAM_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 1, msg_length + 1 + 1); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + TINY_MULTI_SYSTEM_STREAM_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + TINY_MULTI_SYSTEM_STREAM_HEADER_SIZE, 1, 1); parser->state = TINY_MULTI_SYSTEM_STREAM_LOOKING_FOR_START; } break; @@ -143,18 +135,11 @@ static inline size_t tiny_multi_system_stream_encode(uint8_t* buffer, size_t buf } buffer[0] = TINY_MULTI_SYSTEM_STREAM_START_BYTE; - buffer[1] = (uint8_t)msg_size; - buffer[2] = msg_id; - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + TINY_MULTI_SYSTEM_STREAM_HEADER_SIZE, msg, msg_size); - } - - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_size + 1 + 1); - buffer[TINY_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 1, buffer + 1); return total_size; } @@ -163,27 +148,16 @@ static inline size_t tiny_multi_system_stream_encode(uint8_t* buffer, size_t buf * Validate a complete TinyMultiSystemStream packet in a buffer */ static inline frame_msg_info_t tiny_multi_system_stream_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < TINY_MULTI_SYSTEM_STREAM_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != TINY_MULTI_SYSTEM_STREAM_START_BYTE) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - TINY_MULTI_SYSTEM_STREAM_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + TINY_MULTI_SYSTEM_STREAM_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, TINY_MULTI_SYSTEM_STREAM_HEADER_SIZE, 1, 1); } diff --git a/src/struct_frame/boilerplate/c/tiny_seq.h b/src/struct_frame/boilerplate/c/tiny_seq.h index 35f97bc2..1560dc53 100644 --- a/src/struct_frame/boilerplate/c/tiny_seq.h +++ b/src/struct_frame/boilerplate/c/tiny_seq.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -111,18 +111,10 @@ static inline frame_msg_info_t tiny_seq_parse_byte(tiny_seq_parser_t* parser, ui } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - TINY_SEQ_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 1, msg_length + 1 + 1); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + TINY_SEQ_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + TINY_SEQ_HEADER_SIZE, 1, 1); parser->state = TINY_SEQ_LOOKING_FOR_START; } break; @@ -143,18 +135,11 @@ static inline size_t tiny_seq_encode(uint8_t* buffer, size_t buffer_size, } buffer[0] = TINY_SEQ_START_BYTE; - buffer[1] = (uint8_t)msg_size; - buffer[2] = msg_id; - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + TINY_SEQ_HEADER_SIZE, msg, msg_size); - } - - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_size + 1 + 1); - buffer[TINY_SEQ_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_SEQ_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 1, buffer + 1); return total_size; } @@ -163,27 +148,16 @@ static inline size_t tiny_seq_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete TinySeq packet in a buffer */ static inline frame_msg_info_t tiny_seq_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < TINY_SEQ_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != TINY_SEQ_START_BYTE) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - TINY_SEQ_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + TINY_SEQ_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, TINY_SEQ_HEADER_SIZE, 1, 1); } diff --git a/src/struct_frame/boilerplate/c/tiny_sys_comp.h b/src/struct_frame/boilerplate/c/tiny_sys_comp.h index a1a5dfc0..bfd85ddb 100644 --- a/src/struct_frame/boilerplate/c/tiny_sys_comp.h +++ b/src/struct_frame/boilerplate/c/tiny_sys_comp.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -111,18 +111,10 @@ static inline frame_msg_info_t tiny_sys_comp_parse_byte(tiny_sys_comp_parser_t* } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - TINY_SYS_COMP_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 1, msg_length + 1 + 1); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + TINY_SYS_COMP_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + TINY_SYS_COMP_HEADER_SIZE, 1, 1); parser->state = TINY_SYS_COMP_LOOKING_FOR_START; } break; @@ -143,18 +135,11 @@ static inline size_t tiny_sys_comp_encode(uint8_t* buffer, size_t buffer_size, } buffer[0] = TINY_SYS_COMP_START_BYTE; - buffer[1] = (uint8_t)msg_size; - buffer[2] = msg_id; - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + TINY_SYS_COMP_HEADER_SIZE, msg, msg_size); - } - - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_size + 1 + 1); - buffer[TINY_SYS_COMP_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_SYS_COMP_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 1, buffer + 1); return total_size; } @@ -163,27 +148,16 @@ static inline size_t tiny_sys_comp_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete TinySysComp packet in a buffer */ static inline frame_msg_info_t tiny_sys_comp_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < TINY_SYS_COMP_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != TINY_SYS_COMP_START_BYTE) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - TINY_SYS_COMP_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 1, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + TINY_SYS_COMP_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, TINY_SYS_COMP_HEADER_SIZE, 1, 1); } diff --git a/src/struct_frame/boilerplate/c/ubx_frame.h b/src/struct_frame/boilerplate/c/ubx_frame.h index ed52c85f..0cdb6ffe 100644 --- a/src/struct_frame/boilerplate/c/ubx_frame.h +++ b/src/struct_frame/boilerplate/c/ubx_frame.h @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -127,18 +127,10 @@ static inline frame_msg_info_t ubx_frame_parse_byte(ubx_frame_parser_t* parser, } if (parser->buffer_index >= parser->packet_size) { - /* Validate checksum */ - size_t msg_length = parser->packet_size - UBX_FRAME_OVERHEAD; - frame_checksum_t ck = frame_fletcher_checksum( - parser->buffer + 2, msg_length + 1 + 1); - - if (ck.byte1 == parser->buffer[parser->packet_size - 2] && - ck.byte2 == parser->buffer[parser->packet_size - 1]) { - result.valid = true; - result.msg_id = parser->msg_id; - result.msg_len = msg_length; - result.msg_data = parser->buffer + UBX_FRAME_HEADER_SIZE; - } + /* Use shared payload validation with CRC */ + result = frame_validate_payload_with_crc( + parser->buffer, parser->packet_size, + UBX_FRAME_HEADER_SIZE, 1, 2); parser->state = UBX_FRAME_LOOKING_FOR_START1; } break; @@ -160,18 +152,11 @@ static inline size_t ubx_frame_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = UBX_FRAME_START_BYTE1; buffer[1] = UBX_FRAME_START_BYTE2; - buffer[2] = (uint8_t)msg_size; - buffer[3] = msg_id; - /* Write message data */ - if (msg_size > 0 && msg != NULL) { - memcpy(buffer + UBX_FRAME_HEADER_SIZE, msg, msg_size); - } - - /* Calculate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_size + 1 + 1); - buffer[UBX_FRAME_HEADER_SIZE + msg_size] = ck.byte1; - buffer[UBX_FRAME_HEADER_SIZE + msg_size + 1] = ck.byte2; + /* Use shared payload encoding with CRC */ + frame_encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 1, buffer + 2); return total_size; } @@ -180,30 +165,19 @@ static inline size_t ubx_frame_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete UbxFrame packet in a buffer */ static inline frame_msg_info_t ubx_frame_validate_packet(const uint8_t* buffer, size_t length) { - frame_msg_info_t result = {false, 0, 0, NULL}; - if (length < UBX_FRAME_OVERHEAD) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[0] != UBX_FRAME_START_BYTE1) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } if (buffer[1] != UBX_FRAME_START_BYTE2) { - return result; + return (frame_msg_info_t){false, 0, 0, NULL}; } - size_t msg_length = length - UBX_FRAME_OVERHEAD; - - /* Validate checksum */ - frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = (uint8_t*)(buffer + UBX_FRAME_HEADER_SIZE); - } - - return result; + /* Use shared payload validation with CRC */ + return frame_validate_payload_with_crc( + buffer, length, UBX_FRAME_HEADER_SIZE, 1, 2); } diff --git a/src/struct_frame/boilerplate/cpp/BasicDefault.hpp b/src/struct_frame/boilerplate/cpp/BasicDefault.hpp index e991754e..25ffd1fc 100644 --- a/src/struct_frame/boilerplate/cpp/BasicDefault.hpp +++ b/src/struct_frame/boilerplate/cpp/BasicDefault.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -164,17 +164,10 @@ class BasicDefaultParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - BASIC_DEFAULT_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 2, msg_length + 1 + 1); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + BASIC_DEFAULT_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + BASIC_DEFAULT_HEADER_SIZE, 1, 2); state_ = BasicDefaultParserState::LookingForStart1; } break; @@ -205,16 +198,11 @@ inline size_t basic_default_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = BASIC_DEFAULT_START_BYTE1; buffer[1] = BASIC_DEFAULT_START_BYTE2; - buffer[2] = static_cast(msg_size); - buffer[3] = msg_id; - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + BASIC_DEFAULT_HEADER_SIZE, msg, msg_size); - } - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_size + 1 + 1); - buffer[BASIC_DEFAULT_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_DEFAULT_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 1, buffer + 2); return total_size; } @@ -223,24 +211,14 @@ inline size_t basic_default_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete BasicDefault packet in a buffer */ inline FrameMsgInfo basic_default_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < BASIC_DEFAULT_OVERHEAD) return result; + if (length < BASIC_DEFAULT_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != BASIC_DEFAULT_START_BYTE1) return result; - if (buffer[1] != BASIC_DEFAULT_START_BYTE2) return result; - - size_t msg_length = length - BASIC_DEFAULT_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + BASIC_DEFAULT_HEADER_SIZE); - } + if (buffer[0] != BASIC_DEFAULT_START_BYTE1) return FrameMsgInfo(); + if (buffer[1] != BASIC_DEFAULT_START_BYTE2) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, BASIC_DEFAULT_HEADER_SIZE, 1, 2); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/BasicExtended.hpp b/src/struct_frame/boilerplate/cpp/BasicExtended.hpp index c90eae00..2cb6c011 100644 --- a/src/struct_frame/boilerplate/cpp/BasicExtended.hpp +++ b/src/struct_frame/boilerplate/cpp/BasicExtended.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -170,17 +170,10 @@ class BasicExtendedParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - BASIC_EXTENDED_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 2, msg_length + 1 + 2); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + BASIC_EXTENDED_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + BASIC_EXTENDED_HEADER_SIZE, 2, 2); state_ = BasicExtendedParserState::LookingForStart1; } break; @@ -212,17 +205,11 @@ inline size_t basic_extended_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = BASIC_EXTENDED_START_BYTE1; buffer[1] = BASIC_EXTENDED_START_BYTE2; - buffer[2] = static_cast(msg_size & 0xFF); - buffer[3] = static_cast((msg_size >> 8) & 0xFF); - buffer[4] = msg_id; - - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + BASIC_EXTENDED_HEADER_SIZE, msg, msg_size); - } - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_size + 1 + 2); - buffer[BASIC_EXTENDED_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_EXTENDED_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 2, buffer + 2); return total_size; } @@ -231,24 +218,14 @@ inline size_t basic_extended_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete BasicExtended packet in a buffer */ inline FrameMsgInfo basic_extended_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < BASIC_EXTENDED_OVERHEAD) return result; + if (length < BASIC_EXTENDED_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != BASIC_EXTENDED_START_BYTE1) return result; - if (buffer[1] != BASIC_EXTENDED_START_BYTE2) return result; - - size_t msg_length = length - BASIC_EXTENDED_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_length + 1 + 2); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[4]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + BASIC_EXTENDED_HEADER_SIZE); - } + if (buffer[0] != BASIC_EXTENDED_START_BYTE1) return FrameMsgInfo(); + if (buffer[1] != BASIC_EXTENDED_START_BYTE2) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, BASIC_EXTENDED_HEADER_SIZE, 2, 2); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/BasicExtendedLength.hpp b/src/struct_frame/boilerplate/cpp/BasicExtendedLength.hpp index 0e0600de..a3f4b9e4 100644 --- a/src/struct_frame/boilerplate/cpp/BasicExtendedLength.hpp +++ b/src/struct_frame/boilerplate/cpp/BasicExtendedLength.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -170,17 +170,10 @@ class BasicExtendedLengthParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - BASIC_EXTENDED_LENGTH_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 2, msg_length + 1 + 2); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + BASIC_EXTENDED_LENGTH_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + BASIC_EXTENDED_LENGTH_HEADER_SIZE, 2, 2); state_ = BasicExtendedLengthParserState::LookingForStart1; } break; @@ -212,17 +205,11 @@ inline size_t basic_extended_length_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = BASIC_EXTENDED_LENGTH_START_BYTE1; buffer[1] = BASIC_EXTENDED_LENGTH_START_BYTE2; - buffer[2] = static_cast(msg_size & 0xFF); - buffer[3] = static_cast((msg_size >> 8) & 0xFF); - buffer[4] = msg_id; - - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + BASIC_EXTENDED_LENGTH_HEADER_SIZE, msg, msg_size); - } - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_size + 1 + 2); - buffer[BASIC_EXTENDED_LENGTH_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_EXTENDED_LENGTH_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 2, buffer + 2); return total_size; } @@ -231,24 +218,14 @@ inline size_t basic_extended_length_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete BasicExtendedLength packet in a buffer */ inline FrameMsgInfo basic_extended_length_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < BASIC_EXTENDED_LENGTH_OVERHEAD) return result; + if (length < BASIC_EXTENDED_LENGTH_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != BASIC_EXTENDED_LENGTH_START_BYTE1) return result; - if (buffer[1] != BASIC_EXTENDED_LENGTH_START_BYTE2) return result; - - size_t msg_length = length - BASIC_EXTENDED_LENGTH_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_length + 1 + 2); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[4]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + BASIC_EXTENDED_LENGTH_HEADER_SIZE); - } + if (buffer[0] != BASIC_EXTENDED_LENGTH_START_BYTE1) return FrameMsgInfo(); + if (buffer[1] != BASIC_EXTENDED_LENGTH_START_BYTE2) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, BASIC_EXTENDED_LENGTH_HEADER_SIZE, 2, 2); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/BasicExtendedMsgIds.hpp b/src/struct_frame/boilerplate/cpp/BasicExtendedMsgIds.hpp index 3386728b..2258bcb7 100644 --- a/src/struct_frame/boilerplate/cpp/BasicExtendedMsgIds.hpp +++ b/src/struct_frame/boilerplate/cpp/BasicExtendedMsgIds.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -164,17 +164,10 @@ class BasicExtendedMsgIdsParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - BASIC_EXTENDED_MSG_IDS_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 2, msg_length + 1 + 1); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + BASIC_EXTENDED_MSG_IDS_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + BASIC_EXTENDED_MSG_IDS_HEADER_SIZE, 1, 2); state_ = BasicExtendedMsgIdsParserState::LookingForStart1; } break; @@ -205,16 +198,11 @@ inline size_t basic_extended_msg_ids_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = BASIC_EXTENDED_MSG_IDS_START_BYTE1; buffer[1] = BASIC_EXTENDED_MSG_IDS_START_BYTE2; - buffer[2] = static_cast(msg_size); - buffer[3] = msg_id; - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + BASIC_EXTENDED_MSG_IDS_HEADER_SIZE, msg, msg_size); - } - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_size + 1 + 1); - buffer[BASIC_EXTENDED_MSG_IDS_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_EXTENDED_MSG_IDS_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 1, buffer + 2); return total_size; } @@ -223,24 +211,14 @@ inline size_t basic_extended_msg_ids_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete BasicExtendedMsgIds packet in a buffer */ inline FrameMsgInfo basic_extended_msg_ids_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < BASIC_EXTENDED_MSG_IDS_OVERHEAD) return result; + if (length < BASIC_EXTENDED_MSG_IDS_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != BASIC_EXTENDED_MSG_IDS_START_BYTE1) return result; - if (buffer[1] != BASIC_EXTENDED_MSG_IDS_START_BYTE2) return result; - - size_t msg_length = length - BASIC_EXTENDED_MSG_IDS_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + BASIC_EXTENDED_MSG_IDS_HEADER_SIZE); - } + if (buffer[0] != BASIC_EXTENDED_MSG_IDS_START_BYTE1) return FrameMsgInfo(); + if (buffer[1] != BASIC_EXTENDED_MSG_IDS_START_BYTE2) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, BASIC_EXTENDED_MSG_IDS_HEADER_SIZE, 1, 2); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/BasicExtendedMultiSystemStream.hpp b/src/struct_frame/boilerplate/cpp/BasicExtendedMultiSystemStream.hpp index 0ee19a50..3f7dd650 100644 --- a/src/struct_frame/boilerplate/cpp/BasicExtendedMultiSystemStream.hpp +++ b/src/struct_frame/boilerplate/cpp/BasicExtendedMultiSystemStream.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -170,17 +170,10 @@ class BasicExtendedMultiSystemStreamParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - BASIC_EXTENDED_MULTI_SYSTEM_STREAM_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 2, msg_length + 1 + 2); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + BASIC_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + BASIC_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE, 2, 2); state_ = BasicExtendedMultiSystemStreamParserState::LookingForStart1; } break; @@ -212,17 +205,11 @@ inline size_t basic_extended_multi_system_stream_encode(uint8_t* buffer, size_t buffer[0] = BASIC_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE1; buffer[1] = BASIC_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE2; - buffer[2] = static_cast(msg_size & 0xFF); - buffer[3] = static_cast((msg_size >> 8) & 0xFF); - buffer[4] = msg_id; - - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + BASIC_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE, msg, msg_size); - } - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_size + 1 + 2); - buffer[BASIC_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 2, buffer + 2); return total_size; } @@ -231,24 +218,14 @@ inline size_t basic_extended_multi_system_stream_encode(uint8_t* buffer, size_t * Validate a complete BasicExtendedMultiSystemStream packet in a buffer */ inline FrameMsgInfo basic_extended_multi_system_stream_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < BASIC_EXTENDED_MULTI_SYSTEM_STREAM_OVERHEAD) return result; + if (length < BASIC_EXTENDED_MULTI_SYSTEM_STREAM_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != BASIC_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE1) return result; - if (buffer[1] != BASIC_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE2) return result; - - size_t msg_length = length - BASIC_EXTENDED_MULTI_SYSTEM_STREAM_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_length + 1 + 2); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[4]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + BASIC_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE); - } + if (buffer[0] != BASIC_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE1) return FrameMsgInfo(); + if (buffer[1] != BASIC_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE2) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, BASIC_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE, 2, 2); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/BasicMinimal.hpp b/src/struct_frame/boilerplate/cpp/BasicMinimal.hpp index a3eefc1b..31155290 100644 --- a/src/struct_frame/boilerplate/cpp/BasicMinimal.hpp +++ b/src/struct_frame/boilerplate/cpp/BasicMinimal.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -154,10 +154,9 @@ class BasicMinimalParser { } if (buffer_index_ >= packet_size_) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = packet_size_ - BASIC_MINIMAL_OVERHEAD; - result.msg_data = buffer_ + BASIC_MINIMAL_HEADER_SIZE; + // Use shared minimal payload validation + result = validate_payload_minimal( + buffer_, packet_size_, BASIC_MINIMAL_HEADER_SIZE); state_ = BasicMinimalParserState::LookingForStart1; } break; @@ -187,12 +186,10 @@ inline size_t basic_minimal_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = BASIC_MINIMAL_START_BYTE1; buffer[1] = BASIC_MINIMAL_START_BYTE2; - buffer[2] = msg_id; - - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + BASIC_MINIMAL_HEADER_SIZE, msg, msg_size); - } + // Use shared minimal payload encoding + encode_payload_minimal( + buffer + 2, msg_id, msg, msg_size); return total_size; } @@ -201,21 +198,14 @@ inline size_t basic_minimal_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete BasicMinimal packet in a buffer */ inline FrameMsgInfo basic_minimal_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < BASIC_MINIMAL_OVERHEAD) return result; - - if (buffer[0] != BASIC_MINIMAL_START_BYTE1) return result; - if (buffer[1] != BASIC_MINIMAL_START_BYTE2) return result; - - size_t msg_length = length - BASIC_MINIMAL_OVERHEAD; + if (length < BASIC_MINIMAL_OVERHEAD) return FrameMsgInfo(); - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + BASIC_MINIMAL_HEADER_SIZE); + if (buffer[0] != BASIC_MINIMAL_START_BYTE1) return FrameMsgInfo(); + if (buffer[1] != BASIC_MINIMAL_START_BYTE2) return FrameMsgInfo(); - return result; + // Use shared minimal payload validation + return validate_payload_minimal( + buffer, length, BASIC_MINIMAL_HEADER_SIZE); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/BasicMultiSystemStream.hpp b/src/struct_frame/boilerplate/cpp/BasicMultiSystemStream.hpp index a6cc9dd4..b4b1e20c 100644 --- a/src/struct_frame/boilerplate/cpp/BasicMultiSystemStream.hpp +++ b/src/struct_frame/boilerplate/cpp/BasicMultiSystemStream.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -164,17 +164,10 @@ class BasicMultiSystemStreamParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - BASIC_MULTI_SYSTEM_STREAM_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 2, msg_length + 1 + 1); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + BASIC_MULTI_SYSTEM_STREAM_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + BASIC_MULTI_SYSTEM_STREAM_HEADER_SIZE, 1, 2); state_ = BasicMultiSystemStreamParserState::LookingForStart1; } break; @@ -205,16 +198,11 @@ inline size_t basic_multi_system_stream_encode(uint8_t* buffer, size_t buffer_si buffer[0] = BASIC_MULTI_SYSTEM_STREAM_START_BYTE1; buffer[1] = BASIC_MULTI_SYSTEM_STREAM_START_BYTE2; - buffer[2] = static_cast(msg_size); - buffer[3] = msg_id; - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + BASIC_MULTI_SYSTEM_STREAM_HEADER_SIZE, msg, msg_size); - } - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_size + 1 + 1); - buffer[BASIC_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 1, buffer + 2); return total_size; } @@ -223,24 +211,14 @@ inline size_t basic_multi_system_stream_encode(uint8_t* buffer, size_t buffer_si * Validate a complete BasicMultiSystemStream packet in a buffer */ inline FrameMsgInfo basic_multi_system_stream_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < BASIC_MULTI_SYSTEM_STREAM_OVERHEAD) return result; + if (length < BASIC_MULTI_SYSTEM_STREAM_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != BASIC_MULTI_SYSTEM_STREAM_START_BYTE1) return result; - if (buffer[1] != BASIC_MULTI_SYSTEM_STREAM_START_BYTE2) return result; - - size_t msg_length = length - BASIC_MULTI_SYSTEM_STREAM_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + BASIC_MULTI_SYSTEM_STREAM_HEADER_SIZE); - } + if (buffer[0] != BASIC_MULTI_SYSTEM_STREAM_START_BYTE1) return FrameMsgInfo(); + if (buffer[1] != BASIC_MULTI_SYSTEM_STREAM_START_BYTE2) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, BASIC_MULTI_SYSTEM_STREAM_HEADER_SIZE, 1, 2); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/BasicSeq.hpp b/src/struct_frame/boilerplate/cpp/BasicSeq.hpp index 32003090..4a64f4eb 100644 --- a/src/struct_frame/boilerplate/cpp/BasicSeq.hpp +++ b/src/struct_frame/boilerplate/cpp/BasicSeq.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -164,17 +164,10 @@ class BasicSeqParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - BASIC_SEQ_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 2, msg_length + 1 + 1); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + BASIC_SEQ_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + BASIC_SEQ_HEADER_SIZE, 1, 2); state_ = BasicSeqParserState::LookingForStart1; } break; @@ -205,16 +198,11 @@ inline size_t basic_seq_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = BASIC_SEQ_START_BYTE1; buffer[1] = BASIC_SEQ_START_BYTE2; - buffer[2] = static_cast(msg_size); - buffer[3] = msg_id; - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + BASIC_SEQ_HEADER_SIZE, msg, msg_size); - } - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_size + 1 + 1); - buffer[BASIC_SEQ_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_SEQ_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 1, buffer + 2); return total_size; } @@ -223,24 +211,14 @@ inline size_t basic_seq_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete BasicSeq packet in a buffer */ inline FrameMsgInfo basic_seq_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < BASIC_SEQ_OVERHEAD) return result; + if (length < BASIC_SEQ_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != BASIC_SEQ_START_BYTE1) return result; - if (buffer[1] != BASIC_SEQ_START_BYTE2) return result; - - size_t msg_length = length - BASIC_SEQ_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + BASIC_SEQ_HEADER_SIZE); - } + if (buffer[0] != BASIC_SEQ_START_BYTE1) return FrameMsgInfo(); + if (buffer[1] != BASIC_SEQ_START_BYTE2) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, BASIC_SEQ_HEADER_SIZE, 1, 2); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/BasicSysComp.hpp b/src/struct_frame/boilerplate/cpp/BasicSysComp.hpp index 2e7b101d..ab5a3423 100644 --- a/src/struct_frame/boilerplate/cpp/BasicSysComp.hpp +++ b/src/struct_frame/boilerplate/cpp/BasicSysComp.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -164,17 +164,10 @@ class BasicSysCompParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - BASIC_SYS_COMP_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 2, msg_length + 1 + 1); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + BASIC_SYS_COMP_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + BASIC_SYS_COMP_HEADER_SIZE, 1, 2); state_ = BasicSysCompParserState::LookingForStart1; } break; @@ -205,16 +198,11 @@ inline size_t basic_sys_comp_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = BASIC_SYS_COMP_START_BYTE1; buffer[1] = BASIC_SYS_COMP_START_BYTE2; - buffer[2] = static_cast(msg_size); - buffer[3] = msg_id; - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + BASIC_SYS_COMP_HEADER_SIZE, msg, msg_size); - } - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_size + 1 + 1); - buffer[BASIC_SYS_COMP_HEADER_SIZE + msg_size] = ck.byte1; - buffer[BASIC_SYS_COMP_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 1, buffer + 2); return total_size; } @@ -223,24 +211,14 @@ inline size_t basic_sys_comp_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete BasicSysComp packet in a buffer */ inline FrameMsgInfo basic_sys_comp_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < BASIC_SYS_COMP_OVERHEAD) return result; + if (length < BASIC_SYS_COMP_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != BASIC_SYS_COMP_START_BYTE1) return result; - if (buffer[1] != BASIC_SYS_COMP_START_BYTE2) return result; - - size_t msg_length = length - BASIC_SYS_COMP_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + BASIC_SYS_COMP_HEADER_SIZE); - } + if (buffer[0] != BASIC_SYS_COMP_START_BYTE1) return FrameMsgInfo(); + if (buffer[1] != BASIC_SYS_COMP_START_BYTE2) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, BASIC_SYS_COMP_HEADER_SIZE, 1, 2); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/FrameFormatConfig.hpp b/src/struct_frame/boilerplate/cpp/FrameFormatConfig.hpp index 909757db..18ae3e35 100644 --- a/src/struct_frame/boilerplate/cpp/FrameFormatConfig.hpp +++ b/src/struct_frame/boilerplate/cpp/FrameFormatConfig.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -158,17 +158,10 @@ class FrameFormatConfigParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - FRAME_FORMAT_CONFIG_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 2, msg_length + 1); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + FRAME_FORMAT_CONFIG_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + FRAME_FORMAT_CONFIG_HEADER_SIZE, 0, 2); state_ = FrameFormatConfigParserState::LookingForStart1; } break; @@ -198,15 +191,11 @@ inline size_t frame_format_config_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = FRAME_FORMAT_CONFIG_START_BYTE1; buffer[1] = FRAME_FORMAT_CONFIG_START_BYTE2; - buffer[2] = msg_id; - - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + FRAME_FORMAT_CONFIG_HEADER_SIZE, msg, msg_size); - } - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_size + 1); - buffer[FRAME_FORMAT_CONFIG_HEADER_SIZE + msg_size] = ck.byte1; - buffer[FRAME_FORMAT_CONFIG_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 0, buffer + 2); return total_size; } @@ -215,24 +204,14 @@ inline size_t frame_format_config_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete FrameFormatConfig packet in a buffer */ inline FrameMsgInfo frame_format_config_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < FRAME_FORMAT_CONFIG_OVERHEAD) return result; + if (length < FRAME_FORMAT_CONFIG_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != FRAME_FORMAT_CONFIG_START_BYTE1) return result; - if (buffer[1] != FRAME_FORMAT_CONFIG_START_BYTE2) return result; - - size_t msg_length = length - FRAME_FORMAT_CONFIG_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_length + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + FRAME_FORMAT_CONFIG_HEADER_SIZE); - } + if (buffer[0] != FRAME_FORMAT_CONFIG_START_BYTE1) return FrameMsgInfo(); + if (buffer[1] != FRAME_FORMAT_CONFIG_START_BYTE2) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, FRAME_FORMAT_CONFIG_HEADER_SIZE, 0, 2); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/MavlinkV1Frame.hpp b/src/struct_frame/boilerplate/cpp/MavlinkV1Frame.hpp index 72e0c354..af21dc5c 100644 --- a/src/struct_frame/boilerplate/cpp/MavlinkV1Frame.hpp +++ b/src/struct_frame/boilerplate/cpp/MavlinkV1Frame.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -147,17 +147,10 @@ class MavlinkV1FrameParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - MAVLINK_V1_FRAME_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 1, msg_length + 1 + 1); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + MAVLINK_V1_FRAME_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + MAVLINK_V1_FRAME_HEADER_SIZE, 1, 1); state_ = MavlinkV1FrameParserState::LookingForStart; } break; @@ -187,16 +180,11 @@ inline size_t mavlink_v1_frame_encode(uint8_t* buffer, size_t buffer_size, if (buffer_size < total_size) return 0; buffer[0] = MAVLINK_V1_FRAME_START_BYTE; - buffer[1] = static_cast(msg_size); - buffer[2] = msg_id; - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + MAVLINK_V1_FRAME_HEADER_SIZE, msg, msg_size); - } - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_size + 1 + 1); - buffer[MAVLINK_V1_FRAME_HEADER_SIZE + msg_size] = ck.byte1; - buffer[MAVLINK_V1_FRAME_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 1, buffer + 1); return total_size; } @@ -205,23 +193,13 @@ inline size_t mavlink_v1_frame_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete MavlinkV1Frame packet in a buffer */ inline FrameMsgInfo mavlink_v1_frame_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < MAVLINK_V1_FRAME_OVERHEAD) return result; + if (length < MAVLINK_V1_FRAME_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != MAVLINK_V1_FRAME_START_BYTE) return result; - - size_t msg_length = length - MAVLINK_V1_FRAME_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + MAVLINK_V1_FRAME_HEADER_SIZE); - } + if (buffer[0] != MAVLINK_V1_FRAME_START_BYTE) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, MAVLINK_V1_FRAME_HEADER_SIZE, 1, 1); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/MavlinkV2Frame.hpp b/src/struct_frame/boilerplate/cpp/MavlinkV2Frame.hpp index 204d0076..d3d54d3f 100644 --- a/src/struct_frame/boilerplate/cpp/MavlinkV2Frame.hpp +++ b/src/struct_frame/boilerplate/cpp/MavlinkV2Frame.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -147,17 +147,10 @@ class MavlinkV2FrameParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - MAVLINK_V2_FRAME_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 1, msg_length + 1 + 1); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + MAVLINK_V2_FRAME_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + MAVLINK_V2_FRAME_HEADER_SIZE, 1, 1); state_ = MavlinkV2FrameParserState::LookingForStart; } break; @@ -187,16 +180,11 @@ inline size_t mavlink_v2_frame_encode(uint8_t* buffer, size_t buffer_size, if (buffer_size < total_size) return 0; buffer[0] = MAVLINK_V2_FRAME_START_BYTE; - buffer[1] = static_cast(msg_size); - buffer[2] = msg_id; - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + MAVLINK_V2_FRAME_HEADER_SIZE, msg, msg_size); - } - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_size + 1 + 1); - buffer[MAVLINK_V2_FRAME_HEADER_SIZE + msg_size] = ck.byte1; - buffer[MAVLINK_V2_FRAME_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 1, buffer + 1); return total_size; } @@ -205,23 +193,13 @@ inline size_t mavlink_v2_frame_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete MavlinkV2Frame packet in a buffer */ inline FrameMsgInfo mavlink_v2_frame_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < MAVLINK_V2_FRAME_OVERHEAD) return result; + if (length < MAVLINK_V2_FRAME_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != MAVLINK_V2_FRAME_START_BYTE) return result; - - size_t msg_length = length - MAVLINK_V2_FRAME_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + MAVLINK_V2_FRAME_HEADER_SIZE); - } + if (buffer[0] != MAVLINK_V2_FRAME_START_BYTE) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, MAVLINK_V2_FRAME_HEADER_SIZE, 1, 1); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/TinyDefault.hpp b/src/struct_frame/boilerplate/cpp/TinyDefault.hpp index eb2ecb06..bdfda580 100644 --- a/src/struct_frame/boilerplate/cpp/TinyDefault.hpp +++ b/src/struct_frame/boilerplate/cpp/TinyDefault.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -147,17 +147,10 @@ class TinyDefaultParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - TINY_DEFAULT_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 1, msg_length + 1 + 1); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + TINY_DEFAULT_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + TINY_DEFAULT_HEADER_SIZE, 1, 1); state_ = TinyDefaultParserState::LookingForStart; } break; @@ -187,16 +180,11 @@ inline size_t tiny_default_encode(uint8_t* buffer, size_t buffer_size, if (buffer_size < total_size) return 0; buffer[0] = TINY_DEFAULT_START_BYTE; - buffer[1] = static_cast(msg_size); - buffer[2] = msg_id; - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + TINY_DEFAULT_HEADER_SIZE, msg, msg_size); - } - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_size + 1 + 1); - buffer[TINY_DEFAULT_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_DEFAULT_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 1, buffer + 1); return total_size; } @@ -205,23 +193,13 @@ inline size_t tiny_default_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete TinyDefault packet in a buffer */ inline FrameMsgInfo tiny_default_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < TINY_DEFAULT_OVERHEAD) return result; + if (length < TINY_DEFAULT_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != TINY_DEFAULT_START_BYTE) return result; - - size_t msg_length = length - TINY_DEFAULT_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + TINY_DEFAULT_HEADER_SIZE); - } + if (buffer[0] != TINY_DEFAULT_START_BYTE) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, TINY_DEFAULT_HEADER_SIZE, 1, 1); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/TinyExtended.hpp b/src/struct_frame/boilerplate/cpp/TinyExtended.hpp index 91db333c..61ffbacc 100644 --- a/src/struct_frame/boilerplate/cpp/TinyExtended.hpp +++ b/src/struct_frame/boilerplate/cpp/TinyExtended.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -153,17 +153,10 @@ class TinyExtendedParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - TINY_EXTENDED_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 1, msg_length + 1 + 2); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + TINY_EXTENDED_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + TINY_EXTENDED_HEADER_SIZE, 2, 1); state_ = TinyExtendedParserState::LookingForStart; } break; @@ -194,17 +187,11 @@ inline size_t tiny_extended_encode(uint8_t* buffer, size_t buffer_size, if (buffer_size < total_size) return 0; buffer[0] = TINY_EXTENDED_START_BYTE; - buffer[1] = static_cast(msg_size & 0xFF); - buffer[2] = static_cast((msg_size >> 8) & 0xFF); - buffer[3] = msg_id; - - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + TINY_EXTENDED_HEADER_SIZE, msg, msg_size); - } - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_size + 1 + 2); - buffer[TINY_EXTENDED_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_EXTENDED_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 2, buffer + 1); return total_size; } @@ -213,23 +200,13 @@ inline size_t tiny_extended_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete TinyExtended packet in a buffer */ inline FrameMsgInfo tiny_extended_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < TINY_EXTENDED_OVERHEAD) return result; + if (length < TINY_EXTENDED_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != TINY_EXTENDED_START_BYTE) return result; - - size_t msg_length = length - TINY_EXTENDED_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_length + 1 + 2); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + TINY_EXTENDED_HEADER_SIZE); - } + if (buffer[0] != TINY_EXTENDED_START_BYTE) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, TINY_EXTENDED_HEADER_SIZE, 2, 1); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/TinyExtendedLength.hpp b/src/struct_frame/boilerplate/cpp/TinyExtendedLength.hpp index 83fefcd0..da933088 100644 --- a/src/struct_frame/boilerplate/cpp/TinyExtendedLength.hpp +++ b/src/struct_frame/boilerplate/cpp/TinyExtendedLength.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -153,17 +153,10 @@ class TinyExtendedLengthParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - TINY_EXTENDED_LENGTH_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 1, msg_length + 1 + 2); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + TINY_EXTENDED_LENGTH_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + TINY_EXTENDED_LENGTH_HEADER_SIZE, 2, 1); state_ = TinyExtendedLengthParserState::LookingForStart; } break; @@ -194,17 +187,11 @@ inline size_t tiny_extended_length_encode(uint8_t* buffer, size_t buffer_size, if (buffer_size < total_size) return 0; buffer[0] = TINY_EXTENDED_LENGTH_START_BYTE; - buffer[1] = static_cast(msg_size & 0xFF); - buffer[2] = static_cast((msg_size >> 8) & 0xFF); - buffer[3] = msg_id; - - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + TINY_EXTENDED_LENGTH_HEADER_SIZE, msg, msg_size); - } - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_size + 1 + 2); - buffer[TINY_EXTENDED_LENGTH_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_EXTENDED_LENGTH_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 2, buffer + 1); return total_size; } @@ -213,23 +200,13 @@ inline size_t tiny_extended_length_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete TinyExtendedLength packet in a buffer */ inline FrameMsgInfo tiny_extended_length_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < TINY_EXTENDED_LENGTH_OVERHEAD) return result; + if (length < TINY_EXTENDED_LENGTH_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != TINY_EXTENDED_LENGTH_START_BYTE) return result; - - size_t msg_length = length - TINY_EXTENDED_LENGTH_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_length + 1 + 2); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + TINY_EXTENDED_LENGTH_HEADER_SIZE); - } + if (buffer[0] != TINY_EXTENDED_LENGTH_START_BYTE) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, TINY_EXTENDED_LENGTH_HEADER_SIZE, 2, 1); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/TinyExtendedMsgIds.hpp b/src/struct_frame/boilerplate/cpp/TinyExtendedMsgIds.hpp index a41477dd..0b89b0a8 100644 --- a/src/struct_frame/boilerplate/cpp/TinyExtendedMsgIds.hpp +++ b/src/struct_frame/boilerplate/cpp/TinyExtendedMsgIds.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -147,17 +147,10 @@ class TinyExtendedMsgIdsParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - TINY_EXTENDED_MSG_IDS_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 1, msg_length + 1 + 1); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + TINY_EXTENDED_MSG_IDS_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + TINY_EXTENDED_MSG_IDS_HEADER_SIZE, 1, 1); state_ = TinyExtendedMsgIdsParserState::LookingForStart; } break; @@ -187,16 +180,11 @@ inline size_t tiny_extended_msg_ids_encode(uint8_t* buffer, size_t buffer_size, if (buffer_size < total_size) return 0; buffer[0] = TINY_EXTENDED_MSG_IDS_START_BYTE; - buffer[1] = static_cast(msg_size); - buffer[2] = msg_id; - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + TINY_EXTENDED_MSG_IDS_HEADER_SIZE, msg, msg_size); - } - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_size + 1 + 1); - buffer[TINY_EXTENDED_MSG_IDS_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_EXTENDED_MSG_IDS_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 1, buffer + 1); return total_size; } @@ -205,23 +193,13 @@ inline size_t tiny_extended_msg_ids_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete TinyExtendedMsgIds packet in a buffer */ inline FrameMsgInfo tiny_extended_msg_ids_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < TINY_EXTENDED_MSG_IDS_OVERHEAD) return result; + if (length < TINY_EXTENDED_MSG_IDS_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != TINY_EXTENDED_MSG_IDS_START_BYTE) return result; - - size_t msg_length = length - TINY_EXTENDED_MSG_IDS_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + TINY_EXTENDED_MSG_IDS_HEADER_SIZE); - } + if (buffer[0] != TINY_EXTENDED_MSG_IDS_START_BYTE) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, TINY_EXTENDED_MSG_IDS_HEADER_SIZE, 1, 1); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/TinyExtendedMultiSystemStream.hpp b/src/struct_frame/boilerplate/cpp/TinyExtendedMultiSystemStream.hpp index 8c31e4e9..921ae626 100644 --- a/src/struct_frame/boilerplate/cpp/TinyExtendedMultiSystemStream.hpp +++ b/src/struct_frame/boilerplate/cpp/TinyExtendedMultiSystemStream.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -153,17 +153,10 @@ class TinyExtendedMultiSystemStreamParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - TINY_EXTENDED_MULTI_SYSTEM_STREAM_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 1, msg_length + 1 + 2); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + TINY_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + TINY_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE, 2, 1); state_ = TinyExtendedMultiSystemStreamParserState::LookingForStart; } break; @@ -194,17 +187,11 @@ inline size_t tiny_extended_multi_system_stream_encode(uint8_t* buffer, size_t b if (buffer_size < total_size) return 0; buffer[0] = TINY_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE; - buffer[1] = static_cast(msg_size & 0xFF); - buffer[2] = static_cast((msg_size >> 8) & 0xFF); - buffer[3] = msg_id; - - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + TINY_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE, msg, msg_size); - } - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_size + 1 + 2); - buffer[TINY_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 2, buffer + 1); return total_size; } @@ -213,23 +200,13 @@ inline size_t tiny_extended_multi_system_stream_encode(uint8_t* buffer, size_t b * Validate a complete TinyExtendedMultiSystemStream packet in a buffer */ inline FrameMsgInfo tiny_extended_multi_system_stream_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < TINY_EXTENDED_MULTI_SYSTEM_STREAM_OVERHEAD) return result; + if (length < TINY_EXTENDED_MULTI_SYSTEM_STREAM_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != TINY_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE) return result; - - size_t msg_length = length - TINY_EXTENDED_MULTI_SYSTEM_STREAM_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_length + 1 + 2); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + TINY_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE); - } + if (buffer[0] != TINY_EXTENDED_MULTI_SYSTEM_STREAM_START_BYTE) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, TINY_EXTENDED_MULTI_SYSTEM_STREAM_HEADER_SIZE, 2, 1); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/TinyMinimal.hpp b/src/struct_frame/boilerplate/cpp/TinyMinimal.hpp index c3eb8164..d27c0078 100644 --- a/src/struct_frame/boilerplate/cpp/TinyMinimal.hpp +++ b/src/struct_frame/boilerplate/cpp/TinyMinimal.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -137,10 +137,9 @@ class TinyMinimalParser { } if (buffer_index_ >= packet_size_) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = packet_size_ - TINY_MINIMAL_OVERHEAD; - result.msg_data = buffer_ + TINY_MINIMAL_HEADER_SIZE; + // Use shared minimal payload validation + result = validate_payload_minimal( + buffer_, packet_size_, TINY_MINIMAL_HEADER_SIZE); state_ = TinyMinimalParserState::LookingForStart; } break; @@ -169,12 +168,10 @@ inline size_t tiny_minimal_encode(uint8_t* buffer, size_t buffer_size, if (buffer_size < total_size) return 0; buffer[0] = TINY_MINIMAL_START_BYTE; - buffer[1] = msg_id; - - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + TINY_MINIMAL_HEADER_SIZE, msg, msg_size); - } + // Use shared minimal payload encoding + encode_payload_minimal( + buffer + 1, msg_id, msg, msg_size); return total_size; } @@ -183,20 +180,13 @@ inline size_t tiny_minimal_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete TinyMinimal packet in a buffer */ inline FrameMsgInfo tiny_minimal_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < TINY_MINIMAL_OVERHEAD) return result; - - if (buffer[0] != TINY_MINIMAL_START_BYTE) return result; - - size_t msg_length = length - TINY_MINIMAL_OVERHEAD; + if (length < TINY_MINIMAL_OVERHEAD) return FrameMsgInfo(); - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + TINY_MINIMAL_HEADER_SIZE); + if (buffer[0] != TINY_MINIMAL_START_BYTE) return FrameMsgInfo(); - return result; + // Use shared minimal payload validation + return validate_payload_minimal( + buffer, length, TINY_MINIMAL_HEADER_SIZE); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/TinyMultiSystemStream.hpp b/src/struct_frame/boilerplate/cpp/TinyMultiSystemStream.hpp index 7a39970e..017cc040 100644 --- a/src/struct_frame/boilerplate/cpp/TinyMultiSystemStream.hpp +++ b/src/struct_frame/boilerplate/cpp/TinyMultiSystemStream.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -147,17 +147,10 @@ class TinyMultiSystemStreamParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - TINY_MULTI_SYSTEM_STREAM_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 1, msg_length + 1 + 1); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + TINY_MULTI_SYSTEM_STREAM_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + TINY_MULTI_SYSTEM_STREAM_HEADER_SIZE, 1, 1); state_ = TinyMultiSystemStreamParserState::LookingForStart; } break; @@ -187,16 +180,11 @@ inline size_t tiny_multi_system_stream_encode(uint8_t* buffer, size_t buffer_siz if (buffer_size < total_size) return 0; buffer[0] = TINY_MULTI_SYSTEM_STREAM_START_BYTE; - buffer[1] = static_cast(msg_size); - buffer[2] = msg_id; - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + TINY_MULTI_SYSTEM_STREAM_HEADER_SIZE, msg, msg_size); - } - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_size + 1 + 1); - buffer[TINY_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_MULTI_SYSTEM_STREAM_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 1, buffer + 1); return total_size; } @@ -205,23 +193,13 @@ inline size_t tiny_multi_system_stream_encode(uint8_t* buffer, size_t buffer_siz * Validate a complete TinyMultiSystemStream packet in a buffer */ inline FrameMsgInfo tiny_multi_system_stream_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < TINY_MULTI_SYSTEM_STREAM_OVERHEAD) return result; + if (length < TINY_MULTI_SYSTEM_STREAM_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != TINY_MULTI_SYSTEM_STREAM_START_BYTE) return result; - - size_t msg_length = length - TINY_MULTI_SYSTEM_STREAM_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + TINY_MULTI_SYSTEM_STREAM_HEADER_SIZE); - } + if (buffer[0] != TINY_MULTI_SYSTEM_STREAM_START_BYTE) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, TINY_MULTI_SYSTEM_STREAM_HEADER_SIZE, 1, 1); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/TinySeq.hpp b/src/struct_frame/boilerplate/cpp/TinySeq.hpp index a5b9eed8..6d227b4a 100644 --- a/src/struct_frame/boilerplate/cpp/TinySeq.hpp +++ b/src/struct_frame/boilerplate/cpp/TinySeq.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -147,17 +147,10 @@ class TinySeqParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - TINY_SEQ_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 1, msg_length + 1 + 1); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + TINY_SEQ_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + TINY_SEQ_HEADER_SIZE, 1, 1); state_ = TinySeqParserState::LookingForStart; } break; @@ -187,16 +180,11 @@ inline size_t tiny_seq_encode(uint8_t* buffer, size_t buffer_size, if (buffer_size < total_size) return 0; buffer[0] = TINY_SEQ_START_BYTE; - buffer[1] = static_cast(msg_size); - buffer[2] = msg_id; - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + TINY_SEQ_HEADER_SIZE, msg, msg_size); - } - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_size + 1 + 1); - buffer[TINY_SEQ_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_SEQ_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 1, buffer + 1); return total_size; } @@ -205,23 +193,13 @@ inline size_t tiny_seq_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete TinySeq packet in a buffer */ inline FrameMsgInfo tiny_seq_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < TINY_SEQ_OVERHEAD) return result; + if (length < TINY_SEQ_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != TINY_SEQ_START_BYTE) return result; - - size_t msg_length = length - TINY_SEQ_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + TINY_SEQ_HEADER_SIZE); - } + if (buffer[0] != TINY_SEQ_START_BYTE) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, TINY_SEQ_HEADER_SIZE, 1, 1); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/TinySysComp.hpp b/src/struct_frame/boilerplate/cpp/TinySysComp.hpp index 903b94dc..17e0cec1 100644 --- a/src/struct_frame/boilerplate/cpp/TinySysComp.hpp +++ b/src/struct_frame/boilerplate/cpp/TinySysComp.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -147,17 +147,10 @@ class TinySysCompParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - TINY_SYS_COMP_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 1, msg_length + 1 + 1); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + TINY_SYS_COMP_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + TINY_SYS_COMP_HEADER_SIZE, 1, 1); state_ = TinySysCompParserState::LookingForStart; } break; @@ -187,16 +180,11 @@ inline size_t tiny_sys_comp_encode(uint8_t* buffer, size_t buffer_size, if (buffer_size < total_size) return 0; buffer[0] = TINY_SYS_COMP_START_BYTE; - buffer[1] = static_cast(msg_size); - buffer[2] = msg_id; - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + TINY_SYS_COMP_HEADER_SIZE, msg, msg_size); - } - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_size + 1 + 1); - buffer[TINY_SYS_COMP_HEADER_SIZE + msg_size] = ck.byte1; - buffer[TINY_SYS_COMP_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 1, msg_id, msg, msg_size, + 1, buffer + 1); return total_size; } @@ -205,23 +193,13 @@ inline size_t tiny_sys_comp_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete TinySysComp packet in a buffer */ inline FrameMsgInfo tiny_sys_comp_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < TINY_SYS_COMP_OVERHEAD) return result; + if (length < TINY_SYS_COMP_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != TINY_SYS_COMP_START_BYTE) return result; - - size_t msg_length = length - TINY_SYS_COMP_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 1, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + TINY_SYS_COMP_HEADER_SIZE); - } + if (buffer[0] != TINY_SYS_COMP_START_BYTE) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, TINY_SYS_COMP_HEADER_SIZE, 1, 1); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/UbxFrame.hpp b/src/struct_frame/boilerplate/cpp/UbxFrame.hpp index 78887236..1a76da38 100644 --- a/src/struct_frame/boilerplate/cpp/UbxFrame.hpp +++ b/src/struct_frame/boilerplate/cpp/UbxFrame.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -164,17 +164,10 @@ class UbxFrameParser { } if (buffer_index_ >= packet_size_) { - // Validate checksum - size_t msg_length = packet_size_ - UBX_FRAME_OVERHEAD; - FrameChecksum ck = fletcher_checksum(buffer_ + 2, msg_length + 1 + 1); - - if (ck.byte1 == buffer_[packet_size_ - 2] && - ck.byte2 == buffer_[packet_size_ - 1]) { - result.valid = true; - result.msg_id = msg_id_; - result.msg_len = msg_length; - result.msg_data = buffer_ + UBX_FRAME_HEADER_SIZE; - } + // Use shared payload validation with CRC + result = validate_payload_with_crc( + buffer_, packet_size_, + UBX_FRAME_HEADER_SIZE, 1, 2); state_ = UbxFrameParserState::LookingForStart1; } break; @@ -205,16 +198,11 @@ inline size_t ubx_frame_encode(uint8_t* buffer, size_t buffer_size, buffer[0] = UBX_FRAME_START_BYTE1; buffer[1] = UBX_FRAME_START_BYTE2; - buffer[2] = static_cast(msg_size); - buffer[3] = msg_id; - if (msg_size > 0 && msg != nullptr) { - std::memcpy(buffer + UBX_FRAME_HEADER_SIZE, msg, msg_size); - } - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_size + 1 + 1); - buffer[UBX_FRAME_HEADER_SIZE + msg_size] = ck.byte1; - buffer[UBX_FRAME_HEADER_SIZE + msg_size + 1] = ck.byte2; + // Use shared payload encoding with CRC + encode_payload_with_crc( + buffer + 2, msg_id, msg, msg_size, + 1, buffer + 2); return total_size; } @@ -223,24 +211,14 @@ inline size_t ubx_frame_encode(uint8_t* buffer, size_t buffer_size, * Validate a complete UbxFrame packet in a buffer */ inline FrameMsgInfo ubx_frame_validate_packet(const uint8_t* buffer, size_t length) { - FrameMsgInfo result; - - if (length < UBX_FRAME_OVERHEAD) return result; + if (length < UBX_FRAME_OVERHEAD) return FrameMsgInfo(); - if (buffer[0] != UBX_FRAME_START_BYTE1) return result; - if (buffer[1] != UBX_FRAME_START_BYTE2) return result; - - size_t msg_length = length - UBX_FRAME_OVERHEAD; - - FrameChecksum ck = fletcher_checksum(buffer + 2, msg_length + 1 + 1); - if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { - result.valid = true; - result.msg_id = buffer[3]; - result.msg_len = msg_length; - result.msg_data = const_cast(buffer + UBX_FRAME_HEADER_SIZE); - } + if (buffer[0] != UBX_FRAME_START_BYTE1) return FrameMsgInfo(); + if (buffer[1] != UBX_FRAME_START_BYTE2) return FrameMsgInfo(); - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc( + buffer, length, UBX_FRAME_HEADER_SIZE, 1, 2); } } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/frame_base.hpp b/src/struct_frame/boilerplate/cpp/frame_base.hpp index a7897130..8aa17db6 100644 --- a/src/struct_frame/boilerplate/cpp/frame_base.hpp +++ b/src/struct_frame/boilerplate/cpp/frame_base.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser base utilities */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once @@ -64,4 +64,109 @@ struct FrameMsgInfo { : valid(v), msg_id(id), msg_len(len), msg_data(data) {} }; +// ============================================================================= +// Shared Payload Parsing Functions +// ============================================================================= +// These functions handle payload validation/encoding independent of framing. +// Frame formats (Tiny/Basic) use these for the common parsing logic. + +/** + * Validate a payload with CRC (shared by Default, Extended, etc. payload types). + */ +inline FrameMsgInfo validate_payload_with_crc( + const uint8_t* buffer, size_t length, + size_t header_size, size_t length_bytes, size_t crc_start_offset) { + + constexpr size_t footer_size = 2; // CRC is always 2 bytes + const size_t overhead = header_size + footer_size; + + if (length < overhead) { + return FrameMsgInfo(); + } + + size_t msg_length = length - overhead; + + // Calculate expected CRC range: from crc_start_offset to before the CRC bytes + size_t crc_data_len = msg_length + 1 + length_bytes; // msg_id (1) + length_bytes + payload + FrameChecksum ck = fletcher_checksum(buffer + crc_start_offset, crc_data_len); + + if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { + return FrameMsgInfo(true, buffer[header_size - 1], msg_length, + const_cast(buffer + header_size)); + } + + return FrameMsgInfo(); +} + +/** + * Validate a minimal payload (no CRC, no length field). + */ +inline FrameMsgInfo validate_payload_minimal( + const uint8_t* buffer, size_t length, size_t header_size) { + + if (length < header_size) { + return FrameMsgInfo(); + } + + return FrameMsgInfo(true, buffer[header_size - 1], length - header_size, + const_cast(buffer + header_size)); +} + +/** + * Encode payload with length and CRC into output buffer. + * Returns number of bytes written (length + msg_id + payload + CRC) + */ +inline size_t encode_payload_with_crc( + uint8_t* output, uint8_t msg_id, const uint8_t* msg, size_t msg_size, + size_t length_bytes, const uint8_t* crc_start) { + + size_t idx = 0; + + // Add length field + if (length_bytes == 1) { + output[idx++] = static_cast(msg_size & 0xFF); + } else { + output[idx++] = static_cast(msg_size & 0xFF); + output[idx++] = static_cast((msg_size >> 8) & 0xFF); + } + + // Add msg_id + output[idx++] = msg_id; + + // Add payload + if (msg_size > 0 && msg != nullptr) { + std::memcpy(output + idx, msg, msg_size); + idx += msg_size; + } + + // Calculate and add CRC + size_t crc_data_len = msg_size + 1 + length_bytes; + FrameChecksum ck = fletcher_checksum(crc_start, crc_data_len); + output[idx++] = ck.byte1; + output[idx++] = ck.byte2; + + return idx; +} + +/** + * Encode minimal payload (no length, no CRC) into output buffer. + * Returns number of bytes written (msg_id + payload) + */ +inline size_t encode_payload_minimal( + uint8_t* output, uint8_t msg_id, const uint8_t* msg, size_t msg_size) { + + size_t idx = 0; + + // Add msg_id + output[idx++] = msg_id; + + // Add payload + if (msg_size > 0 && msg != nullptr) { + std::memcpy(output + idx, msg, msg_size); + idx += msg_size; + } + + return idx; +} + } // namespace FrameParsers diff --git a/src/struct_frame/boilerplate/cpp/frame_parsers.hpp b/src/struct_frame/boilerplate/cpp/frame_parsers.hpp index 186bfafa..7909e702 100644 --- a/src/struct_frame/boilerplate/cpp/frame_parsers.hpp +++ b/src/struct_frame/boilerplate/cpp/frame_parsers.hpp @@ -1,5 +1,5 @@ /* Automatically generated frame parser main header */ -/* Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. */ +/* Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. */ #pragma once diff --git a/src/struct_frame/boilerplate/js/BasicDefault.js b/src/struct_frame/boilerplate/js/BasicDefault.js index e5f9517d..ce0dbf20 100644 --- a/src/struct_frame/boilerplate/js/BasicDefault.js +++ b/src/struct_frame/boilerplate/js/BasicDefault.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // BasicDefault Frame Format @@ -83,13 +87,13 @@ class BasicDefault { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - BasicDefault.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicDefault.HEADER_SIZE, this.packet_size - BasicDefault.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicDefault.HEADER_SIZE, 1, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicDefaultParserState.LOOKING_FOR_START1; } @@ -103,42 +107,25 @@ class BasicDefault { const output = []; output.push(BasicDefault.START_BYTE1); output.push(BasicDefault.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < BasicDefault.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicDefault.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicDefault.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicDefault.OVERHEAD; - - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicDefault.HEADER_SIZE, buffer.length - BasicDefault.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicDefault.HEADER_SIZE, 1, 2); } } diff --git a/src/struct_frame/boilerplate/js/BasicExtended.js b/src/struct_frame/boilerplate/js/BasicExtended.js index b5348339..d161cc97 100644 --- a/src/struct_frame/boilerplate/js/BasicExtended.js +++ b/src/struct_frame/boilerplate/js/BasicExtended.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // BasicExtended Frame Format @@ -88,13 +92,13 @@ class BasicExtended { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - BasicExtended.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 2); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicExtended.HEADER_SIZE, this.packet_size - BasicExtended.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicExtended.HEADER_SIZE, 2, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicExtendedParserState.LOOKING_FOR_START1; } @@ -108,43 +112,25 @@ class BasicExtended { const output = []; output.push(BasicExtended.START_BYTE1); output.push(BasicExtended.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - output.push((msg.length >> 8) & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 2); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 2); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < BasicExtended.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicExtended.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicExtended.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicExtended.OVERHEAD; - - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 2); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicExtended.HEADER_SIZE, buffer.length - BasicExtended.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicExtended.HEADER_SIZE, 2, 2); } } diff --git a/src/struct_frame/boilerplate/js/BasicExtendedLength.js b/src/struct_frame/boilerplate/js/BasicExtendedLength.js index 1462a441..9ddf0a43 100644 --- a/src/struct_frame/boilerplate/js/BasicExtendedLength.js +++ b/src/struct_frame/boilerplate/js/BasicExtendedLength.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // BasicExtendedLength Frame Format @@ -88,13 +92,13 @@ class BasicExtendedLength { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - BasicExtendedLength.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 2); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicExtendedLength.HEADER_SIZE, this.packet_size - BasicExtendedLength.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicExtendedLength.HEADER_SIZE, 2, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicExtendedLengthParserState.LOOKING_FOR_START1; } @@ -108,43 +112,25 @@ class BasicExtendedLength { const output = []; output.push(BasicExtendedLength.START_BYTE1); output.push(BasicExtendedLength.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - output.push((msg.length >> 8) & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 2); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 2); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < BasicExtendedLength.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicExtendedLength.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicExtendedLength.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicExtendedLength.OVERHEAD; - - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 2); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicExtendedLength.HEADER_SIZE, buffer.length - BasicExtendedLength.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicExtendedLength.HEADER_SIZE, 2, 2); } } diff --git a/src/struct_frame/boilerplate/js/BasicExtendedMsgIds.js b/src/struct_frame/boilerplate/js/BasicExtendedMsgIds.js index 91e2131d..4033a972 100644 --- a/src/struct_frame/boilerplate/js/BasicExtendedMsgIds.js +++ b/src/struct_frame/boilerplate/js/BasicExtendedMsgIds.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // BasicExtendedMsgIds Frame Format @@ -83,13 +87,13 @@ class BasicExtendedMsgIds { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - BasicExtendedMsgIds.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicExtendedMsgIds.HEADER_SIZE, this.packet_size - BasicExtendedMsgIds.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicExtendedMsgIds.HEADER_SIZE, 1, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicExtendedMsgIdsParserState.LOOKING_FOR_START1; } @@ -103,42 +107,25 @@ class BasicExtendedMsgIds { const output = []; output.push(BasicExtendedMsgIds.START_BYTE1); output.push(BasicExtendedMsgIds.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < BasicExtendedMsgIds.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicExtendedMsgIds.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicExtendedMsgIds.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicExtendedMsgIds.OVERHEAD; - - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicExtendedMsgIds.HEADER_SIZE, buffer.length - BasicExtendedMsgIds.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicExtendedMsgIds.HEADER_SIZE, 1, 2); } } diff --git a/src/struct_frame/boilerplate/js/BasicExtendedMultiSystemStream.js b/src/struct_frame/boilerplate/js/BasicExtendedMultiSystemStream.js index f174c64b..6091a0e6 100644 --- a/src/struct_frame/boilerplate/js/BasicExtendedMultiSystemStream.js +++ b/src/struct_frame/boilerplate/js/BasicExtendedMultiSystemStream.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // BasicExtendedMultiSystemStream Frame Format @@ -88,13 +92,13 @@ class BasicExtendedMultiSystemStream { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - BasicExtendedMultiSystemStream.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 2); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicExtendedMultiSystemStream.HEADER_SIZE, this.packet_size - BasicExtendedMultiSystemStream.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicExtendedMultiSystemStream.HEADER_SIZE, 2, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicExtendedMultiSystemStreamParserState.LOOKING_FOR_START1; } @@ -108,43 +112,25 @@ class BasicExtendedMultiSystemStream { const output = []; output.push(BasicExtendedMultiSystemStream.START_BYTE1); output.push(BasicExtendedMultiSystemStream.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - output.push((msg.length >> 8) & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 2); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 2); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < BasicExtendedMultiSystemStream.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicExtendedMultiSystemStream.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicExtendedMultiSystemStream.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicExtendedMultiSystemStream.OVERHEAD; - - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 2); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicExtendedMultiSystemStream.HEADER_SIZE, buffer.length - BasicExtendedMultiSystemStream.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicExtendedMultiSystemStream.HEADER_SIZE, 2, 2); } } diff --git a/src/struct_frame/boilerplate/js/BasicMinimal.js b/src/struct_frame/boilerplate/js/BasicMinimal.js index 3da9d4e2..dddfd621 100644 --- a/src/struct_frame/boilerplate/js/BasicMinimal.js +++ b/src/struct_frame/boilerplate/js/BasicMinimal.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // BasicMinimal Frame Format @@ -82,10 +86,12 @@ class BasicMinimal { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = this.packet_size - BasicMinimal.OVERHEAD; - result.msg_data = new Uint8Array(this.buffer.slice(BasicMinimal.HEADER_SIZE)); + // Use shared minimal payload validation + const validationResult = validate_payload_minimal(this.buffer, BasicMinimal.HEADER_SIZE); + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; this.state = BasicMinimalParserState.LOOKING_FOR_START1; } break; @@ -98,35 +104,25 @@ class BasicMinimal { const output = []; output.push(BasicMinimal.START_BYTE1); output.push(BasicMinimal.START_BYTE2); - output.push(msg_id); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } + // Use shared minimal payload encoding + encode_payload_minimal(output, msg_id, msg); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < BasicMinimal.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicMinimal.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicMinimal.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicMinimal.OVERHEAD; - - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicMinimal.HEADER_SIZE)); - - return result; + // Use shared minimal payload validation + return validate_payload_minimal(buffer, BasicMinimal.HEADER_SIZE); } } diff --git a/src/struct_frame/boilerplate/js/BasicMultiSystemStream.js b/src/struct_frame/boilerplate/js/BasicMultiSystemStream.js index cdae4de5..0f8f464f 100644 --- a/src/struct_frame/boilerplate/js/BasicMultiSystemStream.js +++ b/src/struct_frame/boilerplate/js/BasicMultiSystemStream.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // BasicMultiSystemStream Frame Format @@ -83,13 +87,13 @@ class BasicMultiSystemStream { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - BasicMultiSystemStream.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicMultiSystemStream.HEADER_SIZE, this.packet_size - BasicMultiSystemStream.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicMultiSystemStream.HEADER_SIZE, 1, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicMultiSystemStreamParserState.LOOKING_FOR_START1; } @@ -103,42 +107,25 @@ class BasicMultiSystemStream { const output = []; output.push(BasicMultiSystemStream.START_BYTE1); output.push(BasicMultiSystemStream.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < BasicMultiSystemStream.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicMultiSystemStream.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicMultiSystemStream.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicMultiSystemStream.OVERHEAD; - - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicMultiSystemStream.HEADER_SIZE, buffer.length - BasicMultiSystemStream.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicMultiSystemStream.HEADER_SIZE, 1, 2); } } diff --git a/src/struct_frame/boilerplate/js/BasicSeq.js b/src/struct_frame/boilerplate/js/BasicSeq.js index 752420f2..d97e9244 100644 --- a/src/struct_frame/boilerplate/js/BasicSeq.js +++ b/src/struct_frame/boilerplate/js/BasicSeq.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // BasicSeq Frame Format @@ -83,13 +87,13 @@ class BasicSeq { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - BasicSeq.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicSeq.HEADER_SIZE, this.packet_size - BasicSeq.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicSeq.HEADER_SIZE, 1, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicSeqParserState.LOOKING_FOR_START1; } @@ -103,42 +107,25 @@ class BasicSeq { const output = []; output.push(BasicSeq.START_BYTE1); output.push(BasicSeq.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < BasicSeq.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicSeq.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicSeq.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicSeq.OVERHEAD; - - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicSeq.HEADER_SIZE, buffer.length - BasicSeq.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicSeq.HEADER_SIZE, 1, 2); } } diff --git a/src/struct_frame/boilerplate/js/BasicSysComp.js b/src/struct_frame/boilerplate/js/BasicSysComp.js index 46d35aa3..541e352c 100644 --- a/src/struct_frame/boilerplate/js/BasicSysComp.js +++ b/src/struct_frame/boilerplate/js/BasicSysComp.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // BasicSysComp Frame Format @@ -83,13 +87,13 @@ class BasicSysComp { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - BasicSysComp.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicSysComp.HEADER_SIZE, this.packet_size - BasicSysComp.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicSysComp.HEADER_SIZE, 1, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicSysCompParserState.LOOKING_FOR_START1; } @@ -103,42 +107,25 @@ class BasicSysComp { const output = []; output.push(BasicSysComp.START_BYTE1); output.push(BasicSysComp.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < BasicSysComp.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicSysComp.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicSysComp.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicSysComp.OVERHEAD; - - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicSysComp.HEADER_SIZE, buffer.length - BasicSysComp.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicSysComp.HEADER_SIZE, 1, 2); } } diff --git a/src/struct_frame/boilerplate/js/FrameFormatConfig.js b/src/struct_frame/boilerplate/js/FrameFormatConfig.js index 6e5b3794..b301bc79 100644 --- a/src/struct_frame/boilerplate/js/FrameFormatConfig.js +++ b/src/struct_frame/boilerplate/js/FrameFormatConfig.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // FrameFormatConfig Frame Format @@ -82,13 +86,13 @@ class FrameFormatConfig { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - FrameFormatConfig.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(FrameFormatConfig.HEADER_SIZE, this.packet_size - FrameFormatConfig.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, FrameFormatConfig.HEADER_SIZE, 0, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = FrameFormatConfigParserState.LOOKING_FOR_START1; } @@ -102,41 +106,25 @@ class FrameFormatConfig { const output = []; output.push(FrameFormatConfig.START_BYTE1); output.push(FrameFormatConfig.START_BYTE2); - output.push(msg_id); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 0, 2); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < FrameFormatConfig.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== FrameFormatConfig.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== FrameFormatConfig.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - FrameFormatConfig.OVERHEAD; - - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, FrameFormatConfig.HEADER_SIZE, buffer.length - FrameFormatConfig.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, FrameFormatConfig.HEADER_SIZE, 0, 2); } } diff --git a/src/struct_frame/boilerplate/js/MavlinkV1Frame.js b/src/struct_frame/boilerplate/js/MavlinkV1Frame.js index a4156544..64220368 100644 --- a/src/struct_frame/boilerplate/js/MavlinkV1Frame.js +++ b/src/struct_frame/boilerplate/js/MavlinkV1Frame.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // MavlinkV1Frame Frame Format @@ -69,13 +73,13 @@ class MavlinkV1Frame { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - MavlinkV1Frame.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(MavlinkV1Frame.HEADER_SIZE, this.packet_size - MavlinkV1Frame.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, MavlinkV1Frame.HEADER_SIZE, 1, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = MavlinkV1FrameParserState.LOOKING_FOR_START; } @@ -88,39 +92,22 @@ class MavlinkV1Frame { static encode(msg_id, msg) { const output = []; output.push(MavlinkV1Frame.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < MavlinkV1Frame.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== MavlinkV1Frame.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - MavlinkV1Frame.OVERHEAD; - - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, MavlinkV1Frame.HEADER_SIZE, buffer.length - MavlinkV1Frame.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, MavlinkV1Frame.HEADER_SIZE, 1, 1); } } diff --git a/src/struct_frame/boilerplate/js/MavlinkV2Frame.js b/src/struct_frame/boilerplate/js/MavlinkV2Frame.js index 4ea88ea7..be06bbba 100644 --- a/src/struct_frame/boilerplate/js/MavlinkV2Frame.js +++ b/src/struct_frame/boilerplate/js/MavlinkV2Frame.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // MavlinkV2Frame Frame Format @@ -69,13 +73,13 @@ class MavlinkV2Frame { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - MavlinkV2Frame.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(MavlinkV2Frame.HEADER_SIZE, this.packet_size - MavlinkV2Frame.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, MavlinkV2Frame.HEADER_SIZE, 1, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = MavlinkV2FrameParserState.LOOKING_FOR_START; } @@ -88,39 +92,22 @@ class MavlinkV2Frame { static encode(msg_id, msg) { const output = []; output.push(MavlinkV2Frame.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < MavlinkV2Frame.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== MavlinkV2Frame.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - MavlinkV2Frame.OVERHEAD; - - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, MavlinkV2Frame.HEADER_SIZE, buffer.length - MavlinkV2Frame.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, MavlinkV2Frame.HEADER_SIZE, 1, 1); } } diff --git a/src/struct_frame/boilerplate/js/TinyDefault.js b/src/struct_frame/boilerplate/js/TinyDefault.js index fc81430c..8c461a57 100644 --- a/src/struct_frame/boilerplate/js/TinyDefault.js +++ b/src/struct_frame/boilerplate/js/TinyDefault.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // TinyDefault Frame Format @@ -69,13 +73,13 @@ class TinyDefault { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - TinyDefault.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinyDefault.HEADER_SIZE, this.packet_size - TinyDefault.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinyDefault.HEADER_SIZE, 1, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinyDefaultParserState.LOOKING_FOR_START; } @@ -88,39 +92,22 @@ class TinyDefault { static encode(msg_id, msg) { const output = []; output.push(TinyDefault.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < TinyDefault.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinyDefault.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinyDefault.OVERHEAD; - - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinyDefault.HEADER_SIZE, buffer.length - TinyDefault.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyDefault.HEADER_SIZE, 1, 1); } } diff --git a/src/struct_frame/boilerplate/js/TinyExtended.js b/src/struct_frame/boilerplate/js/TinyExtended.js index f63ebfce..396b6048 100644 --- a/src/struct_frame/boilerplate/js/TinyExtended.js +++ b/src/struct_frame/boilerplate/js/TinyExtended.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // TinyExtended Frame Format @@ -74,13 +78,13 @@ class TinyExtended { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - TinyExtended.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 2); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinyExtended.HEADER_SIZE, this.packet_size - TinyExtended.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinyExtended.HEADER_SIZE, 2, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinyExtendedParserState.LOOKING_FOR_START; } @@ -93,40 +97,22 @@ class TinyExtended { static encode(msg_id, msg) { const output = []; output.push(TinyExtended.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - output.push((msg.length >> 8) & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 2); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 1); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < TinyExtended.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinyExtended.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinyExtended.OVERHEAD; - - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 2); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinyExtended.HEADER_SIZE, buffer.length - TinyExtended.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyExtended.HEADER_SIZE, 2, 1); } } diff --git a/src/struct_frame/boilerplate/js/TinyExtendedLength.js b/src/struct_frame/boilerplate/js/TinyExtendedLength.js index db63e046..1020dd17 100644 --- a/src/struct_frame/boilerplate/js/TinyExtendedLength.js +++ b/src/struct_frame/boilerplate/js/TinyExtendedLength.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // TinyExtendedLength Frame Format @@ -74,13 +78,13 @@ class TinyExtendedLength { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - TinyExtendedLength.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 2); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinyExtendedLength.HEADER_SIZE, this.packet_size - TinyExtendedLength.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinyExtendedLength.HEADER_SIZE, 2, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinyExtendedLengthParserState.LOOKING_FOR_START; } @@ -93,40 +97,22 @@ class TinyExtendedLength { static encode(msg_id, msg) { const output = []; output.push(TinyExtendedLength.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - output.push((msg.length >> 8) & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 2); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 1); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < TinyExtendedLength.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinyExtendedLength.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinyExtendedLength.OVERHEAD; - - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 2); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinyExtendedLength.HEADER_SIZE, buffer.length - TinyExtendedLength.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyExtendedLength.HEADER_SIZE, 2, 1); } } diff --git a/src/struct_frame/boilerplate/js/TinyExtendedMsgIds.js b/src/struct_frame/boilerplate/js/TinyExtendedMsgIds.js index 88c0ff0a..cbad6208 100644 --- a/src/struct_frame/boilerplate/js/TinyExtendedMsgIds.js +++ b/src/struct_frame/boilerplate/js/TinyExtendedMsgIds.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // TinyExtendedMsgIds Frame Format @@ -69,13 +73,13 @@ class TinyExtendedMsgIds { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - TinyExtendedMsgIds.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinyExtendedMsgIds.HEADER_SIZE, this.packet_size - TinyExtendedMsgIds.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinyExtendedMsgIds.HEADER_SIZE, 1, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinyExtendedMsgIdsParserState.LOOKING_FOR_START; } @@ -88,39 +92,22 @@ class TinyExtendedMsgIds { static encode(msg_id, msg) { const output = []; output.push(TinyExtendedMsgIds.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < TinyExtendedMsgIds.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinyExtendedMsgIds.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinyExtendedMsgIds.OVERHEAD; - - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinyExtendedMsgIds.HEADER_SIZE, buffer.length - TinyExtendedMsgIds.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyExtendedMsgIds.HEADER_SIZE, 1, 1); } } diff --git a/src/struct_frame/boilerplate/js/TinyExtendedMultiSystemStream.js b/src/struct_frame/boilerplate/js/TinyExtendedMultiSystemStream.js index e4a76f65..c108a4f8 100644 --- a/src/struct_frame/boilerplate/js/TinyExtendedMultiSystemStream.js +++ b/src/struct_frame/boilerplate/js/TinyExtendedMultiSystemStream.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // TinyExtendedMultiSystemStream Frame Format @@ -74,13 +78,13 @@ class TinyExtendedMultiSystemStream { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - TinyExtendedMultiSystemStream.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 2); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinyExtendedMultiSystemStream.HEADER_SIZE, this.packet_size - TinyExtendedMultiSystemStream.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinyExtendedMultiSystemStream.HEADER_SIZE, 2, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinyExtendedMultiSystemStreamParserState.LOOKING_FOR_START; } @@ -93,40 +97,22 @@ class TinyExtendedMultiSystemStream { static encode(msg_id, msg) { const output = []; output.push(TinyExtendedMultiSystemStream.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - output.push((msg.length >> 8) & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 2); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 1); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < TinyExtendedMultiSystemStream.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinyExtendedMultiSystemStream.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinyExtendedMultiSystemStream.OVERHEAD; - - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 2); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinyExtendedMultiSystemStream.HEADER_SIZE, buffer.length - TinyExtendedMultiSystemStream.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyExtendedMultiSystemStream.HEADER_SIZE, 2, 1); } } diff --git a/src/struct_frame/boilerplate/js/TinyMinimal.js b/src/struct_frame/boilerplate/js/TinyMinimal.js index 814e4321..dc703ef0 100644 --- a/src/struct_frame/boilerplate/js/TinyMinimal.js +++ b/src/struct_frame/boilerplate/js/TinyMinimal.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // TinyMinimal Frame Format @@ -68,10 +72,12 @@ class TinyMinimal { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = this.packet_size - TinyMinimal.OVERHEAD; - result.msg_data = new Uint8Array(this.buffer.slice(TinyMinimal.HEADER_SIZE)); + // Use shared minimal payload validation + const validationResult = validate_payload_minimal(this.buffer, TinyMinimal.HEADER_SIZE); + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; this.state = TinyMinimalParserState.LOOKING_FOR_START; } break; @@ -83,32 +89,22 @@ class TinyMinimal { static encode(msg_id, msg) { const output = []; output.push(TinyMinimal.START_BYTE); - output.push(msg_id); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } + // Use shared minimal payload encoding + encode_payload_minimal(output, msg_id, msg); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < TinyMinimal.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinyMinimal.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinyMinimal.OVERHEAD; - - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinyMinimal.HEADER_SIZE)); - - return result; + // Use shared minimal payload validation + return validate_payload_minimal(buffer, TinyMinimal.HEADER_SIZE); } } diff --git a/src/struct_frame/boilerplate/js/TinyMultiSystemStream.js b/src/struct_frame/boilerplate/js/TinyMultiSystemStream.js index 73926c16..b8eb8cfe 100644 --- a/src/struct_frame/boilerplate/js/TinyMultiSystemStream.js +++ b/src/struct_frame/boilerplate/js/TinyMultiSystemStream.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // TinyMultiSystemStream Frame Format @@ -69,13 +73,13 @@ class TinyMultiSystemStream { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - TinyMultiSystemStream.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinyMultiSystemStream.HEADER_SIZE, this.packet_size - TinyMultiSystemStream.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinyMultiSystemStream.HEADER_SIZE, 1, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinyMultiSystemStreamParserState.LOOKING_FOR_START; } @@ -88,39 +92,22 @@ class TinyMultiSystemStream { static encode(msg_id, msg) { const output = []; output.push(TinyMultiSystemStream.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < TinyMultiSystemStream.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinyMultiSystemStream.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinyMultiSystemStream.OVERHEAD; - - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinyMultiSystemStream.HEADER_SIZE, buffer.length - TinyMultiSystemStream.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyMultiSystemStream.HEADER_SIZE, 1, 1); } } diff --git a/src/struct_frame/boilerplate/js/TinySeq.js b/src/struct_frame/boilerplate/js/TinySeq.js index 7585fe35..931624dc 100644 --- a/src/struct_frame/boilerplate/js/TinySeq.js +++ b/src/struct_frame/boilerplate/js/TinySeq.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // TinySeq Frame Format @@ -69,13 +73,13 @@ class TinySeq { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - TinySeq.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinySeq.HEADER_SIZE, this.packet_size - TinySeq.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinySeq.HEADER_SIZE, 1, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinySeqParserState.LOOKING_FOR_START; } @@ -88,39 +92,22 @@ class TinySeq { static encode(msg_id, msg) { const output = []; output.push(TinySeq.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < TinySeq.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinySeq.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinySeq.OVERHEAD; - - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinySeq.HEADER_SIZE, buffer.length - TinySeq.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinySeq.HEADER_SIZE, 1, 1); } } diff --git a/src/struct_frame/boilerplate/js/TinySysComp.js b/src/struct_frame/boilerplate/js/TinySysComp.js index 9bb54a6a..17d05f9d 100644 --- a/src/struct_frame/boilerplate/js/TinySysComp.js +++ b/src/struct_frame/boilerplate/js/TinySysComp.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // TinySysComp Frame Format @@ -69,13 +73,13 @@ class TinySysComp { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - TinySysComp.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinySysComp.HEADER_SIZE, this.packet_size - TinySysComp.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinySysComp.HEADER_SIZE, 1, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinySysCompParserState.LOOKING_FOR_START; } @@ -88,39 +92,22 @@ class TinySysComp { static encode(msg_id, msg) { const output = []; output.push(TinySysComp.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < TinySysComp.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinySysComp.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinySysComp.OVERHEAD; - - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinySysComp.HEADER_SIZE, buffer.length - TinySysComp.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinySysComp.HEADER_SIZE, 1, 1); } } diff --git a/src/struct_frame/boilerplate/js/UbxFrame.js b/src/struct_frame/boilerplate/js/UbxFrame.js index 53c78983..4ef06951 100644 --- a/src/struct_frame/boilerplate/js/UbxFrame.js +++ b/src/struct_frame/boilerplate/js/UbxFrame.js @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -const { createFrameMsgInfo, fletcher_checksum } = require('./frame_base'); +const { + createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} = require('./frame_base'); // ============================================================================= // UbxFrame Frame Format @@ -83,13 +87,13 @@ class UbxFrame { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - const msg_length = this.packet_size - UbxFrame.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(UbxFrame.HEADER_SIZE, this.packet_size - UbxFrame.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, UbxFrame.HEADER_SIZE, 1, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = UbxFrameParserState.LOOKING_FOR_START1; } @@ -103,42 +107,25 @@ class UbxFrame { const output = []; output.push(UbxFrame.START_BYTE1); output.push(UbxFrame.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2); return new Uint8Array(output); } static validate_packet(buffer) { - const result = createFrameMsgInfo(); - if (buffer.length < UbxFrame.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== UbxFrame.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== UbxFrame.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - UbxFrame.OVERHEAD; - - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, UbxFrame.HEADER_SIZE, buffer.length - UbxFrame.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, UbxFrame.HEADER_SIZE, 1, 2); } } diff --git a/src/struct_frame/boilerplate/js/frame_base.js b/src/struct_frame/boilerplate/js/frame_base.js index a6cb8c3f..3e0164fb 100644 --- a/src/struct_frame/boilerplate/js/frame_base.js +++ b/src/struct_frame/boilerplate/js/frame_base.js @@ -1,5 +1,5 @@ // Automatically generated frame parser base utilities -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. // Frame format type enumeration const FrameFormatType = { @@ -54,8 +54,101 @@ function createFrameMsgInfo() { }; } +// ============================================================================= +// Shared Payload Parsing Functions +// ============================================================================= +// These functions handle payload validation/encoding independent of framing. +// Frame formats (Tiny/Basic) use these for the common parsing logic. + +/** + * Validate a payload with CRC (shared by Default, Extended, etc. payload types). + */ +function validate_payload_with_crc(buffer, headerSize, lengthBytes, crcStartOffset) { + const result = createFrameMsgInfo(); + const footerSize = 2; // CRC is always 2 bytes + const overhead = headerSize + footerSize; + + if (buffer.length < overhead) { + return result; + } + + const msgLength = buffer.length - overhead; + + // Calculate expected CRC range: from crcStartOffset to before the CRC bytes + const crcDataLen = msgLength + 1 + lengthBytes; // msg_id (1) + lengthBytes + payload + const ck = fletcher_checksum(buffer, crcStartOffset, crcStartOffset + crcDataLen); + + if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { + result.valid = true; + result.msg_id = buffer[headerSize - 1]; // msg_id is last byte of header + result.msg_len = msgLength; + result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, headerSize, buffer.length - footerSize)); + } + + return result; +} + +/** + * Validate a minimal payload (no CRC, no length field). + */ +function validate_payload_minimal(buffer, headerSize) { + const result = createFrameMsgInfo(); + + if (buffer.length < headerSize) { + return result; + } + + result.valid = true; + result.msg_id = buffer[headerSize - 1]; // msg_id is last byte of header + result.msg_len = buffer.length - headerSize; + result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, headerSize)); + + return result; +} + +/** + * Encode payload with length and CRC (modifies output array in place). + */ +function encode_payload_with_crc(output, msgId, msg, lengthBytes, crcStartOffset) { + // Add length field + if (lengthBytes === 1) { + output.push(msg.length & 0xFF); + } else { + output.push(msg.length & 0xFF); + output.push((msg.length >> 8) & 0xFF); + } + + // Add msg_id + output.push(msgId); + + // Add payload + for (let i = 0; i < msg.length; i++) { + output.push(msg[i]); + } + + // Calculate and add CRC + const crcDataLen = msg.length + 1 + lengthBytes; + const ck = fletcher_checksum(output, crcStartOffset, crcStartOffset + crcDataLen); + output.push(ck[0]); + output.push(ck[1]); +} + +/** + * Encode minimal payload (no length, no CRC). + */ +function encode_payload_minimal(output, msgId, msg) { + output.push(msgId); + for (let i = 0; i < msg.length; i++) { + output.push(msg[i]); + } +} + module.exports = { FrameFormatType, fletcher_checksum, createFrameMsgInfo, + validate_payload_with_crc, + validate_payload_minimal, + encode_payload_with_crc, + encode_payload_minimal, }; diff --git a/src/struct_frame/boilerplate/js/index.js b/src/struct_frame/boilerplate/js/index.js index c3434fb8..752867ed 100644 --- a/src/struct_frame/boilerplate/js/index.js +++ b/src/struct_frame/boilerplate/js/index.js @@ -1,5 +1,5 @@ // Automatically generated frame parser package -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. // Base utilities const frameBase = require('./frame_base'); diff --git a/src/struct_frame/boilerplate/py/__init__.py b/src/struct_frame/boilerplate/py/__init__.py index 2aebcb59..d5196f34 100644 --- a/src/struct_frame/boilerplate/py/__init__.py +++ b/src/struct_frame/boilerplate/py/__init__.py @@ -1,11 +1,16 @@ # Automatically generated frame parser package -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. # Base utilities from .frame_base import ( FrameFormatType, FrameMsgInfo, fletcher_checksum, + # Shared payload parsing functions + validate_payload_with_crc, + validate_payload_minimal, + encode_payload_with_crc, + encode_payload_minimal, ) # Individual frame format parsers @@ -38,6 +43,11 @@ "FrameFormatType", "FrameMsgInfo", "fletcher_checksum", + # Shared payload parsing functions + "validate_payload_with_crc", + "validate_payload_minimal", + "encode_payload_with_crc", + "encode_payload_minimal", # Frame formats "TinyMinimal", "TinyMinimalParserState", diff --git a/src/struct_frame/boilerplate/py/basic_default.py b/src/struct_frame/boilerplate/py/basic_default.py index 93fea600..c2636701 100644 --- a/src/struct_frame/boilerplate/py/basic_default.py +++ b/src/struct_frame/boilerplate/py/basic_default.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # BasicDefault Frame Format @@ -89,14 +93,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 2, 2 + msg_length + 1 + 1) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 1, 2) self.state = BasicDefaultParserState.LOOKING_FOR_START1 return result @@ -115,12 +113,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: output = [] output.append(self.START_BYTE1) output.append(self.START_BYTE2) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 2, 2 + len(msg) + 1 + 1) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -138,24 +132,13 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < BasicDefault.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != BasicDefault.START_BYTE1: - return result + return FrameMsgInfo() if buffer[1] != BasicDefault.START_BYTE2: - return result - - msg_length = len(buffer) - BasicDefault.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[2] - result.msg_len = msg_length - result.msg_data = bytes(buffer[BasicDefault.HEADER_SIZE:len(buffer) - BasicDefault.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicDefault.HEADER_SIZE, 1, 2) diff --git a/src/struct_frame/boilerplate/py/basic_extended.py b/src/struct_frame/boilerplate/py/basic_extended.py index cef13417..263e547d 100644 --- a/src/struct_frame/boilerplate/py/basic_extended.py +++ b/src/struct_frame/boilerplate/py/basic_extended.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # BasicExtended Frame Format @@ -93,14 +97,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 2, 2 + msg_length + 1 + 2) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 2, 2) self.state = BasicExtendedParserState.LOOKING_FOR_START1 return result @@ -119,13 +117,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: output = [] output.append(self.START_BYTE1) output.append(self.START_BYTE2) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.append((len(msg) >> 8) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 2, 2 + len(msg) + 1 + 2) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 2) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -143,24 +136,13 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < BasicExtended.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != BasicExtended.START_BYTE1: - return result + return FrameMsgInfo() if buffer[1] != BasicExtended.START_BYTE2: - return result - - msg_length = len(buffer) - BasicExtended.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 2) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[2] - result.msg_len = msg_length - result.msg_data = bytes(buffer[BasicExtended.HEADER_SIZE:len(buffer) - BasicExtended.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicExtended.HEADER_SIZE, 2, 2) diff --git a/src/struct_frame/boilerplate/py/basic_extended_length.py b/src/struct_frame/boilerplate/py/basic_extended_length.py index 1d490351..e71100f4 100644 --- a/src/struct_frame/boilerplate/py/basic_extended_length.py +++ b/src/struct_frame/boilerplate/py/basic_extended_length.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # BasicExtendedLength Frame Format @@ -93,14 +97,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 2, 2 + msg_length + 1 + 2) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 2, 2) self.state = BasicExtendedLengthParserState.LOOKING_FOR_START1 return result @@ -119,13 +117,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: output = [] output.append(self.START_BYTE1) output.append(self.START_BYTE2) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.append((len(msg) >> 8) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 2, 2 + len(msg) + 1 + 2) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 2) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -143,24 +136,13 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < BasicExtendedLength.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != BasicExtendedLength.START_BYTE1: - return result + return FrameMsgInfo() if buffer[1] != BasicExtendedLength.START_BYTE2: - return result - - msg_length = len(buffer) - BasicExtendedLength.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 2) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[2] - result.msg_len = msg_length - result.msg_data = bytes(buffer[BasicExtendedLength.HEADER_SIZE:len(buffer) - BasicExtendedLength.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicExtendedLength.HEADER_SIZE, 2, 2) diff --git a/src/struct_frame/boilerplate/py/basic_extended_msg_ids.py b/src/struct_frame/boilerplate/py/basic_extended_msg_ids.py index cf18c8eb..db795a6e 100644 --- a/src/struct_frame/boilerplate/py/basic_extended_msg_ids.py +++ b/src/struct_frame/boilerplate/py/basic_extended_msg_ids.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # BasicExtendedMsgIds Frame Format @@ -89,14 +93,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 2, 2 + msg_length + 1 + 1) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 1, 2) self.state = BasicExtendedMsgIdsParserState.LOOKING_FOR_START1 return result @@ -115,12 +113,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: output = [] output.append(self.START_BYTE1) output.append(self.START_BYTE2) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 2, 2 + len(msg) + 1 + 1) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -138,24 +132,13 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < BasicExtendedMsgIds.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != BasicExtendedMsgIds.START_BYTE1: - return result + return FrameMsgInfo() if buffer[1] != BasicExtendedMsgIds.START_BYTE2: - return result - - msg_length = len(buffer) - BasicExtendedMsgIds.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[2] - result.msg_len = msg_length - result.msg_data = bytes(buffer[BasicExtendedMsgIds.HEADER_SIZE:len(buffer) - BasicExtendedMsgIds.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicExtendedMsgIds.HEADER_SIZE, 1, 2) diff --git a/src/struct_frame/boilerplate/py/basic_extended_multi_system_stream.py b/src/struct_frame/boilerplate/py/basic_extended_multi_system_stream.py index b0b8a065..8648e728 100644 --- a/src/struct_frame/boilerplate/py/basic_extended_multi_system_stream.py +++ b/src/struct_frame/boilerplate/py/basic_extended_multi_system_stream.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # BasicExtendedMultiSystemStream Frame Format @@ -93,14 +97,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 2, 2 + msg_length + 1 + 2) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 2, 2) self.state = BasicExtendedMultiSystemStreamParserState.LOOKING_FOR_START1 return result @@ -119,13 +117,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: output = [] output.append(self.START_BYTE1) output.append(self.START_BYTE2) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.append((len(msg) >> 8) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 2, 2 + len(msg) + 1 + 2) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 2) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -143,24 +136,13 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < BasicExtendedMultiSystemStream.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != BasicExtendedMultiSystemStream.START_BYTE1: - return result + return FrameMsgInfo() if buffer[1] != BasicExtendedMultiSystemStream.START_BYTE2: - return result - - msg_length = len(buffer) - BasicExtendedMultiSystemStream.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 2) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[2] - result.msg_len = msg_length - result.msg_data = bytes(buffer[BasicExtendedMultiSystemStream.HEADER_SIZE:len(buffer) - BasicExtendedMultiSystemStream.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicExtendedMultiSystemStream.HEADER_SIZE, 2, 2) diff --git a/src/struct_frame/boilerplate/py/basic_minimal.py b/src/struct_frame/boilerplate/py/basic_minimal.py index 7d73f069..e68be2b8 100644 --- a/src/struct_frame/boilerplate/py/basic_minimal.py +++ b/src/struct_frame/boilerplate/py/basic_minimal.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # BasicMinimal Frame Format @@ -88,10 +92,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = self.packet_size - self.OVERHEAD - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:]) + # Use shared minimal payload validation + result = validate_payload_minimal(self.buffer, self.HEADER_SIZE) self.state = BasicMinimalParserState.LOOKING_FOR_START1 return result @@ -110,8 +112,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: output = [] output.append(self.START_BYTE1) output.append(self.START_BYTE2) - output.append(msg_id) - output.extend(msg) + # Use shared minimal payload encoding + encode_payload_minimal(output, msg_id, msg) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -129,21 +131,13 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < BasicMinimal.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != BasicMinimal.START_BYTE1: - return result + return FrameMsgInfo() if buffer[1] != BasicMinimal.START_BYTE2: - return result - - msg_length = len(buffer) - BasicMinimal.OVERHEAD + return FrameMsgInfo() - result.valid = True - result.msg_id = buffer[2] - result.msg_len = msg_length - result.msg_data = bytes(buffer[BasicMinimal.HEADER_SIZE:]) - - return result + # Use shared minimal payload validation + return validate_payload_minimal(buffer, BasicMinimal.HEADER_SIZE) diff --git a/src/struct_frame/boilerplate/py/basic_multi_system_stream.py b/src/struct_frame/boilerplate/py/basic_multi_system_stream.py index fda0a261..e665fa0c 100644 --- a/src/struct_frame/boilerplate/py/basic_multi_system_stream.py +++ b/src/struct_frame/boilerplate/py/basic_multi_system_stream.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # BasicMultiSystemStream Frame Format @@ -89,14 +93,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 2, 2 + msg_length + 1 + 1) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 1, 2) self.state = BasicMultiSystemStreamParserState.LOOKING_FOR_START1 return result @@ -115,12 +113,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: output = [] output.append(self.START_BYTE1) output.append(self.START_BYTE2) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 2, 2 + len(msg) + 1 + 1) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -138,24 +132,13 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < BasicMultiSystemStream.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != BasicMultiSystemStream.START_BYTE1: - return result + return FrameMsgInfo() if buffer[1] != BasicMultiSystemStream.START_BYTE2: - return result - - msg_length = len(buffer) - BasicMultiSystemStream.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[2] - result.msg_len = msg_length - result.msg_data = bytes(buffer[BasicMultiSystemStream.HEADER_SIZE:len(buffer) - BasicMultiSystemStream.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicMultiSystemStream.HEADER_SIZE, 1, 2) diff --git a/src/struct_frame/boilerplate/py/basic_seq.py b/src/struct_frame/boilerplate/py/basic_seq.py index 623d2aa9..9bc20793 100644 --- a/src/struct_frame/boilerplate/py/basic_seq.py +++ b/src/struct_frame/boilerplate/py/basic_seq.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # BasicSeq Frame Format @@ -89,14 +93,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 2, 2 + msg_length + 1 + 1) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 1, 2) self.state = BasicSeqParserState.LOOKING_FOR_START1 return result @@ -115,12 +113,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: output = [] output.append(self.START_BYTE1) output.append(self.START_BYTE2) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 2, 2 + len(msg) + 1 + 1) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -138,24 +132,13 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < BasicSeq.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != BasicSeq.START_BYTE1: - return result + return FrameMsgInfo() if buffer[1] != BasicSeq.START_BYTE2: - return result - - msg_length = len(buffer) - BasicSeq.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[2] - result.msg_len = msg_length - result.msg_data = bytes(buffer[BasicSeq.HEADER_SIZE:len(buffer) - BasicSeq.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicSeq.HEADER_SIZE, 1, 2) diff --git a/src/struct_frame/boilerplate/py/basic_sys_comp.py b/src/struct_frame/boilerplate/py/basic_sys_comp.py index 49a44f35..35bccbc8 100644 --- a/src/struct_frame/boilerplate/py/basic_sys_comp.py +++ b/src/struct_frame/boilerplate/py/basic_sys_comp.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # BasicSysComp Frame Format @@ -89,14 +93,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 2, 2 + msg_length + 1 + 1) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 1, 2) self.state = BasicSysCompParserState.LOOKING_FOR_START1 return result @@ -115,12 +113,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: output = [] output.append(self.START_BYTE1) output.append(self.START_BYTE2) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 2, 2 + len(msg) + 1 + 1) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -138,24 +132,13 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < BasicSysComp.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != BasicSysComp.START_BYTE1: - return result + return FrameMsgInfo() if buffer[1] != BasicSysComp.START_BYTE2: - return result - - msg_length = len(buffer) - BasicSysComp.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[2] - result.msg_len = msg_length - result.msg_data = bytes(buffer[BasicSysComp.HEADER_SIZE:len(buffer) - BasicSysComp.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicSysComp.HEADER_SIZE, 1, 2) diff --git a/src/struct_frame/boilerplate/py/frame_base.py b/src/struct_frame/boilerplate/py/frame_base.py index 558e5acb..5a32e6e7 100644 --- a/src/struct_frame/boilerplate/py/frame_base.py +++ b/src/struct_frame/boilerplate/py/frame_base.py @@ -1,5 +1,5 @@ # Automatically generated frame parser base utilities -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import List, Tuple, Union @@ -53,3 +53,114 @@ class FrameMsgInfo: msg_id: int = 0 msg_len: int = 0 msg_data: bytes = b'' + + +# ============================================================================= +# Shared Payload Parsing Functions +# ============================================================================= +# These functions handle payload validation/encoding independent of framing. +# Frame formats (Tiny/Basic) use these for the common parsing logic. + +def validate_payload_with_crc(buffer: Union[bytes, List[int]], header_size: int, + length_bytes: int, crc_start_offset: int = 0) -> FrameMsgInfo: + """ + Validate a payload with CRC (shared by Default, Extended, etc. payload types). + + Args: + buffer: Complete packet buffer (including any start bytes) + header_size: Size of header (start_bytes + length + msg_id + extra fields) + length_bytes: Number of length bytes (1 or 2) + crc_start_offset: Offset from start of buffer where CRC calculation begins + + Returns: + FrameMsgInfo with valid=True if checksum matches + """ + result = FrameMsgInfo() + footer_size = 2 # CRC is always 2 bytes + overhead = header_size + footer_size + + if len(buffer) < overhead: + return result + + msg_length = len(buffer) - overhead + + # Calculate expected CRC range: from crc_start_offset to before the CRC bytes + crc_data_len = msg_length + 1 + length_bytes # msg_id (1) + length_bytes + payload + ck = fletcher_checksum(buffer, crc_start_offset, crc_start_offset + crc_data_len) + + if ck[0] == buffer[-2] and ck[1] == buffer[-1]: + result.valid = True + result.msg_id = buffer[header_size - 1] # msg_id is last byte of header + result.msg_len = msg_length + result.msg_data = bytes(buffer[header_size:len(buffer) - footer_size]) + + return result + + +def validate_payload_minimal(buffer: Union[bytes, List[int]], header_size: int) -> FrameMsgInfo: + """ + Validate a minimal payload (no CRC, no length field). + + Args: + buffer: Complete packet buffer (including any start bytes) + header_size: Size of header (start_bytes + msg_id) + + Returns: + FrameMsgInfo with packet data + """ + result = FrameMsgInfo() + + if len(buffer) < header_size: + return result + + result.valid = True + result.msg_id = buffer[header_size - 1] # msg_id is last byte of header + result.msg_len = len(buffer) - header_size + result.msg_data = bytes(buffer[header_size:]) + + return result + + +def encode_payload_with_crc(output: list, msg_id: int, msg: bytes, + length_bytes: int, crc_start_offset: int) -> None: + """ + Encode payload with length and CRC (modifies output list in place). + + Args: + output: Output list to append to (already contains start bytes) + msg_id: Message ID + msg: Message payload data + length_bytes: Number of length bytes (1 or 2) + crc_start_offset: Offset in output where CRC calculation begins + """ + # Add length field + if length_bytes == 1: + output.append(len(msg) & 0xFF) + else: + output.append(len(msg) & 0xFF) + output.append((len(msg) >> 8) & 0xFF) + + # Add msg_id + output.append(msg_id) + + # Add payload + output.extend(msg) + + # Calculate and add CRC + crc_data_len = len(msg) + 1 + length_bytes + ck = fletcher_checksum(output, crc_start_offset, crc_start_offset + crc_data_len) + output.append(ck[0]) + output.append(ck[1]) + + +def encode_payload_minimal(output: list, msg_id: int, msg: bytes) -> None: + """ + Encode minimal payload (no length, no CRC). + + Args: + output: Output list to append to (already contains start bytes) + msg_id: Message ID + msg: Message payload data + """ + output.append(msg_id) + output.extend(msg) diff --git a/src/struct_frame/boilerplate/py/frame_format_config.py b/src/struct_frame/boilerplate/py/frame_format_config.py index b0ccf4c2..c375e105 100644 --- a/src/struct_frame/boilerplate/py/frame_format_config.py +++ b/src/struct_frame/boilerplate/py/frame_format_config.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # FrameFormatConfig Frame Format @@ -88,14 +92,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 2, 2 + msg_length + 1) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 0, 2) self.state = FrameFormatConfigParserState.LOOKING_FOR_START1 return result @@ -114,11 +112,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: output = [] output.append(self.START_BYTE1) output.append(self.START_BYTE2) - output.append(msg_id) - output.extend(msg) - ck = fletcher_checksum(output, 2, 2 + len(msg) + 1) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 0, 2) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -136,24 +131,13 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < FrameFormatConfig.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != FrameFormatConfig.START_BYTE1: - return result + return FrameMsgInfo() if buffer[1] != FrameFormatConfig.START_BYTE2: - return result - - msg_length = len(buffer) - FrameFormatConfig.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[2] - result.msg_len = msg_length - result.msg_data = bytes(buffer[FrameFormatConfig.HEADER_SIZE:len(buffer) - FrameFormatConfig.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, FrameFormatConfig.HEADER_SIZE, 0, 2) diff --git a/src/struct_frame/boilerplate/py/mavlink_v1_frame.py b/src/struct_frame/boilerplate/py/mavlink_v1_frame.py index 96333fbe..b351009c 100644 --- a/src/struct_frame/boilerplate/py/mavlink_v1_frame.py +++ b/src/struct_frame/boilerplate/py/mavlink_v1_frame.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # MavlinkV1Frame Frame Format @@ -77,14 +81,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 1, 1 + msg_length + 1 + 1) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 1, 1) self.state = MavlinkV1FrameParserState.LOOKING_FOR_START return result @@ -102,12 +100,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: """ output = [] output.append(self.START_BYTE) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 1, 1 + len(msg) + 1 + 1) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -125,22 +119,11 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < MavlinkV1Frame.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != MavlinkV1Frame.START_BYTE: - return result - - msg_length = len(buffer) - MavlinkV1Frame.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[1] - result.msg_len = msg_length - result.msg_data = bytes(buffer[MavlinkV1Frame.HEADER_SIZE:len(buffer) - MavlinkV1Frame.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, MavlinkV1Frame.HEADER_SIZE, 1, 1) diff --git a/src/struct_frame/boilerplate/py/mavlink_v2_frame.py b/src/struct_frame/boilerplate/py/mavlink_v2_frame.py index d653cbe1..a046e81b 100644 --- a/src/struct_frame/boilerplate/py/mavlink_v2_frame.py +++ b/src/struct_frame/boilerplate/py/mavlink_v2_frame.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # MavlinkV2Frame Frame Format @@ -77,14 +81,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 1, 1 + msg_length + 1 + 1) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 1, 1) self.state = MavlinkV2FrameParserState.LOOKING_FOR_START return result @@ -102,12 +100,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: """ output = [] output.append(self.START_BYTE) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 1, 1 + len(msg) + 1 + 1) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -125,22 +119,11 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < MavlinkV2Frame.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != MavlinkV2Frame.START_BYTE: - return result - - msg_length = len(buffer) - MavlinkV2Frame.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[1] - result.msg_len = msg_length - result.msg_data = bytes(buffer[MavlinkV2Frame.HEADER_SIZE:len(buffer) - MavlinkV2Frame.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, MavlinkV2Frame.HEADER_SIZE, 1, 1) diff --git a/src/struct_frame/boilerplate/py/tiny_default.py b/src/struct_frame/boilerplate/py/tiny_default.py index 25efcd78..c085c255 100644 --- a/src/struct_frame/boilerplate/py/tiny_default.py +++ b/src/struct_frame/boilerplate/py/tiny_default.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # TinyDefault Frame Format @@ -77,14 +81,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 1, 1 + msg_length + 1 + 1) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 1, 1) self.state = TinyDefaultParserState.LOOKING_FOR_START return result @@ -102,12 +100,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: """ output = [] output.append(self.START_BYTE) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 1, 1 + len(msg) + 1 + 1) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -125,22 +119,11 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < TinyDefault.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != TinyDefault.START_BYTE: - return result - - msg_length = len(buffer) - TinyDefault.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[1] - result.msg_len = msg_length - result.msg_data = bytes(buffer[TinyDefault.HEADER_SIZE:len(buffer) - TinyDefault.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyDefault.HEADER_SIZE, 1, 1) diff --git a/src/struct_frame/boilerplate/py/tiny_extended.py b/src/struct_frame/boilerplate/py/tiny_extended.py index c6bf322d..9f72a0cb 100644 --- a/src/struct_frame/boilerplate/py/tiny_extended.py +++ b/src/struct_frame/boilerplate/py/tiny_extended.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # TinyExtended Frame Format @@ -81,14 +85,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 1, 1 + msg_length + 1 + 2) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 2, 1) self.state = TinyExtendedParserState.LOOKING_FOR_START return result @@ -106,13 +104,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: """ output = [] output.append(self.START_BYTE) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.append((len(msg) >> 8) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 1, 1 + len(msg) + 1 + 2) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 1) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -130,22 +123,11 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < TinyExtended.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != TinyExtended.START_BYTE: - return result - - msg_length = len(buffer) - TinyExtended.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 2) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[1] - result.msg_len = msg_length - result.msg_data = bytes(buffer[TinyExtended.HEADER_SIZE:len(buffer) - TinyExtended.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyExtended.HEADER_SIZE, 2, 1) diff --git a/src/struct_frame/boilerplate/py/tiny_extended_length.py b/src/struct_frame/boilerplate/py/tiny_extended_length.py index 87214843..4b57fa05 100644 --- a/src/struct_frame/boilerplate/py/tiny_extended_length.py +++ b/src/struct_frame/boilerplate/py/tiny_extended_length.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # TinyExtendedLength Frame Format @@ -81,14 +85,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 1, 1 + msg_length + 1 + 2) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 2, 1) self.state = TinyExtendedLengthParserState.LOOKING_FOR_START return result @@ -106,13 +104,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: """ output = [] output.append(self.START_BYTE) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.append((len(msg) >> 8) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 1, 1 + len(msg) + 1 + 2) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 1) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -130,22 +123,11 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < TinyExtendedLength.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != TinyExtendedLength.START_BYTE: - return result - - msg_length = len(buffer) - TinyExtendedLength.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 2) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[1] - result.msg_len = msg_length - result.msg_data = bytes(buffer[TinyExtendedLength.HEADER_SIZE:len(buffer) - TinyExtendedLength.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyExtendedLength.HEADER_SIZE, 2, 1) diff --git a/src/struct_frame/boilerplate/py/tiny_extended_msg_ids.py b/src/struct_frame/boilerplate/py/tiny_extended_msg_ids.py index a8d4d6db..bed30ef2 100644 --- a/src/struct_frame/boilerplate/py/tiny_extended_msg_ids.py +++ b/src/struct_frame/boilerplate/py/tiny_extended_msg_ids.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # TinyExtendedMsgIds Frame Format @@ -77,14 +81,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 1, 1 + msg_length + 1 + 1) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 1, 1) self.state = TinyExtendedMsgIdsParserState.LOOKING_FOR_START return result @@ -102,12 +100,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: """ output = [] output.append(self.START_BYTE) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 1, 1 + len(msg) + 1 + 1) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -125,22 +119,11 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < TinyExtendedMsgIds.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != TinyExtendedMsgIds.START_BYTE: - return result - - msg_length = len(buffer) - TinyExtendedMsgIds.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[1] - result.msg_len = msg_length - result.msg_data = bytes(buffer[TinyExtendedMsgIds.HEADER_SIZE:len(buffer) - TinyExtendedMsgIds.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyExtendedMsgIds.HEADER_SIZE, 1, 1) diff --git a/src/struct_frame/boilerplate/py/tiny_extended_multi_system_stream.py b/src/struct_frame/boilerplate/py/tiny_extended_multi_system_stream.py index 70adf9d9..1f8b6adb 100644 --- a/src/struct_frame/boilerplate/py/tiny_extended_multi_system_stream.py +++ b/src/struct_frame/boilerplate/py/tiny_extended_multi_system_stream.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # TinyExtendedMultiSystemStream Frame Format @@ -81,14 +85,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 1, 1 + msg_length + 1 + 2) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 2, 1) self.state = TinyExtendedMultiSystemStreamParserState.LOOKING_FOR_START return result @@ -106,13 +104,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: """ output = [] output.append(self.START_BYTE) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.append((len(msg) >> 8) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 1, 1 + len(msg) + 1 + 2) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 1) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -130,22 +123,11 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < TinyExtendedMultiSystemStream.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != TinyExtendedMultiSystemStream.START_BYTE: - return result - - msg_length = len(buffer) - TinyExtendedMultiSystemStream.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 2) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[1] - result.msg_len = msg_length - result.msg_data = bytes(buffer[TinyExtendedMultiSystemStream.HEADER_SIZE:len(buffer) - TinyExtendedMultiSystemStream.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyExtendedMultiSystemStream.HEADER_SIZE, 2, 1) diff --git a/src/struct_frame/boilerplate/py/tiny_minimal.py b/src/struct_frame/boilerplate/py/tiny_minimal.py index 3ef9e57d..eeccb9c7 100644 --- a/src/struct_frame/boilerplate/py/tiny_minimal.py +++ b/src/struct_frame/boilerplate/py/tiny_minimal.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # TinyMinimal Frame Format @@ -76,10 +80,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = self.packet_size - self.OVERHEAD - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:]) + # Use shared minimal payload validation + result = validate_payload_minimal(self.buffer, self.HEADER_SIZE) self.state = TinyMinimalParserState.LOOKING_FOR_START return result @@ -97,8 +99,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: """ output = [] output.append(self.START_BYTE) - output.append(msg_id) - output.extend(msg) + # Use shared minimal payload encoding + encode_payload_minimal(output, msg_id, msg) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -116,19 +118,11 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < TinyMinimal.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != TinyMinimal.START_BYTE: - return result - - msg_length = len(buffer) - TinyMinimal.OVERHEAD + return FrameMsgInfo() - result.valid = True - result.msg_id = buffer[1] - result.msg_len = msg_length - result.msg_data = bytes(buffer[TinyMinimal.HEADER_SIZE:]) - - return result + # Use shared minimal payload validation + return validate_payload_minimal(buffer, TinyMinimal.HEADER_SIZE) diff --git a/src/struct_frame/boilerplate/py/tiny_multi_system_stream.py b/src/struct_frame/boilerplate/py/tiny_multi_system_stream.py index 721d6889..10f43174 100644 --- a/src/struct_frame/boilerplate/py/tiny_multi_system_stream.py +++ b/src/struct_frame/boilerplate/py/tiny_multi_system_stream.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # TinyMultiSystemStream Frame Format @@ -77,14 +81,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 1, 1 + msg_length + 1 + 1) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 1, 1) self.state = TinyMultiSystemStreamParserState.LOOKING_FOR_START return result @@ -102,12 +100,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: """ output = [] output.append(self.START_BYTE) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 1, 1 + len(msg) + 1 + 1) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -125,22 +119,11 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < TinyMultiSystemStream.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != TinyMultiSystemStream.START_BYTE: - return result - - msg_length = len(buffer) - TinyMultiSystemStream.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[1] - result.msg_len = msg_length - result.msg_data = bytes(buffer[TinyMultiSystemStream.HEADER_SIZE:len(buffer) - TinyMultiSystemStream.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyMultiSystemStream.HEADER_SIZE, 1, 1) diff --git a/src/struct_frame/boilerplate/py/tiny_seq.py b/src/struct_frame/boilerplate/py/tiny_seq.py index 39797efe..92b57f2f 100644 --- a/src/struct_frame/boilerplate/py/tiny_seq.py +++ b/src/struct_frame/boilerplate/py/tiny_seq.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # TinySeq Frame Format @@ -77,14 +81,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 1, 1 + msg_length + 1 + 1) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 1, 1) self.state = TinySeqParserState.LOOKING_FOR_START return result @@ -102,12 +100,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: """ output = [] output.append(self.START_BYTE) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 1, 1 + len(msg) + 1 + 1) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -125,22 +119,11 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < TinySeq.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != TinySeq.START_BYTE: - return result - - msg_length = len(buffer) - TinySeq.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[1] - result.msg_len = msg_length - result.msg_data = bytes(buffer[TinySeq.HEADER_SIZE:len(buffer) - TinySeq.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinySeq.HEADER_SIZE, 1, 1) diff --git a/src/struct_frame/boilerplate/py/tiny_sys_comp.py b/src/struct_frame/boilerplate/py/tiny_sys_comp.py index f2310ecb..c4a40e32 100644 --- a/src/struct_frame/boilerplate/py/tiny_sys_comp.py +++ b/src/struct_frame/boilerplate/py/tiny_sys_comp.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # TinySysComp Frame Format @@ -77,14 +81,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 1, 1 + msg_length + 1 + 1) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 1, 1) self.state = TinySysCompParserState.LOOKING_FOR_START return result @@ -102,12 +100,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: """ output = [] output.append(self.START_BYTE) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 1, 1 + len(msg) + 1 + 1) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -125,22 +119,11 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < TinySysComp.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != TinySysComp.START_BYTE: - return result - - msg_length = len(buffer) - TinySysComp.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[1] - result.msg_len = msg_length - result.msg_data = bytes(buffer[TinySysComp.HEADER_SIZE:len(buffer) - TinySysComp.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinySysComp.HEADER_SIZE, 1, 1) diff --git a/src/struct_frame/boilerplate/py/ubx_frame.py b/src/struct_frame/boilerplate/py/ubx_frame.py index cf048fe5..6938ee7b 100644 --- a/src/struct_frame/boilerplate/py/ubx_frame.py +++ b/src/struct_frame/boilerplate/py/ubx_frame.py @@ -1,9 +1,13 @@ # Automatically generated frame parser -# Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +# Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. from enum import Enum from typing import Callable, List, Union -from .frame_base import FrameMsgInfo, fletcher_checksum +from .frame_base import ( + FrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +) # ============================================================================= # UbxFrame Frame Format @@ -89,14 +93,8 @@ def parse_byte(self, byte: int) -> FrameMsgInfo: self.buffer.append(byte) if len(self.buffer) >= self.packet_size: - # Validate checksum - msg_length = self.packet_size - self.OVERHEAD - ck = fletcher_checksum(self.buffer, 2, 2 + msg_length + 1 + 1) - if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]: - result.valid = True - result.msg_id = self.msg_id - result.msg_len = msg_length - result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE]) + # Use shared payload validation with CRC + result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, 1, 2) self.state = UbxFrameParserState.LOOKING_FOR_START1 return result @@ -115,12 +113,8 @@ def encode(self, msg_id: int, msg: bytes) -> bytes: output = [] output.append(self.START_BYTE1) output.append(self.START_BYTE2) - output.append(msg_id) - output.append(len(msg) & 0xFF) - output.extend(msg) - ck = fletcher_checksum(output, 2, 2 + len(msg) + 1 + 1) - output.append(ck[0]) - output.append(ck[1]) + # Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2) return bytes(output) def encode_msg(self, msg) -> bytes: @@ -138,24 +132,13 @@ def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo: Returns: FrameMsgInfo with valid=True if packet is valid """ - result = FrameMsgInfo() - if len(buffer) < UbxFrame.OVERHEAD: - return result + return FrameMsgInfo() if buffer[0] != UbxFrame.START_BYTE1: - return result + return FrameMsgInfo() if buffer[1] != UbxFrame.START_BYTE2: - return result - - msg_length = len(buffer) - UbxFrame.OVERHEAD + return FrameMsgInfo() - # Validate checksum - ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1) - if ck[0] == buffer[-2] and ck[1] == buffer[-1]: - result.valid = True - result.msg_id = buffer[2] - result.msg_len = msg_length - result.msg_data = bytes(buffer[UbxFrame.HEADER_SIZE:len(buffer) - UbxFrame.FOOTER_SIZE]) - - return result + # Use shared payload validation with CRC + return validate_payload_with_crc(buffer, UbxFrame.HEADER_SIZE, 1, 2) diff --git a/src/struct_frame/boilerplate/ts/BasicDefault.ts b/src/struct_frame/boilerplate/ts/BasicDefault.ts index 64b08bb3..49ff2901 100644 --- a/src/struct_frame/boilerplate/ts/BasicDefault.ts +++ b/src/struct_frame/boilerplate/ts/BasicDefault.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // BasicDefault Frame Format @@ -102,14 +106,13 @@ export class BasicDefault { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - BasicDefault.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicDefault.HEADER_SIZE, this.packet_size - BasicDefault.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicDefault.HEADER_SIZE, 1, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicDefaultParserState.LOOKING_FOR_START1; } @@ -129,14 +132,8 @@ export class BasicDefault { const output: number[] = []; output.push(BasicDefault.START_BYTE1); output.push(BasicDefault.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2); return new Uint8Array(output); } @@ -146,30 +143,18 @@ export class BasicDefault { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < BasicDefault.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicDefault.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicDefault.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicDefault.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicDefault.HEADER_SIZE, buffer.length - BasicDefault.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicDefault.HEADER_SIZE, 1, 2); } } diff --git a/src/struct_frame/boilerplate/ts/BasicExtended.ts b/src/struct_frame/boilerplate/ts/BasicExtended.ts index 3771dcad..ff76fdbd 100644 --- a/src/struct_frame/boilerplate/ts/BasicExtended.ts +++ b/src/struct_frame/boilerplate/ts/BasicExtended.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // BasicExtended Frame Format @@ -108,14 +112,13 @@ export class BasicExtended { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - BasicExtended.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 2); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicExtended.HEADER_SIZE, this.packet_size - BasicExtended.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicExtended.HEADER_SIZE, 2, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicExtendedParserState.LOOKING_FOR_START1; } @@ -135,15 +138,8 @@ export class BasicExtended { const output: number[] = []; output.push(BasicExtended.START_BYTE1); output.push(BasicExtended.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - output.push((msg.length >> 8) & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 2); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 2); return new Uint8Array(output); } @@ -153,30 +149,18 @@ export class BasicExtended { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < BasicExtended.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicExtended.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicExtended.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicExtended.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 2); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicExtended.HEADER_SIZE, buffer.length - BasicExtended.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicExtended.HEADER_SIZE, 2, 2); } } diff --git a/src/struct_frame/boilerplate/ts/BasicExtendedLength.ts b/src/struct_frame/boilerplate/ts/BasicExtendedLength.ts index 2605cbe0..46788e2b 100644 --- a/src/struct_frame/boilerplate/ts/BasicExtendedLength.ts +++ b/src/struct_frame/boilerplate/ts/BasicExtendedLength.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // BasicExtendedLength Frame Format @@ -108,14 +112,13 @@ export class BasicExtendedLength { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - BasicExtendedLength.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 2); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicExtendedLength.HEADER_SIZE, this.packet_size - BasicExtendedLength.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicExtendedLength.HEADER_SIZE, 2, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicExtendedLengthParserState.LOOKING_FOR_START1; } @@ -135,15 +138,8 @@ export class BasicExtendedLength { const output: number[] = []; output.push(BasicExtendedLength.START_BYTE1); output.push(BasicExtendedLength.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - output.push((msg.length >> 8) & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 2); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 2); return new Uint8Array(output); } @@ -153,30 +149,18 @@ export class BasicExtendedLength { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < BasicExtendedLength.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicExtendedLength.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicExtendedLength.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicExtendedLength.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 2); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicExtendedLength.HEADER_SIZE, buffer.length - BasicExtendedLength.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicExtendedLength.HEADER_SIZE, 2, 2); } } diff --git a/src/struct_frame/boilerplate/ts/BasicExtendedMsgIds.ts b/src/struct_frame/boilerplate/ts/BasicExtendedMsgIds.ts index 18df02be..de274a05 100644 --- a/src/struct_frame/boilerplate/ts/BasicExtendedMsgIds.ts +++ b/src/struct_frame/boilerplate/ts/BasicExtendedMsgIds.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // BasicExtendedMsgIds Frame Format @@ -102,14 +106,13 @@ export class BasicExtendedMsgIds { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - BasicExtendedMsgIds.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicExtendedMsgIds.HEADER_SIZE, this.packet_size - BasicExtendedMsgIds.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicExtendedMsgIds.HEADER_SIZE, 1, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicExtendedMsgIdsParserState.LOOKING_FOR_START1; } @@ -129,14 +132,8 @@ export class BasicExtendedMsgIds { const output: number[] = []; output.push(BasicExtendedMsgIds.START_BYTE1); output.push(BasicExtendedMsgIds.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2); return new Uint8Array(output); } @@ -146,30 +143,18 @@ export class BasicExtendedMsgIds { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < BasicExtendedMsgIds.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicExtendedMsgIds.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicExtendedMsgIds.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicExtendedMsgIds.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicExtendedMsgIds.HEADER_SIZE, buffer.length - BasicExtendedMsgIds.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicExtendedMsgIds.HEADER_SIZE, 1, 2); } } diff --git a/src/struct_frame/boilerplate/ts/BasicExtendedMultiSystemStream.ts b/src/struct_frame/boilerplate/ts/BasicExtendedMultiSystemStream.ts index f8a6800a..de25edef 100644 --- a/src/struct_frame/boilerplate/ts/BasicExtendedMultiSystemStream.ts +++ b/src/struct_frame/boilerplate/ts/BasicExtendedMultiSystemStream.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // BasicExtendedMultiSystemStream Frame Format @@ -108,14 +112,13 @@ export class BasicExtendedMultiSystemStream { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - BasicExtendedMultiSystemStream.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 2); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicExtendedMultiSystemStream.HEADER_SIZE, this.packet_size - BasicExtendedMultiSystemStream.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicExtendedMultiSystemStream.HEADER_SIZE, 2, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicExtendedMultiSystemStreamParserState.LOOKING_FOR_START1; } @@ -135,15 +138,8 @@ export class BasicExtendedMultiSystemStream { const output: number[] = []; output.push(BasicExtendedMultiSystemStream.START_BYTE1); output.push(BasicExtendedMultiSystemStream.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - output.push((msg.length >> 8) & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 2); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 2); return new Uint8Array(output); } @@ -153,30 +149,18 @@ export class BasicExtendedMultiSystemStream { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < BasicExtendedMultiSystemStream.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicExtendedMultiSystemStream.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicExtendedMultiSystemStream.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicExtendedMultiSystemStream.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 2); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicExtendedMultiSystemStream.HEADER_SIZE, buffer.length - BasicExtendedMultiSystemStream.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicExtendedMultiSystemStream.HEADER_SIZE, 2, 2); } } diff --git a/src/struct_frame/boilerplate/ts/BasicMinimal.ts b/src/struct_frame/boilerplate/ts/BasicMinimal.ts index b08ba744..8a8362d2 100644 --- a/src/struct_frame/boilerplate/ts/BasicMinimal.ts +++ b/src/struct_frame/boilerplate/ts/BasicMinimal.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // BasicMinimal Frame Format @@ -100,10 +104,12 @@ export class BasicMinimal { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = this.packet_size - BasicMinimal.OVERHEAD; - result.msg_data = new Uint8Array(this.buffer.slice(BasicMinimal.HEADER_SIZE)); + // Use shared minimal payload validation + const validationResult = validate_payload_minimal(this.buffer, BasicMinimal.HEADER_SIZE); + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; this.state = BasicMinimalParserState.LOOKING_FOR_START1; } break; @@ -122,10 +128,8 @@ export class BasicMinimal { const output: number[] = []; output.push(BasicMinimal.START_BYTE1); output.push(BasicMinimal.START_BYTE2); - output.push(msg_id); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } + // Use shared minimal payload encoding + encode_payload_minimal(output, msg_id, msg); return new Uint8Array(output); } @@ -135,26 +139,18 @@ export class BasicMinimal { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < BasicMinimal.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicMinimal.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicMinimal.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicMinimal.OVERHEAD; - - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicMinimal.HEADER_SIZE)); - - return result; + // Use shared minimal payload validation + return validate_payload_minimal(buffer, BasicMinimal.HEADER_SIZE); } } diff --git a/src/struct_frame/boilerplate/ts/BasicMultiSystemStream.ts b/src/struct_frame/boilerplate/ts/BasicMultiSystemStream.ts index 6cd2cef2..7464f456 100644 --- a/src/struct_frame/boilerplate/ts/BasicMultiSystemStream.ts +++ b/src/struct_frame/boilerplate/ts/BasicMultiSystemStream.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // BasicMultiSystemStream Frame Format @@ -102,14 +106,13 @@ export class BasicMultiSystemStream { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - BasicMultiSystemStream.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicMultiSystemStream.HEADER_SIZE, this.packet_size - BasicMultiSystemStream.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicMultiSystemStream.HEADER_SIZE, 1, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicMultiSystemStreamParserState.LOOKING_FOR_START1; } @@ -129,14 +132,8 @@ export class BasicMultiSystemStream { const output: number[] = []; output.push(BasicMultiSystemStream.START_BYTE1); output.push(BasicMultiSystemStream.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2); return new Uint8Array(output); } @@ -146,30 +143,18 @@ export class BasicMultiSystemStream { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < BasicMultiSystemStream.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicMultiSystemStream.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicMultiSystemStream.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicMultiSystemStream.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicMultiSystemStream.HEADER_SIZE, buffer.length - BasicMultiSystemStream.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicMultiSystemStream.HEADER_SIZE, 1, 2); } } diff --git a/src/struct_frame/boilerplate/ts/BasicSeq.ts b/src/struct_frame/boilerplate/ts/BasicSeq.ts index 4a684e36..551c357d 100644 --- a/src/struct_frame/boilerplate/ts/BasicSeq.ts +++ b/src/struct_frame/boilerplate/ts/BasicSeq.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // BasicSeq Frame Format @@ -102,14 +106,13 @@ export class BasicSeq { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - BasicSeq.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicSeq.HEADER_SIZE, this.packet_size - BasicSeq.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicSeq.HEADER_SIZE, 1, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicSeqParserState.LOOKING_FOR_START1; } @@ -129,14 +132,8 @@ export class BasicSeq { const output: number[] = []; output.push(BasicSeq.START_BYTE1); output.push(BasicSeq.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2); return new Uint8Array(output); } @@ -146,30 +143,18 @@ export class BasicSeq { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < BasicSeq.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicSeq.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicSeq.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicSeq.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicSeq.HEADER_SIZE, buffer.length - BasicSeq.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicSeq.HEADER_SIZE, 1, 2); } } diff --git a/src/struct_frame/boilerplate/ts/BasicSysComp.ts b/src/struct_frame/boilerplate/ts/BasicSysComp.ts index 6af82076..7e86fe1c 100644 --- a/src/struct_frame/boilerplate/ts/BasicSysComp.ts +++ b/src/struct_frame/boilerplate/ts/BasicSysComp.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // BasicSysComp Frame Format @@ -102,14 +106,13 @@ export class BasicSysComp { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - BasicSysComp.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(BasicSysComp.HEADER_SIZE, this.packet_size - BasicSysComp.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, BasicSysComp.HEADER_SIZE, 1, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = BasicSysCompParserState.LOOKING_FOR_START1; } @@ -129,14 +132,8 @@ export class BasicSysComp { const output: number[] = []; output.push(BasicSysComp.START_BYTE1); output.push(BasicSysComp.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2); return new Uint8Array(output); } @@ -146,30 +143,18 @@ export class BasicSysComp { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < BasicSysComp.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== BasicSysComp.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== BasicSysComp.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - BasicSysComp.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, BasicSysComp.HEADER_SIZE, buffer.length - BasicSysComp.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, BasicSysComp.HEADER_SIZE, 1, 2); } } diff --git a/src/struct_frame/boilerplate/ts/FrameFormatConfig.ts b/src/struct_frame/boilerplate/ts/FrameFormatConfig.ts index 60774f83..aa85962a 100644 --- a/src/struct_frame/boilerplate/ts/FrameFormatConfig.ts +++ b/src/struct_frame/boilerplate/ts/FrameFormatConfig.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // FrameFormatConfig Frame Format @@ -100,14 +104,13 @@ export class FrameFormatConfig { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - FrameFormatConfig.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(FrameFormatConfig.HEADER_SIZE, this.packet_size - FrameFormatConfig.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, FrameFormatConfig.HEADER_SIZE, 0, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = FrameFormatConfigParserState.LOOKING_FOR_START1; } @@ -127,13 +130,8 @@ export class FrameFormatConfig { const output: number[] = []; output.push(FrameFormatConfig.START_BYTE1); output.push(FrameFormatConfig.START_BYTE2); - output.push(msg_id); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 0, 2); return new Uint8Array(output); } @@ -143,30 +141,18 @@ export class FrameFormatConfig { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < FrameFormatConfig.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== FrameFormatConfig.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== FrameFormatConfig.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - FrameFormatConfig.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, FrameFormatConfig.HEADER_SIZE, buffer.length - FrameFormatConfig.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, FrameFormatConfig.HEADER_SIZE, 0, 2); } } diff --git a/src/struct_frame/boilerplate/ts/MavlinkV1Frame.ts b/src/struct_frame/boilerplate/ts/MavlinkV1Frame.ts index 77349218..6fa25b04 100644 --- a/src/struct_frame/boilerplate/ts/MavlinkV1Frame.ts +++ b/src/struct_frame/boilerplate/ts/MavlinkV1Frame.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // MavlinkV1Frame Frame Format @@ -88,14 +92,13 @@ export class MavlinkV1Frame { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - MavlinkV1Frame.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(MavlinkV1Frame.HEADER_SIZE, this.packet_size - MavlinkV1Frame.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, MavlinkV1Frame.HEADER_SIZE, 1, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = MavlinkV1FrameParserState.LOOKING_FOR_START; } @@ -114,14 +117,8 @@ export class MavlinkV1Frame { static encode(msg_id: number, msg: Uint8Array | number[]): Uint8Array { const output: number[] = []; output.push(MavlinkV1Frame.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1); return new Uint8Array(output); } @@ -131,27 +128,15 @@ export class MavlinkV1Frame { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < MavlinkV1Frame.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== MavlinkV1Frame.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - MavlinkV1Frame.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, MavlinkV1Frame.HEADER_SIZE, buffer.length - MavlinkV1Frame.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, MavlinkV1Frame.HEADER_SIZE, 1, 1); } } diff --git a/src/struct_frame/boilerplate/ts/MavlinkV2Frame.ts b/src/struct_frame/boilerplate/ts/MavlinkV2Frame.ts index 47df48c2..1c5bdef9 100644 --- a/src/struct_frame/boilerplate/ts/MavlinkV2Frame.ts +++ b/src/struct_frame/boilerplate/ts/MavlinkV2Frame.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // MavlinkV2Frame Frame Format @@ -88,14 +92,13 @@ export class MavlinkV2Frame { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - MavlinkV2Frame.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(MavlinkV2Frame.HEADER_SIZE, this.packet_size - MavlinkV2Frame.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, MavlinkV2Frame.HEADER_SIZE, 1, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = MavlinkV2FrameParserState.LOOKING_FOR_START; } @@ -114,14 +117,8 @@ export class MavlinkV2Frame { static encode(msg_id: number, msg: Uint8Array | number[]): Uint8Array { const output: number[] = []; output.push(MavlinkV2Frame.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1); return new Uint8Array(output); } @@ -131,27 +128,15 @@ export class MavlinkV2Frame { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < MavlinkV2Frame.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== MavlinkV2Frame.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - MavlinkV2Frame.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, MavlinkV2Frame.HEADER_SIZE, buffer.length - MavlinkV2Frame.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, MavlinkV2Frame.HEADER_SIZE, 1, 1); } } diff --git a/src/struct_frame/boilerplate/ts/TinyDefault.ts b/src/struct_frame/boilerplate/ts/TinyDefault.ts index 8a14d075..66f376a2 100644 --- a/src/struct_frame/boilerplate/ts/TinyDefault.ts +++ b/src/struct_frame/boilerplate/ts/TinyDefault.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // TinyDefault Frame Format @@ -88,14 +92,13 @@ export class TinyDefault { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - TinyDefault.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinyDefault.HEADER_SIZE, this.packet_size - TinyDefault.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinyDefault.HEADER_SIZE, 1, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinyDefaultParserState.LOOKING_FOR_START; } @@ -114,14 +117,8 @@ export class TinyDefault { static encode(msg_id: number, msg: Uint8Array | number[]): Uint8Array { const output: number[] = []; output.push(TinyDefault.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1); return new Uint8Array(output); } @@ -131,27 +128,15 @@ export class TinyDefault { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < TinyDefault.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinyDefault.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinyDefault.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinyDefault.HEADER_SIZE, buffer.length - TinyDefault.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyDefault.HEADER_SIZE, 1, 1); } } diff --git a/src/struct_frame/boilerplate/ts/TinyExtended.ts b/src/struct_frame/boilerplate/ts/TinyExtended.ts index 35292c40..67d69c4e 100644 --- a/src/struct_frame/boilerplate/ts/TinyExtended.ts +++ b/src/struct_frame/boilerplate/ts/TinyExtended.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // TinyExtended Frame Format @@ -94,14 +98,13 @@ export class TinyExtended { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - TinyExtended.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 2); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinyExtended.HEADER_SIZE, this.packet_size - TinyExtended.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinyExtended.HEADER_SIZE, 2, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinyExtendedParserState.LOOKING_FOR_START; } @@ -120,15 +123,8 @@ export class TinyExtended { static encode(msg_id: number, msg: Uint8Array | number[]): Uint8Array { const output: number[] = []; output.push(TinyExtended.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - output.push((msg.length >> 8) & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 2); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 1); return new Uint8Array(output); } @@ -138,27 +134,15 @@ export class TinyExtended { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < TinyExtended.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinyExtended.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinyExtended.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 2); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinyExtended.HEADER_SIZE, buffer.length - TinyExtended.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyExtended.HEADER_SIZE, 2, 1); } } diff --git a/src/struct_frame/boilerplate/ts/TinyExtendedLength.ts b/src/struct_frame/boilerplate/ts/TinyExtendedLength.ts index 6026a279..54c81ac9 100644 --- a/src/struct_frame/boilerplate/ts/TinyExtendedLength.ts +++ b/src/struct_frame/boilerplate/ts/TinyExtendedLength.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // TinyExtendedLength Frame Format @@ -94,14 +98,13 @@ export class TinyExtendedLength { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - TinyExtendedLength.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 2); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinyExtendedLength.HEADER_SIZE, this.packet_size - TinyExtendedLength.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinyExtendedLength.HEADER_SIZE, 2, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinyExtendedLengthParserState.LOOKING_FOR_START; } @@ -120,15 +123,8 @@ export class TinyExtendedLength { static encode(msg_id: number, msg: Uint8Array | number[]): Uint8Array { const output: number[] = []; output.push(TinyExtendedLength.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - output.push((msg.length >> 8) & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 2); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 1); return new Uint8Array(output); } @@ -138,27 +134,15 @@ export class TinyExtendedLength { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < TinyExtendedLength.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinyExtendedLength.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinyExtendedLength.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 2); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinyExtendedLength.HEADER_SIZE, buffer.length - TinyExtendedLength.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyExtendedLength.HEADER_SIZE, 2, 1); } } diff --git a/src/struct_frame/boilerplate/ts/TinyExtendedMsgIds.ts b/src/struct_frame/boilerplate/ts/TinyExtendedMsgIds.ts index 23902cc3..32d573cb 100644 --- a/src/struct_frame/boilerplate/ts/TinyExtendedMsgIds.ts +++ b/src/struct_frame/boilerplate/ts/TinyExtendedMsgIds.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // TinyExtendedMsgIds Frame Format @@ -88,14 +92,13 @@ export class TinyExtendedMsgIds { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - TinyExtendedMsgIds.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinyExtendedMsgIds.HEADER_SIZE, this.packet_size - TinyExtendedMsgIds.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinyExtendedMsgIds.HEADER_SIZE, 1, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinyExtendedMsgIdsParserState.LOOKING_FOR_START; } @@ -114,14 +117,8 @@ export class TinyExtendedMsgIds { static encode(msg_id: number, msg: Uint8Array | number[]): Uint8Array { const output: number[] = []; output.push(TinyExtendedMsgIds.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1); return new Uint8Array(output); } @@ -131,27 +128,15 @@ export class TinyExtendedMsgIds { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < TinyExtendedMsgIds.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinyExtendedMsgIds.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinyExtendedMsgIds.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinyExtendedMsgIds.HEADER_SIZE, buffer.length - TinyExtendedMsgIds.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyExtendedMsgIds.HEADER_SIZE, 1, 1); } } diff --git a/src/struct_frame/boilerplate/ts/TinyExtendedMultiSystemStream.ts b/src/struct_frame/boilerplate/ts/TinyExtendedMultiSystemStream.ts index d51b18b9..e399e197 100644 --- a/src/struct_frame/boilerplate/ts/TinyExtendedMultiSystemStream.ts +++ b/src/struct_frame/boilerplate/ts/TinyExtendedMultiSystemStream.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // TinyExtendedMultiSystemStream Frame Format @@ -94,14 +98,13 @@ export class TinyExtendedMultiSystemStream { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - TinyExtendedMultiSystemStream.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 2); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinyExtendedMultiSystemStream.HEADER_SIZE, this.packet_size - TinyExtendedMultiSystemStream.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinyExtendedMultiSystemStream.HEADER_SIZE, 2, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinyExtendedMultiSystemStreamParserState.LOOKING_FOR_START; } @@ -120,15 +123,8 @@ export class TinyExtendedMultiSystemStream { static encode(msg_id: number, msg: Uint8Array | number[]): Uint8Array { const output: number[] = []; output.push(TinyExtendedMultiSystemStream.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - output.push((msg.length >> 8) & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 2); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 2, 1); return new Uint8Array(output); } @@ -138,27 +134,15 @@ export class TinyExtendedMultiSystemStream { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < TinyExtendedMultiSystemStream.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinyExtendedMultiSystemStream.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinyExtendedMultiSystemStream.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 2); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinyExtendedMultiSystemStream.HEADER_SIZE, buffer.length - TinyExtendedMultiSystemStream.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyExtendedMultiSystemStream.HEADER_SIZE, 2, 1); } } diff --git a/src/struct_frame/boilerplate/ts/TinyMinimal.ts b/src/struct_frame/boilerplate/ts/TinyMinimal.ts index bedeef30..f8748f59 100644 --- a/src/struct_frame/boilerplate/ts/TinyMinimal.ts +++ b/src/struct_frame/boilerplate/ts/TinyMinimal.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // TinyMinimal Frame Format @@ -86,10 +90,12 @@ export class TinyMinimal { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = this.packet_size - TinyMinimal.OVERHEAD; - result.msg_data = new Uint8Array(this.buffer.slice(TinyMinimal.HEADER_SIZE)); + // Use shared minimal payload validation + const validationResult = validate_payload_minimal(this.buffer, TinyMinimal.HEADER_SIZE); + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; this.state = TinyMinimalParserState.LOOKING_FOR_START; } break; @@ -107,10 +113,8 @@ export class TinyMinimal { static encode(msg_id: number, msg: Uint8Array | number[]): Uint8Array { const output: number[] = []; output.push(TinyMinimal.START_BYTE); - output.push(msg_id); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } + // Use shared minimal payload encoding + encode_payload_minimal(output, msg_id, msg); return new Uint8Array(output); } @@ -120,23 +124,15 @@ export class TinyMinimal { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < TinyMinimal.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinyMinimal.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinyMinimal.OVERHEAD; - - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinyMinimal.HEADER_SIZE)); - - return result; + // Use shared minimal payload validation + return validate_payload_minimal(buffer, TinyMinimal.HEADER_SIZE); } } diff --git a/src/struct_frame/boilerplate/ts/TinyMultiSystemStream.ts b/src/struct_frame/boilerplate/ts/TinyMultiSystemStream.ts index da5bcf97..e14cb78a 100644 --- a/src/struct_frame/boilerplate/ts/TinyMultiSystemStream.ts +++ b/src/struct_frame/boilerplate/ts/TinyMultiSystemStream.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // TinyMultiSystemStream Frame Format @@ -88,14 +92,13 @@ export class TinyMultiSystemStream { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - TinyMultiSystemStream.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinyMultiSystemStream.HEADER_SIZE, this.packet_size - TinyMultiSystemStream.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinyMultiSystemStream.HEADER_SIZE, 1, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinyMultiSystemStreamParserState.LOOKING_FOR_START; } @@ -114,14 +117,8 @@ export class TinyMultiSystemStream { static encode(msg_id: number, msg: Uint8Array | number[]): Uint8Array { const output: number[] = []; output.push(TinyMultiSystemStream.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1); return new Uint8Array(output); } @@ -131,27 +128,15 @@ export class TinyMultiSystemStream { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < TinyMultiSystemStream.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinyMultiSystemStream.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinyMultiSystemStream.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinyMultiSystemStream.HEADER_SIZE, buffer.length - TinyMultiSystemStream.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinyMultiSystemStream.HEADER_SIZE, 1, 1); } } diff --git a/src/struct_frame/boilerplate/ts/TinySeq.ts b/src/struct_frame/boilerplate/ts/TinySeq.ts index 1b9cd4d5..f65ba648 100644 --- a/src/struct_frame/boilerplate/ts/TinySeq.ts +++ b/src/struct_frame/boilerplate/ts/TinySeq.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // TinySeq Frame Format @@ -88,14 +92,13 @@ export class TinySeq { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - TinySeq.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinySeq.HEADER_SIZE, this.packet_size - TinySeq.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinySeq.HEADER_SIZE, 1, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinySeqParserState.LOOKING_FOR_START; } @@ -114,14 +117,8 @@ export class TinySeq { static encode(msg_id: number, msg: Uint8Array | number[]): Uint8Array { const output: number[] = []; output.push(TinySeq.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1); return new Uint8Array(output); } @@ -131,27 +128,15 @@ export class TinySeq { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < TinySeq.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinySeq.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinySeq.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinySeq.HEADER_SIZE, buffer.length - TinySeq.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinySeq.HEADER_SIZE, 1, 1); } } diff --git a/src/struct_frame/boilerplate/ts/TinySysComp.ts b/src/struct_frame/boilerplate/ts/TinySysComp.ts index 43f73d42..bc77aa29 100644 --- a/src/struct_frame/boilerplate/ts/TinySysComp.ts +++ b/src/struct_frame/boilerplate/ts/TinySysComp.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // TinySysComp Frame Format @@ -88,14 +92,13 @@ export class TinySysComp { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - TinySysComp.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(TinySysComp.HEADER_SIZE, this.packet_size - TinySysComp.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, TinySysComp.HEADER_SIZE, 1, 1); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = TinySysCompParserState.LOOKING_FOR_START; } @@ -114,14 +117,8 @@ export class TinySysComp { static encode(msg_id: number, msg: Uint8Array | number[]): Uint8Array { const output: number[] = []; output.push(TinySysComp.START_BYTE); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 1, 1 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 1); return new Uint8Array(output); } @@ -131,27 +128,15 @@ export class TinySysComp { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < TinySysComp.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== TinySysComp.START_BYTE) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - TinySysComp.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 1, 1 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[1]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, TinySysComp.HEADER_SIZE, buffer.length - TinySysComp.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, TinySysComp.HEADER_SIZE, 1, 1); } } diff --git a/src/struct_frame/boilerplate/ts/UbxFrame.ts b/src/struct_frame/boilerplate/ts/UbxFrame.ts index e848316c..84d8634a 100644 --- a/src/struct_frame/boilerplate/ts/UbxFrame.ts +++ b/src/struct_frame/boilerplate/ts/UbxFrame.ts @@ -1,7 +1,11 @@ // Automatically generated frame parser -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. -import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from './frame_base'; +import { + FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + validate_payload_with_crc, validate_payload_minimal, + encode_payload_with_crc, encode_payload_minimal, +} from './frame_base'; // ============================================================================= // UbxFrame Frame Format @@ -102,14 +106,13 @@ export class UbxFrame { this.buffer.push(byte); if (this.buffer.length >= this.packet_size) { - // Validate checksum - const msg_length = this.packet_size - UbxFrame.OVERHEAD; - const ck = fletcher_checksum(this.buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) { - result.valid = true; - result.msg_id = this.msg_id; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(this.buffer.slice(UbxFrame.HEADER_SIZE, this.packet_size - UbxFrame.FOOTER_SIZE)); + // Use shared payload validation with CRC + const validationResult = validate_payload_with_crc(this.buffer, UbxFrame.HEADER_SIZE, 1, 2); + if (validationResult.valid) { + result.valid = validationResult.valid; + result.msg_id = validationResult.msg_id; + result.msg_len = validationResult.msg_len; + result.msg_data = validationResult.msg_data; } this.state = UbxFrameParserState.LOOKING_FOR_START1; } @@ -129,14 +132,8 @@ export class UbxFrame { const output: number[] = []; output.push(UbxFrame.START_BYTE1); output.push(UbxFrame.START_BYTE2); - output.push(msg_id); - output.push(msg.length & 0xFF); - for (let i = 0; i < msg.length; i++) { - output.push(msg[i]); - } - const ck = fletcher_checksum(output, 2, 2 + msg.length + 1 + 1); - output.push(ck[0]); - output.push(ck[1]); + // Use shared payload encoding with CRC + encode_payload_with_crc(output, msg_id, msg, 1, 2); return new Uint8Array(output); } @@ -146,30 +143,18 @@ export class UbxFrame { * @returns FrameMsgInfo with valid=true if packet is valid */ static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo { - const result = createFrameMsgInfo(); - if (buffer.length < UbxFrame.OVERHEAD) { - return result; + return createFrameMsgInfo(); } if (buffer[0] !== UbxFrame.START_BYTE1) { - return result; + return createFrameMsgInfo(); } if (buffer[1] !== UbxFrame.START_BYTE2) { - return result; + return createFrameMsgInfo(); } - const msg_length = buffer.length - UbxFrame.OVERHEAD; - - // Validate checksum - const ck = fletcher_checksum(buffer, 2, 2 + msg_length + 1 + 1); - if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { - result.valid = true; - result.msg_id = buffer[2]; - result.msg_len = msg_length; - result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, UbxFrame.HEADER_SIZE, buffer.length - UbxFrame.FOOTER_SIZE)); - } - - return result; + // Use shared payload validation with CRC + return validate_payload_with_crc(buffer, UbxFrame.HEADER_SIZE, 1, 2); } } diff --git a/src/struct_frame/boilerplate/ts/frame_base.ts b/src/struct_frame/boilerplate/ts/frame_base.ts index ed282df6..fb26a9ec 100644 --- a/src/struct_frame/boilerplate/ts/frame_base.ts +++ b/src/struct_frame/boilerplate/ts/frame_base.ts @@ -1,5 +1,5 @@ // Automatically generated frame parser base utilities -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. // Frame format type enumeration export enum FrameFormatType { @@ -61,3 +61,110 @@ export function createFrameMsgInfo(): FrameMsgInfo { msg_data: new Uint8Array(0) }; } + +// ============================================================================= +// Shared Payload Parsing Functions +// ============================================================================= +// These functions handle payload validation/encoding independent of framing. +// Frame formats (Tiny/Basic) use these for the common parsing logic. + +/** + * Validate a payload with CRC (shared by Default, Extended, etc. payload types). + */ +export function validate_payload_with_crc( + buffer: Uint8Array | number[], + headerSize: number, + lengthBytes: number, + crcStartOffset: number +): FrameMsgInfo { + const result = createFrameMsgInfo(); + const footerSize = 2; // CRC is always 2 bytes + const overhead = headerSize + footerSize; + + if (buffer.length < overhead) { + return result; + } + + const msgLength = buffer.length - overhead; + + // Calculate expected CRC range: from crcStartOffset to before the CRC bytes + const crcDataLen = msgLength + 1 + lengthBytes; // msg_id (1) + lengthBytes + payload + const ck = fletcher_checksum(buffer, crcStartOffset, crcStartOffset + crcDataLen); + + if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { + result.valid = true; + result.msg_id = buffer[headerSize - 1]; // msg_id is last byte of header + result.msg_len = msgLength; + result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, headerSize, buffer.length - footerSize)); + } + + return result; +} + +/** + * Validate a minimal payload (no CRC, no length field). + */ +export function validate_payload_minimal( + buffer: Uint8Array | number[], + headerSize: number +): FrameMsgInfo { + const result = createFrameMsgInfo(); + + if (buffer.length < headerSize) { + return result; + } + + result.valid = true; + result.msg_id = buffer[headerSize - 1]; // msg_id is last byte of header + result.msg_len = buffer.length - headerSize; + result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, headerSize)); + + return result; +} + +/** + * Encode payload with length and CRC (modifies output array in place). + */ +export function encode_payload_with_crc( + output: number[], + msgId: number, + msg: Uint8Array | number[], + lengthBytes: number, + crcStartOffset: number +): void { + // Add length field + if (lengthBytes === 1) { + output.push(msg.length & 0xFF); + } else { + output.push(msg.length & 0xFF); + output.push((msg.length >> 8) & 0xFF); + } + + // Add msg_id + output.push(msgId); + + // Add payload + for (let i = 0; i < msg.length; i++) { + output.push(msg[i]); + } + + // Calculate and add CRC + const crcDataLen = msg.length + 1 + lengthBytes; + const ck = fletcher_checksum(output, crcStartOffset, crcStartOffset + crcDataLen); + output.push(ck[0]); + output.push(ck[1]); +} + +/** + * Encode minimal payload (no length, no CRC). + */ +export function encode_payload_minimal( + output: number[], + msgId: number, + msg: Uint8Array | number[] +): void { + output.push(msgId); + for (let i = 0; i < msg.length; i++) { + output.push(msg[i]); + } +} diff --git a/src/struct_frame/boilerplate/ts/index.ts b/src/struct_frame/boilerplate/ts/index.ts index 5490e38d..8f54f20d 100644 --- a/src/struct_frame/boilerplate/ts/index.ts +++ b/src/struct_frame/boilerplate/ts/index.ts @@ -1,5 +1,5 @@ // Automatically generated frame parser package -// Generated by 0.0.1 at Thu Dec 4 19:40:48 2025. +// Generated by 0.0.1 at Thu Dec 4 20:27:20 2025. // Base utilities export { @@ -7,6 +7,11 @@ export { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum, + // Shared payload parsing functions + validate_payload_with_crc, + validate_payload_minimal, + encode_payload_with_crc, + encode_payload_minimal, } from './frame_base'; // Individual frame format parsers diff --git a/src/struct_frame/frame_format.py b/src/struct_frame/frame_format.py index fdf14a80..2b638b88 100644 --- a/src/struct_frame/frame_format.py +++ b/src/struct_frame/frame_format.py @@ -126,6 +126,39 @@ def get_enum_value(self): name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name) return name.upper() + def get_payload_type(self): + """ + Get the payload type identifier for this frame format. + + The payload type identifies the structure of the payload portion, + excluding start bytes. Formats with the same payload type can share + payload parsing/encoding logic. + + Returns a tuple: (has_crc, has_length, length_bytes, header_fields_tuple) + where header_fields_tuple identifies additional header fields. + """ + # Get list of header fields (sequence, system_id, component_id, package_id) + header_fields = [] + for field in self.fields: + if field.is_sequence: + header_fields.append('sequence') + if field.is_system_id: + header_fields.append('system_id') + if field.is_component_id: + header_fields.append('component_id') + if field.is_package_id: + header_fields.append('package_id') + + return (self.has_crc, self.has_length, self.length_bytes, tuple(header_fields)) + + def get_payload_header_size(self): + """ + Get the size of the payload header (excluding start bytes). + + This includes: msg_id (1) + length_bytes (if any) + additional header fields + """ + return self.header_size - len(self.start_bytes) + def __repr__(self): return (f"FrameFormat({self.name}, start_bytes={self.start_bytes}, " f"has_crc={self.has_crc}, has_length={self.has_length})") @@ -184,6 +217,21 @@ def get_format_by_start_byte(self, start_byte): matches.append(fmt) return matches + def get_payload_types(self): + """ + Get unique payload types and their representative formats. + + Returns a dictionary mapping payload_type tuple to list of formats with that type. + This allows code generation to create shared payload parsers. + """ + payload_types = {} + for fmt in self.formats.values(): + payload_type = fmt.get_payload_type() + if payload_type not in payload_types: + payload_types[payload_type] = [] + payload_types[payload_type].append(fmt) + return payload_types + def __iter__(self): return iter(self.formats.values()) diff --git a/src/struct_frame/frame_parser_c_gen.py b/src/struct_frame/frame_parser_c_gen.py index e0bc4b70..db9d636a 100644 --- a/src/struct_frame/frame_parser_c_gen.py +++ b/src/struct_frame/frame_parser_c_gen.py @@ -77,6 +77,145 @@ def generate_base(formats): size_t msg_len; uint8_t* msg_data; } frame_msg_info_t; + +/*=========================================================================== + * Shared Payload Parsing Functions + *=========================================================================== + * These functions handle payload validation/encoding independent of framing. + * Frame formats (Tiny/Basic) use these for the common parsing logic. + */ + +/** + * Validate a payload with CRC (shared by Default, Extended, etc. payload types). + * + * @param buffer Complete packet buffer (including any start bytes) + * @param length Total buffer length + * @param header_size Size of header (start_bytes + length + msg_id + extra fields) + * @param length_bytes Number of length bytes (1 or 2) + * @param crc_start_offset Offset from start of buffer where CRC calculation begins + * @return frame_msg_info_t with valid=true if checksum matches + */ +static inline frame_msg_info_t frame_validate_payload_with_crc( + const uint8_t* buffer, size_t length, + size_t header_size, size_t length_bytes, size_t crc_start_offset) { + + frame_msg_info_t result = {false, 0, 0, NULL}; + const size_t footer_size = 2; /* CRC is always 2 bytes */ + const size_t overhead = header_size + footer_size; + + if (length < overhead) { + return result; + } + + size_t msg_length = length - overhead; + + /* Calculate expected CRC range: from crc_start_offset to before the CRC bytes */ + size_t crc_data_len = msg_length + 1 + length_bytes; /* msg_id (1) + length_bytes + payload */ + frame_checksum_t ck = frame_fletcher_checksum(buffer + crc_start_offset, crc_data_len); + + if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { + result.valid = true; + result.msg_id = buffer[header_size - 1]; /* msg_id is last byte of header */ + result.msg_len = msg_length; + result.msg_data = (uint8_t*)(buffer + header_size); + } + + return result; +} + +/** + * Validate a minimal payload (no CRC, no length field). + * + * @param buffer Complete packet buffer (including any start bytes) + * @param length Total buffer length + * @param header_size Size of header (start_bytes + msg_id) + * @return frame_msg_info_t with packet data + */ +static inline frame_msg_info_t frame_validate_payload_minimal( + const uint8_t* buffer, size_t length, size_t header_size) { + + frame_msg_info_t result = {false, 0, 0, NULL}; + + if (length < header_size) { + return result; + } + + result.valid = true; + result.msg_id = buffer[header_size - 1]; /* msg_id is last byte of header */ + result.msg_len = length - header_size; + result.msg_data = (uint8_t*)(buffer + header_size); + + return result; +} + +/** + * Encode payload with length and CRC into output buffer. + * + * @param output Output buffer to write to (after start bytes) + * @param msg_id Message ID + * @param msg Message payload data + * @param msg_size Size of message payload + * @param length_bytes Number of length bytes (1 or 2) + * @param crc_start Pointer to start of CRC calculation (typically after start bytes) + * @return Number of bytes written (length + msg_id + payload + CRC) + */ +static inline size_t frame_encode_payload_with_crc( + uint8_t* output, uint8_t msg_id, const uint8_t* msg, size_t msg_size, + size_t length_bytes, const uint8_t* crc_start) { + + size_t idx = 0; + + /* Add length field */ + if (length_bytes == 1) { + output[idx++] = (uint8_t)(msg_size & 0xFF); + } else { + output[idx++] = (uint8_t)(msg_size & 0xFF); + output[idx++] = (uint8_t)((msg_size >> 8) & 0xFF); + } + + /* Add msg_id */ + output[idx++] = msg_id; + + /* Add payload */ + if (msg_size > 0 && msg != NULL) { + memcpy(output + idx, msg, msg_size); + idx += msg_size; + } + + /* Calculate and add CRC */ + size_t crc_data_len = msg_size + 1 + length_bytes; + frame_checksum_t ck = frame_fletcher_checksum(crc_start, crc_data_len); + output[idx++] = ck.byte1; + output[idx++] = ck.byte2; + + return idx; +} + +/** + * Encode minimal payload (no length, no CRC) into output buffer. + * + * @param output Output buffer to write to (after start bytes) + * @param msg_id Message ID + * @param msg Message payload data + * @param msg_size Size of message payload + * @return Number of bytes written (msg_id + payload) + */ +static inline size_t frame_encode_payload_minimal( + uint8_t* output, uint8_t msg_id, const uint8_t* msg, size_t msg_size) { + + size_t idx = 0; + + /* Add msg_id */ + output[idx++] = msg_id; + + /* Add payload */ + if (msg_size > 0 && msg != NULL) { + memcpy(output + idx, msg, msg_size); + idx += msg_size; + } + + return idx; +} ''' @staticmethod @@ -156,6 +295,111 @@ def generate_header(formats): uint8_t* msg_data; } frame_msg_info_t; +/*=========================================================================== + * Shared Payload Parsing Functions + *=========================================================================== + * These functions handle payload validation/encoding independent of framing. + * Frame formats (Tiny/Basic) use these for the common parsing logic. + */ + +/** + * Validate a payload with CRC (shared by Default, Extended, etc. payload types). + */ +static inline frame_msg_info_t frame_validate_payload_with_crc( + const uint8_t* buffer, size_t length, + size_t header_size, size_t length_bytes, size_t crc_start_offset) { + + frame_msg_info_t result = {false, 0, 0, NULL}; + const size_t footer_size = 2; + const size_t overhead = header_size + footer_size; + + if (length < overhead) { + return result; + } + + size_t msg_length = length - overhead; + size_t crc_data_len = msg_length + 1 + length_bytes; + frame_checksum_t ck = frame_fletcher_checksum(buffer + crc_start_offset, crc_data_len); + + if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { + result.valid = true; + result.msg_id = buffer[header_size - 1]; + result.msg_len = msg_length; + result.msg_data = (uint8_t*)(buffer + header_size); + } + + return result; +} + +/** + * Validate a minimal payload (no CRC, no length field). + */ +static inline frame_msg_info_t frame_validate_payload_minimal( + const uint8_t* buffer, size_t length, size_t header_size) { + + frame_msg_info_t result = {false, 0, 0, NULL}; + + if (length < header_size) { + return result; + } + + result.valid = true; + result.msg_id = buffer[header_size - 1]; + result.msg_len = length - header_size; + result.msg_data = (uint8_t*)(buffer + header_size); + + return result; +} + +/** + * Encode payload with length and CRC into output buffer. + */ +static inline size_t frame_encode_payload_with_crc( + uint8_t* output, uint8_t msg_id, const uint8_t* msg, size_t msg_size, + size_t length_bytes, const uint8_t* crc_start) { + + size_t idx = 0; + + if (length_bytes == 1) { + output[idx++] = (uint8_t)(msg_size & 0xFF); + } else { + output[idx++] = (uint8_t)(msg_size & 0xFF); + output[idx++] = (uint8_t)((msg_size >> 8) & 0xFF); + } + + output[idx++] = msg_id; + + if (msg_size > 0 && msg != NULL) { + memcpy(output + idx, msg, msg_size); + idx += msg_size; + } + + size_t crc_data_len = msg_size + 1 + length_bytes; + frame_checksum_t ck = frame_fletcher_checksum(crc_start, crc_data_len); + output[idx++] = ck.byte1; + output[idx++] = ck.byte2; + + return idx; +} + +/** + * Encode minimal payload (no length, no CRC) into output buffer. + */ +static inline size_t frame_encode_payload_minimal( + uint8_t* output, uint8_t msg_id, const uint8_t* msg, size_t msg_size) { + + size_t idx = 0; + + output[idx++] = msg_id; + + if (msg_size > 0 && msg != NULL) { + memcpy(output + idx, msg, msg_size); + idx += msg_size; + } + + return idx; +} + ''' # Generate individual frame format code @@ -392,7 +636,7 @@ def generate_format(fmt): yield f' }}\n' yield f' break;\n\n' - # PAYLOAD state + # PAYLOAD state - uses shared payload validation yield f' case {PREFIX}_GETTING_PAYLOAD:\n' yield f' if (parser->buffer_index < parser->buffer_max_size) {{\n' yield f' parser->buffer[parser->buffer_index++] = byte;\n' @@ -400,25 +644,15 @@ def generate_format(fmt): yield f' if (parser->buffer_index >= parser->packet_size) {{\n' if fmt.has_crc: - yield f' /* Validate checksum */\n' - yield f' size_t msg_length = parser->packet_size - {PREFIX}_OVERHEAD;\n' - yield f' frame_checksum_t ck = frame_fletcher_checksum(\n' - yield f' parser->buffer + {len(fmt.start_bytes)}, msg_length + 1' - if fmt.has_length: - yield f' + {fmt.length_bytes}' - yield f');\n\n' - yield f' if (ck.byte1 == parser->buffer[parser->packet_size - 2] &&\n' - yield f' ck.byte2 == parser->buffer[parser->packet_size - 1]) {{\n' - yield f' result.valid = true;\n' - yield f' result.msg_id = parser->msg_id;\n' - yield f' result.msg_len = msg_length;\n' - yield f' result.msg_data = parser->buffer + {PREFIX}_HEADER_SIZE;\n' - yield f' }}\n' + crc_start = len(fmt.start_bytes) + yield f' /* Use shared payload validation with CRC */\n' + yield f' result = frame_validate_payload_with_crc(\n' + yield f' parser->buffer, parser->packet_size,\n' + yield f' {PREFIX}_HEADER_SIZE, {fmt.length_bytes}, {crc_start});\n' else: - yield f' result.valid = true;\n' - yield f' result.msg_id = parser->msg_id;\n' - yield f' result.msg_len = parser->packet_size - {PREFIX}_OVERHEAD;\n' - yield f' result.msg_data = parser->buffer + {PREFIX}_HEADER_SIZE;\n' + yield f' /* Use shared minimal payload validation */\n' + yield f' result = frame_validate_payload_minimal(\n' + yield f' parser->buffer, parser->packet_size, {PREFIX}_HEADER_SIZE);\n' if fmt.start_bytes: yield f' parser->state = {PREFIX}_LOOKING_FOR_START{"1" if len(fmt.start_bytes) > 1 else ""};\n' @@ -431,7 +665,7 @@ def generate_format(fmt): yield f' return result;\n' yield f'}}\n\n' - # Generate encode function + # Generate encode function - uses shared payload encoding yield f'/**\n' yield f' * Encode a message with {name} format\n' yield f' * Returns the number of bytes written, or 0 on failure\n' @@ -443,82 +677,56 @@ def generate_format(fmt): yield f' return 0;\n' yield f' }}\n\n' - # Write header + # Write start bytes (frame-specific) idx = 0 for i, (sb_name, sb_value) in enumerate(fmt.start_bytes): yield f' buffer[{idx}] = {PREFIX}_START_BYTE{i + 1 if len(fmt.start_bytes) > 1 else ""};\n' idx += 1 - # Write length BEFORE msg_id (per frame_formats.proto definition) - if fmt.has_length: - if fmt.length_bytes == 1: - yield f' buffer[{idx}] = (uint8_t)msg_size;\n' - else: - yield f' buffer[{idx}] = (uint8_t)(msg_size & 0xFF);\n' - yield f' buffer[{idx + 1}] = (uint8_t)((msg_size >> 8) & 0xFF);\n' - idx += fmt.length_bytes - - yield f' buffer[{idx}] = msg_id;\n' - idx += 1 - - yield f'\n /* Write message data */\n' - yield f' if (msg_size > 0 && msg != NULL) {{\n' - yield f' memcpy(buffer + {PREFIX}_HEADER_SIZE, msg, msg_size);\n' - yield f' }}\n\n' - + # Use shared payload encoding function if fmt.has_crc: - yield f' /* Calculate checksum */\n' - yield f' frame_checksum_t ck = frame_fletcher_checksum(buffer + {len(fmt.start_bytes)}, msg_size + 1' - if fmt.has_length: - yield f' + {fmt.length_bytes}' - yield f');\n' - yield f' buffer[{PREFIX}_HEADER_SIZE + msg_size] = ck.byte1;\n' - yield f' buffer[{PREFIX}_HEADER_SIZE + msg_size + 1] = ck.byte2;\n' + crc_start = len(fmt.start_bytes) + yield f'\n /* Use shared payload encoding with CRC */\n' + yield f' frame_encode_payload_with_crc(\n' + yield f' buffer + {len(fmt.start_bytes)}, msg_id, msg, msg_size,\n' + yield f' {fmt.length_bytes}, buffer + {crc_start});\n' + else: + yield f'\n /* Use shared minimal payload encoding */\n' + yield f' frame_encode_payload_minimal(\n' + yield f' buffer + {len(fmt.start_bytes)}, msg_id, msg, msg_size);\n' yield f'\n return total_size;\n' yield f'}}\n\n' - # Generate validate_packet function + # Generate validate_packet function - uses shared payload validation yield f'/**\n' yield f' * Validate a complete {name} packet in a buffer\n' yield f' */\n' yield f'static inline frame_msg_info_t {prefix}_validate_packet(const uint8_t* buffer, size_t length) {{\n' - yield f' frame_msg_info_t result = {{false, 0, 0, NULL}};\n\n' yield f' if (length < {PREFIX}_OVERHEAD) {{\n' - yield f' return result;\n' + yield f' return (frame_msg_info_t){{false, 0, 0, NULL}};\n' yield f' }}\n\n' # Check start bytes if fmt.start_bytes: for i, (sb_name, sb_value) in enumerate(fmt.start_bytes): yield f' if (buffer[{i}] != {PREFIX}_START_BYTE{i + 1 if len(fmt.start_bytes) > 1 else ""}) {{\n' - yield f' return result;\n' + yield f' return (frame_msg_info_t){{false, 0, 0, NULL}};\n' yield f' }}\n' - yield f'\n size_t msg_length = length - {PREFIX}_OVERHEAD;\n\n' - - # Calculate msg_id offset: start_bytes + length_bytes (if has_length) - msg_id_offset = len(fmt.start_bytes) + (fmt.length_bytes if fmt.has_length else 0) + yield f'\n' + # Use shared payload validation function if fmt.has_crc: - yield f' /* Validate checksum */\n' - yield f' frame_checksum_t ck = frame_fletcher_checksum(buffer + {len(fmt.start_bytes)}, msg_length + 1' - if fmt.has_length: - yield f' + {fmt.length_bytes}' - yield f');\n' - yield f' if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) {{\n' - yield f' result.valid = true;\n' - yield f' result.msg_id = buffer[{msg_id_offset}];\n' - yield f' result.msg_len = msg_length;\n' - yield f' result.msg_data = (uint8_t*)(buffer + {PREFIX}_HEADER_SIZE);\n' - yield f' }}\n' + crc_start = len(fmt.start_bytes) + yield f' /* Use shared payload validation with CRC */\n' + yield f' return frame_validate_payload_with_crc(\n' + yield f' buffer, length, {PREFIX}_HEADER_SIZE, {fmt.length_bytes}, {crc_start});\n' else: - yield f' result.valid = true;\n' - yield f' result.msg_id = buffer[{msg_id_offset}];\n' - yield f' result.msg_len = msg_length;\n' - yield f' result.msg_data = (uint8_t*)(buffer + {PREFIX}_HEADER_SIZE);\n' + yield f' /* Use shared minimal payload validation */\n' + yield f' return frame_validate_payload_minimal(\n' + yield f' buffer, length, {PREFIX}_HEADER_SIZE);\n' - yield f'\n return result;\n' yield f'}}\n\n' diff --git a/src/struct_frame/frame_parser_cpp_gen.py b/src/struct_frame/frame_parser_cpp_gen.py index 85524764..e0a8468f 100644 --- a/src/struct_frame/frame_parser_cpp_gen.py +++ b/src/struct_frame/frame_parser_cpp_gen.py @@ -79,6 +79,111 @@ def generate_base(formats): : valid(v), msg_id(id), msg_len(len), msg_data(data) {} }; +// ============================================================================= +// Shared Payload Parsing Functions +// ============================================================================= +// These functions handle payload validation/encoding independent of framing. +// Frame formats (Tiny/Basic) use these for the common parsing logic. + +/** + * Validate a payload with CRC (shared by Default, Extended, etc. payload types). + */ +inline FrameMsgInfo validate_payload_with_crc( + const uint8_t* buffer, size_t length, + size_t header_size, size_t length_bytes, size_t crc_start_offset) { + + constexpr size_t footer_size = 2; // CRC is always 2 bytes + const size_t overhead = header_size + footer_size; + + if (length < overhead) { + return FrameMsgInfo(); + } + + size_t msg_length = length - overhead; + + // Calculate expected CRC range: from crc_start_offset to before the CRC bytes + size_t crc_data_len = msg_length + 1 + length_bytes; // msg_id (1) + length_bytes + payload + FrameChecksum ck = fletcher_checksum(buffer + crc_start_offset, crc_data_len); + + if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { + return FrameMsgInfo(true, buffer[header_size - 1], msg_length, + const_cast(buffer + header_size)); + } + + return FrameMsgInfo(); +} + +/** + * Validate a minimal payload (no CRC, no length field). + */ +inline FrameMsgInfo validate_payload_minimal( + const uint8_t* buffer, size_t length, size_t header_size) { + + if (length < header_size) { + return FrameMsgInfo(); + } + + return FrameMsgInfo(true, buffer[header_size - 1], length - header_size, + const_cast(buffer + header_size)); +} + +/** + * Encode payload with length and CRC into output buffer. + * Returns number of bytes written (length + msg_id + payload + CRC) + */ +inline size_t encode_payload_with_crc( + uint8_t* output, uint8_t msg_id, const uint8_t* msg, size_t msg_size, + size_t length_bytes, const uint8_t* crc_start) { + + size_t idx = 0; + + // Add length field + if (length_bytes == 1) { + output[idx++] = static_cast(msg_size & 0xFF); + } else { + output[idx++] = static_cast(msg_size & 0xFF); + output[idx++] = static_cast((msg_size >> 8) & 0xFF); + } + + // Add msg_id + output[idx++] = msg_id; + + // Add payload + if (msg_size > 0 && msg != nullptr) { + std::memcpy(output + idx, msg, msg_size); + idx += msg_size; + } + + // Calculate and add CRC + size_t crc_data_len = msg_size + 1 + length_bytes; + FrameChecksum ck = fletcher_checksum(crc_start, crc_data_len); + output[idx++] = ck.byte1; + output[idx++] = ck.byte2; + + return idx; +} + +/** + * Encode minimal payload (no length, no CRC) into output buffer. + * Returns number of bytes written (msg_id + payload) + */ +inline size_t encode_payload_minimal( + uint8_t* output, uint8_t msg_id, const uint8_t* msg, size_t msg_size) { + + size_t idx = 0; + + // Add msg_id + output[idx++] = msg_id; + + // Add payload + if (msg_size > 0 && msg != nullptr) { + std::memcpy(output + idx, msg, msg_size); + idx += msg_size; + } + + return idx; +} + } // namespace FrameParsers ''' @@ -159,6 +264,88 @@ def generate_header(formats): : valid(v), msg_id(id), msg_len(len), msg_data(data) {} }; +// ============================================================================= +// Shared Payload Parsing Functions +// ============================================================================= +// These functions handle payload validation/encoding independent of framing. +// Frame formats (Tiny/Basic) use these for the common parsing logic. + +inline FrameMsgInfo validate_payload_with_crc( + const uint8_t* buffer, size_t length, + size_t header_size, size_t length_bytes, size_t crc_start_offset) { + + constexpr size_t footer_size = 2; + const size_t overhead = header_size + footer_size; + + if (length < overhead) { + return FrameMsgInfo(); + } + + size_t msg_length = length - overhead; + size_t crc_data_len = msg_length + 1 + length_bytes; + FrameChecksum ck = fletcher_checksum(buffer + crc_start_offset, crc_data_len); + + if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) { + return FrameMsgInfo(true, buffer[header_size - 1], msg_length, + const_cast(buffer + header_size)); + } + + return FrameMsgInfo(); +} + +inline FrameMsgInfo validate_payload_minimal( + const uint8_t* buffer, size_t length, size_t header_size) { + + if (length < header_size) { + return FrameMsgInfo(); + } + + return FrameMsgInfo(true, buffer[header_size - 1], length - header_size, + const_cast(buffer + header_size)); +} + +inline size_t encode_payload_with_crc( + uint8_t* output, uint8_t msg_id, const uint8_t* msg, size_t msg_size, + size_t length_bytes, const uint8_t* crc_start) { + + size_t idx = 0; + + if (length_bytes == 1) { + output[idx++] = static_cast(msg_size & 0xFF); + } else { + output[idx++] = static_cast(msg_size & 0xFF); + output[idx++] = static_cast((msg_size >> 8) & 0xFF); + } + + output[idx++] = msg_id; + + if (msg_size > 0 && msg != nullptr) { + std::memcpy(output + idx, msg, msg_size); + idx += msg_size; + } + + size_t crc_data_len = msg_size + 1 + length_bytes; + FrameChecksum ck = fletcher_checksum(crc_start, crc_data_len); + output[idx++] = ck.byte1; + output[idx++] = ck.byte2; + + return idx; +} + +inline size_t encode_payload_minimal( + uint8_t* output, uint8_t msg_id, const uint8_t* msg, size_t msg_size) { + + size_t idx = 0; + output[idx++] = msg_id; + + if (msg_size > 0 && msg != nullptr) { + std::memcpy(output + idx, msg, msg_size); + idx += msg_size; + } + + return idx; +} + ''' # Generate individual frame format classes @@ -405,7 +592,7 @@ def generate_format(fmt): yield f' }}\n' yield f' break;\n\n' - # GettingPayload state + # GettingPayload state - uses shared payload validation yield f' case {class_name}ParserState::GettingPayload:\n' yield f' if (buffer_index_ < buffer_max_size_) {{\n' yield f' buffer_[buffer_index_++] = byte;\n' @@ -413,25 +600,15 @@ def generate_format(fmt): yield f' if (buffer_index_ >= packet_size_) {{\n' if fmt.has_crc: - yield f' // Validate checksum\n' - yield f' size_t msg_length = packet_size_ - {PREFIX}_OVERHEAD;\n' - crc_data_start = len(fmt.start_bytes) - crc_data_len = f'msg_length + 1' - if fmt.has_length: - crc_data_len += f' + {fmt.length_bytes}' - yield f' FrameChecksum ck = fletcher_checksum(buffer_ + {crc_data_start}, {crc_data_len});\n\n' - yield f' if (ck.byte1 == buffer_[packet_size_ - 2] &&\n' - yield f' ck.byte2 == buffer_[packet_size_ - 1]) {{\n' - yield f' result.valid = true;\n' - yield f' result.msg_id = msg_id_;\n' - yield f' result.msg_len = msg_length;\n' - yield f' result.msg_data = buffer_ + {PREFIX}_HEADER_SIZE;\n' - yield f' }}\n' + crc_start = len(fmt.start_bytes) + yield f' // Use shared payload validation with CRC\n' + yield f' result = validate_payload_with_crc(\n' + yield f' buffer_, packet_size_,\n' + yield f' {PREFIX}_HEADER_SIZE, {fmt.length_bytes}, {crc_start});\n' else: - yield f' result.valid = true;\n' - yield f' result.msg_id = msg_id_;\n' - yield f' result.msg_len = packet_size_ - {PREFIX}_OVERHEAD;\n' - yield f' result.msg_data = buffer_ + {PREFIX}_HEADER_SIZE;\n' + yield f' // Use shared minimal payload validation\n' + yield f' result = validate_payload_minimal(\n' + yield f' buffer_, packet_size_, {PREFIX}_HEADER_SIZE);\n' reset_state = 'LookingForStart1' if len(fmt.start_bytes) > 1 else ('LookingForStart' if fmt.start_bytes else 'GettingMsgId') yield f' state_ = {class_name}ParserState::{reset_state};\n' @@ -456,7 +633,7 @@ def generate_format(fmt): yield f' MsgLengthCallback get_msg_length_;\n' yield f'}};\n\n' - # Static encode function + # Static encode function - uses shared payload encoding yield f'/**\n' yield f' * Encode a message with {name} format\n' yield f' * Returns the number of bytes written, or 0 on failure\n' @@ -466,76 +643,52 @@ def generate_format(fmt): yield f' size_t total_size = {PREFIX}_OVERHEAD + msg_size;\n' yield f' if (buffer_size < total_size) return 0;\n\n' + # Write start bytes (frame-specific) idx = 0 for i, (sb_name, sb_value) in enumerate(fmt.start_bytes): const_name = f'{PREFIX}_START_BYTE{i + 1}' if len(fmt.start_bytes) > 1 else f'{PREFIX}_START_BYTE' yield f' buffer[{idx}] = {const_name};\n' idx += 1 - # Write length BEFORE msg_id (per frame_formats.proto definition) - if fmt.has_length: - if fmt.length_bytes == 1: - yield f' buffer[{idx}] = static_cast(msg_size);\n' - else: - yield f' buffer[{idx}] = static_cast(msg_size & 0xFF);\n' - yield f' buffer[{idx + 1}] = static_cast((msg_size >> 8) & 0xFF);\n' - idx += fmt.length_bytes - - yield f' buffer[{idx}] = msg_id;\n' - idx += 1 - - yield f'\n if (msg_size > 0 && msg != nullptr) {{\n' - yield f' std::memcpy(buffer + {PREFIX}_HEADER_SIZE, msg, msg_size);\n' - yield f' }}\n\n' - + # Use shared payload encoding function if fmt.has_crc: - crc_data_start = len(fmt.start_bytes) - crc_data_len = f'msg_size + 1' - if fmt.has_length: - crc_data_len += f' + {fmt.length_bytes}' - yield f' FrameChecksum ck = fletcher_checksum(buffer + {crc_data_start}, {crc_data_len});\n' - yield f' buffer[{PREFIX}_HEADER_SIZE + msg_size] = ck.byte1;\n' - yield f' buffer[{PREFIX}_HEADER_SIZE + msg_size + 1] = ck.byte2;\n' + crc_start = len(fmt.start_bytes) + yield f'\n // Use shared payload encoding with CRC\n' + yield f' encode_payload_with_crc(\n' + yield f' buffer + {len(fmt.start_bytes)}, msg_id, msg, msg_size,\n' + yield f' {fmt.length_bytes}, buffer + {crc_start});\n' + else: + yield f'\n // Use shared minimal payload encoding\n' + yield f' encode_payload_minimal(\n' + yield f' buffer + {len(fmt.start_bytes)}, msg_id, msg, msg_size);\n' yield f'\n return total_size;\n' yield f'}}\n\n' - # Static validate_packet function + # Static validate_packet function - uses shared payload validation yield f'/**\n' yield f' * Validate a complete {name} packet in a buffer\n' yield f' */\n' yield f'inline FrameMsgInfo {camel_to_snake(name)}_validate_packet(const uint8_t* buffer, size_t length) {{\n' - yield f' FrameMsgInfo result;\n\n' - yield f' if (length < {PREFIX}_OVERHEAD) return result;\n\n' + yield f' if (length < {PREFIX}_OVERHEAD) return FrameMsgInfo();\n\n' for i, (sb_name, sb_value) in enumerate(fmt.start_bytes): const_name = f'{PREFIX}_START_BYTE{i + 1}' if len(fmt.start_bytes) > 1 else f'{PREFIX}_START_BYTE' - yield f' if (buffer[{i}] != {const_name}) return result;\n' - - yield f'\n size_t msg_length = length - {PREFIX}_OVERHEAD;\n\n' + yield f' if (buffer[{i}] != {const_name}) return FrameMsgInfo();\n' - # Calculate msg_id offset: start_bytes + length_bytes (if has_length) - msg_id_offset = len(fmt.start_bytes) + (fmt.length_bytes if fmt.has_length else 0) + yield f'\n' + # Use shared payload validation function if fmt.has_crc: - crc_data_start = len(fmt.start_bytes) - crc_data_len = f'msg_length + 1' - if fmt.has_length: - crc_data_len += f' + {fmt.length_bytes}' - yield f' FrameChecksum ck = fletcher_checksum(buffer + {crc_data_start}, {crc_data_len});\n' - yield f' if (ck.byte1 == buffer[length - 2] && ck.byte2 == buffer[length - 1]) {{\n' - yield f' result.valid = true;\n' - yield f' result.msg_id = buffer[{msg_id_offset}];\n' - yield f' result.msg_len = msg_length;\n' - yield f' result.msg_data = const_cast(buffer + {PREFIX}_HEADER_SIZE);\n' - yield f' }}\n' + crc_start = len(fmt.start_bytes) + yield f' // Use shared payload validation with CRC\n' + yield f' return validate_payload_with_crc(\n' + yield f' buffer, length, {PREFIX}_HEADER_SIZE, {fmt.length_bytes}, {crc_start});\n' else: - yield f' result.valid = true;\n' - yield f' result.msg_id = buffer[{msg_id_offset}];\n' - yield f' result.msg_len = msg_length;\n' - yield f' result.msg_data = const_cast(buffer + {PREFIX}_HEADER_SIZE);\n' + yield f' // Use shared minimal payload validation\n' + yield f' return validate_payload_minimal(\n' + yield f' buffer, length, {PREFIX}_HEADER_SIZE);\n' - yield f'\n return result;\n' yield f'}}\n\n' diff --git a/src/struct_frame/frame_parser_py_gen.py b/src/struct_frame/frame_parser_py_gen.py index c376bd42..5047f21e 100644 --- a/src/struct_frame/frame_parser_py_gen.py +++ b/src/struct_frame/frame_parser_py_gen.py @@ -70,6 +70,120 @@ class FrameMsgInfo: msg_id: int = 0 msg_len: int = 0 msg_data: bytes = b\'\' + + +''' + + # Generate shared payload validation functions + yield '''# ============================================================================= +# Shared Payload Parsing Functions +# ============================================================================= +# These functions handle payload validation/encoding independent of framing. +# Frame formats (Tiny/Basic) use these for the common parsing logic. + +def validate_payload_with_crc(buffer: Union[bytes, List[int]], header_size: int, + length_bytes: int, crc_start_offset: int = 0) -> FrameMsgInfo: + """ + Validate a payload with CRC (shared by Default, Extended, etc. payload types). + + Args: + buffer: Complete packet buffer (including any start bytes) + header_size: Size of header (start_bytes + length + msg_id + extra fields) + length_bytes: Number of length bytes (1 or 2) + crc_start_offset: Offset from start of buffer where CRC calculation begins + + Returns: + FrameMsgInfo with valid=True if checksum matches + """ + result = FrameMsgInfo() + footer_size = 2 # CRC is always 2 bytes + overhead = header_size + footer_size + + if len(buffer) < overhead: + return result + + msg_length = len(buffer) - overhead + + # Calculate expected CRC range: from crc_start_offset to before the CRC bytes + crc_data_len = msg_length + 1 + length_bytes # msg_id (1) + length_bytes + payload + ck = fletcher_checksum(buffer, crc_start_offset, crc_start_offset + crc_data_len) + + if ck[0] == buffer[-2] and ck[1] == buffer[-1]: + result.valid = True + result.msg_id = buffer[header_size - 1] # msg_id is last byte of header + result.msg_len = msg_length + result.msg_data = bytes(buffer[header_size:len(buffer) - footer_size]) + + return result + + +def validate_payload_minimal(buffer: Union[bytes, List[int]], header_size: int) -> FrameMsgInfo: + """ + Validate a minimal payload (no CRC, no length field). + + Args: + buffer: Complete packet buffer (including any start bytes) + header_size: Size of header (start_bytes + msg_id) + + Returns: + FrameMsgInfo with packet data + """ + result = FrameMsgInfo() + + if len(buffer) < header_size: + return result + + result.valid = True + result.msg_id = buffer[header_size - 1] # msg_id is last byte of header + result.msg_len = len(buffer) - header_size + result.msg_data = bytes(buffer[header_size:]) + + return result + + +def encode_payload_with_crc(output: list, msg_id: int, msg: bytes, + length_bytes: int, crc_start_offset: int) -> None: + """ + Encode payload with length and CRC (modifies output list in place). + + Args: + output: Output list to append to (already contains start bytes) + msg_id: Message ID + msg: Message payload data + length_bytes: Number of length bytes (1 or 2) + crc_start_offset: Offset in output where CRC calculation begins + """ + # Add length field + if length_bytes == 1: + output.append(len(msg) & 0xFF) + else: + output.append(len(msg) & 0xFF) + output.append((len(msg) >> 8) & 0xFF) + + # Add msg_id + output.append(msg_id) + + # Add payload + output.extend(msg) + + # Calculate and add CRC + crc_data_len = len(msg) + 1 + length_bytes + ck = fletcher_checksum(output, crc_start_offset, crc_start_offset + crc_data_len) + output.append(ck[0]) + output.append(ck[1]) + + +def encode_payload_minimal(output: list, msg_id: int, msg: bytes) -> None: + """ + Encode minimal payload (no length, no CRC). + + Args: + output: Output list to append to (already contains start bytes) + msg_id: Message ID + msg: Message payload data + """ + output.append(msg_id) + output.extend(msg) ''' @staticmethod @@ -79,7 +193,11 @@ def generate_format_file(fmt): yield f'# Generated by {version} at {time.asctime()}.\n\n' yield 'from enum import Enum\n' yield 'from typing import Callable, List, Union\n' - yield 'from .frame_base import FrameMsgInfo, fletcher_checksum\n\n' + yield 'from .frame_base import (\n' + yield ' FrameMsgInfo, fletcher_checksum,\n' + yield ' validate_payload_with_crc, validate_payload_minimal,\n' + yield ' encode_payload_with_crc, encode_payload_minimal,\n' + yield ')\n\n' yield from FrameParserPyGen.generate_format(fmt) @@ -93,6 +211,11 @@ def generate_init(formats): yield ' FrameFormatType,\n' yield ' FrameMsgInfo,\n' yield ' fletcher_checksum,\n' + yield ' # Shared payload parsing functions\n' + yield ' validate_payload_with_crc,\n' + yield ' validate_payload_minimal,\n' + yield ' encode_payload_with_crc,\n' + yield ' encode_payload_minimal,\n' yield ')\n\n' yield '# Individual frame format parsers\n' @@ -106,6 +229,11 @@ def generate_init(formats): yield ' "FrameFormatType",\n' yield ' "FrameMsgInfo",\n' yield ' "fletcher_checksum",\n' + yield ' # Shared payload parsing functions\n' + yield ' "validate_payload_with_crc",\n' + yield ' "validate_payload_minimal",\n' + yield ' "encode_payload_with_crc",\n' + yield ' "encode_payload_minimal",\n' yield ' # Frame formats\n' for fmt in formats: yield f' "{fmt.name}",\n' @@ -157,6 +285,120 @@ class FrameMsgInfo: msg_data: bytes = b'' +''' + + # Generate shared payload parsing functions + yield '''# ============================================================================= +# Shared Payload Parsing Functions +# ============================================================================= +# These functions handle payload validation/encoding independent of framing. +# Frame formats (Tiny/Basic) use these for the common parsing logic. + +def validate_payload_with_crc(buffer: Union[bytes, List[int]], header_size: int, + length_bytes: int, crc_start_offset: int = 0) -> FrameMsgInfo: + """ + Validate a payload with CRC (shared by Default, Extended, etc. payload types). + + Args: + buffer: Complete packet buffer (including any start bytes) + header_size: Size of header (start_bytes + length + msg_id + extra fields) + length_bytes: Number of length bytes (1 or 2) + crc_start_offset: Offset from start of buffer where CRC calculation begins + + Returns: + FrameMsgInfo with valid=True if checksum matches + """ + result = FrameMsgInfo() + footer_size = 2 # CRC is always 2 bytes + overhead = header_size + footer_size + + if len(buffer) < overhead: + return result + + msg_length = len(buffer) - overhead + + # Calculate expected CRC range: from crc_start_offset to before the CRC bytes + crc_data_len = msg_length + 1 + length_bytes # msg_id (1) + length_bytes + payload + ck = fletcher_checksum(buffer, crc_start_offset, crc_start_offset + crc_data_len) + + if ck[0] == buffer[-2] and ck[1] == buffer[-1]: + result.valid = True + result.msg_id = buffer[header_size - 1] # msg_id is last byte of header + result.msg_len = msg_length + result.msg_data = bytes(buffer[header_size:len(buffer) - footer_size]) + + return result + + +def validate_payload_minimal(buffer: Union[bytes, List[int]], header_size: int) -> FrameMsgInfo: + """ + Validate a minimal payload (no CRC, no length field). + + Args: + buffer: Complete packet buffer (including any start bytes) + header_size: Size of header (start_bytes + msg_id) + + Returns: + FrameMsgInfo with packet data + """ + result = FrameMsgInfo() + + if len(buffer) < header_size: + return result + + result.valid = True + result.msg_id = buffer[header_size - 1] # msg_id is last byte of header + result.msg_len = len(buffer) - header_size + result.msg_data = bytes(buffer[header_size:]) + + return result + + +def encode_payload_with_crc(output: list, msg_id: int, msg: bytes, + length_bytes: int, crc_start_offset: int) -> None: + """ + Encode payload with length and CRC (modifies output list in place). + + Args: + output: Output list to append to (already contains start bytes) + msg_id: Message ID + msg: Message payload data + length_bytes: Number of length bytes (1 or 2) + crc_start_offset: Offset in output where CRC calculation begins + """ + # Add length field + if length_bytes == 1: + output.append(len(msg) & 0xFF) + else: + output.append(len(msg) & 0xFF) + output.append((len(msg) >> 8) & 0xFF) + + # Add msg_id + output.append(msg_id) + + # Add payload + output.extend(msg) + + # Calculate and add CRC + crc_data_len = len(msg) + 1 + length_bytes + ck = fletcher_checksum(output, crc_start_offset, crc_start_offset + crc_data_len) + output.append(ck[0]) + output.append(ck[1]) + + +def encode_payload_minimal(output: list, msg_id: int, msg: bytes) -> None: + """ + Encode minimal payload (no length, no CRC). + + Args: + output: Output list to append to (already contains start bytes) + msg_id: Message ID + msg: Message payload data + """ + output.append(msg_id) + output.extend(msg) + + ''' # Generate individual frame format classes @@ -331,36 +573,25 @@ def generate_format(fmt): yield f' self.state = {class_name}ParserState.GETTING_PAYLOAD\n' yield '\n' - # GETTING_PAYLOAD state + # GETTING_PAYLOAD state - uses shared payload validation yield f' elif self.state == {class_name}ParserState.GETTING_PAYLOAD:\n' yield f' self.buffer.append(byte)\n\n' yield f' if len(self.buffer) >= self.packet_size:\n' if fmt.has_crc: - yield f' # Validate checksum\n' - yield f' msg_length = self.packet_size - self.OVERHEAD\n' crc_start = len(fmt.start_bytes) - crc_len = f'msg_length + 1' - if fmt.has_length: - crc_len += f' + {fmt.length_bytes}' - yield f' ck = fletcher_checksum(self.buffer, {crc_start}, {crc_start} + {crc_len})\n' - yield f' if ck[0] == self.buffer[-2] and ck[1] == self.buffer[-1]:\n' - yield f' result.valid = True\n' - yield f' result.msg_id = self.msg_id\n' - yield f' result.msg_len = msg_length\n' - yield f' result.msg_data = bytes(self.buffer[self.HEADER_SIZE:self.packet_size - self.FOOTER_SIZE])\n' + yield f' # Use shared payload validation with CRC\n' + yield f' result = validate_payload_with_crc(self.buffer, self.HEADER_SIZE, {fmt.length_bytes}, {crc_start})\n' else: - yield f' result.valid = True\n' - yield f' result.msg_id = self.msg_id\n' - yield f' result.msg_len = self.packet_size - self.OVERHEAD\n' - yield f' result.msg_data = bytes(self.buffer[self.HEADER_SIZE:])\n' + yield f' # Use shared minimal payload validation\n' + yield f' result = validate_payload_minimal(self.buffer, self.HEADER_SIZE)\n' reset_state = 'LOOKING_FOR_START1' if len(fmt.start_bytes) > 1 else ('LOOKING_FOR_START' if fmt.start_bytes else 'GETTING_MSG_ID') yield f' self.state = {class_name}ParserState.{reset_state}\n' yield '\n' yield f' return result\n\n' - # encode method + # encode method - uses shared payload encoding functions yield f' def encode(self, msg_id: int, msg: bytes) -> bytes:\n' yield f' """\n' yield f' Encode a message with {name} format\n' @@ -374,29 +605,19 @@ def generate_format(fmt): yield f' """\n' yield f' output = []\n' - # Write header + # Write start bytes (frame-specific) for i, (sb_name, sb_value) in enumerate(fmt.start_bytes): const_name = f'self.START_BYTE{i + 1}' if len(fmt.start_bytes) > 1 else 'self.START_BYTE' yield f' output.append({const_name})\n' - yield f' output.append(msg_id)\n' - - if fmt.has_length: - if fmt.length_bytes == 1: - yield f' output.append(len(msg) & 0xFF)\n' - else: - yield f' output.append(len(msg) & 0xFF)\n' - yield f' output.append((len(msg) >> 8) & 0xFF)\n' - - yield f' output.extend(msg)\n' + # Use shared payload encoding function if fmt.has_crc: crc_start = len(fmt.start_bytes) - crc_len = 'len(msg) + 1' - if fmt.has_length: - crc_len += f' + {fmt.length_bytes}' - yield f' ck = fletcher_checksum(output, {crc_start}, {crc_start} + {crc_len})\n' - yield f' output.append(ck[0])\n' - yield f' output.append(ck[1])\n' + yield f' # Use shared payload encoding with CRC\n' + yield f' encode_payload_with_crc(output, msg_id, msg, {fmt.length_bytes}, {crc_start})\n' + else: + yield f' # Use shared minimal payload encoding\n' + yield f' encode_payload_minimal(output, msg_id, msg)\n' yield f' return bytes(output)\n\n' @@ -405,7 +626,7 @@ def generate_format(fmt): yield f' """Encode a message object (must have msg_id and pack() method)"""\n' yield f' return self.encode(msg.msg_id, msg.pack())\n\n' - # validate_packet method + # validate_packet method - uses shared payload validation functions yield f' @staticmethod\n' yield f' def validate_packet(buffer: Union[bytes, List[int]]) -> FrameMsgInfo:\n' yield f' """\n' @@ -417,37 +638,25 @@ def generate_format(fmt): yield f' Returns:\n' yield f' FrameMsgInfo with valid=True if packet is valid\n' yield f' """\n' - yield f' result = FrameMsgInfo()\n\n' yield f' if len(buffer) < {class_name}.OVERHEAD:\n' - yield f' return result\n\n' + yield f' return FrameMsgInfo()\n\n' # Check start bytes for i, (sb_name, sb_value) in enumerate(fmt.start_bytes): const_name = f'{class_name}.START_BYTE{i + 1}' if len(fmt.start_bytes) > 1 else f'{class_name}.START_BYTE' yield f' if buffer[{i}] != {const_name}:\n' - yield f' return result\n' + yield f' return FrameMsgInfo()\n' - yield f'\n msg_length = len(buffer) - {class_name}.OVERHEAD\n\n' + yield f'\n' + # Use shared payload validation function if fmt.has_crc: crc_start = len(fmt.start_bytes) - crc_len = 'msg_length + 1' - if fmt.has_length: - crc_len += f' + {fmt.length_bytes}' - yield f' # Validate checksum\n' - yield f' ck = fletcher_checksum(buffer, {crc_start}, {crc_start} + {crc_len})\n' - yield f' if ck[0] == buffer[-2] and ck[1] == buffer[-1]:\n' - yield f' result.valid = True\n' - yield f' result.msg_id = buffer[{len(fmt.start_bytes)}]\n' - yield f' result.msg_len = msg_length\n' - yield f' result.msg_data = bytes(buffer[{class_name}.HEADER_SIZE:len(buffer) - {class_name}.FOOTER_SIZE])\n' + yield f' # Use shared payload validation with CRC\n' + yield f' return validate_payload_with_crc(buffer, {class_name}.HEADER_SIZE, {fmt.length_bytes}, {crc_start})\n' else: - yield f' result.valid = True\n' - yield f' result.msg_id = buffer[{len(fmt.start_bytes)}]\n' - yield f' result.msg_len = msg_length\n' - yield f' result.msg_data = bytes(buffer[{class_name}.HEADER_SIZE:])\n' - - yield f'\n return result\n' + yield f' # Use shared minimal payload validation\n' + yield f' return validate_payload_minimal(buffer, {class_name}.HEADER_SIZE)\n' def generate_py_frame_parsers(formats): diff --git a/src/struct_frame/frame_parser_ts_gen.py b/src/struct_frame/frame_parser_ts_gen.py index 83e7d7b4..cdf8fff3 100644 --- a/src/struct_frame/frame_parser_ts_gen.py +++ b/src/struct_frame/frame_parser_ts_gen.py @@ -79,6 +79,113 @@ def generate_base(formats): msg_data: new Uint8Array(0) }; } + +// ============================================================================= +// Shared Payload Parsing Functions +// ============================================================================= +// These functions handle payload validation/encoding independent of framing. +// Frame formats (Tiny/Basic) use these for the common parsing logic. + +/** + * Validate a payload with CRC (shared by Default, Extended, etc. payload types). + */ +export function validate_payload_with_crc( + buffer: Uint8Array | number[], + headerSize: number, + lengthBytes: number, + crcStartOffset: number +): FrameMsgInfo { + const result = createFrameMsgInfo(); + const footerSize = 2; // CRC is always 2 bytes + const overhead = headerSize + footerSize; + + if (buffer.length < overhead) { + return result; + } + + const msgLength = buffer.length - overhead; + + // Calculate expected CRC range: from crcStartOffset to before the CRC bytes + const crcDataLen = msgLength + 1 + lengthBytes; // msg_id (1) + lengthBytes + payload + const ck = fletcher_checksum(buffer, crcStartOffset, crcStartOffset + crcDataLen); + + if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { + result.valid = true; + result.msg_id = buffer[headerSize - 1]; // msg_id is last byte of header + result.msg_len = msgLength; + result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, headerSize, buffer.length - footerSize)); + } + + return result; +} + +/** + * Validate a minimal payload (no CRC, no length field). + */ +export function validate_payload_minimal( + buffer: Uint8Array | number[], + headerSize: number +): FrameMsgInfo { + const result = createFrameMsgInfo(); + + if (buffer.length < headerSize) { + return result; + } + + result.valid = true; + result.msg_id = buffer[headerSize - 1]; // msg_id is last byte of header + result.msg_len = buffer.length - headerSize; + result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, headerSize)); + + return result; +} + +/** + * Encode payload with length and CRC (modifies output array in place). + */ +export function encode_payload_with_crc( + output: number[], + msgId: number, + msg: Uint8Array | number[], + lengthBytes: number, + crcStartOffset: number +): void { + // Add length field + if (lengthBytes === 1) { + output.push(msg.length & 0xFF); + } else { + output.push(msg.length & 0xFF); + output.push((msg.length >> 8) & 0xFF); + } + + // Add msg_id + output.push(msgId); + + // Add payload + for (let i = 0; i < msg.length; i++) { + output.push(msg[i]); + } + + // Calculate and add CRC + const crcDataLen = msg.length + 1 + lengthBytes; + const ck = fletcher_checksum(output, crcStartOffset, crcStartOffset + crcDataLen); + output.push(ck[0]); + output.push(ck[1]); +} + +/** + * Encode minimal payload (no length, no CRC). + */ +export function encode_payload_minimal( + output: number[], + msgId: number, + msg: Uint8Array | number[] +): void { + output.push(msgId); + for (let i = 0; i < msg.length; i++) { + output.push(msg[i]); + } +} ''' @staticmethod @@ -86,7 +193,11 @@ def generate_format_file(fmt): """Generate a TypeScript file for a single frame format""" yield '// Automatically generated frame parser\n' yield f'// Generated by {version} at {time.asctime()}.\n\n' - yield 'import { FrameMsgInfo, createFrameMsgInfo, fletcher_checksum } from \'./frame_base\';\n\n' + yield 'import {\n' + yield ' FrameMsgInfo, createFrameMsgInfo, fletcher_checksum,\n' + yield ' validate_payload_with_crc, validate_payload_minimal,\n' + yield ' encode_payload_with_crc, encode_payload_minimal,\n' + yield '} from \'./frame_base\';\n\n' yield from FrameParserTsGen.generate_format(fmt) @@ -101,6 +212,11 @@ def generate_index(formats): yield ' FrameMsgInfo,\n' yield ' createFrameMsgInfo,\n' yield ' fletcher_checksum,\n' + yield ' // Shared payload parsing functions\n' + yield ' validate_payload_with_crc,\n' + yield ' validate_payload_minimal,\n' + yield ' encode_payload_with_crc,\n' + yield ' encode_payload_minimal,\n' yield '} from \'./frame_base\';\n\n' yield '// Individual frame format parsers\n' @@ -160,6 +276,113 @@ def generate(formats): }; } +// ============================================================================= +// Shared Payload Parsing Functions +// ============================================================================= +// These functions handle payload validation/encoding independent of framing. +// Frame formats (Tiny/Basic) use these for the common parsing logic. + +/** + * Validate a payload with CRC (shared by Default, Extended, etc. payload types). + */ +export function validate_payload_with_crc( + buffer: Uint8Array | number[], + headerSize: number, + lengthBytes: number, + crcStartOffset: number +): FrameMsgInfo { + const result = createFrameMsgInfo(); + const footerSize = 2; // CRC is always 2 bytes + const overhead = headerSize + footerSize; + + if (buffer.length < overhead) { + return result; + } + + const msgLength = buffer.length - overhead; + + // Calculate expected CRC range: from crcStartOffset to before the CRC bytes + const crcDataLen = msgLength + 1 + lengthBytes; // msg_id (1) + lengthBytes + payload + const ck = fletcher_checksum(buffer, crcStartOffset, crcStartOffset + crcDataLen); + + if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { + result.valid = true; + result.msg_id = buffer[headerSize - 1]; // msg_id is last byte of header + result.msg_len = msgLength; + result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, headerSize, buffer.length - footerSize)); + } + + return result; +} + +/** + * Validate a minimal payload (no CRC, no length field). + */ +export function validate_payload_minimal( + buffer: Uint8Array | number[], + headerSize: number +): FrameMsgInfo { + const result = createFrameMsgInfo(); + + if (buffer.length < headerSize) { + return result; + } + + result.valid = true; + result.msg_id = buffer[headerSize - 1]; // msg_id is last byte of header + result.msg_len = buffer.length - headerSize; + result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, headerSize)); + + return result; +} + +/** + * Encode payload with length and CRC (modifies output array in place). + */ +export function encode_payload_with_crc( + output: number[], + msgId: number, + msg: Uint8Array | number[], + lengthBytes: number, + crcStartOffset: number +): void { + // Add length field + if (lengthBytes === 1) { + output.push(msg.length & 0xFF); + } else { + output.push(msg.length & 0xFF); + output.push((msg.length >> 8) & 0xFF); + } + + // Add msg_id + output.push(msgId); + + // Add payload + for (let i = 0; i < msg.length; i++) { + output.push(msg[i]); + } + + // Calculate and add CRC + const crcDataLen = msg.length + 1 + lengthBytes; + const ck = fletcher_checksum(output, crcStartOffset, crcStartOffset + crcDataLen); + output.push(ck[0]); + output.push(ck[1]); +} + +/** + * Encode minimal payload (no length, no CRC). + */ +export function encode_payload_minimal( + output: number[], + msgId: number, + msg: Uint8Array | number[] +): void { + output.push(msgId); + for (let i = 0; i < msg.length; i++) { + output.push(msg[i]); + } +} + ''' # Generate individual frame format classes @@ -354,30 +577,28 @@ def generate_format(fmt): yield f' }}\n' yield f' break;\n\n' - # GETTING_PAYLOAD state + # GETTING_PAYLOAD state - uses shared payload validation yield f' case {class_name}ParserState.GETTING_PAYLOAD:\n' yield f' this.buffer.push(byte);\n\n' yield f' if (this.buffer.length >= this.packet_size) {{\n' if fmt.has_crc: - yield f' // Validate checksum\n' - yield f' const msg_length = this.packet_size - {class_name}.OVERHEAD;\n' crc_start = len(fmt.start_bytes) - crc_len = f'msg_length + 1' - if fmt.has_length: - crc_len += f' + {fmt.length_bytes}' - yield f' const ck = fletcher_checksum(this.buffer, {crc_start}, {crc_start} + {crc_len});\n' - yield f' if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) {{\n' - yield f' result.valid = true;\n' - yield f' result.msg_id = this.msg_id;\n' - yield f' result.msg_len = msg_length;\n' - yield f' result.msg_data = new Uint8Array(this.buffer.slice({class_name}.HEADER_SIZE, this.packet_size - {class_name}.FOOTER_SIZE));\n' + yield f' // Use shared payload validation with CRC\n' + yield f' const validationResult = validate_payload_with_crc(this.buffer, {class_name}.HEADER_SIZE, {fmt.length_bytes}, {crc_start});\n' + yield f' if (validationResult.valid) {{\n' + yield f' result.valid = validationResult.valid;\n' + yield f' result.msg_id = validationResult.msg_id;\n' + yield f' result.msg_len = validationResult.msg_len;\n' + yield f' result.msg_data = validationResult.msg_data;\n' yield f' }}\n' else: - yield f' result.valid = true;\n' - yield f' result.msg_id = this.msg_id;\n' - yield f' result.msg_len = this.packet_size - {class_name}.OVERHEAD;\n' - yield f' result.msg_data = new Uint8Array(this.buffer.slice({class_name}.HEADER_SIZE));\n' + yield f' // Use shared minimal payload validation\n' + yield f' const validationResult = validate_payload_minimal(this.buffer, {class_name}.HEADER_SIZE);\n' + yield f' result.valid = validationResult.valid;\n' + yield f' result.msg_id = validationResult.msg_id;\n' + yield f' result.msg_len = validationResult.msg_len;\n' + yield f' result.msg_data = validationResult.msg_data;\n' reset_state = 'LOOKING_FOR_START1' if len(fmt.start_bytes) > 1 else ('LOOKING_FOR_START' if fmt.start_bytes else 'GETTING_MSG_ID') yield f' this.state = {class_name}ParserState.{reset_state};\n' @@ -388,7 +609,7 @@ def generate_format(fmt): yield f' return result;\n' yield f' }}\n\n' - # encode method + # encode method - uses shared payload encoding functions yield f' /**\n' yield f' * Encode a message with {name} format\n' yield f' * @param msg_id Message ID\n' @@ -398,76 +619,52 @@ def generate_format(fmt): yield f' static encode(msg_id: number, msg: Uint8Array | number[]): Uint8Array {{\n' yield f' const output: number[] = [];\n' - # Write header + # Write start bytes (frame-specific) for i, (sb_name, sb_value) in enumerate(fmt.start_bytes): const_name = f'{class_name}.START_BYTE{i + 1}' if len(fmt.start_bytes) > 1 else f'{class_name}.START_BYTE' yield f' output.push({const_name});\n' - yield f' output.push(msg_id);\n' - - if fmt.has_length: - if fmt.length_bytes == 1: - yield f' output.push(msg.length & 0xFF);\n' - else: - yield f' output.push(msg.length & 0xFF);\n' - yield f' output.push((msg.length >> 8) & 0xFF);\n' - - yield f' for (let i = 0; i < msg.length; i++) {{\n' - yield f' output.push(msg[i]);\n' - yield f' }}\n' + # Use shared payload encoding function if fmt.has_crc: crc_start = len(fmt.start_bytes) - crc_len = 'msg.length + 1' - if fmt.has_length: - crc_len += f' + {fmt.length_bytes}' - yield f' const ck = fletcher_checksum(output, {crc_start}, {crc_start} + {crc_len});\n' - yield f' output.push(ck[0]);\n' - yield f' output.push(ck[1]);\n' + yield f' // Use shared payload encoding with CRC\n' + yield f' encode_payload_with_crc(output, msg_id, msg, {fmt.length_bytes}, {crc_start});\n' + else: + yield f' // Use shared minimal payload encoding\n' + yield f' encode_payload_minimal(output, msg_id, msg);\n' yield f' return new Uint8Array(output);\n' yield f' }}\n\n' - # validate_packet static method + # validate_packet static method - uses shared payload validation functions yield f' /**\n' yield f' * Validate a complete {name} packet in a buffer\n' yield f' * @param buffer Buffer containing the complete packet\n' yield f' * @returns FrameMsgInfo with valid=true if packet is valid\n' yield f' */\n' yield f' static validate_packet(buffer: Uint8Array | number[]): FrameMsgInfo {{\n' - yield f' const result = createFrameMsgInfo();\n\n' yield f' if (buffer.length < {class_name}.OVERHEAD) {{\n' - yield f' return result;\n' + yield f' return createFrameMsgInfo();\n' yield f' }}\n\n' # Check start bytes for i, (sb_name, sb_value) in enumerate(fmt.start_bytes): const_name = f'{class_name}.START_BYTE{i + 1}' if len(fmt.start_bytes) > 1 else f'{class_name}.START_BYTE' yield f' if (buffer[{i}] !== {const_name}) {{\n' - yield f' return result;\n' + yield f' return createFrameMsgInfo();\n' yield f' }}\n' - yield f'\n const msg_length = buffer.length - {class_name}.OVERHEAD;\n\n' + yield f'\n' + # Use shared payload validation function if fmt.has_crc: crc_start = len(fmt.start_bytes) - crc_len = 'msg_length + 1' - if fmt.has_length: - crc_len += f' + {fmt.length_bytes}' - yield f' // Validate checksum\n' - yield f' const ck = fletcher_checksum(buffer, {crc_start}, {crc_start} + {crc_len});\n' - yield f' if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) {{\n' - yield f' result.valid = true;\n' - yield f' result.msg_id = buffer[{len(fmt.start_bytes)}];\n' - yield f' result.msg_len = msg_length;\n' - yield f' result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, {class_name}.HEADER_SIZE, buffer.length - {class_name}.FOOTER_SIZE));\n' - yield f' }}\n' + yield f' // Use shared payload validation with CRC\n' + yield f' return validate_payload_with_crc(buffer, {class_name}.HEADER_SIZE, {fmt.length_bytes}, {crc_start});\n' else: - yield f' result.valid = true;\n' - yield f' result.msg_id = buffer[{len(fmt.start_bytes)}];\n' - yield f' result.msg_len = msg_length;\n' - yield f' result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, {class_name}.HEADER_SIZE));\n' + yield f' // Use shared minimal payload validation\n' + yield f' return validate_payload_minimal(buffer, {class_name}.HEADER_SIZE);\n' - yield f'\n return result;\n' yield f' }}\n' yield f'}}\n' @@ -546,10 +743,103 @@ def generate_base(formats): }; } +// ============================================================================= +// Shared Payload Parsing Functions +// ============================================================================= +// These functions handle payload validation/encoding independent of framing. +// Frame formats (Tiny/Basic) use these for the common parsing logic. + +/** + * Validate a payload with CRC (shared by Default, Extended, etc. payload types). + */ +function validate_payload_with_crc(buffer, headerSize, lengthBytes, crcStartOffset) { + const result = createFrameMsgInfo(); + const footerSize = 2; // CRC is always 2 bytes + const overhead = headerSize + footerSize; + + if (buffer.length < overhead) { + return result; + } + + const msgLength = buffer.length - overhead; + + // Calculate expected CRC range: from crcStartOffset to before the CRC bytes + const crcDataLen = msgLength + 1 + lengthBytes; // msg_id (1) + lengthBytes + payload + const ck = fletcher_checksum(buffer, crcStartOffset, crcStartOffset + crcDataLen); + + if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { + result.valid = true; + result.msg_id = buffer[headerSize - 1]; // msg_id is last byte of header + result.msg_len = msgLength; + result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, headerSize, buffer.length - footerSize)); + } + + return result; +} + +/** + * Validate a minimal payload (no CRC, no length field). + */ +function validate_payload_minimal(buffer, headerSize) { + const result = createFrameMsgInfo(); + + if (buffer.length < headerSize) { + return result; + } + + result.valid = true; + result.msg_id = buffer[headerSize - 1]; // msg_id is last byte of header + result.msg_len = buffer.length - headerSize; + result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, headerSize)); + + return result; +} + +/** + * Encode payload with length and CRC (modifies output array in place). + */ +function encode_payload_with_crc(output, msgId, msg, lengthBytes, crcStartOffset) { + // Add length field + if (lengthBytes === 1) { + output.push(msg.length & 0xFF); + } else { + output.push(msg.length & 0xFF); + output.push((msg.length >> 8) & 0xFF); + } + + // Add msg_id + output.push(msgId); + + // Add payload + for (let i = 0; i < msg.length; i++) { + output.push(msg[i]); + } + + // Calculate and add CRC + const crcDataLen = msg.length + 1 + lengthBytes; + const ck = fletcher_checksum(output, crcStartOffset, crcStartOffset + crcDataLen); + output.push(ck[0]); + output.push(ck[1]); +} + +/** + * Encode minimal payload (no length, no CRC). + */ +function encode_payload_minimal(output, msgId, msg) { + output.push(msgId); + for (let i = 0; i < msg.length; i++) { + output.push(msg[i]); + } +} + module.exports = { FrameFormatType, fletcher_checksum, createFrameMsgInfo, + validate_payload_with_crc, + validate_payload_minimal, + encode_payload_with_crc, + encode_payload_minimal, }; ''' @@ -558,7 +848,11 @@ def generate_format_file(fmt): """Generate a JavaScript file for a single frame format""" yield '// Automatically generated frame parser\n' yield f'// Generated by {version} at {time.asctime()}.\n\n' - yield 'const { createFrameMsgInfo, fletcher_checksum } = require(\'./frame_base\');\n\n' + yield 'const {\n' + yield ' createFrameMsgInfo, fletcher_checksum,\n' + yield ' validate_payload_with_crc, validate_payload_minimal,\n' + yield ' encode_payload_with_crc, encode_payload_minimal,\n' + yield '} = require(\'./frame_base\');\n\n' yield from FrameParserJsGen.generate_format(fmt) @@ -630,6 +924,95 @@ def generate(formats): }; } +// ============================================================================= +// Shared Payload Parsing Functions +// ============================================================================= +// These functions handle payload validation/encoding independent of framing. +// Frame formats (Tiny/Basic) use these for the common parsing logic. + +/** + * Validate a payload with CRC (shared by Default, Extended, etc. payload types). + */ +function validate_payload_with_crc(buffer, headerSize, lengthBytes, crcStartOffset) { + const result = createFrameMsgInfo(); + const footerSize = 2; // CRC is always 2 bytes + const overhead = headerSize + footerSize; + + if (buffer.length < overhead) { + return result; + } + + const msgLength = buffer.length - overhead; + + // Calculate expected CRC range: from crcStartOffset to before the CRC bytes + const crcDataLen = msgLength + 1 + lengthBytes; // msg_id (1) + lengthBytes + payload + const ck = fletcher_checksum(buffer, crcStartOffset, crcStartOffset + crcDataLen); + + if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) { + result.valid = true; + result.msg_id = buffer[headerSize - 1]; // msg_id is last byte of header + result.msg_len = msgLength; + result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, headerSize, buffer.length - footerSize)); + } + + return result; +} + +/** + * Validate a minimal payload (no CRC, no length field). + */ +function validate_payload_minimal(buffer, headerSize) { + const result = createFrameMsgInfo(); + + if (buffer.length < headerSize) { + return result; + } + + result.valid = true; + result.msg_id = buffer[headerSize - 1]; // msg_id is last byte of header + result.msg_len = buffer.length - headerSize; + result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, headerSize)); + + return result; +} + +/** + * Encode payload with length and CRC (modifies output array in place). + */ +function encode_payload_with_crc(output, msgId, msg, lengthBytes, crcStartOffset) { + // Add length field + if (lengthBytes === 1) { + output.push(msg.length & 0xFF); + } else { + output.push(msg.length & 0xFF); + output.push((msg.length >> 8) & 0xFF); + } + + // Add msg_id + output.push(msgId); + + // Add payload + for (let i = 0; i < msg.length; i++) { + output.push(msg[i]); + } + + // Calculate and add CRC + const crcDataLen = msg.length + 1 + lengthBytes; + const ck = fletcher_checksum(output, crcStartOffset, crcStartOffset + crcDataLen); + output.push(ck[0]); + output.push(ck[1]); +} + +/** + * Encode minimal payload (no length, no CRC). + */ +function encode_payload_minimal(output, msgId, msg) { + output.push(msgId); + for (let i = 0; i < msg.length; i++) { + output.push(msg[i]); + } +} + ''' # Generate individual frame format classes @@ -643,6 +1026,10 @@ def generate(formats): yield ' FrameFormatType,\n' yield ' fletcher_checksum,\n' yield ' createFrameMsgInfo,\n' + yield ' validate_payload_with_crc,\n' + yield ' validate_payload_minimal,\n' + yield ' encode_payload_with_crc,\n' + yield ' encode_payload_minimal,\n' for fmt in formats: yield f' {fmt.name},\n' yield f' {fmt.name}ParserState,\n' @@ -801,29 +1188,28 @@ def generate_format(fmt): yield f' }}\n' yield f' break;\n\n' - # GETTING_PAYLOAD state + # GETTING_PAYLOAD state - uses shared payload validation yield f' case {class_name}ParserState.GETTING_PAYLOAD:\n' yield f' this.buffer.push(byte);\n\n' yield f' if (this.buffer.length >= this.packet_size) {{\n' if fmt.has_crc: - yield f' const msg_length = this.packet_size - {class_name}.OVERHEAD;\n' crc_start = len(fmt.start_bytes) - crc_len = f'msg_length + 1' - if fmt.has_length: - crc_len += f' + {fmt.length_bytes}' - yield f' const ck = fletcher_checksum(this.buffer, {crc_start}, {crc_start} + {crc_len});\n' - yield f' if (ck[0] === this.buffer[this.buffer.length - 2] && ck[1] === this.buffer[this.buffer.length - 1]) {{\n' - yield f' result.valid = true;\n' - yield f' result.msg_id = this.msg_id;\n' - yield f' result.msg_len = msg_length;\n' - yield f' result.msg_data = new Uint8Array(this.buffer.slice({class_name}.HEADER_SIZE, this.packet_size - {class_name}.FOOTER_SIZE));\n' + yield f' // Use shared payload validation with CRC\n' + yield f' const validationResult = validate_payload_with_crc(this.buffer, {class_name}.HEADER_SIZE, {fmt.length_bytes}, {crc_start});\n' + yield f' if (validationResult.valid) {{\n' + yield f' result.valid = validationResult.valid;\n' + yield f' result.msg_id = validationResult.msg_id;\n' + yield f' result.msg_len = validationResult.msg_len;\n' + yield f' result.msg_data = validationResult.msg_data;\n' yield f' }}\n' else: - yield f' result.valid = true;\n' - yield f' result.msg_id = this.msg_id;\n' - yield f' result.msg_len = this.packet_size - {class_name}.OVERHEAD;\n' - yield f' result.msg_data = new Uint8Array(this.buffer.slice({class_name}.HEADER_SIZE));\n' + yield f' // Use shared minimal payload validation\n' + yield f' const validationResult = validate_payload_minimal(this.buffer, {class_name}.HEADER_SIZE);\n' + yield f' result.valid = validationResult.valid;\n' + yield f' result.msg_id = validationResult.msg_id;\n' + yield f' result.msg_len = validationResult.msg_len;\n' + yield f' result.msg_data = validationResult.msg_data;\n' reset_state = 'LOOKING_FOR_START1' if len(fmt.start_bytes) > 1 else ('LOOKING_FOR_START' if fmt.start_bytes else 'GETTING_MSG_ID') yield f' this.state = {class_name}ParserState.{reset_state};\n' @@ -834,72 +1220,50 @@ def generate_format(fmt): yield f' return result;\n' yield f' }}\n\n' - # Static encode method + # Static encode method - uses shared payload encoding functions yield f' static encode(msg_id, msg) {{\n' yield f' const output = [];\n' + # Write start bytes (frame-specific) for i, (sb_name, sb_value) in enumerate(fmt.start_bytes): const_name = f'{class_name}.START_BYTE{i + 1}' if len(fmt.start_bytes) > 1 else f'{class_name}.START_BYTE' yield f' output.push({const_name});\n' - yield f' output.push(msg_id);\n' - - if fmt.has_length: - if fmt.length_bytes == 1: - yield f' output.push(msg.length & 0xFF);\n' - else: - yield f' output.push(msg.length & 0xFF);\n' - yield f' output.push((msg.length >> 8) & 0xFF);\n' - - yield f' for (let i = 0; i < msg.length; i++) {{\n' - yield f' output.push(msg[i]);\n' - yield f' }}\n' + # Use shared payload encoding function if fmt.has_crc: crc_start = len(fmt.start_bytes) - crc_len = 'msg.length + 1' - if fmt.has_length: - crc_len += f' + {fmt.length_bytes}' - yield f' const ck = fletcher_checksum(output, {crc_start}, {crc_start} + {crc_len});\n' - yield f' output.push(ck[0]);\n' - yield f' output.push(ck[1]);\n' + yield f' // Use shared payload encoding with CRC\n' + yield f' encode_payload_with_crc(output, msg_id, msg, {fmt.length_bytes}, {crc_start});\n' + else: + yield f' // Use shared minimal payload encoding\n' + yield f' encode_payload_minimal(output, msg_id, msg);\n' yield f' return new Uint8Array(output);\n' yield f' }}\n\n' - # Static validate_packet method + # Static validate_packet method - uses shared payload validation functions yield f' static validate_packet(buffer) {{\n' - yield f' const result = createFrameMsgInfo();\n\n' yield f' if (buffer.length < {class_name}.OVERHEAD) {{\n' - yield f' return result;\n' + yield f' return createFrameMsgInfo();\n' yield f' }}\n\n' for i, (sb_name, sb_value) in enumerate(fmt.start_bytes): const_name = f'{class_name}.START_BYTE{i + 1}' if len(fmt.start_bytes) > 1 else f'{class_name}.START_BYTE' yield f' if (buffer[{i}] !== {const_name}) {{\n' - yield f' return result;\n' + yield f' return createFrameMsgInfo();\n' yield f' }}\n' - yield f'\n const msg_length = buffer.length - {class_name}.OVERHEAD;\n\n' + yield f'\n' + # Use shared payload validation function if fmt.has_crc: crc_start = len(fmt.start_bytes) - crc_len = 'msg_length + 1' - if fmt.has_length: - crc_len += f' + {fmt.length_bytes}' - yield f' const ck = fletcher_checksum(buffer, {crc_start}, {crc_start} + {crc_len});\n' - yield f' if (ck[0] === buffer[buffer.length - 2] && ck[1] === buffer[buffer.length - 1]) {{\n' - yield f' result.valid = true;\n' - yield f' result.msg_id = buffer[{len(fmt.start_bytes)}];\n' - yield f' result.msg_len = msg_length;\n' - yield f' result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, {class_name}.HEADER_SIZE, buffer.length - {class_name}.FOOTER_SIZE));\n' - yield f' }}\n' + yield f' // Use shared payload validation with CRC\n' + yield f' return validate_payload_with_crc(buffer, {class_name}.HEADER_SIZE, {fmt.length_bytes}, {crc_start});\n' else: - yield f' result.valid = true;\n' - yield f' result.msg_id = buffer[{len(fmt.start_bytes)}];\n' - yield f' result.msg_len = msg_length;\n' - yield f' result.msg_data = new Uint8Array(Array.prototype.slice.call(buffer, {class_name}.HEADER_SIZE));\n' + yield f' // Use shared minimal payload validation\n' + yield f' return validate_payload_minimal(buffer, {class_name}.HEADER_SIZE);\n' - yield f'\n return result;\n' yield f' }}\n' yield f'}}\n'