command: Support 2-byte message ids
Allow command ids, response ids, and output ids to be either 1 or 2 bytes long. This increases the total number of message types from 128 to 16384. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// Code for parsing incoming commands and encoding outgoing messages
|
||||
//
|
||||
// Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
|
||||
// Copyright (C) 2016-2024 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
@@ -69,6 +69,28 @@ parse_int(uint8_t **pp)
|
||||
return v;
|
||||
}
|
||||
|
||||
// Write an encoded msgid (optimized 2-byte VLQ encoder)
|
||||
static uint8_t *
|
||||
encode_msgid(uint8_t *p, uint_fast16_t encoded_msgid)
|
||||
{
|
||||
if (encoded_msgid >= 0x80)
|
||||
*p++ = (encoded_msgid >> 7) | 0x80;
|
||||
*p++ = encoded_msgid & 0x7f;
|
||||
return p;
|
||||
}
|
||||
|
||||
// Parse an encoded msgid (optimized 2-byte parser, return as positive number)
|
||||
uint_fast16_t
|
||||
command_parse_msgid(uint8_t **pp)
|
||||
{
|
||||
uint8_t *p = *pp;
|
||||
uint_fast16_t encoded_msgid = *p++;
|
||||
if (encoded_msgid & 0x80)
|
||||
encoded_msgid = ((encoded_msgid & 0x7f) << 7) | (*p++);
|
||||
*pp = p;
|
||||
return encoded_msgid;
|
||||
}
|
||||
|
||||
// Parse an incoming command into 'args'
|
||||
uint8_t *
|
||||
command_parsef(uint8_t *p, uint8_t *maxend
|
||||
@@ -119,7 +141,7 @@ command_encodef(uint8_t *buf, const struct command_encoder *ce, va_list args)
|
||||
uint8_t *maxend = &p[max_size - MESSAGE_MIN];
|
||||
uint_fast8_t num_params = READP(ce->num_params);
|
||||
const uint8_t *param_types = READP(ce->param_types);
|
||||
*p++ = READP(ce->msg_id);
|
||||
p = encode_msgid(p, READP(ce->encoded_msgid));
|
||||
while (num_params--) {
|
||||
if (p > maxend)
|
||||
goto error;
|
||||
@@ -227,7 +249,7 @@ DECL_SHUTDOWN(sendf_shutdown);
|
||||
|
||||
// Find the command handler associated with a command
|
||||
static const struct command_parser *
|
||||
command_lookup_parser(uint_fast8_t cmdid)
|
||||
command_lookup_parser(uint_fast16_t cmdid)
|
||||
{
|
||||
if (!cmdid || cmdid >= READP(command_index_size))
|
||||
shutdown("Invalid command");
|
||||
@@ -309,7 +331,7 @@ command_dispatch(uint8_t *buf, uint_fast8_t msglen)
|
||||
uint8_t *p = &buf[MESSAGE_HEADER_SIZE];
|
||||
uint8_t *msgend = &buf[msglen-MESSAGE_TRAILER_SIZE];
|
||||
while (p < msgend) {
|
||||
uint_fast8_t cmdid = *p++;
|
||||
uint_fast16_t cmdid = command_parse_msgid(&p);
|
||||
const struct command_parser *cp = command_lookup_parser(cmdid);
|
||||
uint32_t args[READP(cp->num_args)];
|
||||
p = command_parsef(p, msgend, cp, args);
|
||||
|
||||
@@ -57,11 +57,13 @@
|
||||
#define MESSAGE_SYNC 0x7E
|
||||
|
||||
struct command_encoder {
|
||||
uint8_t msg_id, max_size, num_params;
|
||||
uint16_t encoded_msgid;
|
||||
uint8_t max_size, num_params;
|
||||
const uint8_t *param_types;
|
||||
};
|
||||
struct command_parser {
|
||||
uint8_t msg_id, num_args, flags, num_params;
|
||||
uint16_t encoded_msgid;
|
||||
uint8_t num_args, flags, num_params;
|
||||
const uint8_t *param_types;
|
||||
void (*func)(uint32_t *args);
|
||||
};
|
||||
@@ -72,6 +74,7 @@ enum {
|
||||
|
||||
// command.c
|
||||
void *command_decode_ptr(uint32_t v);
|
||||
uint_fast16_t command_parse_msgid(uint8_t **pp);
|
||||
uint8_t *command_parsef(uint8_t *p, uint8_t *maxend
|
||||
, const struct command_parser *cp, uint32_t *args);
|
||||
uint_fast8_t command_encode_and_frame(
|
||||
@@ -86,7 +89,7 @@ int_fast8_t command_find_and_dispatch(uint8_t *buf, uint_fast8_t buf_len
|
||||
|
||||
// out/compile_time_request.c (auto generated file)
|
||||
extern const struct command_parser command_index[];
|
||||
extern const uint8_t command_index_size;
|
||||
extern const uint16_t command_index_size;
|
||||
extern const uint8_t command_identify_data[];
|
||||
extern const uint32_t command_identify_size;
|
||||
const struct command_encoder *ctr_lookup_encoder(const char *str);
|
||||
|
||||
@@ -141,7 +141,7 @@ do_dispatch(uint8_t *buf, uint32_t msglen)
|
||||
uint8_t *msgend = &buf[msglen-MESSAGE_TRAILER_SIZE];
|
||||
while (p < msgend) {
|
||||
// Parse command
|
||||
uint_fast8_t cmdid = *p++;
|
||||
uint_fast16_t cmdid = command_parse_msgid(&p);
|
||||
const struct command_parser *cp = &SHARED_MEM->command_index[cmdid];
|
||||
if (!cmdid || cmdid >= SHARED_MEM->command_index_size
|
||||
|| cp->num_args > ARRAY_SIZE(SHARED_MEM->next_command_args)) {
|
||||
|
||||
Reference in New Issue
Block a user