mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-20 16:46:14 +00:00
esp_modem: Fixed race condition on exiting PPP mode
esp_modem_stop_ppp() stops both ppp netif and switches the modem back to command mode. IF these two actions are not synchronised, we might experience issues of * active PPP session trying to send/receive uart-data * command mode already active before modem switched to it both resulting in crashes. Fixed by introducing the transition mode and running these actions in sequence * set esp-modem to transition mode * enter command mode, wait for the reply or re-sync * close the PPP netif * wait until the netif closes Other fixes include ignoring certain events if modem component not ready or not in appropriate mode: * ignoring all UART events comming from DTE with no DCE attached * ignore pattern detection in PPP mode Closes https://github.com/espressif/esp-idf/issues/6013 Closes https://github.com/espressif/esp-idf/issues/5737 Closes https://github.com/espressif/esp-idf/issues/6024 Closes https://github.com/espressif/esp-idf/issues/6058 Closes https://github.com/espressif/esp-idf/issues/5563 Closes https://github.com/espressif/esp-idf/issues/5695 Closes https://github.com/espressif/esp-idf/issues/5633 Closes https://github.com/espressif/esp-idf/issues/4482 Related https://github.com/espressif/esp-idf/pull/4849 Related https://github.com/espressif/esp-idf/pull/4653
This commit is contained in:
@@ -294,15 +294,31 @@ static esp_err_t sim800_set_working_mode(modem_dce_t *dce, modem_mode_t mode)
|
||||
switch (mode) {
|
||||
case MODEM_COMMAND_MODE:
|
||||
dce->handle_line = sim800_handle_exit_data_mode;
|
||||
DCE_CHECK(dte->send_cmd(dte, "+++", MODEM_COMMAND_TIMEOUT_MODE_CHANGE) == ESP_OK, "send command failed", err);
|
||||
DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "enter command mode failed", err);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000)); // spec: 1s delay for the modem to recognize the escape sequence
|
||||
if (dte->send_cmd(dte, "+++", MODEM_COMMAND_TIMEOUT_MODE_CHANGE) != ESP_OK) {
|
||||
// "+++" Could fail if we are already in the command mode.
|
||||
// in that case we ignore the timeout and re-sync the modem
|
||||
ESP_LOGI(DCE_TAG, "Sending \"+++\" command failed");
|
||||
dce->handle_line = esp_modem_dce_handle_response_default;
|
||||
DCE_CHECK(dte->send_cmd(dte, "AT\r", MODEM_COMMAND_TIMEOUT_DEFAULT) == ESP_OK, "send command failed", err);
|
||||
DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "sync failed", err);
|
||||
} else {
|
||||
DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "enter command mode failed", err);
|
||||
}
|
||||
ESP_LOGD(DCE_TAG, "enter command mode ok");
|
||||
dce->mode = MODEM_COMMAND_MODE;
|
||||
break;
|
||||
case MODEM_PPP_MODE:
|
||||
dce->handle_line = sim800_handle_atd_ppp;
|
||||
DCE_CHECK(dte->send_cmd(dte, "ATD*99#\r", MODEM_COMMAND_TIMEOUT_MODE_CHANGE) == ESP_OK, "send command failed", err);
|
||||
DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "enter ppp mode failed", err);
|
||||
if (dce->state != MODEM_STATE_SUCCESS) {
|
||||
// Initiate PPP mode could fail, if we've already "dialed" the data call before.
|
||||
// in that case we retry with "ATO" to just resume the data mode
|
||||
ESP_LOGD(DCE_TAG, "enter ppp mode failed, retry with ATO");
|
||||
dce->handle_line = sim800_handle_atd_ppp;
|
||||
DCE_CHECK(dte->send_cmd(dte, "ATO\r", MODEM_COMMAND_TIMEOUT_MODE_CHANGE) == ESP_OK, "send command failed", err);
|
||||
DCE_CHECK(dce->state == MODEM_STATE_SUCCESS, "enter ppp mode failed", err);
|
||||
}
|
||||
ESP_LOGD(DCE_TAG, "enter ppp mode ok");
|
||||
dce->mode = MODEM_PPP_MODE;
|
||||
break;
|
||||
|
Reference in New Issue
Block a user