From a243d7e878e7ce6278083dab83a0be66ee3fbf03 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Fri, 1 Jul 2022 13:52:45 +0200 Subject: [PATCH] fix(esp_modem): Update ap2ppp example to recover network on disconnection Closes https://github.com/espressif/esp-protocols/issues/44 --- .../examples/ap_to_pppos/main/ap_to_pppos.c | 48 ++++++++++++++----- .../examples/ap_to_pppos/main/network_dce.c | 27 +++++++++-- .../examples/ap_to_pppos/main/network_dce.cpp | 41 ++++++++++++++-- .../examples/ap_to_pppos/main/network_dce.h | 9 +++- components/esp_modem/src/esp_modem_c_api.cpp | 26 +++++----- .../esp_modem/test/target/main/NetworkDCE.cpp | 2 +- 6 files changed, 116 insertions(+), 37 deletions(-) diff --git a/components/esp_modem/examples/ap_to_pppos/main/ap_to_pppos.c b/components/esp_modem/examples/ap_to_pppos/main/ap_to_pppos.c index ceba06f1d..634b8c18f 100644 --- a/components/esp_modem/examples/ap_to_pppos/main/ap_to_pppos.c +++ b/components/esp_modem/examples/ap_to_pppos/main/ap_to_pppos.c @@ -124,6 +124,38 @@ void wifi_init_softap(void) EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS, EXAMPLE_ESP_WIFI_CHANNEL); } +void start_network(void) +{ + EventBits_t bits = 0; + while ((bits & CONNECT_BIT) == 0) { + if (!modem_check_sync()) { + ESP_LOGE(TAG, "Modem does not respond, maybe in DATA mode? ...exiting network mode"); + modem_stop_network(); + if (!modem_check_sync()) { + ESP_LOGE(TAG, "Modem does not respond to AT ...restarting"); + modem_reset(); + ESP_LOGI(TAG, "Restarted"); + } + continue; + } + if (!modem_check_signal()) { + ESP_LOGI(TAG, "Poor signal ...will check after 5s"); + vTaskDelay(pdMS_TO_TICKS(5000)); + continue; + } + if (!modem_start_network()) { + ESP_LOGE(TAG, "Modem could not enter network mode ...will retry after 10s"); + vTaskDelay(pdMS_TO_TICKS(10000)); + continue; + } + bits = xEventGroupWaitBits(event_group, (DISCONNECT_BIT | CONNECT_BIT), pdTRUE, pdFALSE, pdMS_TO_TICKS(30000)); + if (bits & DISCONNECT_BIT) { + ESP_LOGE(TAG, "Modem got disconnected ...retrying"); + modem_stop_network(); + } + } +} + void app_main(void) { // Initialize NVS @@ -149,16 +181,7 @@ void app_main(void) ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event, NULL)); // Start the PPP network and wait for connection - modem_start_network(); - EventBits_t bits; - do { - bits = xEventGroupWaitBits(event_group, (CONNECT_BIT | DISCONNECT_BIT), pdTRUE, pdFALSE, portMAX_DELAY); - if (bits & DISCONNECT_BIT) { - ESP_LOGW(TAG, "Modem got disconnected from the PPP server: retrying..."); - modem_stop_network(); - modem_start_network(); - } - } while ((bits & CONNECT_BIT) == 0); + start_network(); // Initialize the AP and setup the NAT esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap(); @@ -172,11 +195,10 @@ void app_main(void) // Provide a recovery if disconnection of some kind registered while (true) { - bits = xEventGroupWaitBits(event_group, DISCONNECT_BIT, pdTRUE, pdFALSE, portMAX_DELAY); + EventBits_t bits = xEventGroupWaitBits(event_group, DISCONNECT_BIT, pdTRUE, pdFALSE, portMAX_DELAY); if (bits & DISCONNECT_BIT) { - ESP_LOGW(TAG, "Modem got disconnected from the PPP server: restarting the network..."); modem_stop_network(); - modem_start_network(); + start_network(); } } } diff --git a/components/esp_modem/examples/ap_to_pppos/main/network_dce.c b/components/esp_modem/examples/ap_to_pppos/main/network_dce.c index 8c825a0fd..f79a46c5c 100644 --- a/components/esp_modem/examples/ap_to_pppos/main/network_dce.c +++ b/components/esp_modem/examples/ap_to_pppos/main/network_dce.c @@ -47,12 +47,31 @@ void modem_deinit_network(void) } } -void modem_start_network() +bool modem_start_network() { - esp_modem_set_mode(dce, ESP_MODEM_MODE_DATA); + return esp_modem_set_mode(dce, ESP_MODEM_MODE_DATA) == ESP_OK; } -void modem_stop_network() +bool modem_stop_network() { - esp_modem_set_mode(dce, ESP_MODEM_MODE_COMMAND); + return esp_modem_set_mode(dce, ESP_MODEM_MODE_COMMAND); +} + +bool modem_check_sync() +{ + return esp_modem_sync(dce) == ESP_OK; +} + +void modem_reset() +{ + esp_modem_reset(dce); +} + +bool modem_check_signal() +{ + int rssi, ber; + if (esp_modem_get_signal_quality(dce, &rssi, &ber) == ESP_OK) { + return rssi != 99 && rssi > 5; + } + return false; } diff --git a/components/esp_modem/examples/ap_to_pppos/main/network_dce.cpp b/components/esp_modem/examples/ap_to_pppos/main/network_dce.cpp index 1f27d1a28..13e0c0c84 100644 --- a/components/esp_modem/examples/ap_to_pppos/main/network_dce.cpp +++ b/components/esp_modem/examples/ap_to_pppos/main/network_dce.cpp @@ -79,6 +79,24 @@ public: } } + bool sync() + { + return dce_commands::sync(dte.get()) == command_result::OK; + } + + void reset() + { + dce_commands::reset(dte.get()); + } + + bool check_signal() + { + int rssi, ber; + if (dce_commands::get_signal_quality(dte.get(), rssi, ber) != command_result::OK) + return false; + return rssi != 99 && rssi > 5; + } + [[maybe_unused]] bool init_sim(const std::string &pin) { // switch to command mode (in case we were in PPP mode) @@ -166,14 +184,14 @@ extern "C" esp_err_t modem_init_network(esp_netif_t *netif) return ESP_OK; } -extern "C" void modem_start_network() +extern "C" bool modem_start_network() { - dce->set_mode(esp_modem::modem_mode::DATA_MODE); + return dce->set_mode(esp_modem::modem_mode::DATA_MODE); } -extern "C" void modem_stop_network() +extern "C" bool modem_stop_network() { - dce->set_mode(esp_modem::modem_mode::COMMAND_MODE); + return dce->set_mode(esp_modem::modem_mode::COMMAND_MODE); } extern "C" void modem_deinit_network() @@ -182,4 +200,19 @@ extern "C" void modem_deinit_network() dce = nullptr; } +extern "C" bool modem_check_sync() +{ + return dce->get_module()->sync(); +} + +extern "C" void modem_reset() +{ + dce->get_module()->reset(); +} + +extern "C" bool modem_check_signal() +{ + return dce->get_module()->check_signal(); +} + } \ No newline at end of file diff --git a/components/esp_modem/examples/ap_to_pppos/main/network_dce.h b/components/esp_modem/examples/ap_to_pppos/main/network_dce.h index 4d9e3c23f..5c7d4a96f 100644 --- a/components/esp_modem/examples/ap_to_pppos/main/network_dce.h +++ b/components/esp_modem/examples/ap_to_pppos/main/network_dce.h @@ -31,13 +31,18 @@ void modem_deinit_network(); /** * @brief Starts the PPP network */ -void modem_start_network(); +bool modem_start_network(); /** * @brief Stops the PPP network */ -void modem_stop_network(); +bool modem_stop_network(); +bool modem_check_sync(); + +void modem_reset(); + +bool modem_check_signal(); #ifdef __cplusplus } diff --git a/components/esp_modem/src/esp_modem_c_api.cpp b/components/esp_modem/src/esp_modem_c_api.cpp index e1a9e9d9c..1f1bbfeae 100644 --- a/components/esp_modem/src/esp_modem_c_api.cpp +++ b/components/esp_modem/src/esp_modem_c_api.cpp @@ -122,20 +122,15 @@ extern "C" esp_err_t esp_modem_set_mode(esp_modem_dce_t *dce_wrap, esp_modem_dce return ESP_ERR_INVALID_ARG; } if (mode == ESP_MODEM_MODE_DATA) { - dce_wrap->dce->set_data(); - } else if (mode == ESP_MODEM_MODE_COMMAND) { - dce_wrap->dce->exit_data(); - } else if (mode == ESP_MODEM_MODE_CMUX) { - if (dce_wrap->dce->set_mode(modem_mode::CMUX_MODE) && - // automatically switch to data mode for the primary terminal - dce_wrap->dce->set_mode(modem_mode::DATA_MODE)) { - return ESP_OK; - } - return ESP_FAIL; - } else { - return ESP_ERR_NOT_SUPPORTED; + return dce_wrap->dce->set_mode(modem_mode::DATA_MODE) ? ESP_OK : ESP_FAIL; } - return ESP_OK; + if (mode == ESP_MODEM_MODE_COMMAND) { + return dce_wrap->dce->set_mode(modem_mode::COMMAND_MODE) ? ESP_OK : ESP_FAIL; + } + if (mode == ESP_MODEM_MODE_CMUX) { + return dce_wrap->dce->set_mode(modem_mode::CMUX_MODE) ? ESP_OK : ESP_FAIL; + } + return ESP_ERR_NOT_SUPPORTED; } extern "C" esp_err_t esp_modem_read_pin(esp_modem_dce_t *dce_wrap, bool *pin) @@ -393,3 +388,8 @@ extern "C" esp_err_t esp_modem_set_gnss_power_mode(esp_modem_dce_t *dce_wrap, in } return command_response_to_esp_err(dce_wrap->dce->set_gnss_power_mode(mode)); } + +extern "C" esp_err_t esp_modem_reset(esp_modem_dce_t *dce_wrap) +{ + return command_response_to_esp_err(dce_wrap->dce->reset()); +} diff --git a/components/esp_modem/test/target/main/NetworkDCE.cpp b/components/esp_modem/test/target/main/NetworkDCE.cpp index d53e84e20..c14f0d17e 100644 --- a/components/esp_modem/test/target/main/NetworkDCE.cpp +++ b/components/esp_modem/test/target/main/NetworkDCE.cpp @@ -87,7 +87,7 @@ esp_err_t modem_init_network(esp_netif_t *netif) return NetModule::init(netif); } -void modem_start_network() +esp_err_t modem_start_network() { NetModule::start(); }