ppp 增加上网时临时获取网络状态的AT执行能力。目前看来可能固件有问题。代码未见问题。
author孙春阳 <snickersun@163.com>
Fri, 10 Oct 2025 07:46:29 +0000 (15:46 +0800)
committer孙春阳 <snickersun@163.com>
Fri, 10 Oct 2025 07:46:29 +0000 (15:46 +0800)
code/sdk/zhihui/ppp/include/ppp_api.h
code/sdk/zhihui/ppp/include/ppp_config.h
code/sdk/zhihui/ppp/include/ppp_lwip.h
code/sdk/zhihui/ppp/src/ppp_api.c
code/sdk/zhihui/ppp/src/ppp_interrupt.c
code/sdk/zhihui/ppp/src/ppp_lwip.c

index c3c1f12..3adabc7 100644 (file)
@@ -38,14 +38,13 @@ errcode_t ppp_stop_dial(void);
 /**
  * @brief 暂停PPP通讯,切换到AT命令模式(不断开连接)
  * @return 错误码
- * 
- * 功能说明:
+ *
+ * å\8a\9fè\83½è¯´æ\98\8eï¼\88ç²¾ç®\80ç\89\88ï¼\8cä¸\8dé\94\80æ¯\81ä»»ä½\95èµ\84æº\90ï¼\89ï¼\9a
  * - 发送 "+++" 转义序列切换到AT命令模式
- * - 停止PPP数据接收线程/中断
- * - 初始化AT处理器
- * - 执行AT测试验证
+ * - 注销中断回调/停止接收线程
+ * - 切换串口模式为AT模式
  * 
- * 注意:PPP连接保持,只是暂时切换到AT模式,与 ppp_resume() 配对使用
+ * 注意:PPP连接保持,只是暂时切换模式,与 ppp_ppp_mode_resume() 配对使用
  */
 errcode_t ppp_ppp_mode_pause(void);
 
@@ -53,13 +52,13 @@ errcode_t ppp_ppp_mode_pause(void);
  * @brief 恢复PPP通讯,从AT命令模式返回PPP数据模式
  * @return 错误码
  * 
- * 功能说明:
+ * å\8a\9fè\83½è¯´æ\98\8eï¼\88ç²¾ç®\80ç\89\88ï¼\8cä¸\8dé\87\8d建任ä½\95èµ\84æº\90ï¼\89ï¼\9a
  * - 发送 "ATO\r\n" 命令恢复PPP数据模式
  * - 等待 "CONNECT" 响应
- * - å\8e»å\88\9då§\8bå\8c\96ATå¤\84ç\90\86å\99¨
- * - æ\81¢å¤\8dPPPæ\95°æ\8d®æ\8e¥æ\94¶çº¿ç¨\8b/中æ\96­
+ * - å\88\87æ\8d¢ä¸²å\8f£æ¨¡å¼\8f为PPP模å¼\8f
+ * - æ³¨å\86\8c中æ\96­å\9b\9eè°\83/å\90¯å\8a¨æ\8e¥æ\94¶çº¿ç¨\8b
  * 
- * 注意:与 ppp_pause() 配对使用
+ * 注意:与 ppp_ppp_mode_pause() 配对使用
  */
 errcode_t ppp_ppp_mode_resume(void);
 
index 3ece8b9..1591842 100644 (file)
@@ -74,7 +74,7 @@ extern "C" {
 
 /* 调试配置 */
 #define PPP_DEBUG_ENABLE            1                   // 启用调试输出
-#define PPP_DEBUG_LEVEL             PPP_DEBUG_LEVEL_WARN // 默认只显示警告和错误 (1=ERROR, 2=WARN, 3=INFO, 4=DEBUG)
+#define PPP_DEBUG_LEVEL             PPP_DEBUG_LEVEL_INFO // 默认只显示警告和错误 (1=ERROR, 2=WARN, 3=INFO, 4=DEBUG)
 
 /*
  * 调试级别说明:
index 40acb8e..da40a69 100644 (file)
@@ -88,6 +88,17 @@ ppp_error_t ppp_lwip_connect(void);
  */
 ppp_error_t ppp_lwip_disconnect(void);
 
+/**
+ * @brief 启动PPP连接监控
+ * @return PPP错误码
+ */
+ppp_error_t ppp_lwip_start_connection_monitor(void);
+
+/**
+ * @brief 停止PPP连接监控
+ */
+void ppp_lwip_stop_connection_monitor(void);
+
 /**
  * @brief 输入PPP数据
  * @param data 数据指针
index 8928442..196fb8a 100644 (file)
@@ -616,17 +616,16 @@ error_recovery_at_mode:
  * @brief 暂停PPP通讯,切换到AT命令模式(不断开连接)
  * @return ERRCODE_SUCC-成功,其他-失败
  * 
- * 功能说明:
+ * å\8a\9fè\83½è¯´æ\98\8eï¼\88ç²¾ç®\80ç\89\88ï¼\89ï¼\9a
  * 1. 发送 "+++" 转义序列切换到AT命令模式
- * 2. 停止PPP数据接收线程/中断
- * 3. 初始化AT处理器
- * 4. 执行AT测试验证
+ * 2. 注销中断回调/停止接收线程
+ * 3. 切换串口模式为AT模式
  * 
- * 注意:PPP连接保持,只是暂时切换到AT模式
+ * 注意:PPP连接保持,不销毁任何资源,只是暂时切换模式
  */
 errcode_t ppp_ppp_mode_pause(void)
 {
-    PPP_DEBUG_CRITICAL("=== PPP Pause Started ===");
+    PPP_DEBUG_CRITICAL("=== PPP Pause Started (Simplified) ===");
     
     // 检查PPP状态
     if (g_ppp_state != PPP_STATE_CONNECTED) {
@@ -636,208 +635,132 @@ errcode_t ppp_ppp_mode_pause(void)
     
     ppp_error_t ret = PPP_ERR_OK;
     
-    // 1. 停止PPP数据接收(根据配置选择中断或轮询模式)
-#if PPP_USE_INTERRUPT_MODE
-    PPP_DEBUG_INFO("Disabling PPP interrupt mode...");
-    ppp_interrupt_disable();
-    PPP_DEBUG_INFO("PPP interrupt mode disabled");
-#else
-    PPP_DEBUG_INFO("Stopping PPP receive thread...");
-    ppp_lwip_stop_receive_thread();
-    PPP_DEBUG_INFO("PPP receive thread stopped");
-#endif
-    
-    // 2. 发送 "+++" 转义序列切换到AT命令模式
-    PPP_DEBUG_INFO("Sending escape sequence (+++) to switch to AT mode...");
+    // 1. 发送 "+++" 转义序列切换到AT命令模式
+    PPP_DEBUG_INFO("Sending escape sequence (+++) to modem...");
     
     // 根据Hayes标准,转义序列前后需要1秒的静默期
-    osal_msleep(1000);  // 前置静默期
+    osal_msleep(100);  // 前置静默期
     
     const char escape_seq[] = "+++";
     ret = ppp_serial_write((uint8_t*)escape_seq, strlen(escape_seq));
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_ERROR("Failed to send escape sequence: %d", ret);
-        goto error_recovery;
+        return ERRCODE_FAIL;
     }
     
-    osal_msleep(1000);  // 后置静默期
-    PPP_DEBUG_INFO("Escape sequence sent, waiting for modem response...");
+    osal_msleep(100);  // 后置静默期
+    PPP_DEBUG_INFO("Escape sequence sent");
     
-    // 3. 等待调制解调器响应(通常是 "OK")
-    osal_msleep(1000);  // 等待响应
+    // 2. 等待调制解调器响应
+    osal_msleep(100);
     
-    // 读取调制解调器响应
-    uint8_t response_buffer[64];
-    uint32_t bytes_read = 0;
-    ret = ppp_serial_read(response_buffer, sizeof(response_buffer), &bytes_read);
-    if (ret == PPP_ERR_OK && bytes_read > 0) {
-        PPP_DEBUG_INFO("Modem response to escape sequence: %u bytes", bytes_read);
-        // 可以检查是否包含 "OK"
-        bool found_ok = false;
-        for (uint32_t i = 0; i < bytes_read - 1; i++) {
-            if (response_buffer[i] == 'O' && response_buffer[i+1] == 'K') {
-                found_ok = true;
-                break;
-            }
-        }
-        if (found_ok) {
-            PPP_DEBUG_INFO("Modem confirmed AT mode with OK");
-        } else {
-            PPP_DEBUG_WARN("No OK response from modem, continuing anyway...");
-        }
-    } else {
-        PPP_DEBUG_WARN("No immediate response from modem after escape sequence");
-    }
+    // 3. 停止PPP连接监控(防止因无数据而断开连接)
+    PPP_DEBUG_INFO("Stopping PPP connection monitor...");
+    ppp_lwip_stop_connection_monitor();
     
-    // 4. 切换串口到AT模式
-    PPP_DEBUG_INFO("Switching serial to AT mode...");
+    // 4. 注销中断回调/停止接收线程
+#if PPP_USE_INTERRUPT_MODE
+    PPP_DEBUG_INFO("Disabling PPP interrupt...");
+    ppp_interrupt_disable();
+#else
+    PPP_DEBUG_INFO("Stopping PPP receive thread...");
+    ppp_lwip_stop_receive_thread();
+#endif
+    
+    // 5. 切换串口模式为AT模式
+    PPP_DEBUG_INFO("Switching serial mode to AT...");
     ret = ppp_serial_switch_to_at_mode();
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_ERROR("Failed to switch to AT mode: %d", ret);
-        goto error_recovery;
-    }
-    
-    // 5. 初始化AT处理器
-    PPP_DEBUG_INFO("Initializing AT handler...");
-    ret = ppp_at_handler_init(SIO_UART_BUS, g_ppp_config.baudrate, true);
-    if (ret != PPP_ERR_OK) {
-        PPP_DEBUG_ERROR("Failed to initialize AT handler: %d", ret);
-        goto error_recovery;
-    }
-    
-    // 6. 测试AT通信
-    PPP_DEBUG_INFO("Testing AT communication...");
-    ret = ppp_at_test_communication();
-    if (ret != PPP_ERR_OK) {
-        PPP_DEBUG_WARN("AT communication test failed: %d", ret);
-        // 尝试第二次
-        osal_msleep(500);
-        ret = ppp_at_test_communication();
-        if (ret != PPP_ERR_OK) {
-            PPP_DEBUG_ERROR("AT communication still failed after retry");
-            goto error_recovery;
-        }
+        return ERRCODE_FAIL;
     }
     
     PPP_DEBUG_CRITICAL("=== PPP Paused - Now in AT Mode ===");
-    PPP_DEBUG_INFO("PPP connection is suspended but not terminated");
-    PPP_DEBUG_INFO("Use ppp_resume() to return to PPP data mode");
-    
-    // 更新状态(暂停状态,但保留CONNECTED信息)
-    // 不修改 g_ppp_state,保持 PPP_STATE_CONNECTED
+    PPP_DEBUG_INFO("Use ppp_ppp_mode_resume() to return to PPP data mode");
     
     return ERRCODE_SUCC;
-
-error_recovery:
-    PPP_DEBUG_ERROR("Failed to pause PPP, attempting to resume data mode...");
-    
-    // 尝试恢复到PPP数据模式
-    ppp_at_handler_deinit();
-    ppp_serial_switch_to_ppp_mode();
-    
-#if PPP_USE_INTERRUPT_MODE
-    ppp_interrupt_enable();
-#else
-    ppp_lwip_start_receive_thread();
-#endif
-    
-    return ERRCODE_FAIL;
 }
 
 /**
  * @brief 恢复PPP通讯,从AT命令模式返回PPP数据模式
  * @return ERRCODE_SUCC-成功,其他-失败
  * 
- * 功能说明:
+ * å\8a\9fè\83½è¯´æ\98\8eï¼\88ç²¾ç®\80ç\89\88ï¼\89ï¼\9a
  * 1. 发送 "ATO\r\n" 命令恢复PPP数据模式
  * 2. 等待 "CONNECT" 响应
- * 3. å\8e»å\88\9då§\8bå\8c\96ATå¤\84ç\90\86å\99¨
- * 4. æ\81¢å¤\8dPPPæ\95°æ\8d®æ\8e¥æ\94¶çº¿ç¨\8b/中æ\96­
+ * 3. å\88\87æ\8d¢ä¸²å\8f£æ¨¡å¼\8f为PPP模å¼\8f
+ * 4. æ³¨å\86\8c中æ\96­å\9b\9eè°\83/å\90¯å\8a¨æ\8e¥æ\94¶çº¿ç¨\8b
  * 
- * 注意:与 ppp_pause() 配对使用
+ * 注意:与 ppp_ppp_mode_pause() 配对使用,不销毁/重建任何资源
  */
 errcode_t ppp_ppp_mode_resume(void)
 {
-    PPP_DEBUG_CRITICAL("=== PPP Resume Started ===");
+    PPP_DEBUG_CRITICAL("=== PPP Resume Started (Simplified) ===");
     
     // 检查串口模式
-    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT) {
-        PPP_DEBUG_ERROR("Serial not in AT mode, cannot resume (mode: %d)", 
-                       ppp_serial_get_mode());
-        return ERRCODE_FAIL;
+    ppp_serial_mode_t current_mode = ppp_serial_get_mode();
+    PPP_DEBUG_INFO("Current serial mode: %d (expected AT mode: %d)", current_mode, PPP_SERIAL_MODE_AT);
+    
+    if (current_mode != PPP_SERIAL_MODE_AT) {
+        PPP_DEBUG_WARN("Serial not in AT mode, forcing switch...");
+        ppp_error_t switch_ret = ppp_serial_switch_to_at_mode();
+        if (switch_ret != PPP_ERR_OK) {
+            PPP_DEBUG_ERROR("Failed to switch to AT mode: %d", switch_ret);
+            return ERRCODE_FAIL;
+        }
     }
     
     ppp_error_t ret = PPP_ERR_OK;
     
-    // 1. 发送 ATO 命令恢复数据模式
-    PPP_DEBUG_INFO("Sending ATO command to resume PPP data mode...");
-    
-    const char ato_cmd[] = "ATO\r\n";
-    ret = ppp_serial_write((uint8_t*)ato_cmd, strlen(ato_cmd));
+    // ⚠️ 关键修复:临时初始化 AT handler 用于发送 ATO 和接收 CONNECT
+    // 因为 pause 简化版不初始化 AT handler,resume 需要临时初始化
+    PPP_DEBUG_INFO("Temporarily initializing AT handler for ATO command...");
+    ret = ppp_at_handler_init(SIO_UART_BUS, g_ppp_config.baudrate, true);
     if (ret != PPP_ERR_OK) {
-        PPP_DEBUG_ERROR("Failed to send ATO command: %d", ret);
+        PPP_DEBUG_ERROR("Failed to initialize AT handler: %d", ret);
         return ERRCODE_FAIL;
     }
     
-    PPP_DEBUG_INFO("ATO command sent, waiting for CONNECT response...");
-    
-    // 2. 等待 CONNECT 响应(最多等待10秒)
-    bool connect_found = false;
-    uint8_t response_buffer[128];
-    uint32_t total_wait = 0;
-    const uint32_t max_wait = 10000;  // 10秒超时
+    // 1. 发送 ATO 命令恢复PPP数据模式(通过 AT handler)
+    PPP_DEBUG_INFO("Sending ATO command to modem...");
+    char response[128] = {0};
+    uint32_t response_len = 0;
     
-    while (total_wait < max_wait) {
-        uint32_t bytes_read = 0;
-        ret = ppp_serial_read(response_buffer, sizeof(response_buffer), &bytes_read);
-        
-        if (ret == PPP_ERR_OK && bytes_read > 0) {
-            PPP_DEBUG_INFO("Received %u bytes from modem", bytes_read);
-            
-            // 检查是否包含 "CONNECT"
-            for (uint32_t i = 0; i < bytes_read - 6; i++) {
-                if (strncmp((char*)&response_buffer[i], "CONNECT", 7) == 0) {
-                    connect_found = true;
-                    PPP_DEBUG_INFO("Received CONNECT response from modem");
-                    break;
-                }
-            }
-            
-            if (connect_found) {
-                break;
-            }
-        }
-        
-        osal_msleep(500);
-        total_wait += 500;
+    ret = ppp_execute_at_command("ATO", response, sizeof(response), &response_len, 5000);
+    if (ret != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to send ATO command");
+        ppp_at_handler_deinit();
+        return ERRCODE_FAIL;
     }
     
-    if (!connect_found) {
-        PPP_DEBUG_ERROR("Timeout waiting for CONNECT response after ATO");
+    // 2. 检查响应是否包含 "CONNECT"
+    if (strstr(response, "CONNECT") == NULL) {
+        PPP_DEBUG_ERROR("ATO response does not contain CONNECT: %s", response);
+        ppp_at_handler_deinit();
         return ERRCODE_FAIL;
     }
+    PPP_DEBUG_INFO("Received CONNECT response from ATO command");
     
-    // 3. 去初始化AT处理器
-    PPP_DEBUG_INFO("Deinitializing AT handler...");
+    // 3. 去初始化 AT handler(已完成 ATO 命令)
+    PPP_DEBUG_INFO("Deinitializing AT handler after ATO...");
     ppp_at_handler_deinit();
     
-    // 4. 切换串口到PPP数据模式
-    PPP_DEBUG_INFO("Switching serial to PPP data mode...");
+    // 4. 切换串口模式为PPP数据模式
+    PPP_DEBUG_INFO("Switching serial mode to PPP data...");
     ret = ppp_serial_switch_to_ppp_mode();
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_ERROR("Failed to switch to PPP data mode: %d", ret);
         return ERRCODE_FAIL;
     }
     
-    // 5. æ\81¢å¤\8dPPPæ\95°æ\8d®æ\8e¥æ\94¶ï¼\88æ ¹æ\8d®é\85\8dç½®é\80\89æ\8b©ä¸­æ\96­æ\88\96轮询模å¼\8fï¼\89
+    // 5. æ³¨å\86\8c中æ\96­å\9b\9eè°\83/å\90¯å\8a¨æ\8e¥æ\94¶çº¿ç¨\8b
 #if PPP_USE_INTERRUPT_MODE
-    PPP_DEBUG_INFO("Re-enabling PPP interrupt mode...");
+    PPP_DEBUG_INFO("Re-enabling PPP interrupt...");
     ret = ppp_interrupt_enable();
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_ERROR("Failed to enable PPP interrupt: %d", ret);
         return ERRCODE_FAIL;
     }
-    PPP_DEBUG_INFO("PPP interrupt mode re-enabled");
 #else
     PPP_DEBUG_INFO("Restarting PPP receive thread...");
     ret = ppp_lwip_start_receive_thread();
@@ -845,13 +768,53 @@ errcode_t ppp_ppp_mode_resume(void)
         PPP_DEBUG_ERROR("Failed to restart PPP receive thread: %d", ret);
         return ERRCODE_FAIL;
     }
-    PPP_DEBUG_INFO("PPP receive thread restarted");
 #endif
     
-    PPP_DEBUG_CRITICAL("=== PPP Resumed - Back to Data Mode ===");
-    PPP_DEBUG_INFO("PPP connection restored and active");
+    // 6. 恢复PPP连接监控
+    PPP_DEBUG_INFO("Restarting PPP connection monitor...");
+    ret = ppp_lwip_start_connection_monitor();
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_WARN("Failed to restart connection monitor: %d (non-critical)", ret);
+        // 不返回错误,连接监控失败不影响核心功能
+    }
     
-    // 状态保持 PPP_STATE_CONNECTED(未改变)
+    // 7. ⚠️ 关键修复:检查 PPP 协议栈状态,必要时重新协商
+    // 因为 Pause 期间 modem 进入 AT 模式,PPP 协议层可能需要重新同步
+    PPP_DEBUG_INFO("Verifying PPP protocol stack status...");
+    
+    if (ppp_lwip_is_connected()) {
+        PPP_DEBUG_INFO("lwIP reports PPP is connected, checking protocol phase...");
+        
+        // 等待一小段时间让数据开始流动
+        osal_msleep(200);
+        
+        // 再次检查连接状态
+        if (!ppp_lwip_is_connected()) {
+            PPP_DEBUG_WARN("PPP connection lost during resume, reconnecting...");
+            ret = ppp_lwip_connect();
+            if (ret != PPP_ERR_OK) {
+                PPP_DEBUG_ERROR("Failed to reconnect PPP: %d", ret);
+                return ERRCODE_FAIL;
+            }
+            PPP_DEBUG_INFO("PPP reconnection initiated");
+        } else {
+            PPP_DEBUG_INFO("PPP connection verified, should be operational");
+        }
+    } else {
+        // PPP 未连接,需要重新协商
+        PPP_DEBUG_WARN("PPP not connected after resume, starting negotiation...");
+        ret = ppp_lwip_connect();
+        if (ret != PPP_ERR_OK) {
+            PPP_DEBUG_ERROR("Failed to start PPP negotiation: %d", ret);
+            return ERRCODE_FAIL;
+        }
+        PPP_DEBUG_INFO("PPP negotiation started, waiting for connection...");
+        
+        // 更新状态为 CONNECTING
+        g_ppp_state = PPP_STATE_CONNECTING;
+    }
+    
+    PPP_DEBUG_CRITICAL("=== PPP Resumed - Back to Data Mode ===");
     
     return ERRCODE_SUCC;
 }
@@ -1957,24 +1920,42 @@ errcode_t ppp_api_get_default_netif(char* netif_name, uint32_t buffer_size)
 
 errcode_t ppp_api_update_netinfo_in_all_mode(void)
 {
-
     errcode_t ret = ERRCODE_SUCC;
     uint8_t need_resume = 0;
+    uint8_t need_deinit_at = 0;
+    
+    // 1. 如果在 PPP 模式,先暂停
     if(ppp_serial_get_mode() == PPP_SERIAL_MODE_PPP_DATA) {
-        PPP_DEBUG_ERROR("In ppp mode pause it");
-        ppp_ppp_mode_pause();
+        PPP_DEBUG_INFO("In PPP mode, pausing...");
+        if (ppp_ppp_mode_pause() != ERRCODE_SUCC) {
+            PPP_DEBUG_ERROR("Failed to pause PPP mode");
+            return ERRCODE_FAIL;
+        }
         need_resume = 1;
-    }else{
-        PPP_DEBUG_ERROR("In AT mode");
+        
+        // 2. 暂停后需要初始化 AT handler 才能执行 AT 命令
+        PPP_DEBUG_INFO("Initializing AT handler for command execution...");
+        ppp_error_t at_ret = ppp_at_handler_init(SIO_UART_BUS, g_ppp_config.baudrate, true);
+        if (at_ret != PPP_ERR_OK) {
+            PPP_DEBUG_ERROR("Failed to initialize AT handler: %d", at_ret);
+            // 尝试恢复 PPP 模式
+            ppp_ppp_mode_resume();
+            return ERRCODE_FAIL;
+        }
+        need_deinit_at = 1;
+    } else {
+        PPP_DEBUG_INFO("Already in AT mode");
         need_resume = 0;
+        need_deinit_at = 0;
     }
-     // 更新信号强度
-    PPP_DEBUG_CRITICAL("Step 2: Starting signal strength update...");
+    
+    // 3. 执行 AT 命令更新信息
+    PPP_DEBUG_CRITICAL("Starting signal strength update...");
     if (ppp_api_update_signal() != ERRCODE_SUCC) {
         PPP_DEBUG_ERROR("Failed to update signal");
         ret = ERRCODE_FAIL;
     } else {
-        PPP_DEBUG_CRITICAL("Step 2: Signal strength update completed successfully");
+        PPP_DEBUG_CRITICAL("Signal strength update completed successfully");
     }
     
     // 更新网络状态
@@ -1988,8 +1969,43 @@ errcode_t ppp_api_update_netinfo_in_all_mode(void)
         ret = ERRCODE_FAIL;
     }
 
-    if( need_resume) {
-        ppp_ppp_mode_resume();
+    // 4. 如果需要,去初始化 AT handler 并恢复 PPP 模式
+    if (need_resume) {
+        // 先去初始化 AT handler
+        if (need_deinit_at) {
+            PPP_DEBUG_INFO("Deinitializing AT handler...");
+            ppp_at_handler_deinit();
+        }
+        
+        // 然后恢复 PPP 模式
+        PPP_DEBUG_INFO("Resuming PPP mode...");
+        errcode_t resume_ret = ppp_ppp_mode_resume();
+        if (resume_ret != ERRCODE_SUCC) {
+            PPP_DEBUG_ERROR("Failed to resume PPP mode: %d", resume_ret);
+            PPP_DEBUG_ERROR("Forcing PPP mode recovery...");
+            
+            // 强制恢复到 PPP 模式
+            ppp_serial_switch_to_ppp_mode();
+            
+            #if PPP_USE_INTERRUPT_MODE
+                ppp_error_t int_ret = ppp_interrupt_enable();
+                if (int_ret != PPP_ERR_OK) {
+                    PPP_DEBUG_ERROR("Failed to enable interrupt after forced recovery: %d", int_ret);
+                } else {
+                    PPP_DEBUG_INFO("PPP interrupt mode re-enabled after forced recovery");
+                }
+            #else
+                ppp_error_t thread_ret = ppp_lwip_start_receive_thread();
+                if (thread_ret != PPP_ERR_OK) {
+                    PPP_DEBUG_ERROR("Failed to start receive thread after forced recovery: %d", thread_ret);
+                } else {
+                    PPP_DEBUG_INFO("PPP receive thread restarted after forced recovery");
+                }
+            #endif
+            
+            PPP_DEBUG_WARN("PPP mode forcefully recovered, but connection may be unstable");
+            ret = ERRCODE_FAIL;
+        }
     }
      
     return ret;
index 066142c..36583d0 100644 (file)
@@ -614,6 +614,10 @@ ppp_error_t ppp_interrupt_disable(void)
     // 4. 删除消息队列
     osal_msg_queue_delete(g_ppp_irq_msg_queue);
     
+    // ⚠️ 关键修复:清零队列句柄,否则下次 osal_msg_queue_create 会因为队列句柄非0而失败或创建新队列
+    // osal_msg_queue_delete 不会清零队列句柄,但下次 create 需要它为 0
+    g_ppp_irq_msg_queue = 0;
+    
     // 5. 清空乒乓缓冲区
     for (uint8_t i = 0; i < PPP_PING_PONG_BUFFER_COUNT; i++) {
         g_ping_pong_buffers[i].write_pos = 0;
index b57fa1e..e0ff8b7 100644 (file)
@@ -71,8 +71,8 @@ static void ppp_lwip_netif_status_callback(struct netif *netif);
 static uint32_t ppp_lwip_get_time_ms(void);
 static void ppp_lwip_record_data_activity(void);
 static void ppp_lwip_monitor_thread(void *arg);
-static ppp_error_t ppp_lwip_start_connection_monitor(void);
-static void ppp_lwip_stop_connection_monitor(void);
+ppp_error_t ppp_lwip_start_connection_monitor(void);
+void ppp_lwip_stop_connection_monitor(void);
 
 /* 函数前向声明 */
 static void ppp_lwip_print_mru_status(void);
@@ -130,7 +130,7 @@ static void ppp_lwip_monitor_thread(void *arg)
 /**
  * @brief 启动PPP连接监控
  */
-static ppp_error_t ppp_lwip_start_connection_monitor(void)
+ppp_error_t ppp_lwip_start_connection_monitor(void)
 {
     if (g_ppp_monitor_enabled) {
         PPP_DEBUG_WARN("PPP connection monitor already running");
@@ -156,7 +156,7 @@ static ppp_error_t ppp_lwip_start_connection_monitor(void)
 /**
  * @brief 停止PPP连接监控
  */
-static void ppp_lwip_stop_connection_monitor(void)
+void ppp_lwip_stop_connection_monitor(void)
 {
     if (g_ppp_monitor_enabled) {
         PPP_DEBUG_INFO("Stopping PPP connection monitor...");