Track ESP-NOW slaves in a shared registry and respond to CLIENT_INFO with protobuf ClientInfoResponse; ESP-NOW path upserts registry entries. Co-authored-by: Cursor <cursoragent@cursor.com>
78 lines
2.2 KiB
C
78 lines
2.2 KiB
C
#include "client_registry.h"
|
|
#include "cmd_client_info.h"
|
|
#include "cmd_handler.h"
|
|
#include "esp_log.h"
|
|
#include "pb_encode.h"
|
|
#include "uart_messages.pb.h"
|
|
#include "uart_proto.h"
|
|
|
|
static const char *TAG = "[CLIENT_INFO]";
|
|
|
|
static bool encode_client_mac(pb_ostream_t *stream, const pb_field_t *field,
|
|
void *const *arg) {
|
|
const uint8_t *mac = (const uint8_t *)*arg;
|
|
if (mac == NULL) {
|
|
return true;
|
|
}
|
|
if (!pb_encode_tag_for_field(stream, field)) {
|
|
return false;
|
|
}
|
|
return pb_encode_string(stream, mac, CLIENT_MAC_LEN);
|
|
}
|
|
|
|
static bool encode_clients_list(pb_ostream_t *stream, const pb_field_t *field,
|
|
void *const *arg) {
|
|
(void)arg;
|
|
|
|
size_t count = client_registry_count();
|
|
for (size_t i = 0; i < count; i++) {
|
|
const client_info_t *client = client_registry_at(i);
|
|
if (client == NULL) {
|
|
continue;
|
|
}
|
|
|
|
alox_ClientInfo proto = alox_ClientInfo_init_zero;
|
|
proto.id = client->id;
|
|
proto.available = client->available;
|
|
proto.used = client->used;
|
|
proto.last_ping = client->last_ping;
|
|
proto.last_success_ping = client->last_success_ping;
|
|
proto.version = client->version;
|
|
proto.mac.funcs.encode = encode_client_mac;
|
|
proto.mac.arg = (void *)client->mac;
|
|
|
|
if (!pb_encode_tag_for_field(stream, field)) {
|
|
return false;
|
|
}
|
|
if (!pb_encode_submessage(stream, alox_ClientInfo_fields, &proto)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void handle_client_info(const uint8_t *data, size_t len) {
|
|
(void)data;
|
|
(void)len;
|
|
|
|
alox_UartMessage response = alox_UartMessage_init_zero;
|
|
response.type = alox_MessageType_CLIENT_INFO;
|
|
response.which_payload = alox_UartMessage_client_info_response_tag;
|
|
response.payload.client_info_response.clients.funcs.encode =
|
|
encode_clients_list;
|
|
response.payload.client_info_response.clients.arg = NULL;
|
|
|
|
ESP_LOGI(TAG, "sending %u clients", (unsigned)client_registry_count());
|
|
|
|
if (uart_send_uart_message(&response) != ESP_OK) {
|
|
ESP_LOGE(TAG, "failed to send response");
|
|
}
|
|
}
|
|
|
|
void cmd_client_info_register(void) {
|
|
if (msg_register_handler(alox_MessageType_CLIENT_INFO, handle_client_info) !=
|
|
ESP_OK) {
|
|
ESP_LOGE(TAG, "register failed");
|
|
}
|
|
}
|