fix(modem): Fixed mode transitions between any state and UNDEF

Closes https://github.com/espressif/esp-protocols/issues/320
This commit is contained in:
David Cermak
2023-11-02 20:47:02 +01:00
parent 7c5a832821
commit 93cb2caadb
3 changed files with 28 additions and 8 deletions

View File

@ -235,7 +235,9 @@ extern "C" void app_main(void)
if (c->get_count_of(&SetModeArgs::mode)) { if (c->get_count_of(&SetModeArgs::mode)) {
auto mode = c->get_string_of(&SetModeArgs::mode); auto mode = c->get_string_of(&SetModeArgs::mode);
modem_mode dev_mode; modem_mode dev_mode;
if (mode == "CMUX1") { if (mode == "UNDEF") {
dev_mode = esp_modem::modem_mode::UNDEF;
} else if (mode == "CMUX1") {
dev_mode = esp_modem::modem_mode::CMUX_MANUAL_MODE; dev_mode = esp_modem::modem_mode::CMUX_MANUAL_MODE;
} else if (mode == "CMUX2") { } else if (mode == "CMUX2") {
dev_mode = esp_modem::modem_mode::CMUX_MANUAL_EXIT; dev_mode = esp_modem::modem_mode::CMUX_MANUAL_EXIT;

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -96,6 +96,11 @@ bool DCE_Mode::set_unsafe(DTE *dte, ModuleIf *device, Netif &netif, modem_mode m
{ {
switch (m) { switch (m) {
case modem_mode::UNDEF: case modem_mode::UNDEF:
if (!dte->set_mode(m)) {
return false;
}
mode = m;
return true;
case modem_mode::DUAL_MODE: // Only DTE can be in Dual mode case modem_mode::DUAL_MODE: // Only DTE can be in Dual mode
break; break;
case modem_mode::COMMAND_MODE: case modem_mode::COMMAND_MODE:
@ -151,7 +156,7 @@ bool DCE_Mode::set_unsafe(DTE *dte, ModuleIf *device, Netif &netif, modem_mode m
mode = modem_mode::CMUX_MANUAL_MODE; mode = modem_mode::CMUX_MANUAL_MODE;
return true; return true;
case modem_mode::CMUX_MANUAL_EXIT: case modem_mode::CMUX_MANUAL_EXIT:
if (mode != modem_mode::CMUX_MANUAL_MODE) { if (mode != modem_mode::CMUX_MANUAL_MODE && mode != modem_mode::UNDEF) {
return false; return false;
} }
if (!dte->set_mode(m)) { if (!dte->set_mode(m)) {
@ -160,7 +165,7 @@ bool DCE_Mode::set_unsafe(DTE *dte, ModuleIf *device, Netif &netif, modem_mode m
mode = modem_mode::COMMAND_MODE; mode = modem_mode::COMMAND_MODE;
return true; return true;
case modem_mode::CMUX_MANUAL_SWAP: case modem_mode::CMUX_MANUAL_SWAP:
if (mode != modem_mode::CMUX_MANUAL_MODE) { if (mode != modem_mode::CMUX_MANUAL_MODE && mode != modem_mode::UNDEF) {
return false; return false;
} }
if (!dte->set_mode(m)) { if (!dte->set_mode(m)) {
@ -168,12 +173,12 @@ bool DCE_Mode::set_unsafe(DTE *dte, ModuleIf *device, Netif &netif, modem_mode m
} }
return true; return true;
case modem_mode::CMUX_MANUAL_DATA: case modem_mode::CMUX_MANUAL_DATA:
if (mode != modem_mode::CMUX_MANUAL_MODE) { if (mode != modem_mode::CMUX_MANUAL_MODE && mode != modem_mode::UNDEF) {
return false; return false;
} }
return transitions::enter_data(*dte, *device, netif); return transitions::enter_data(*dte, *device, netif);
case modem_mode::CMUX_MANUAL_COMMAND: case modem_mode::CMUX_MANUAL_COMMAND:
if (mode != modem_mode::CMUX_MANUAL_MODE) { if (mode != modem_mode::CMUX_MANUAL_MODE && mode != modem_mode::UNDEF) {
return false; return false;
} }
return transitions::exit_data(*dte, *device, netif); return transitions::exit_data(*dte, *device, netif);

View File

@ -151,10 +151,14 @@ command_result DTE::command(const std::string &cmd, got_line_cb got_line, uint32
bool DTE::exit_cmux() bool DTE::exit_cmux()
{ {
if (!cmux_term) {
return false;
}
if (!cmux_term->deinit()) { if (!cmux_term->deinit()) {
return false; return false;
} }
exit_cmux_internal(); exit_cmux_internal();
cmux_term.reset();
return true; return true;
} }
@ -174,6 +178,10 @@ void DTE::exit_cmux_internal()
bool DTE::setup_cmux() bool DTE::setup_cmux()
{ {
if (cmux_term) {
ESP_LOGE("esp_modem_dte", "Cannot setup_cmux(), cmux_term already exists");
return false;
}
cmux_term = std::make_shared<CMux>(primary_term, std::move(buffer)); cmux_term = std::make_shared<CMux>(primary_term, std::move(buffer));
if (cmux_term == nullptr) { if (cmux_term == nullptr) {
return false; return false;
@ -198,6 +206,11 @@ bool DTE::setup_cmux()
bool DTE::set_mode(modem_mode m) bool DTE::set_mode(modem_mode m)
{ {
// transitions (any) -> UNDEF
if (m == modem_mode::UNDEF) {
mode = m;
return true;
}
// transitions (COMMAND|UNDEF) -> CMUX // transitions (COMMAND|UNDEF) -> CMUX
if (m == modem_mode::CMUX_MODE) { if (m == modem_mode::CMUX_MODE) {
if (mode == modem_mode::UNDEF || mode == modem_mode::COMMAND_MODE) { if (mode == modem_mode::UNDEF || mode == modem_mode::COMMAND_MODE) {
@ -246,7 +259,7 @@ bool DTE::set_mode(modem_mode m)
return false; return false;
} }
// manual CMUX transitions: Exit CMUX // manual CMUX transitions: Exit CMUX
if (m == modem_mode::CMUX_MANUAL_EXIT && mode == modem_mode::CMUX_MANUAL_MODE) { if (m == modem_mode::CMUX_MANUAL_EXIT && (mode == modem_mode::CMUX_MANUAL_MODE || mode == modem_mode::UNDEF)) {
if (exit_cmux()) { if (exit_cmux()) {
mode = modem_mode::COMMAND_MODE; mode = modem_mode::COMMAND_MODE;
return true; return true;
@ -255,7 +268,7 @@ bool DTE::set_mode(modem_mode m)
return false; return false;
} }
// manual CMUX transitions: Swap terminals // manual CMUX transitions: Swap terminals
if (m == modem_mode::CMUX_MANUAL_SWAP && mode == modem_mode::CMUX_MANUAL_MODE) { if (m == modem_mode::CMUX_MANUAL_SWAP && (mode == modem_mode::CMUX_MANUAL_MODE || mode == modem_mode::UNDEF)) {
secondary_term.swap(primary_term); secondary_term.swap(primary_term);
set_command_callbacks(); set_command_callbacks();
return true; return true;