Add client registry and CLIENT_INFO UART command on master.

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>
This commit is contained in:
2026-05-18 22:26:42 +02:00
co-authored by Cursor
parent 81e479ecd1
commit 92e146e2ed
8 changed files with 261 additions and 51 deletions
+9 -47
View File
@@ -1,3 +1,4 @@
#include "client_registry.h"
#include "esp_now_comm.h"
#include "esp_err.h"
#include "esp_event.h"
@@ -20,8 +21,6 @@
#define ESPNOW_MSG_DISCOVER 1
#define ESPNOW_MSG_SLAVE_INFO 2
#define ESPNOW_DISCOVER_INTERVAL_MS 500
#define ESPNOW_MAX_SLAVES 16
static const uint8_t ESPNOW_BCAST[ESP_NOW_ETH_ALEN] = {0xff, 0xff, 0xff,
0xff, 0xff, 0xff};
@@ -45,19 +44,9 @@ typedef struct __attribute__((packed)) {
uint8_t used;
} espnow_slave_info_packet_t;
typedef struct {
uint8_t mac[ESP_NOW_ETH_ALEN];
uint32_t slave_id;
uint32_t version;
bool available;
bool used;
bool seen;
} slave_entry_t;
static app_config_t s_config;
static uint8_t s_wifi_channel;
static uint8_t s_own_mac[ESP_NOW_ETH_ALEN];
static slave_entry_t s_slaves[ESPNOW_MAX_SLAVES];
static bool s_slave_joined;
static uint8_t s_master_mac[ESP_NOW_ETH_ALEN];
@@ -97,30 +86,6 @@ static esp_err_t ensure_peer(const uint8_t *mac) {
static esp_err_t ensure_broadcast_peer(void) { return ensure_peer(ESPNOW_BCAST); }
static slave_entry_t *find_slave(const uint8_t *mac) {
for (int i = 0; i < ESPNOW_MAX_SLAVES; i++) {
if (s_slaves[i].seen && mac_equal(s_slaves[i].mac, mac)) {
return &s_slaves[i];
}
}
return NULL;
}
static slave_entry_t *alloc_slave(const uint8_t *mac) {
slave_entry_t *existing = find_slave(mac);
if (existing != NULL) {
return existing;
}
for (int i = 0; i < ESPNOW_MAX_SLAVES; i++) {
if (!s_slaves[i].seen) {
memcpy(s_slaves[i].mac, mac, ESP_NOW_ETH_ALEN);
s_slaves[i].seen = true;
return &s_slaves[i];
}
}
return NULL;
}
static void send_slave_info(const uint8_t *dest_mac) {
espnow_slave_info_packet_t pkt = {
.magic = ESPNOW_MAGIC,
@@ -169,22 +134,19 @@ static void handle_slave_info(const espnow_slave_info_packet_t *pkt) {
return;
}
bool is_new = (find_slave(pkt->mac) == NULL);
slave_entry_t *entry = alloc_slave(pkt->mac);
if (entry == NULL) {
ESP_LOGW(TAG, "slave table full");
bool is_new = false;
esp_err_t err = client_registry_upsert(
pkt->mac, pkt->slave_id, pkt->version, pkt->available != 0,
pkt->used != 0, &is_new);
if (err != ESP_OK) {
ESP_LOGW(TAG, "client registry full");
return;
}
entry->slave_id = pkt->slave_id;
entry->version = pkt->version;
entry->available = pkt->available != 0;
entry->used = pkt->used != 0;
char mac_str[18];
mac_to_str(pkt->mac, mac_str, sizeof(mac_str));
if (is_new) {
ESP_LOGI(TAG, "slave joined id=%lu mac=%s ver=%lu",
ESP_LOGI(TAG, "client registered id=%lu mac=%s ver=%lu",
(unsigned long)pkt->slave_id, mac_str,
(unsigned long)pkt->version);
}
@@ -278,7 +240,7 @@ esp_err_t esp_now_comm_init(const app_config_t *config) {
memset(&s_config, 0, sizeof(s_config));
memcpy(&s_config, config, sizeof(s_config));
memset(s_slaves, 0, sizeof(s_slaves));
client_registry_init();
s_slave_joined = false;
memset(s_master_mac, 0, sizeof(s_master_mac));