aboutsummaryrefslogtreecommitdiffstats
path: root/src/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/command.c')
-rw-r--r--src/command.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/command.c b/src/command.c
index 39c09458..d2d05aff 100644
--- a/src/command.c
+++ b/src/command.c
@@ -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);