Binary protocol example binprot.c
This commit is contained in:
parent
433837e33d
commit
355f96d5e7
1 changed files with 68 additions and 0 deletions
68
binprot.c
Normal file
68
binprot.c
Normal 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;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue