Binary protocol example binprot.c

This commit is contained in:
Imbus 2025-06-25 08:37:14 +02:00
parent 433837e33d
commit 355f96d5e7

68
binprot.c Normal file
View file

@ -0,0 +1,68 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
/*
* Example binary protocol for passing small, statically sized messages.
*
* These messages are efficient and easily serializable. Since there is no variable length payload in the message, no
* parsing is required, and a simple cast into whatever reciever buffer you're using, or a memcpy into a preallocated
* CommandMessage, is enough. Keep in mind; the largest member of the data union determines the size of the struct.
*/
// clang-format off
typedef enum {
CMD_SET_LEVEL = 1,
CMD_SET_LIGHTS = 2,
CMD_SET_DISTANCE_FACTOR = 3
} CommandType;
typedef struct __attribute__((__packed__)) {
uint8_t type;
union {
struct { uint8_t level; } set_level;
struct { uint8_t on; } set_lights; // 1 = on, 0 = off
struct { float factor; } set_distance;
} data;
/* NOTE: Consider adding crc checksum here, or in a wrapper struct */
} CommandMessage;
// clang-format on
void print_command(CommandMessage *m) {
switch (m->type) {
case CMD_SET_LEVEL:
printf("Type: SetLevel\nPayload: %d\n", m->data.set_level.level);
break;
case CMD_SET_LIGHTS:
printf("Type: SetLights\nPayload: %d\n", m->data.set_lights.on);
break;
case CMD_SET_DISTANCE_FACTOR:
printf("Type: SetDistanceFactor\nPayload: %.2f\n", m->data.set_distance.factor);
break;
}
}
char buf[sizeof(CommandMessage)];
int main(void) {
CommandMessage m = {CMD_SET_LIGHTS, .data.set_lights.on = 1};
memcpy(buf, &m, sizeof(CommandMessage));
/* Here we can send buf through a socket, to uart, wherever */
CommandMessage r = {0};
memcpy(&r, &buf, sizeof(CommandMessage));
/* We can then dispatch based on the message type */
print_command(&r);
m.type = CMD_SET_LEVEL;
m.data.set_level.level = 10;
print_command(&m);
m.type = CMD_SET_DISTANCE_FACTOR;
m.data.set_distance.factor = 1337.42;
print_command(&m);
return 0;
}