/** * @file zh_nrf24_gateway.h * * nRF24L01+ gateway for ESP-IDF. * * Receives RF sensor telemetry and posts it as events on the default * ESP event loop. Pairing is fully internal: the gateway allocates * per-type device IDs, persists the binding table in NVS and sends * ACK packets. * * Events emitted: * - ZH_NRF_GATEWAY_EVENT_SENSOR_DATA — sensor telemetry * - ZH_NRF_GATEWAY_EVENT_SENSOR_PAIRED — a new {id, type} binding was * created and the ACK was successfully delivered to the sensor * * Binding table semantics: * - each binding is a pair {id, type}; * - the same id may be reused across different types; * - on pairing, the gateway allocates the smallest free id in 1..254 * for the requested type; * - deleting a binding makes its id available to the next pairing * request of the same type. */ #pragma once #include #include #include #include "esp_err.h" #include "esp_event.h" #include "driver/spi_master.h" #include "zh_nrf24_config.h" #ifdef __cplusplus extern "C" { #endif /** Max entries in the binding table (RAM and NVS). */ #define ZH_NRF_GATEWAY_MAX_BINDINGS 254 ESP_EVENT_DECLARE_BASE(ZH_NRF_GATEWAY_EVENTS); typedef enum { /** * Sensor telemetry received. * Event data: zh_nrf24_sensor_transmitted_data_t */ ZH_NRF_GATEWAY_EVENT_SENSOR_DATA, /** * A new {id, type} binding was created (pairing succeeded and the * ACK was delivered to the sensor). * Event data: zh_nrf_gateway_binding_t */ ZH_NRF_GATEWAY_EVENT_SENSOR_PAIRED, } zh_nrf_gateway_event_t; typedef struct { spi_host_device_t spi_host; int pin_sck; int pin_miso; int pin_mosi; int pin_csn; int pin_ce; int pin_irq; uint8_t channel; uint32_t address; uint32_t spi_clock_hz; } zh_nrf_gateway_config_t; /** A single {id, type} binding. */ typedef struct { uint8_t id; /**< 1..254, 0xFF = unassigned */ uint8_t type; /**< zh_nrf24_sensor_type_t */ } zh_nrf_gateway_binding_t; esp_err_t zh_nrf_gateway_init(const zh_nrf_gateway_config_t *config); esp_err_t zh_nrf_gateway_start(void); /* ===================== BINDING TABLE API ===================== */ size_t zh_nrf_gateway_bindings_get(zh_nrf_gateway_binding_t *buf, size_t max_count); size_t zh_nrf_gateway_bindings_count(void); bool zh_nrf_gateway_binding_exists(uint8_t id, uint8_t type); /** * @brief Delete a {id, type} binding. * * Composite key: both @p id AND @p type must match. If only one matches, * nothing is deleted and ESP_ERR_NOT_FOUND is returned. * * @return ESP_OK / ESP_ERR_NOT_FOUND / ESP_ERR_INVALID_ARG / ESP_ERR_INVALID_STATE / NVS error */ esp_err_t zh_nrf_gateway_binding_delete(uint8_t id, uint8_t type); /** Delete every binding whose id equals @p id (any type). Returns count, or -err. */ int zh_nrf_gateway_bindings_delete_by_id(uint8_t id); /** Delete every binding whose type equals @p type (any id). Returns count, or -err. */ int zh_nrf_gateway_bindings_delete_by_type(uint8_t type); /** Remove all bindings (persisted). */ esp_err_t zh_nrf_gateway_binding_clear_all(void); #ifdef __cplusplus } #endif