feat: Add TARGET command — runtime UDP destination config
- TARGET <ip> [port] command to change data destination live - NVS persistence for target_ip and target_port - Falls back to Kconfig defaults when no NVS config - target= field added to STATUS reply - config_save_str helper for NVS string storage
This commit is contained in:
@@ -108,11 +108,18 @@ static uint8_t s_ble_own_addr_type;
|
||||
static int s_udp_socket = -1;
|
||||
static struct sockaddr_in s_dest_addr;
|
||||
static char s_udp_buffer[2048];
|
||||
static char s_target_ip[16]; /* runtime target IP (NVS or Kconfig default) */
|
||||
static uint16_t s_target_port; /* runtime target port */
|
||||
|
||||
/* --- NVS helpers --- */
|
||||
|
||||
static void config_load_nvs(void)
|
||||
{
|
||||
/* Start with Kconfig defaults for target */
|
||||
strncpy(s_target_ip, CONFIG_CSI_UDP_TARGET_IP, sizeof(s_target_ip) - 1);
|
||||
s_target_ip[sizeof(s_target_ip) - 1] = '\0';
|
||||
s_target_port = CONFIG_CSI_UDP_TARGET_PORT;
|
||||
|
||||
nvs_handle_t h;
|
||||
if (nvs_open("csi_config", NVS_READONLY, &h) == ESP_OK) {
|
||||
int32_t val;
|
||||
@@ -135,9 +142,16 @@ static void config_load_nvs(void)
|
||||
if (nvs_get_i8(h, "ble_scan", &ble) == ESP_OK) {
|
||||
s_ble_enabled = (ble != 0);
|
||||
}
|
||||
size_t ip_len = sizeof(s_target_ip);
|
||||
nvs_get_str(h, "target_ip", s_target_ip, &ip_len);
|
||||
int32_t port;
|
||||
if (nvs_get_i32(h, "target_port", &port) == ESP_OK && port > 0 && port <= 65535) {
|
||||
s_target_port = (uint16_t)port;
|
||||
}
|
||||
nvs_close(h);
|
||||
ESP_LOGI(TAG, "NVS loaded: rate=%d tx_power=%d adaptive=%d threshold=%.6f ble=%d",
|
||||
s_send_frequency, s_tx_power_dbm, s_adaptive, s_motion_threshold, s_ble_enabled);
|
||||
ESP_LOGI(TAG, "NVS loaded: rate=%d tx_power=%d adaptive=%d threshold=%.6f ble=%d target=%s:%d",
|
||||
s_send_frequency, s_tx_power_dbm, s_adaptive, s_motion_threshold, s_ble_enabled,
|
||||
s_target_ip, s_target_port);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "NVS: no saved config, using defaults");
|
||||
}
|
||||
@@ -165,6 +179,17 @@ static esp_err_t config_save_i8(const char *key, int8_t value)
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t config_save_str(const char *key, const char *value)
|
||||
{
|
||||
nvs_handle_t h;
|
||||
esp_err_t err = nvs_open("csi_config", NVS_READWRITE, &h);
|
||||
if (err != ESP_OK) return err;
|
||||
err = nvs_set_str(h, key, value);
|
||||
if (err == ESP_OK) err = nvs_commit(h);
|
||||
nvs_close(h);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* --- LED --- */
|
||||
|
||||
static void led_gpio_init(void)
|
||||
@@ -401,11 +426,11 @@ static void udp_socket_init(void)
|
||||
|
||||
memset(&s_dest_addr, 0, sizeof(s_dest_addr));
|
||||
s_dest_addr.sin_family = AF_INET;
|
||||
s_dest_addr.sin_port = htons(CONFIG_CSI_UDP_TARGET_PORT);
|
||||
inet_pton(AF_INET, CONFIG_CSI_UDP_TARGET_IP, &s_dest_addr.sin_addr);
|
||||
s_dest_addr.sin_port = htons(s_target_port);
|
||||
inet_pton(AF_INET, s_target_ip, &s_dest_addr.sin_addr);
|
||||
|
||||
ESP_LOGI(TAG, "UDP socket initialized, sending to %s:%d",
|
||||
CONFIG_CSI_UDP_TARGET_IP, CONFIG_CSI_UDP_TARGET_PORT);
|
||||
s_target_ip, s_target_port);
|
||||
}
|
||||
|
||||
/* --- Ping --- */
|
||||
@@ -699,11 +724,11 @@ static int cmd_handle(const char *cmd, char *reply, size_t reply_size)
|
||||
}
|
||||
|
||||
snprintf(reply, reply_size,
|
||||
"OK STATUS uptime=%s heap=%lu rssi=%d tx_power=%d rate=%d hostname=%s version=%s adaptive=%s motion=%d ble=%s",
|
||||
"OK STATUS uptime=%s heap=%lu rssi=%d tx_power=%d rate=%d hostname=%s version=%s adaptive=%s motion=%d ble=%s target=%s:%d",
|
||||
uptime_str, (unsigned long)heap, rssi, (int)s_tx_power_dbm,
|
||||
s_send_frequency, CONFIG_CSI_HOSTNAME, app_desc->version,
|
||||
s_adaptive ? "on" : "off", s_motion_detected ? 1 : 0,
|
||||
s_ble_enabled ? "on" : "off");
|
||||
s_ble_enabled ? "on" : "off", s_target_ip, s_target_port);
|
||||
return strlen(reply);
|
||||
}
|
||||
|
||||
@@ -740,6 +765,38 @@ static int cmd_handle(const char *cmd, char *reply, size_t reply_size)
|
||||
return strlen(reply);
|
||||
}
|
||||
|
||||
/* TARGET <ip> [port] */
|
||||
if (strncmp(cmd, "TARGET ", 7) == 0) {
|
||||
char ip_buf[16] = {0};
|
||||
int port = s_target_port;
|
||||
/* parse: "TARGET 192.168.1.10" or "TARGET 192.168.1.10 5500" */
|
||||
if (sscanf(cmd + 7, "%15s %d", ip_buf, &port) < 1) {
|
||||
snprintf(reply, reply_size, "ERR TARGET <ip> [port]");
|
||||
return strlen(reply);
|
||||
}
|
||||
/* validate IP */
|
||||
struct in_addr test_addr;
|
||||
if (inet_pton(AF_INET, ip_buf, &test_addr) != 1) {
|
||||
snprintf(reply, reply_size, "ERR TARGET invalid IP");
|
||||
return strlen(reply);
|
||||
}
|
||||
if (port < 1 || port > 65535) {
|
||||
snprintf(reply, reply_size, "ERR TARGET port range 1-65535");
|
||||
return strlen(reply);
|
||||
}
|
||||
strncpy(s_target_ip, ip_buf, sizeof(s_target_ip) - 1);
|
||||
s_target_ip[sizeof(s_target_ip) - 1] = '\0';
|
||||
s_target_port = (uint16_t)port;
|
||||
/* update live socket destination */
|
||||
s_dest_addr.sin_port = htons(s_target_port);
|
||||
inet_pton(AF_INET, s_target_ip, &s_dest_addr.sin_addr);
|
||||
/* persist */
|
||||
config_save_str("target_ip", s_target_ip);
|
||||
config_save_i32("target_port", (int32_t)s_target_port);
|
||||
snprintf(reply, reply_size, "OK TARGET %s:%d", s_target_ip, s_target_port);
|
||||
return strlen(reply);
|
||||
}
|
||||
|
||||
/* BLE ON/OFF */
|
||||
if (strncmp(cmd, "BLE ", 4) == 0) {
|
||||
const char *arg = cmd + 4;
|
||||
|
||||
Reference in New Issue
Block a user