diff --git a/components/esp_wifi_remote/eppp/wifi_remote_rpc_client.cpp b/components/esp_wifi_remote/eppp/wifi_remote_rpc_client.cpp index 708a98e13b2..c287cc1679e 100644 --- a/components/esp_wifi_remote/eppp/wifi_remote_rpc_client.cpp +++ b/components/esp_wifi_remote/eppp/wifi_remote_rpc_client.cpp @@ -51,7 +51,7 @@ class Sync { } esp_err_t wait_for(EventBits_t bits, uint32_t timeout = portMAX_DELAY) { - return xEventGroupWaitBits(events, bits, pdTRUE, pdTRUE, timeout) == bits ? ESP_OK : ESP_FAIL; + return (xEventGroupWaitBits(events, bits, pdTRUE, pdTRUE, timeout) & bits) == bits ? ESP_OK : ESP_FAIL; } esp_err_t notify(EventBits_t bits) { @@ -76,6 +76,7 @@ class Sync { const int request = 1; const int resp_header = 2; const int resp_payload = 4; + const int restart = 8; }; class RpcInstance { @@ -85,8 +86,8 @@ class RpcInstance { template esp_err_t send(api_id id, T *t) { - ESP_RETURN_ON_ERROR(sync.notify(sync.request), TAG, "failed to notify req"); pending_resp = id; + ESP_RETURN_ON_ERROR(sync.notify(sync.request), TAG, "failed to notify req"); ESP_RETURN_ON_ERROR(rpc.send(id, t), TAG, "Failed to send request"); return ESP_OK; } @@ -94,8 +95,8 @@ class RpcInstance { // overload of the templated method (used for functions with no arguments) esp_err_t send(api_id id) { - ESP_RETURN_ON_ERROR(sync.notify(sync.request), TAG, "failed to notify req"); pending_resp = id; + ESP_RETURN_ON_ERROR(sync.notify(sync.request), TAG, "failed to notify req"); ESP_RETURN_ON_ERROR(rpc.send(id), TAG, "Failed to send request"); return ESP_OK; } @@ -111,6 +112,7 @@ class RpcInstance { esp_err_t init() { ESP_RETURN_ON_FALSE(netif = wifi_remote_eppp_init(EPPP_CLIENT), ESP_FAIL, TAG, "Failed to connect to EPPP server"); + ESP_RETURN_ON_ERROR(esp_event_handler_register(IP_EVENT, IP_EVENT_PPP_GOT_IP, got_ip, this), TAG, "Failed to register event"); ESP_RETURN_ON_ERROR(sync.init(), TAG, "Failed to init sync primitives"); ESP_RETURN_ON_ERROR(rpc.init(), TAG, "Failed to init RPC engine"); return xTaskCreate(task, "client", 8192, this, 5, nullptr) == pdTRUE ? ESP_OK : ESP_FAIL; @@ -176,9 +178,22 @@ class RpcInstance { static void task(void *ctx) { auto instance = static_cast(ctx); - while (instance->perform() == ESP_OK) {} + do { + while (instance->perform() == ESP_OK) {} + } while (instance->restart() == ESP_OK); vTaskDelete(nullptr); } + esp_err_t restart() + { + rpc.deinit(); + ESP_RETURN_ON_ERROR(sync.wait_for(sync.restart, pdMS_TO_TICKS(10000)), TAG, "Didn't receive EPPP address in time"); + return rpc.init(); + } + static void got_ip(void *ctx, esp_event_base_t base, int32_t id, void *data) + { + auto instance = static_cast(ctx); + instance->sync.notify(instance->sync.restart); + } esp_netif_t *netif{nullptr}; }; @@ -204,20 +219,17 @@ RpcInstance *RpcEngine::init_client() cfg.clientkey_bytes = sizeof(client::key); cfg.common_name = "espressif.local"; - tls_ = esp_tls_init(); - if (!tls_) { - ESP_LOGE(TAG, "Failed to allocate esp_tls handle!"); - goto exit; - } - if (esp_tls_conn_new_sync(host, strlen(host), rpc_port, &cfg, tls_) <= 0) { - ESP_LOGE(TAG, "Failed to open a new connection %s", host); - goto exit; + ESP_RETURN_ON_FALSE(tls_ = esp_tls_init(), nullptr, TAG, "Failed to create ESP-TLS instance"); + int retries = 0; + while (esp_tls_conn_new_sync(host, strlen(host), rpc_port, &cfg, tls_) <= 0) { + esp_tls_conn_destroy(tls_); + tls_ = nullptr; + ESP_RETURN_ON_FALSE(retries++ < 3, nullptr, TAG, "Failed to open connection to %s", host); + ESP_LOGW(TAG, "Connection to RPC server failed! Will retry in %d second(s)", retries); + vTaskDelay(pdMS_TO_TICKS(1000 * retries)); + ESP_RETURN_ON_FALSE(tls_ = esp_tls_init(), nullptr, TAG, "Failed to create ESP-TLS instance"); } return &client::instance; -exit: - esp_tls_conn_destroy(tls_); - tls_ = nullptr; - return nullptr; } } // namespace eppp_rpc diff --git a/components/esp_wifi_remote/eppp/wifi_remote_rpc_impl.hpp b/components/esp_wifi_remote/eppp/wifi_remote_rpc_impl.hpp index 1f2f441c30c..30a0104db2e 100644 --- a/components/esp_wifi_remote/eppp/wifi_remote_rpc_impl.hpp +++ b/components/esp_wifi_remote/eppp/wifi_remote_rpc_impl.hpp @@ -86,6 +86,19 @@ class RpcEngine { return instance == nullptr ? ESP_FAIL : ESP_OK; } + void deinit() + { + if (tls_ == nullptr) { + return; + } + if (role_ == role::CLIENT) { + esp_tls_conn_destroy(tls_); + } else if (role_ == role::SERVER) { + esp_tls_server_session_delete(tls_); + } + tls_ = nullptr; + } + template esp_err_t send(api_id id, T *t) { diff --git a/components/esp_wifi_remote/eppp/wifi_remote_rpc_server.cpp b/components/esp_wifi_remote/eppp/wifi_remote_rpc_server.cpp index 03ce52080c4..0a8645d9525 100644 --- a/components/esp_wifi_remote/eppp/wifi_remote_rpc_server.cpp +++ b/components/esp_wifi_remote/eppp/wifi_remote_rpc_server.cpp @@ -54,7 +54,7 @@ class RpcInstance { { auto instance = static_cast(ctx); while (instance->perform() == ESP_OK) {} - vTaskDelete(nullptr); + esp_restart(); } esp_err_t start_server() { diff --git a/components/esp_wifi_remote/idf_component.yml b/components/esp_wifi_remote/idf_component.yml index 9acde64a710..826097bc890 100644 --- a/components/esp_wifi_remote/idf_component.yml +++ b/components/esp_wifi_remote/idf_component.yml @@ -5,6 +5,6 @@ dependencies: espressif/eppp_link: version: '0.0.1' idf: - version: '5.3' + version: '>=5.3' # espressif/esp_hosted: # version: '*' diff --git a/components/esp_wifi_remote/test/smoke_test/main/idf_component.yml b/components/esp_wifi_remote/test/smoke_test/main/idf_component.yml index ecffade5699..cb6183a90c0 100644 --- a/components/esp_wifi_remote/test/smoke_test/main/idf_component.yml +++ b/components/esp_wifi_remote/test/smoke_test/main/idf_component.yml @@ -2,7 +2,7 @@ dependencies: ## Required IDF version idf: - version: "5.3" + version: '>=5.3' espressif/esp_wifi_remote: version: "*" override_path: ../../..