* @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) {
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();
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;
}
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");
}
// 更新网络状态
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;