feat: implement OTA updates over HTTP(S), initiated over MQTT
This commit is contained in:
@@ -7,21 +7,29 @@
|
||||
|
||||
#define TAG "mqtt_publisher"
|
||||
#define TOPIC_PREFIX "localiser/sensor"
|
||||
#define TOPIC_OTA_BROADCAST "localiser/ota"
|
||||
|
||||
static esp_mqtt_client_handle_t s_client = NULL;
|
||||
static char s_sensor_id[32];
|
||||
static EventGroupHandle_t s_evt = NULL;
|
||||
static mqtt_reconfigure_data_t s_reconfigure_data;
|
||||
static mqtt_ota_data_t s_ota_data;
|
||||
|
||||
const mqtt_reconfigure_data_t *mqtt_publisher_get_reconfigure_data(void)
|
||||
{
|
||||
return &s_reconfigure_data;
|
||||
}
|
||||
|
||||
const mqtt_ota_data_t *mqtt_publisher_get_ota_data(void)
|
||||
{
|
||||
return &s_ota_data;
|
||||
}
|
||||
|
||||
/* Pre-built topic strings */
|
||||
static char s_topic_rssi[96];
|
||||
static char s_topic_announce[96];
|
||||
static char s_topic_cmd[96];
|
||||
static char s_topic_ota[96];
|
||||
|
||||
static void build_topics(void)
|
||||
{
|
||||
@@ -31,6 +39,8 @@ static void build_topics(void)
|
||||
"%s/%s/announce", TOPIC_PREFIX, s_sensor_id);
|
||||
snprintf(s_topic_cmd, sizeof(s_topic_cmd),
|
||||
"%s/%s/cmd", TOPIC_PREFIX, s_sensor_id);
|
||||
snprintf(s_topic_ota, sizeof(s_topic_ota),
|
||||
"%s/%s/ota", TOPIC_PREFIX, s_sensor_id);
|
||||
}
|
||||
|
||||
static void handle_cmd(const char *data, int data_len)
|
||||
@@ -50,6 +60,15 @@ static void handle_cmd(const char *data, int data_len)
|
||||
else if (strcmp(a, "selected") == 0) xEventGroupSetBits(s_evt, MQTT_SELECTED_BIT);
|
||||
else if (strcmp(a, "deselected") == 0) xEventGroupSetBits(s_evt, MQTT_DESELECTED_BIT);
|
||||
else if (strcmp(a, "factory_reset") == 0) xEventGroupSetBits(s_evt, MQTT_FACTORY_RESET_BIT);
|
||||
else if (strcmp(a, "ota") == 0) {
|
||||
memset(&s_ota_data, 0, sizeof(s_ota_data));
|
||||
cJSON *url_j = cJSON_GetObjectItemCaseSensitive(root, "url");
|
||||
cJSON *ver_j = cJSON_GetObjectItemCaseSensitive(root, "version");
|
||||
if (cJSON_IsString(url_j)) strncpy(s_ota_data.url, url_j->valuestring, sizeof(s_ota_data.url) - 1);
|
||||
if (cJSON_IsString(ver_j)) strncpy(s_ota_data.version, ver_j->valuestring, sizeof(s_ota_data.version) - 1);
|
||||
if (s_ota_data.url[0] != '\0') xEventGroupSetBits(s_evt, MQTT_OTA_BIT);
|
||||
else ESP_LOGW(TAG, "OTA cmd missing url");
|
||||
}
|
||||
else if (strcmp(a, "reconfigure_settings") == 0) {
|
||||
memset(&s_reconfigure_data, 0, sizeof(s_reconfigure_data));
|
||||
cJSON *ssid_j = cJSON_GetObjectItemCaseSensitive(root, "ssid");
|
||||
@@ -75,6 +94,7 @@ static void mqtt_event_handler(void *arg, esp_event_base_t base,
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "Connected to broker");
|
||||
esp_mqtt_client_subscribe(s_client, s_topic_cmd, 1);
|
||||
esp_mqtt_client_subscribe(s_client, TOPIC_OTA_BROADCAST, 1);
|
||||
xEventGroupSetBits(s_evt, MQTT_CONNECTED_BIT);
|
||||
mqtt_publisher_announce();
|
||||
break;
|
||||
@@ -85,7 +105,8 @@ static void mqtt_event_handler(void *arg, esp_event_base_t base,
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DATA:
|
||||
if (strncmp(event->topic, s_topic_cmd, event->topic_len) == 0) {
|
||||
if (strncmp(event->topic, s_topic_cmd, event->topic_len) == 0 ||
|
||||
strncmp(event->topic, TOPIC_OTA_BROADCAST, event->topic_len) == 0) {
|
||||
handle_cmd(event->data, event->data_len);
|
||||
}
|
||||
break;
|
||||
@@ -150,3 +171,13 @@ void mqtt_publisher_send_beacon(const char *type, const char *id, int8_t tx_powe
|
||||
type, id, (int)tx_power, (int)rssi);
|
||||
esp_mqtt_client_publish(s_client, s_topic_rssi, payload, len, 1, 0);
|
||||
}
|
||||
|
||||
void mqtt_publisher_send_ota_status(const char *status, const char *version)
|
||||
{
|
||||
if (!s_client) return;
|
||||
|
||||
char payload[96];
|
||||
int len = snprintf(payload, sizeof(payload),
|
||||
"{\"status\":\"%s\",\"version\":\"%s\"}", status, version ? version : "");
|
||||
esp_mqtt_client_publish(s_client, s_topic_ota, payload, len, 1, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user