Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 205 additions & 0 deletions src/struct_frame/boilerplate/c/basic_frame.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
/* Automatically generated frame parser */
/* Generated by 0.0.1 at Wed Dec 3 17:57:16 2025. */

#pragma once

#include "frame_base.h"

/*===========================================================================
* BasicFrame Frame Format
*===========================================================================*/

/* BasicFrame constants */
#define BASIC_FRAME_START_BYTE1 0x90
#define BASIC_FRAME_START_BYTE2 0x91
#define BASIC_FRAME_HEADER_SIZE 3 /* start_byte1 + start_byte2 + msg_id */
#define BASIC_FRAME_FOOTER_SIZE 2 /* crc(2 bytes) */
#define BASIC_FRAME_OVERHEAD (BASIC_FRAME_HEADER_SIZE + BASIC_FRAME_FOOTER_SIZE)

/* BasicFrame parser states */
typedef enum basic_frame_parser_state {
BASIC_FRAME_LOOKING_FOR_START1 = 0,
BASIC_FRAME_LOOKING_FOR_START2 = 1,
BASIC_FRAME_GETTING_MSG_ID = 2,
BASIC_FRAME_GETTING_PAYLOAD = 3
} basic_frame_parser_state_t;

/* BasicFrame parser state structure */
typedef struct basic_frame_parser {
basic_frame_parser_state_t state;
uint8_t* buffer;
size_t buffer_max_size;
size_t buffer_index;
size_t packet_size;
uint8_t msg_id;
/* User-provided function to get message length from msg_id (for non-length frames) */
bool (*get_msg_length)(uint8_t msg_id, size_t* length);
} basic_frame_parser_t;

/* BasicFrame encode buffer structure */
typedef struct basic_frame_encode_buffer {
uint8_t* data;
size_t max_size;
size_t size;
bool in_progress;
size_t reserved_msg_size;
} basic_frame_encode_buffer_t;

/**
* Initialize a BasicFrame parser
*/
static inline void basic_frame_parser_init(basic_frame_parser_t* parser,
uint8_t* buffer, size_t buffer_size,
bool (*get_msg_length)(uint8_t msg_id, size_t* length)) {
parser->state = BASIC_FRAME_LOOKING_FOR_START1;
parser->buffer = buffer;
parser->buffer_max_size = buffer_size;
parser->buffer_index = 0;
parser->packet_size = 0;
parser->msg_id = 0;
parser->get_msg_length = get_msg_length;
}

/**
* Reset BasicFrame parser state
*/
static inline void basic_frame_parser_reset(basic_frame_parser_t* parser) {
parser->state = BASIC_FRAME_LOOKING_FOR_START1;
parser->buffer_index = 0;
parser->packet_size = 0;
parser->msg_id = 0;
}

/**
* Parse a single byte with BasicFrame format
* Returns frame_msg_info_t with valid=true when a complete valid message is received
*/
static inline frame_msg_info_t basic_frame_parse_byte(basic_frame_parser_t* parser, uint8_t byte) {
frame_msg_info_t result = {false, 0, 0, NULL};

switch (parser->state) {
case BASIC_FRAME_LOOKING_FOR_START1:
if (byte == BASIC_FRAME_START_BYTE1) {
parser->buffer[0] = byte;
parser->buffer_index = 1;
parser->state = BASIC_FRAME_LOOKING_FOR_START2;
}
break;

case BASIC_FRAME_LOOKING_FOR_START2:
if (byte == BASIC_FRAME_START_BYTE2) {
parser->buffer[1] = byte;
parser->buffer_index = 2;
parser->state = BASIC_FRAME_GETTING_MSG_ID;
} else if (byte == BASIC_FRAME_START_BYTE1) {
parser->buffer[0] = byte;
parser->buffer_index = 1;
parser->state = BASIC_FRAME_LOOKING_FOR_START2;
} else {
parser->state = BASIC_FRAME_LOOKING_FOR_START1;
}
break;

case BASIC_FRAME_GETTING_MSG_ID:
parser->buffer[parser->buffer_index++] = byte;
parser->msg_id = byte;
{
size_t msg_length = 0;
if (parser->get_msg_length && parser->get_msg_length(byte, &msg_length)) {
parser->packet_size = BASIC_FRAME_OVERHEAD + msg_length;
if (parser->packet_size <= parser->buffer_max_size) {
parser->state = BASIC_FRAME_GETTING_PAYLOAD;
} else {
parser->state = BASIC_FRAME_LOOKING_FOR_START1;
}
} else {
parser->state = BASIC_FRAME_LOOKING_FOR_START1;
}
}
break;

case BASIC_FRAME_GETTING_PAYLOAD:
if (parser->buffer_index < parser->buffer_max_size) {
parser->buffer[parser->buffer_index++] = byte;
}

if (parser->buffer_index >= parser->packet_size) {
/* Validate checksum */
size_t msg_length = parser->packet_size - BASIC_FRAME_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 + BASIC_FRAME_HEADER_SIZE;
}
parser->state = BASIC_FRAME_LOOKING_FOR_START1;
}
break;
}

return result;
}

/**
* Encode a message with BasicFrame format
* Returns the number of bytes written, or 0 on failure
*/
static inline size_t basic_frame_encode(uint8_t* buffer, size_t buffer_size,
uint8_t msg_id, const uint8_t* msg, size_t msg_size) {
size_t total_size = BASIC_FRAME_OVERHEAD + msg_size;
if (buffer_size < total_size) {
return 0;
}

buffer[0] = BASIC_FRAME_START_BYTE1;
buffer[1] = BASIC_FRAME_START_BYTE2;
buffer[2] = msg_id;

/* Write message data */
if (msg_size > 0 && msg != NULL) {
memcpy(buffer + BASIC_FRAME_HEADER_SIZE, msg, msg_size);
}

/* Calculate checksum */
frame_checksum_t ck = frame_fletcher_checksum(buffer + 2, msg_size + 1);
buffer[BASIC_FRAME_HEADER_SIZE + msg_size] = ck.byte1;
buffer[BASIC_FRAME_HEADER_SIZE + msg_size + 1] = ck.byte2;

return total_size;
}

/**
* Validate a complete BasicFrame packet in a buffer
*/
static inline frame_msg_info_t basic_frame_validate_packet(const uint8_t* buffer, size_t length) {
frame_msg_info_t result = {false, 0, 0, NULL};

if (length < BASIC_FRAME_OVERHEAD) {
return result;
}

if (buffer[0] != BASIC_FRAME_START_BYTE1) {
return result;
}
if (buffer[1] != BASIC_FRAME_START_BYTE2) {
return result;
}

size_t msg_length = length - BASIC_FRAME_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 + BASIC_FRAME_HEADER_SIZE);
}

return result;
}

189 changes: 189 additions & 0 deletions src/struct_frame/boilerplate/c/basic_frame_no_crc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/* Automatically generated frame parser */
/* Generated by 0.0.1 at Wed Dec 3 17:57:16 2025. */

#pragma once

#include "frame_base.h"

/*===========================================================================
* BasicFrameNoCrc Frame Format
*===========================================================================*/

/* BasicFrameNoCrc constants */
#define BASIC_FRAME_NO_CRC_START_BYTE1 0x90
#define BASIC_FRAME_NO_CRC_START_BYTE2 0x95
#define BASIC_FRAME_NO_CRC_HEADER_SIZE 3 /* start_byte1 + start_byte2 + msg_id */
#define BASIC_FRAME_NO_CRC_FOOTER_SIZE 0 /* no footer */
#define BASIC_FRAME_NO_CRC_OVERHEAD (BASIC_FRAME_NO_CRC_HEADER_SIZE + BASIC_FRAME_NO_CRC_FOOTER_SIZE)

/* BasicFrameNoCrc parser states */
typedef enum basic_frame_no_crc_parser_state {
BASIC_FRAME_NO_CRC_LOOKING_FOR_START1 = 0,
BASIC_FRAME_NO_CRC_LOOKING_FOR_START2 = 1,
BASIC_FRAME_NO_CRC_GETTING_MSG_ID = 2,
BASIC_FRAME_NO_CRC_GETTING_PAYLOAD = 3
} basic_frame_no_crc_parser_state_t;

/* BasicFrameNoCrc parser state structure */
typedef struct basic_frame_no_crc_parser {
basic_frame_no_crc_parser_state_t state;
uint8_t* buffer;
size_t buffer_max_size;
size_t buffer_index;
size_t packet_size;
uint8_t msg_id;
/* User-provided function to get message length from msg_id (for non-length frames) */
bool (*get_msg_length)(uint8_t msg_id, size_t* length);
} basic_frame_no_crc_parser_t;

/* BasicFrameNoCrc encode buffer structure */
typedef struct basic_frame_no_crc_encode_buffer {
uint8_t* data;
size_t max_size;
size_t size;
bool in_progress;
size_t reserved_msg_size;
} basic_frame_no_crc_encode_buffer_t;

/**
* Initialize a BasicFrameNoCrc parser
*/
static inline void basic_frame_no_crc_parser_init(basic_frame_no_crc_parser_t* parser,
uint8_t* buffer, size_t buffer_size,
bool (*get_msg_length)(uint8_t msg_id, size_t* length)) {
parser->state = BASIC_FRAME_NO_CRC_LOOKING_FOR_START1;
parser->buffer = buffer;
parser->buffer_max_size = buffer_size;
parser->buffer_index = 0;
parser->packet_size = 0;
parser->msg_id = 0;
parser->get_msg_length = get_msg_length;
}

/**
* Reset BasicFrameNoCrc parser state
*/
static inline void basic_frame_no_crc_parser_reset(basic_frame_no_crc_parser_t* parser) {
parser->state = BASIC_FRAME_NO_CRC_LOOKING_FOR_START1;
parser->buffer_index = 0;
parser->packet_size = 0;
parser->msg_id = 0;
}

/**
* Parse a single byte with BasicFrameNoCrc format
* Returns frame_msg_info_t with valid=true when a complete valid message is received
*/
static inline frame_msg_info_t basic_frame_no_crc_parse_byte(basic_frame_no_crc_parser_t* parser, uint8_t byte) {
frame_msg_info_t result = {false, 0, 0, NULL};

switch (parser->state) {
case BASIC_FRAME_NO_CRC_LOOKING_FOR_START1:
if (byte == BASIC_FRAME_NO_CRC_START_BYTE1) {
parser->buffer[0] = byte;
parser->buffer_index = 1;
parser->state = BASIC_FRAME_NO_CRC_LOOKING_FOR_START2;
}
break;

case BASIC_FRAME_NO_CRC_LOOKING_FOR_START2:
if (byte == BASIC_FRAME_NO_CRC_START_BYTE2) {
parser->buffer[1] = byte;
parser->buffer_index = 2;
parser->state = BASIC_FRAME_NO_CRC_GETTING_MSG_ID;
} else if (byte == BASIC_FRAME_NO_CRC_START_BYTE1) {
parser->buffer[0] = byte;
parser->buffer_index = 1;
parser->state = BASIC_FRAME_NO_CRC_LOOKING_FOR_START2;
} else {
parser->state = BASIC_FRAME_NO_CRC_LOOKING_FOR_START1;
}
break;

case BASIC_FRAME_NO_CRC_GETTING_MSG_ID:
parser->buffer[parser->buffer_index++] = byte;
parser->msg_id = byte;
{
size_t msg_length = 0;
if (parser->get_msg_length && parser->get_msg_length(byte, &msg_length)) {
parser->packet_size = BASIC_FRAME_NO_CRC_OVERHEAD + msg_length;
if (parser->packet_size <= parser->buffer_max_size) {
parser->state = BASIC_FRAME_NO_CRC_GETTING_PAYLOAD;
} else {
parser->state = BASIC_FRAME_NO_CRC_LOOKING_FOR_START1;
}
} else {
parser->state = BASIC_FRAME_NO_CRC_LOOKING_FOR_START1;
}
}
break;

case BASIC_FRAME_NO_CRC_GETTING_PAYLOAD:
if (parser->buffer_index < parser->buffer_max_size) {
parser->buffer[parser->buffer_index++] = byte;
}

if (parser->buffer_index >= parser->packet_size) {
result.valid = true;
result.msg_id = parser->msg_id;
result.msg_len = parser->packet_size - BASIC_FRAME_NO_CRC_OVERHEAD;
result.msg_data = parser->buffer + BASIC_FRAME_NO_CRC_HEADER_SIZE;
parser->state = BASIC_FRAME_NO_CRC_LOOKING_FOR_START1;
}
break;
}

return result;
}

/**
* Encode a message with BasicFrameNoCrc format
* Returns the number of bytes written, or 0 on failure
*/
static inline size_t basic_frame_no_crc_encode(uint8_t* buffer, size_t buffer_size,
uint8_t msg_id, const uint8_t* msg, size_t msg_size) {
size_t total_size = BASIC_FRAME_NO_CRC_OVERHEAD + msg_size;
if (buffer_size < total_size) {
return 0;
}

buffer[0] = BASIC_FRAME_NO_CRC_START_BYTE1;
buffer[1] = BASIC_FRAME_NO_CRC_START_BYTE2;
buffer[2] = msg_id;

/* Write message data */
if (msg_size > 0 && msg != NULL) {
memcpy(buffer + BASIC_FRAME_NO_CRC_HEADER_SIZE, msg, msg_size);
}


return total_size;
}

/**
* Validate a complete BasicFrameNoCrc packet in a buffer
*/
static inline frame_msg_info_t basic_frame_no_crc_validate_packet(const uint8_t* buffer, size_t length) {
frame_msg_info_t result = {false, 0, 0, NULL};

if (length < BASIC_FRAME_NO_CRC_OVERHEAD) {
return result;
}

if (buffer[0] != BASIC_FRAME_NO_CRC_START_BYTE1) {
return result;
}
if (buffer[1] != BASIC_FRAME_NO_CRC_START_BYTE2) {
return result;
}

size_t msg_length = length - BASIC_FRAME_NO_CRC_OVERHEAD;

result.valid = true;
result.msg_id = buffer[2];
result.msg_len = msg_length;
result.msg_data = (uint8_t*)(buffer + BASIC_FRAME_NO_CRC_HEADER_SIZE);

return result;
}

Loading