// // Created by misaki on 2025/9/4. // #include "ota_ws.h" #include "esp_log.h" #include "esp_websocket_client.h" #include "esp_ota_ops.h" #include "esp_http_client.h" #include "esp_https_ota.h" #include "cJSON.h" #include "esp_system.h" #include "esp_mac.h" static const char *TAG = "OTA_WS"; #define FW_VERSION "1.0.1" // ←每次发布修改这里 #define WS_URL_FMT "ws://%s:%d/ws?mac=%02X%02X%02X%02X%02X%02X" static esp_websocket_client_handle_t ws = NULL; static void ota_start(const char *url) { esp_http_client_config_t config = { .url = url, .keep_alive_enable = true, }; esp_https_ota_config_t ota_cfg = { .http_config = &config }; ESP_LOGI(TAG, "开始下载固件..."); esp_err_t ret = esp_https_ota(&ota_cfg); if (ret == ESP_OK) { ESP_LOGI(TAG, "下载完成,重启"); esp_restart(); } else { ESP_LOGE(TAG, "OTA 失败:%s", esp_err_to_name(ret)); } } static void ws_event(void *arg, esp_event_base_t base, int32_t id, void *data) { esp_websocket_event_data_t *d = (esp_websocket_event_data_t *)data; switch (id) { case WEBSOCKET_EVENT_CONNECTED: ESP_LOGI(TAG, "WebSocket 已连接"); break; case WEBSOCKET_EVENT_DATA: if (d->op_code == WS_TRANSPORT_OPCODES_TEXT) { char *json = malloc(d->data_len + 1); if (!json) break; memcpy(json, d->data_ptr, d->data_len); json[d->data_len] = 0; cJSON *root = cJSON_Parse(json); free(json); if (root) { cJSON *cmd = cJSON_GetObjectItem(root, "cmd"); if (cmd && strcmp(cmd->valuestring, "upgrade") == 0) { const char *url = cJSON_GetObjectItem(root, "url")->valuestring; ESP_LOGI(TAG, "收到升级指令,URL=%s", url); ota_start(url); } cJSON_Delete(root); } } break; case WEBSOCKET_EVENT_DISCONNECTED: ESP_LOGW(TAG, "WS 断开,5 秒后重连..."); vTaskDelay(pdMS_TO_TICKS(5000)); esp_websocket_client_start(ws); break; default: break; } } esp_err_t ota_ws_start(const char *server_ip, uint16_t port) { if (ws) return ESP_OK; uint8_t mac[6]; esp_efuse_mac_get_default(mac); char uri[128]; snprintf(uri, sizeof(uri), WS_URL_FMT, server_ip, port, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); esp_websocket_client_config_t cfg = { .uri = uri, .ping_interval_sec = 30, }; ws = esp_websocket_client_init(&cfg); esp_websocket_register_events(ws, WEBSOCKET_EVENT_ANY, ws_event, NULL); esp_websocket_client_start(ws); return ESP_OK; }