wip:
This commit is contained in:
1 parent
0daf4de19f
commit
036b856a93
2 files changed
+153
-44
No files matched your search
+83
-21
@@ -202,7 +202,7 @@ static esp_err_t nrf_irq_init(void)
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* NVS BINDING TABLE
|
||||
* NVS BINDING TABLE (internal)
|
||||
* ============================================================ */
|
||||
static esp_err_t bindings_load(void)
|
||||
{
|
||||
@@ -251,22 +251,30 @@ static esp_err_t bindings_save(void)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Caller must hold bindings_mutex. */
|
||||
static bool bindings_exists_locked(uint8_t id, uint8_t type)
|
||||
{
|
||||
for (uint16_t i = 0; i < s_ctx.bindings.count; i++) {
|
||||
if (s_ctx.bindings.items[i].id == id &&
|
||||
s_ctx.bindings.items[i].type == type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Caller must hold bindings_mutex. */
|
||||
static uint8_t bindings_alloc_id(uint8_t type)
|
||||
{
|
||||
for (uint16_t id = BINDING_ID_MIN; id <= BINDING_ID_MAX; id++) {
|
||||
bool used = false;
|
||||
for (uint16_t i = 0; i < s_ctx.bindings.count; i++) {
|
||||
if (s_ctx.bindings.items[i].id == id &&
|
||||
s_ctx.bindings.items[i].type == type) {
|
||||
used = true;
|
||||
break;
|
||||
}
|
||||
if (!bindings_exists_locked((uint8_t)id, type)) {
|
||||
return (uint8_t)id;
|
||||
}
|
||||
if (!used) return (uint8_t)id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Caller must hold bindings_mutex. */
|
||||
static esp_err_t bindings_add(uint8_t id, uint8_t type)
|
||||
{
|
||||
if (s_ctx.bindings.count >= ZH_NRF_GATEWAY_MAX_BINDINGS) {
|
||||
@@ -278,6 +286,7 @@ static esp_err_t bindings_add(uint8_t id, uint8_t type)
|
||||
return bindings_save();
|
||||
}
|
||||
|
||||
/* Caller must hold bindings_mutex. */
|
||||
static esp_err_t bindings_delete(uint8_t id, uint8_t type)
|
||||
{
|
||||
for (uint16_t i = 0; i < s_ctx.bindings.count; i++) {
|
||||
@@ -319,18 +328,38 @@ bool zh_nrf_gateway_binding_exists(uint8_t id, uint8_t type)
|
||||
{
|
||||
if (!s_ctx.initialized || !s_ctx.bindings_mutex) return false;
|
||||
xSemaphoreTake(s_ctx.bindings_mutex, portMAX_DELAY);
|
||||
bool found = false;
|
||||
for (uint16_t i = 0; i < s_ctx.bindings.count; i++) {
|
||||
if (s_ctx.bindings.items[i].id == id &&
|
||||
s_ctx.bindings.items[i].type == type) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool found = bindings_exists_locked(id, type);
|
||||
xSemaphoreGive(s_ctx.bindings_mutex);
|
||||
return found;
|
||||
}
|
||||
|
||||
int zh_nrf_gateway_binding_auto_register(uint8_t id, uint8_t type)
|
||||
{
|
||||
if (!s_ctx.initialized || !s_ctx.bindings_mutex) return -ESP_ERR_INVALID_STATE;
|
||||
if (id < BINDING_ID_MIN || id > BINDING_ID_MAX) return -ESP_ERR_INVALID_ARG;
|
||||
if (zh_get_nrf24_sensor_payload_size(type) == 0) return -ESP_ERR_INVALID_ARG;
|
||||
|
||||
xSemaphoreTake(s_ctx.bindings_mutex, portMAX_DELAY);
|
||||
|
||||
int result = 0;
|
||||
if (!bindings_exists_locked(id, type)) {
|
||||
esp_err_t err = bindings_add(id, type);
|
||||
if (err == ESP_OK) {
|
||||
result = 1;
|
||||
} else {
|
||||
if (s_ctx.bindings.count > 0 &&
|
||||
s_ctx.bindings.items[s_ctx.bindings.count - 1].id == id &&
|
||||
s_ctx.bindings.items[s_ctx.bindings.count - 1].type == type) {
|
||||
s_ctx.bindings.count--;
|
||||
}
|
||||
result = -(int)err;
|
||||
}
|
||||
}
|
||||
|
||||
xSemaphoreGive(s_ctx.bindings_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
esp_err_t zh_nrf_gateway_binding_delete(uint8_t id, uint8_t type)
|
||||
{
|
||||
if (!s_ctx.initialized) return ESP_ERR_INVALID_STATE;
|
||||
@@ -526,7 +555,6 @@ static void handle_pairing_request(const uint8_t *data)
|
||||
return;
|
||||
}
|
||||
|
||||
/* --- ACK delivered → binding is final. Notify the application. --- */
|
||||
ESP_LOGI(TAG, "Pairing complete: id=%u type=%u", new_id, req_type);
|
||||
|
||||
zh_nrf_gateway_binding_t paired = {
|
||||
@@ -564,6 +592,37 @@ static void handle_sensor_data(const uint8_t *buf, uint8_t len)
|
||||
len, expected, d.type);
|
||||
}
|
||||
|
||||
/* ----- Auto-register unknown {id, type} ----- */
|
||||
if (d.id >= BINDING_ID_MIN && d.id <= BINDING_ID_MAX) {
|
||||
int r = zh_nrf_gateway_binding_auto_register((uint8_t)d.id,
|
||||
(uint8_t)d.type);
|
||||
if (r == 1) {
|
||||
ESP_LOGI(TAG, "Auto-registered sensor: id=%d type=%d (%s)",
|
||||
d.id, d.type,
|
||||
zh_get_nrf24_sensor_type_name((zh_nrf24_sensor_type_t)d.type));
|
||||
|
||||
zh_nrf_gateway_binding_t b = {
|
||||
.id = (uint8_t)d.id,
|
||||
.type = (uint8_t)d.type,
|
||||
};
|
||||
esp_err_t perr = esp_event_post(ZH_NRF_GATEWAY_EVENTS,
|
||||
ZH_NRF_GATEWAY_EVENT_SENSOR_REGISTERED,
|
||||
&b, sizeof(b),
|
||||
pdMS_TO_TICKS(100));
|
||||
if (perr != ESP_OK) {
|
||||
ESP_LOGW(TAG, "esp_event_post(registered) failed: %s",
|
||||
esp_err_to_name(perr));
|
||||
}
|
||||
} else if (r < 0) {
|
||||
ESP_LOGW(TAG, "Auto-register failed for id=%d type=%d: %s",
|
||||
d.id, d.type, esp_err_to_name((esp_err_t)(-r)));
|
||||
}
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Sensor id %d out of range [%d..%d], skipping auto-register",
|
||||
d.id, BINDING_ID_MIN, BINDING_ID_MAX);
|
||||
}
|
||||
|
||||
/* ----- Parse type-specific fields ----- */
|
||||
switch (d.type) {
|
||||
case ZH_NRF24_SENSOR_TOUCH_SWITCH:
|
||||
break;
|
||||
@@ -598,11 +657,12 @@ static void handle_sensor_data(const uint8_t *buf, uint8_t len)
|
||||
break;
|
||||
}
|
||||
|
||||
/* ----- Post SENSOR_DATA ----- */
|
||||
esp_err_t err = esp_event_post(ZH_NRF_GATEWAY_EVENTS,
|
||||
ZH_NRF_GATEWAY_EVENT_SENSOR_DATA,
|
||||
&d, sizeof(d), pdMS_TO_TICKS(100));
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGW(TAG, "esp_event_post failed: %s", esp_err_to_name(err));
|
||||
ESP_LOGW(TAG, "esp_event_post(data) failed: %s", esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,10 +772,10 @@ esp_err_t zh_nrf_gateway_init(const zh_nrf_gateway_config_t *config)
|
||||
nrf_write_register(NRF_REG_CONFIG, 0x00);
|
||||
nrf_write_register(NRF_REG_EN_AA, 0x01);
|
||||
nrf_write_register(NRF_REG_EN_RXADDR, 0x01);
|
||||
nrf_write_register(NRF_REG_SETUP_AW, 0x01);
|
||||
nrf_write_register(NRF_REG_SETUP_AW, 0x01); /* 3-byte address */
|
||||
nrf_write_register(NRF_REG_SETUP_RETR, 0xFF);
|
||||
nrf_write_register(NRF_REG_RF_CH, s_ctx.cfg.channel);
|
||||
nrf_write_register(NRF_REG_RF_SETUP, 0x26); /* 250 kbps, 0 dBm */
|
||||
nrf_write_register(NRF_REG_RF_SETUP, 0x26); /* 250 kbps, 0 dBm */
|
||||
|
||||
uint8_t addr_bytes[3] = {
|
||||
(uint8_t)(s_ctx.cfg.address >> 0),
|
||||
@@ -728,10 +788,12 @@ esp_err_t zh_nrf_gateway_init(const zh_nrf_gateway_config_t *config)
|
||||
nrf_write_register(NRF_REG_STATUS,
|
||||
NRF_STATUS_RX_DR | NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT);
|
||||
|
||||
/* Enable Dynamic Payload Length */
|
||||
nrf_activate();
|
||||
nrf_write_register(NRF_REG_FEATURE, NRF_FEATURE_EN_DPL);
|
||||
nrf_write_register(NRF_REG_DYNPD, NRF_DYNPD_DPL_P0);
|
||||
|
||||
/* Enter RX */
|
||||
nrf_write_register(NRF_REG_CONFIG, NRF_CONFIG_RX_UNMASKED);
|
||||
vTaskDelay(pdMS_TO_TICKS(5));
|
||||
nrf_ce_high();
|
||||
|
||||
Reference in new issue
Block a user