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
284284constexpr std::array<uint8_t , 16 > lcp_echo_request = {0x7e , 0xff , 0x03 , 0xc0 , 0x21 , 0x09 , 0x01 , 0x00 , 0x08 , 0x99 , 0xd1 , 0x35 , 0xc1 , 0x8e , 0x2c , 0x7e };
285285constexpr 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 };
286290const size_t mode = 1 << 0 ;
287291const 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 }
0 commit comments