fix(esp_modem): Update ap2ppp example to recover network on disconnection

Closes https://github.com/espressif/esp-protocols/issues/44
This commit is contained in:
David Cermak
2022-07-01 13:52:45 +02:00
parent ef1bae5cdd
commit a243d7e878
6 changed files with 116 additions and 37 deletions

View File

@ -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();
}
}
}

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -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
}

View File

@ -122,21 +122,16 @@ 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 dce_wrap->dce->set_mode(modem_mode::DATA_MODE) ? ESP_OK : ESP_FAIL;
}
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_FAIL;
} else {
return ESP_ERR_NOT_SUPPORTED;
}
return ESP_OK;
}
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());
}

View File

@ -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();
}