Centralize protobuf decode, response init/send, registration, and common nanopb encode callbacks; refactor existing cmd_* modules to use them. Co-authored-by: Cursor <cursoragent@cursor.com>
83 lines
2.1 KiB
C
83 lines
2.1 KiB
C
#include "uart_cmd.h"
|
|
#include "esp_log.h"
|
|
#include "pb_decode.h"
|
|
#include "pb_encode.h"
|
|
#include "uart_proto.h"
|
|
#include <string.h>
|
|
|
|
static const char *TAG = "[UART_CMD]";
|
|
|
|
esp_err_t uart_cmd_decode(const uint8_t *data, size_t len, alox_UartMessage *out) {
|
|
if (out == NULL) {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
|
|
alox_UartMessage zero = alox_UartMessage_init_zero;
|
|
*out = zero;
|
|
if (len == 0) {
|
|
return ESP_OK;
|
|
}
|
|
if (data == NULL) {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
|
|
pb_istream_t stream = pb_istream_from_buffer(data, len);
|
|
if (!pb_decode(&stream, alox_UartMessage_fields, out)) {
|
|
return ESP_FAIL;
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
|
|
void uart_cmd_init_response(alox_UartMessage *msg, alox_MessageType type,
|
|
pb_size_t which_payload) {
|
|
if (msg == NULL) {
|
|
return;
|
|
}
|
|
alox_UartMessage zero = alox_UartMessage_init_zero;
|
|
*msg = zero;
|
|
msg->type = type;
|
|
msg->which_payload = which_payload;
|
|
}
|
|
|
|
esp_err_t uart_cmd_send(const alox_UartMessage *msg, const char *log_tag) {
|
|
esp_err_t err = uart_send_uart_message(msg);
|
|
if (err != ESP_OK && log_tag != NULL) {
|
|
ESP_LOGE(log_tag, "failed to send UART response");
|
|
}
|
|
return err;
|
|
}
|
|
|
|
esp_err_t uart_cmd_register(alox_MessageType type, msg_callback_t cb) {
|
|
esp_err_t err = msg_register_handler((uint16_t)type, cb);
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "register handler for type %u failed", (unsigned)type);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
bool uart_cmd_encode_string(pb_ostream_t *stream, const pb_field_t *field,
|
|
void *const *arg) {
|
|
const char *str = (const char *)*arg;
|
|
if (str == NULL) {
|
|
str = "";
|
|
}
|
|
if (!pb_encode_tag_for_field(stream, field)) {
|
|
return false;
|
|
}
|
|
return pb_encode_string(stream, (const pb_byte_t *)str, strlen(str));
|
|
}
|
|
|
|
bool uart_cmd_encode_bytes(pb_ostream_t *stream, const pb_field_t *field,
|
|
void *const *arg) {
|
|
const uart_cmd_bytes_t *blob = (const uart_cmd_bytes_t *)*arg;
|
|
|
|
(void)field;
|
|
if (blob == NULL || blob->data == NULL) {
|
|
return true;
|
|
}
|
|
if (!pb_encode_tag_for_field(stream, field)) {
|
|
return false;
|
|
}
|
|
return pb_encode_string(stream, blob->data, blob->len);
|
|
}
|