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:
@@ -0,0 +1,104 @@
|
||||
#include "client_registry.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/idf_additions.h"
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
client_info_t info;
|
||||
bool active;
|
||||
} client_slot_t;
|
||||
|
||||
static client_slot_t s_clients[CLIENT_REGISTRY_MAX];
|
||||
|
||||
static uint32_t now_ms(void) {
|
||||
return (uint32_t)(xTaskGetTickCount() * portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
static bool mac_equal(const uint8_t *a, const uint8_t *b) {
|
||||
return memcmp(a, b, CLIENT_MAC_LEN) == 0;
|
||||
}
|
||||
|
||||
void client_registry_init(void) { memset(s_clients, 0, sizeof(s_clients)); }
|
||||
|
||||
const client_info_t *
|
||||
client_registry_find_by_mac(const uint8_t mac[CLIENT_MAC_LEN]) {
|
||||
if (mac == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for (size_t i = 0; i < CLIENT_REGISTRY_MAX; i++) {
|
||||
if (s_clients[i].active && mac_equal(s_clients[i].info.mac, mac)) {
|
||||
return &s_clients[i].info;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_err_t client_registry_upsert(const uint8_t mac[CLIENT_MAC_LEN], uint32_t id,
|
||||
uint32_t version, bool available, bool used,
|
||||
bool *out_is_new) {
|
||||
if (mac == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
uint32_t ts = now_ms();
|
||||
client_slot_t *slot = NULL;
|
||||
bool is_new = false;
|
||||
|
||||
for (size_t i = 0; i < CLIENT_REGISTRY_MAX; i++) {
|
||||
if (s_clients[i].active && mac_equal(s_clients[i].info.mac, mac)) {
|
||||
slot = &s_clients[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (slot == NULL) {
|
||||
for (size_t i = 0; i < CLIENT_REGISTRY_MAX; i++) {
|
||||
if (!s_clients[i].active) {
|
||||
slot = &s_clients[i];
|
||||
slot->active = true;
|
||||
memcpy(slot->info.mac, mac, CLIENT_MAC_LEN);
|
||||
is_new = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (slot == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
slot->info.id = id;
|
||||
slot->info.version = version;
|
||||
slot->info.available = available;
|
||||
slot->info.used = used;
|
||||
slot->info.last_ping = ts;
|
||||
slot->info.last_success_ping = ts;
|
||||
|
||||
if (out_is_new != NULL) {
|
||||
*out_is_new = is_new;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
size_t client_registry_count(void) {
|
||||
size_t n = 0;
|
||||
for (size_t i = 0; i < CLIENT_REGISTRY_MAX; i++) {
|
||||
if (s_clients[i].active) {
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
const client_info_t *client_registry_at(size_t index) {
|
||||
size_t n = 0;
|
||||
for (size_t i = 0; i < CLIENT_REGISTRY_MAX; i++) {
|
||||
if (!s_clients[i].active) {
|
||||
continue;
|
||||
}
|
||||
if (n == index) {
|
||||
return &s_clients[i].info;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
Reference in New Issue
Block a user