mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-19 13:32:21 +02:00
feat(esp-modem): Add support for manual CMUX operations
Closes https://github.com/espressif/esp-protocols/issues/168
This commit is contained in:
@ -14,6 +14,59 @@
|
||||
|
||||
namespace esp_modem {
|
||||
|
||||
namespace transitions {
|
||||
|
||||
static bool exit_data(DTE &dte, ModuleIf &device, Netif &netif)
|
||||
{
|
||||
netif.stop();
|
||||
auto signal = std::make_shared<SignalGroup>();
|
||||
std::weak_ptr<SignalGroup> weak_signal = signal;
|
||||
dte.set_read_cb([weak_signal](uint8_t *data, size_t len) -> bool {
|
||||
if (memchr(data, '\n', len))
|
||||
{
|
||||
ESP_LOG_BUFFER_HEXDUMP("esp-modem: debug_data", data, len, ESP_LOG_DEBUG);
|
||||
const auto pass = std::list<std::string_view>({"NO CARRIER", "DISCONNECTED"});
|
||||
std::string_view response((char *) data, len);
|
||||
for (auto &it : pass)
|
||||
if (response.find(it) != std::string::npos) {
|
||||
if (auto signal = weak_signal.lock()) {
|
||||
signal->set(1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
netif.wait_until_ppp_exits();
|
||||
if (!signal->wait(1, 2000)) {
|
||||
if (!device.set_mode(modem_mode::COMMAND_MODE)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
dte.set_read_cb(nullptr);
|
||||
if (!dte.set_mode(modem_mode::COMMAND_MODE)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool enter_data(DTE &dte, ModuleIf &device, Netif &netif)
|
||||
{
|
||||
if (!device.setup_data_mode()) {
|
||||
return false;
|
||||
}
|
||||
if (!device.set_mode(modem_mode::DATA_MODE)) {
|
||||
return false;
|
||||
}
|
||||
if (!dte.set_mode(modem_mode::DATA_MODE)) {
|
||||
return false;
|
||||
}
|
||||
netif.start();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace transitions
|
||||
|
||||
/**
|
||||
* Set mode while the entire DTE is locked
|
||||
*/
|
||||
@ -36,8 +89,8 @@ bool DCE_Mode::set_unsafe(DTE *dte, ModuleIf *device, Netif &netif, modem_mode m
|
||||
switch (m) {
|
||||
case modem_mode::UNDEF:
|
||||
break;
|
||||
case modem_mode::COMMAND_MODE: {
|
||||
if (mode == modem_mode::COMMAND_MODE) {
|
||||
case modem_mode::COMMAND_MODE:
|
||||
if (mode == modem_mode::COMMAND_MODE || mode >= modem_mode::CMUX_MANUAL_MODE) {
|
||||
return false;
|
||||
}
|
||||
if (mode == modem_mode::CMUX_MODE) {
|
||||
@ -49,59 +102,23 @@ bool DCE_Mode::set_unsafe(DTE *dte, ModuleIf *device, Netif &netif, modem_mode m
|
||||
mode = m;
|
||||
return true;
|
||||
}
|
||||
netif.stop();
|
||||
auto signal = std::make_shared<SignalGroup>();
|
||||
std::weak_ptr<SignalGroup> weak_signal = signal;
|
||||
dte->set_read_cb([weak_signal](uint8_t *data, size_t len) -> bool {
|
||||
if (memchr(data, '\n', len))
|
||||
{
|
||||
ESP_LOG_BUFFER_HEXDUMP("esp-modem: debug_data", data, len, ESP_LOG_DEBUG);
|
||||
const auto pass = std::list<std::string_view>({"NO CARRIER", "DISCONNECTED"});
|
||||
std::string_view response((char *) data, len);
|
||||
for (auto &it : pass)
|
||||
if (response.find(it) != std::string::npos) {
|
||||
if (auto signal = weak_signal.lock()) {
|
||||
signal->set(1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
netif.wait_until_ppp_exits();
|
||||
if (!signal->wait(1, 2000)) {
|
||||
if (!device->set_mode(modem_mode::COMMAND_MODE)) {
|
||||
mode = modem_mode::UNDEF;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
dte->set_read_cb(nullptr);
|
||||
if (!dte->set_mode(modem_mode::COMMAND_MODE)) {
|
||||
if (!transitions::exit_data(*dte, *device, netif)) {
|
||||
mode = modem_mode::UNDEF;
|
||||
return false;
|
||||
}
|
||||
mode = m;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case modem_mode::DATA_MODE:
|
||||
if (mode == modem_mode::DATA_MODE || mode == modem_mode::CMUX_MODE) {
|
||||
if (mode == modem_mode::DATA_MODE || mode == modem_mode::CMUX_MODE || mode >= modem_mode::CMUX_MANUAL_MODE) {
|
||||
return false;
|
||||
}
|
||||
if (!device->setup_data_mode()) {
|
||||
if (!transitions::enter_data(*dte, *device, netif)) {
|
||||
return false;
|
||||
}
|
||||
if (!device->set_mode(modem_mode::DATA_MODE)) {
|
||||
return false;
|
||||
}
|
||||
if (!dte->set_mode(modem_mode::DATA_MODE)) {
|
||||
return false;
|
||||
}
|
||||
netif.start();
|
||||
mode = m;
|
||||
return true;
|
||||
case modem_mode::CMUX_MODE:
|
||||
if (mode == modem_mode::DATA_MODE || mode == modem_mode::CMUX_MODE) {
|
||||
if (mode == modem_mode::DATA_MODE || mode == modem_mode::CMUX_MODE || mode >= modem_mode::CMUX_MANUAL_MODE) {
|
||||
return false;
|
||||
}
|
||||
device->set_mode(modem_mode::CMUX_MODE); // switch the device into CMUX mode
|
||||
@ -111,17 +128,46 @@ bool DCE_Mode::set_unsafe(DTE *dte, ModuleIf *device, Netif &netif, modem_mode m
|
||||
return false;
|
||||
}
|
||||
mode = modem_mode::CMUX_MODE;
|
||||
if (!device->setup_data_mode()) {
|
||||
return transitions::enter_data(*dte, *device, netif);
|
||||
case modem_mode::CMUX_MANUAL_MODE:
|
||||
if (mode != modem_mode::COMMAND_MODE) {
|
||||
return false;
|
||||
}
|
||||
if (!device->set_mode(modem_mode::DATA_MODE)) {
|
||||
device->set_mode(modem_mode::CMUX_MODE);
|
||||
usleep(100'000);
|
||||
|
||||
if (!dte->set_mode(m)) {
|
||||
return false;
|
||||
}
|
||||
if (!dte->set_mode(modem_mode::DATA_MODE)) {
|
||||
return false;
|
||||
}
|
||||
netif.start();
|
||||
mode = modem_mode::CMUX_MANUAL_MODE;
|
||||
return true;
|
||||
case modem_mode::CMUX_MANUAL_EXIT:
|
||||
if (mode != modem_mode::CMUX_MANUAL_MODE) {
|
||||
return false;
|
||||
}
|
||||
if (!dte->set_mode(m)) {
|
||||
return false;
|
||||
}
|
||||
mode = modem_mode::COMMAND_MODE;
|
||||
return true;
|
||||
case modem_mode::CMUX_MANUAL_SWAP:
|
||||
if (mode != modem_mode::CMUX_MANUAL_MODE) {
|
||||
return false;
|
||||
}
|
||||
if (!dte->set_mode(m)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case modem_mode::CMUX_MANUAL_DATA:
|
||||
if (mode != modem_mode::CMUX_MANUAL_MODE) {
|
||||
return false;
|
||||
}
|
||||
return transitions::enter_data(*dte, *device, netif);
|
||||
case modem_mode::CMUX_MANUAL_COMMAND:
|
||||
if (mode != modem_mode::CMUX_MANUAL_MODE) {
|
||||
return false;
|
||||
}
|
||||
return transitions::exit_data(*dte, *device, netif);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
Reference in New Issue
Block a user