Skip to content

Commit af8272d

Browse files
authored
Merge pull request #825 from david-cermak/fix/modem_auto_mode
[modem]: Fix autodetect to support ACFC mode in PPP frames
2 parents 01952f2 + 8b328a6 commit af8272d

File tree

2 files changed

+41
-16
lines changed

2 files changed

+41
-16
lines changed

components/esp_modem/src/esp_modem_dce.cpp

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -283,6 +283,10 @@ namespace ppp {
283283
// Test that we're in the PPP mode by sending an LCP protocol echo request and expecting LCP echo reply
284284
constexpr std::array<uint8_t, 16> lcp_echo_request = {0x7e, 0xff, 0x03, 0xc0, 0x21, 0x09, 0x01, 0x00, 0x08, 0x99, 0xd1, 0x35, 0xc1, 0x8e, 0x2c, 0x7e };
285285
constexpr std::array<uint8_t, 5> lcp_echo_reply_head = {0x7e, 0xff, 0x7d, 0x23, 0xc0};
286+
// PPP frame delimiter
287+
constexpr uint8_t ppp_delimiter = 0x7e;
288+
// LCP protocol ID
289+
constexpr std::array<uint8_t, 2> lcp_protocol_id = {0xc0, 0x21};
286290
const size_t mode = 1 << 0;
287291
const int timeout = 200;
288292
}
@@ -325,27 +329,48 @@ modem_mode DCE_Mode::guess_unsafe(DTE *dte, bool with_cmux)
325329
ESP_LOG_BUFFER_HEXDUMP("esp-modem: guess mode data:", reply, reply_pos, ESP_LOG_DEBUG);
326330

327331
// Check whether the response resembles the "golden" reply (for these 3 protocols)
328-
if (reply_pos >= sizeof(probe::ppp::lcp_echo_reply_head)) {
329-
// check for initial 2 bytes
330-
auto *ptr = static_cast<uint8_t *>(memmem(reply, reply_pos, probe::ppp::lcp_echo_reply_head.data(), 2));
331-
// and check the other two bytes for protocol ID:
332-
// * either LCP reply
333-
if (ptr && ptr[3] == probe::ppp::lcp_echo_reply_head[3] && ptr[4] == probe::ppp::lcp_echo_reply_head[4]) {
334-
if (auto signal = weak_signal.lock()) {
335-
signal->set(probe::ppp::mode);
336-
}
337-
}
338-
// * or LCP conf request
339-
if (ptr && ptr[3] == probe::ppp::lcp_echo_request[3] && ptr[4] == probe::ppp::lcp_echo_request[4]) {
340-
if (auto signal = weak_signal.lock()) {
341-
signal->set(probe::ppp::mode);
332+
if (reply_pos >= 3) { // Minimum size needed for basic PPP detection
333+
// Check for PPP detection - look for both traditional format and alternative formats
334+
335+
// Look for PPP frame delimiter (0x7E)
336+
auto *ppp_start = static_cast<uint8_t *>(memchr(reply, probe::ppp::ppp_delimiter, reply_pos));
337+
if (ppp_start) {
338+
size_t remaining = reply_pos - (ppp_start - reply);
339+
340+
// Look for LCP protocol ID anywhere within reasonable distance after delimiter
341+
if (remaining >= 5) { // Reasonable minimum for finding protocol ID
342+
// Check for original expected pattern
343+
if (memmem(ppp_start, remaining, probe::ppp::lcp_echo_reply_head.data(), 2)) {
344+
// Check for protocol ID in original format position
345+
uint8_t *protocol_pos = ppp_start + 3;
346+
if ((protocol_pos + 1) < (reply + reply_pos) &&
347+
(protocol_pos[0] == probe::ppp::lcp_echo_reply_head[3] &&
348+
protocol_pos[1] == probe::ppp::lcp_echo_reply_head[4])) {
349+
if (auto signal = weak_signal.lock()) {
350+
signal->set(probe::ppp::mode);
351+
return command_result::OK;
352+
}
353+
}
354+
}
355+
356+
// Also check for direct LCP protocol ID after delimiter (alternative format)
357+
if (remaining >= 3 && memmem(ppp_start + 1, remaining - 1,
358+
probe::ppp::lcp_protocol_id.data(),
359+
probe::ppp::lcp_protocol_id.size())) {
360+
if (auto signal = weak_signal.lock()) {
361+
signal->set(probe::ppp::mode);
362+
return command_result::OK;
363+
}
364+
}
342365
}
343366
}
344367
}
368+
345369
if (reply_pos >= 4 && memmem(reply, reply_pos, probe::cmd::reply, sizeof(probe::cmd::reply))) {
346370
if (reply[0] != 0xf9) { // double check that the reply is not wrapped in CMUX headers
347371
if (auto signal = weak_signal.lock()) {
348372
signal->set(probe::cmd::mode);
373+
return command_result::OK;
349374
}
350375
}
351376
}
@@ -356,6 +381,7 @@ modem_mode DCE_Mode::guess_unsafe(DTE *dte, bool with_cmux)
356381
if (ptr && (ptr[3] >> 2) == 0) {
357382
if (auto signal = weak_signal.lock()) {
358383
signal->set(probe::cmux::mode);
384+
return command_result::OK;
359385
}
360386
}
361387
}

components/esp_modem/src/esp_modem_dte.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,6 @@ void DTE::on_read(got_line_cb on_read_cb)
359359
auto res = on_read_cb(data, len);
360360
if (res == command_result::OK || res == command_result::FAIL) {
361361
primary_term->set_read_cb(nullptr);
362-
internal_lock.unlock();
363362
return true;
364363
}
365364
return false;

0 commit comments

Comments
 (0)