PPP 可以ping通了,还需要 优化代码,日志太多,默认不能自动可以使用,需要用at逐个执行指令。
author孙春阳 <snickersun@163.com>
Mon, 15 Sep 2025 02:49:38 +0000 (10:49 +0800)
committer孙春阳 <snickersun@163.com>
Mon, 15 Sep 2025 02:49:38 +0000 (10:49 +0800)
13 files changed:
code/sdk/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/include/lwip/lwipopts_default.h
code/sdk/zhihui/4g/cat1Service/Service/cat1_runtime.c
code/sdk/zhihui/ppp/CMakeLists.txt
code/sdk/zhihui/ppp/example/ppp_at_cmd.c
code/sdk/zhihui/ppp/include/ppp_api.h
code/sdk/zhihui/ppp/include/ppp_config.h
code/sdk/zhihui/ppp/include/ppp_serial.h
code/sdk/zhihui/ppp/src/ppp_api.c
code/sdk/zhihui/ppp/src/ppp_at_handler.c
code/sdk/zhihui/ppp/src/ppp_cat1_api.c
code/sdk/zhihui/ppp/src/ppp_lwip.c
code/sdk/zhihui/ppp/src/ppp_lwip_thread.c [new file with mode: 0644]
code/sdk/zhihui/ppp/src/ppp_serial.c

index 2416d01..f48813e 100644 (file)
@@ -193,6 +193,10 @@ extern "C" {
 #define SIO_UART_BUS           UART_BUS_0
 #endif
 
+#ifndef SIO_UART_IRQ_NUM
+#define SIO_UART_IRQ_NUM       UART_0_IRQN
+#endif
+
 #ifndef SIO_UART_BAUDRATE
 #define SIO_UART_BAUDRATE      921600
 #endif
index 1ee2958..b00c0fa 100644 (file)
@@ -24,9 +24,9 @@ typedef struct
     int sim ;
     int signal ;
     char opera[64] ;
-    char imei[20] ;
-    char pyVer[20] ;
-    char iccid[20] ;
+    char imei[32] ;
+    char pyVer[32] ;
+    char iccid[32] ;
     char modemVer[64] ;
 }cat1_runtime_status_t;
 
index 9fb16f0..7984cdc 100644 (file)
@@ -17,6 +17,7 @@ set(SOURCES
     src/ppp_at_handler.c
     src/ppp_serial.c
     src/ppp_lwip.c
+    src/ppp_lwip_thread.c
     src/ppp_debug.c
     src/ppp_power_ctl.c
     src/ppp_cat1_api.c
@@ -68,6 +69,15 @@ set(PUBLIC_DEFINES
     PRINTPKT_SUPPORT=1
     PPP_DEBUG=LWIP_DBG_ON
     PPP_INPROC_IRQ_SAFE=0
+    # 添加IPCP相关配置
+    IPCP_SUPPORT=1
+    PPP_DNS=1
+    LWIP_DNS=1
+    DNS_TABLE_SIZE=2
+    # 启用IPCP调试
+    IPCP_DEBUG=LWIP_DBG_ON
+    # 确保IPCP功能完全启用
+    PPP_IPV4_SUPPORT=1
     # PPP_OPTIONS=1 
     SUPPORT_PPP_SERVICE
     SUPPORT_AT_PPP
index b6a995b..91d137f 100644 (file)
@@ -1014,6 +1014,560 @@ static errcode_t at_ppp_show_runtime(uint8_t *para, uint32_t paraLen)
     return ERRCODE_SUCC;
 }
 
+/* PPP连接状态检查指令 */
+static errcode_t at_ppp_check_connection(uint8_t *para, uint32_t paraLen)
+{
+    (void)para;
+    (void)paraLen;
+    
+    char status_info[2048];
+    errcode_t ret = ppp_api_check_connection(status_info, sizeof(status_info));
+    
+    if (ret == ERRCODE_SUCC) {
+        ppp_print_info("PPP CONNECTION CHECK:\n%s", status_info);
+    } else {
+        ppp_print_err("PPP CONNECTION CHECK: Failed to get connection status\n");
+        return ERRCODE_FAIL;
+    }
+    
+    return ERRCODE_SUCC;
+}
+
+/* 网络接口列表显示指令 */
+static errcode_t at_ppp_list_netif(uint8_t *para, uint32_t paraLen)
+{
+    (void)para;
+    (void)paraLen;
+    
+    char interfaces_info[2048];
+    errcode_t ret = ppp_api_list_network_interfaces(interfaces_info, sizeof(interfaces_info));
+    
+    if (ret == ERRCODE_SUCC) {
+        ppp_print_info("%s", interfaces_info);
+    } else {
+        ppp_print_err("Failed to get network interfaces list\n");
+        return ERRCODE_FAIL;
+    }
+    
+    return ERRCODE_SUCC;
+}
+
+/* 设置默认网络接口指令 */
+static errcode_t at_ppp_set_default_netif(uint8_t *para, uint32_t paraLen)
+{
+    if (paraLen == 0) {
+        ppp_print_err("Missing interface parameter\n");
+        ppp_print_info("Usage: AT^PPPSETDEFAULTNETIF=<interface_name>\n");
+        ppp_print_info("Example: AT^PPPSETDEFAULTNETIF=pp0\n");
+        return ERRCODE_FAIL;
+    }
+    
+    // 提取接口名称
+    char interface_name[32];
+    if (paraLen >= sizeof(interface_name)) {
+        ppp_print_err("Interface name too long (max %d chars)\n", sizeof(interface_name) - 1);
+        return ERRCODE_FAIL;
+    }
+    
+    memcpy(interface_name, para, paraLen);
+    interface_name[paraLen] = '\0';
+    
+    char result_info[2048];
+    errcode_t ret = ppp_api_set_default_netif_with_status(interface_name, result_info, sizeof(result_info));
+    
+    if (ret == ERRCODE_SUCC) {
+        ppp_print_info("%s", result_info);
+    } else {
+        ppp_print_err("%s", result_info);
+        return ERRCODE_FAIL;
+    }
+    
+    return ERRCODE_SUCC;
+}
+
+/* 获取当前默认网络接口指令 */
+static errcode_t at_ppp_get_default_netif(uint8_t *para, uint32_t paraLen)
+{
+    (void)para;
+    (void)paraLen;
+    
+    char result_info[2048];
+    errcode_t ret = ppp_api_get_default_netif_with_status(result_info, sizeof(result_info));
+    
+    if (ret == ERRCODE_SUCC) {
+        ppp_print_info("%s", result_info);
+    } else {
+        ppp_print_err("%s", result_info);
+        return ERRCODE_FAIL;
+    }
+    
+    return ERRCODE_SUCC;
+}
+
+/* PPP IPCP诊断指令 */
+static errcode_t at_ppp_diagnose_ipcp(uint8_t *para, uint32_t paraLen)
+{
+    (void)para;
+    (void)paraLen;
+    
+    ppp_print_info("Starting PPP IPCP diagnosis...\n");
+    
+    errcode_t ret = ppp_diagnose_ipcp_status();
+    if (ret == ERRCODE_SUCC) {
+        ppp_print_info("PPP IPCP diagnosis completed successfully\n");
+    } else {
+        ppp_print_err("PPP IPCP diagnosis failed\n");
+        return ERRCODE_FAIL;
+    }
+    
+    return ERRCODE_SUCC;
+}
+
+/* PPP强制激活网络接口指令 */
+static errcode_t at_ppp_force_netif_up(uint8_t *para, uint32_t paraLen)
+{
+    (void)para;
+    (void)paraLen;
+    
+    ppp_print_info("Forcing PPP network interface activation...\n");
+    
+    char result_info[2048];
+    errcode_t ret = ppp_api_force_netif_up(result_info, sizeof(result_info));
+    
+    if (ret == ERRCODE_SUCC) {
+        ppp_print_info("%s", result_info);
+    } else {
+        ppp_print_err("%s", result_info);
+        return ERRCODE_FAIL;
+    }
+    
+    return ERRCODE_SUCC;
+}
+
+/* PPP强制IPCP重新协商指令 */
+static errcode_t at_ppp_force_ipcp_renegotiation(uint8_t *para, uint32_t paraLen)
+{
+    (void)para;
+    (void)paraLen;
+    
+    ppp_print_info("Starting IPCP renegotiation...\n");
+    
+    char result_info[2048];
+    errcode_t ret = ppp_api_force_ipcp_renegotiation(result_info, sizeof(result_info));
+    
+    if (ret == ERRCODE_SUCC) {
+        ppp_print_info("%s", result_info);
+    } else {
+        ppp_print_err("%s", result_info);
+        return ERRCODE_FAIL;
+    }
+    
+    return ERRCODE_SUCC;
+}
+
+/* PPP数据包发送测试指令 */
+static errcode_t at_ppp_send_test_packet(uint8_t *para, uint32_t paraLen)
+{
+    (void)para;
+    (void)paraLen;
+    
+    ppp_print_info("=== PPP Test Packet Sending ===\n");
+    
+    // 检查PPP状态
+    ppp_state_t ppp_state = ppp_get_state();
+    if (ppp_state != PPP_STATE_CONNECTED) {
+        ppp_print_err("PPP not connected (state: %d). Please run AT^PPPSTARTDIAL first.\n", ppp_state);
+        return ERRCODE_FAIL;
+    }
+    
+    ppp_print_info("Sending multiple test packets to trigger PPP negotiation...\n");
+    
+    // 1. 发送LCP Configure-Request (Link Control Protocol)
+    ppp_print_info("\n1. Sending LCP Configure-Request...\n");
+    uint8_t lcp_config_req[] = {
+        0x7E,                   // PPP Flag
+        0xFF, 0x03,            // Address and Control (standard)
+        0xC0, 0x21,            // LCP Protocol (0xC021)
+        0x01,                  // Configure-Request
+        0x01,                  // Identifier
+        0x00, 0x04,            // Length (4 bytes payload)
+        0x7E                   // PPP Flag
+    };
+    
+    ppp_error_t ret = ppp_serial_write(lcp_config_req, sizeof(lcp_config_req));
+    if (ret == PPP_ERR_OK) {
+        ppp_print_info("LCP Configure-Request sent successfully (%d bytes)\n", sizeof(lcp_config_req));
+    } else {
+        ppp_print_err("Failed to send LCP packet: %d\n", ret);
+    }
+    
+    // 等待一下,看是否有响应
+    ppp_print_info("Waiting 2 seconds for LCP response...\n");
+    osal_msleep(2000);
+    
+    // 2. 发送IPCP Configure-Request (IP Control Protocol)
+    ppp_print_info("\n2. Sending IPCP Configure-Request...\n");
+    uint8_t ipcp_config_req[] = {
+        0x7E,                   // PPP Flag
+        0xFF, 0x03,            // Address and Control
+        0x80, 0x21,            // IPCP Protocol (0x8021)
+        0x01,                  // Configure-Request
+        0x02,                  // Identifier (different from LCP)
+        0x00, 0x0A,            // Length (10 bytes payload)
+        0x03, 0x06,            // IP Address Option (type=3, length=6)
+        0x00, 0x00, 0x00, 0x00, // IP Address (0.0.0.0 = request assignment)
+        0x7E                   // PPP Flag
+    };
+    
+    ret = ppp_serial_write(ipcp_config_req, sizeof(ipcp_config_req));
+    if (ret == PPP_ERR_OK) {
+        ppp_print_info("IPCP Configure-Request sent successfully (%d bytes)\n", sizeof(ipcp_config_req));
+    } else {
+        ppp_print_err("Failed to send IPCP packet: %d\n", ret);
+    }
+    
+    // 等待响应
+    ppp_print_info("Waiting 3 seconds for IPCP response...\n");
+    osal_msleep(3000);
+    
+    // 3. 发送一个简单的Echo-Request来测试连通性
+    ppp_print_info("\n3. Sending LCP Echo-Request...\n");
+    uint8_t echo_req[] = {
+        0x7E,                   // PPP Flag
+        0xFF, 0x03,            // Address and Control
+        0xC0, 0x21,            // LCP Protocol
+        0x09,                  // Echo-Request
+        0x03,                  // Identifier
+        0x00, 0x08,            // Length (8 bytes payload)
+        0x12, 0x34, 0x56, 0x78, // Magic Number
+        0x7E                   // PPP Flag
+    };
+    
+    ret = ppp_serial_write(echo_req, sizeof(echo_req));
+    if (ret == PPP_ERR_OK) {
+        ppp_print_info("LCP Echo-Request sent successfully (%d bytes)\n", sizeof(echo_req));
+    } else {
+        ppp_print_err("Failed to send Echo packet: %d\n", ret);
+    }
+    
+    ppp_print_info("\nTest packets sent. Check PPP RX thread logs for responses.\n");
+    ppp_print_info("Expected responses:\n");
+    ppp_print_info("- LCP Configure-Ack/Nak (C0 21 02/03)\n");
+    ppp_print_info("- IPCP Configure-Ack/Nak (80 21 02/03)\n");
+    ppp_print_info("- LCP Echo-Reply (C0 21 0A)\n");
+    
+    return ERRCODE_SUCC;
+}
+
+/* PPP数据流统计查看指令 */
+static errcode_t at_ppp_check_data_flow(uint8_t *para, uint32_t paraLen)
+{
+    (void)para;
+    (void)paraLen;
+    
+    ppp_print_info("=== PPP Data Flow Check ===\n");
+    
+    // 检查PPP状态
+    ppp_state_t ppp_state = ppp_get_state();
+    const char* state_str = "UNKNOWN";
+    switch (ppp_state) {
+        case PPP_STATE_IDLE: state_str = "IDLE"; break;
+        case PPP_STATE_INITIALIZED: state_str = "INITIALIZED"; break;
+        case PPP_STATE_CONNECTING: state_str = "CONNECTING"; break;
+        case PPP_STATE_CONNECTED: state_str = "CONNECTED"; break;
+        case PPP_STATE_DISCONNECTING: state_str = "DISCONNECTING"; break;
+        case PPP_STATE_ERROR: state_str = "ERROR"; break;
+        default: state_str = "UNKNOWN"; break;
+    }
+    
+    ppp_print_info("PPP State: %s (%d)\n", state_str, ppp_state);
+    
+    // 检查lwIP连接状态
+    bool lwip_connected = ppp_lwip_is_connected();
+    ppp_print_info("lwIP Connected: %s\n", lwip_connected ? "YES" : "NO");
+    
+    // 简单的串口统计信息提示
+    ppp_print_info("Serial Statistics: Use AT^PPPSTATUS for detailed info\n");
+    ppp_print_info("Data Flow: Check PPP RX thread logs for packet info\n");
+    
+    ppp_print_info("=== End Check ===\n");
+    
+    return ERRCODE_SUCC;
+}
+
+/* UART回调测试指令 */
+static errcode_t at_ppp_test_uart_callback(uint8_t *para, uint32_t paraLen)
+{
+    (void)para;
+    (void)paraLen;
+    
+    ppp_print_info("=== UART Callback Test ===\n");
+    
+    // 检查当前串口模式
+    ppp_print_info("Testing UART callback functionality...\n");
+    
+    // 尝试读取一些数据来触发回调
+    ppp_print_info("Please send some data to UART to test callback...\n");
+    ppp_print_info("Waiting 5 seconds for data...\n");
+    
+    // 等待5秒,看是否有数据到达
+    for (int i = 0; i < 5; i++) {
+        osal_msleep(1000);
+        ppp_print_info("Waiting... %d/5\n", i + 1);
+    }
+    
+    ppp_print_info("Test completed. Check logs for callback activity.\n");
+    ppp_print_info("If no 'Received X bytes' logs appear, UART callback is not working.\n");
+    
+    return ERRCODE_SUCC;
+}
+
+/* PPP发送测试指令 */
+static errcode_t at_ppp_test_send(uint8_t *para, uint32_t paraLen)
+{
+    (void)para;
+    (void)paraLen;
+    
+    ppp_print_info("=== PPP Send Test ===\n");
+    
+    // 检查当前PPP状态
+    ppp_state_t ppp_state = ppp_get_state();
+    if (ppp_state != PPP_STATE_CONNECTED) {
+        ppp_print_err("PPP not connected (state: %d). Please run AT^PPPSTARTDIAL first.\n", ppp_state);
+        return ERRCODE_FAIL;
+    }
+    
+    // 测试发送一个简单的PPP数据包
+    uint8_t test_packet[] = {
+        0x7E,       // PPP Flag
+        0xFF, 0x03, // Address and Control
+        0xC0, 0x21, // LCP Protocol
+        0x01,       // Configure-Request
+        0x01,       // Identifier
+        0x00, 0x04, // Length (4 bytes)
+        0x7E        // PPP Flag
+    };
+    
+    ppp_print_info("Sending test PPP packet (%d bytes)...\n", sizeof(test_packet));
+    
+    ppp_error_t ret = ppp_serial_write(test_packet, sizeof(test_packet));
+    if (ret == PPP_ERR_OK) {
+        ppp_print_info("PPP test packet sent successfully!\n");
+        ppp_print_info("Check logs for 'PPP TX Data' to verify transmission.\n");
+    } else {
+        ppp_print_err("Failed to send PPP test packet: %d\n", ret);
+    }
+    
+    return (ret == PPP_ERR_OK) ? ERRCODE_SUCC : ERRCODE_FAIL;
+}
+
+/* UART直接测试指令 */
+static errcode_t at_ppp_test_uart_direct(uint8_t *para, uint32_t paraLen)
+{
+    (void)para;
+    (void)paraLen;
+    
+    ppp_print_info("=== UART Direct Test ===\n");
+    
+    // 检查当前PPP状态
+    ppp_state_t ppp_state = ppp_get_state();
+    if (ppp_state != PPP_STATE_CONNECTED) {
+        ppp_print_err("PPP not connected (state: %d). Please run AT^PPPSTARTDIAL first.\n", ppp_state);
+        return ERRCODE_FAIL;
+    }
+    
+    ppp_print_info("Testing UART write/read in PPP data mode...\n");
+    
+    // 发送一个简单的测试字符串
+    const char *test_msg = "TEST123\r\n";
+    uint32_t test_len = strlen(test_msg);
+    
+    ppp_print_info("Sending test string: \"%s\" (%d bytes)\n", test_msg, test_len);
+    
+    ppp_error_t ret = ppp_serial_write((const uint8_t *)test_msg, test_len);
+    if (ret == PPP_ERR_OK) {
+        ppp_print_info("Test string sent successfully!\n");
+    } else {
+        ppp_print_err("Failed to send test string: %d\n", ret);
+        return ERRCODE_FAIL;
+    }
+    
+    // 等待并尝试读取响应
+    ppp_print_info("Waiting 3 seconds for any response...\n");
+    
+    for (int i = 0; i < 3; i++) {
+        osal_msleep(1000);
+        
+        uint8_t rx_buffer[256];
+        uint32_t bytes_read = 0;
+        
+        ppp_error_t read_ret = ppp_serial_read(rx_buffer, sizeof(rx_buffer), &bytes_read);
+        if (read_ret == PPP_ERR_OK && bytes_read > 0) {
+            ppp_print_info("Received %d bytes: ", bytes_read);
+            for (uint32_t j = 0; j < bytes_read && j < 32; j++) {
+                ppp_print_info("%02X ", rx_buffer[j]);
+            }
+            ppp_print_info("\n");
+            
+            // 也打印可读字符
+            ppp_print_info("As text: ");
+            for (uint32_t j = 0; j < bytes_read && j < 32; j++) {
+                if (rx_buffer[j] >= 32 && rx_buffer[j] <= 126) {
+                    ppp_print_info("%c", rx_buffer[j]);
+                } else {
+                    ppp_print_info(".");
+                }
+            }
+            ppp_print_info("\n");
+        }
+        
+        ppp_print_info("Wait %d/3...\n", i + 1);
+    }
+    
+    ppp_print_info("UART direct test completed.\n");
+    ppp_print_info("If no data received, UART may not be working in PPP mode.\n");
+    
+    return ERRCODE_SUCC;
+}
+
+/* AT模式UART测试指令 - 用于对比 */
+static errcode_t at_ppp_test_uart_at_mode(uint8_t *para, uint32_t paraLen)
+{
+    (void)para;
+    (void)paraLen;
+    
+    ppp_print_info("=== AT Mode UART Test ===\n");
+    
+    // 检查当前PPP状态
+    ppp_state_t ppp_state = ppp_get_state();
+    if (ppp_state == PPP_STATE_CONNECTED) {
+        ppp_print_err("PPP is connected (state: %d). This test is for AT mode only.\n", ppp_state);
+        ppp_print_err("Please run AT^PPPSTOPDIAL first to switch back to AT mode.\n");
+        return ERRCODE_FAIL;
+    }
+    
+    ppp_print_info("Testing UART in AT mode for comparison...\n");
+    
+    // 发送一个AT命令来测试
+    char response[256];
+    uint32_t response_len;
+    
+    ppp_print_info("Sending AT command for UART test...\n");
+    
+    errcode_t ret = ppp_test_execute_at_command("AT", response, sizeof(response), &response_len, 5000);
+    if (ret == ERRCODE_SUCC) {
+        ppp_print_info("AT mode UART test SUCCESS!\n");
+        ppp_print_info("Response (%d bytes): %s\n", response_len, response);
+        
+        // 打印十六进制
+        ppp_print_info("Response hex: ");
+        for (uint32_t i = 0; i < response_len && i < 32; i++) {
+            ppp_print_info("%02X ", (uint8_t)response[i]);
+        }
+        ppp_print_info("\n");
+    } else {
+        ppp_print_err("AT mode UART test FAILED: %d\n", ret);
+    }
+    
+    ppp_print_info("AT mode test completed.\n");
+    ppp_print_info("This proves AT mode UART works. Compare with PPP mode results.\n");
+    
+    return ERRCODE_SUCC;
+}
+
+/* PPP接收线程状态检查指令 */
+static errcode_t at_ppp_check_rx_thread(uint8_t *para, uint32_t paraLen)
+{
+    (void)para;
+    (void)paraLen;
+    
+    ppp_print_info("=== PPP RX Thread Status Check ===\n");
+    
+    // 检查当前PPP状态
+    ppp_state_t ppp_state = ppp_get_state();
+    ppp_print_info("PPP State: %d\n", ppp_state);
+    
+    if (ppp_state != PPP_STATE_CONNECTED) {
+        ppp_print_err("PPP not connected. PPP RX thread may not be running.\n");
+        return ERRCODE_FAIL;
+    }
+    
+    ppp_print_info("PPP is connected. Checking RX thread status...\n");
+    
+    // 等待一段时间,观察是否有PPP RX Thread的周期性日志
+    ppp_print_info("Waiting 5 seconds for PPP RX Thread logs...\n");
+    ppp_print_info("Expected logs: 'PPP RX Thread: X loops, Y packets, Z total bytes'\n");
+    
+    for (int i = 0; i < 5; i++) {
+        osal_msleep(1000);
+        ppp_print_info("Waiting... %d/5 seconds\n", i + 1);
+    }
+    
+    ppp_print_info("Check completed.\n");
+    ppp_print_info("If you saw 'PPP RX Thread: X loops...' logs above, the thread is running.\n");
+    ppp_print_info("If no such logs appeared, the PPP RX thread may not be running!\n");
+    
+    return ERRCODE_SUCC;
+}
+
+/* UART读取性能测试指令 */
+static errcode_t at_ppp_test_uart_performance(uint8_t *para, uint32_t paraLen)
+{
+    (void)para;
+    (void)paraLen;
+    
+    ppp_print_info("=== UART Read Performance Test ===\n");
+    
+    // 检查当前PPP状态
+    ppp_state_t ppp_state = ppp_get_state();
+    if (ppp_state != PPP_STATE_CONNECTED) {
+        ppp_print_err("PPP not connected (state: %d). Please run AT^PPPSTARTDIAL first.\n", ppp_state);
+        return ERRCODE_FAIL;
+    }
+    
+    ppp_print_info("Testing UART read performance in PPP mode...\n");
+    
+    uint8_t buffer[256];
+    uint32_t bytes_read;
+    uint32_t total_reads = 0;
+    uint32_t total_time = 0;
+    uint32_t max_time = 0;
+    uint32_t min_time = 0xFFFFFFFF;
+    
+    ppp_print_info("Performing 10 UART read tests...\n");
+    
+    for (int i = 0; i < 10; i++) {
+        uint32_t start_time = osal_get_jiffies();
+        ppp_error_t ret = ppp_serial_read(buffer, sizeof(buffer), &bytes_read);
+        uint32_t read_time = osal_jiffies_to_msecs(osal_get_jiffies() - start_time);
+        
+        total_reads++;
+        total_time += read_time;
+        
+        if (read_time > max_time) max_time = read_time;
+        if (read_time < min_time) min_time = read_time;
+        
+        ppp_print_info("Read %d: %u ms, %u bytes, ret=%d\n", i+1, read_time, bytes_read, ret);
+        
+        osal_msleep(100);  // 间隔100ms
+    }
+    
+    ppp_print_info("\n=== Performance Results ===\n");
+    ppp_print_info("Total reads: %u\n", total_reads);
+    ppp_print_info("Average time: %u ms\n", total_time / total_reads);
+    ppp_print_info("Min time: %u ms\n", min_time);
+    ppp_print_info("Max time: %u ms\n", max_time);
+    
+    if (total_time / total_reads > 50) {
+        ppp_print_warning("UART read is slow! Average %u ms > 50ms\n", total_time / total_reads);
+        ppp_print_warning("This explains why PPP RX thread is slow!\n");
+    } else {
+        ppp_print_info("UART read performance is normal.\n");
+    }
+    
+    return ERRCODE_SUCC;
+}
+
 static const at_cmd_table_t g_ppp_cmd[] = {
     { (char *)"AT^CAT1POWER",       cat1_power, (char *)"1" },
     { (char *)"AT^CAT1GETSIGNAL",   at_cat1_getsignal, (char *)"1" },
@@ -1041,6 +1595,21 @@ static const at_cmd_table_t g_ppp_cmd[] = {
     { (char *)"AT^PPPRUNTIMEUPDATE", at_ppp_update_runtime, (char *)" " },
     { (char *)"AT^PPPSINGLEUPDATE", at_ppp_update_single_runtime, (char *)"imei|signal|operator|iccid|version|network|sim" },
     { (char *)"AT^PPPRUNTIMESHOW",  at_ppp_show_runtime, (char *)" " },
+    { (char *)"AT^PPPCHECKCONNECTION", at_ppp_check_connection, (char *)" " },
+    { (char *)"AT^PPPLISTNETIF",    at_ppp_list_netif, (char *)" " },
+    { (char *)"AT^PPPSETDEFAULTNETIF", at_ppp_set_default_netif, (char *)"interface_name" },
+    { (char *)"AT^PPPGETDEFAULTNETIF", at_ppp_get_default_netif, (char *)" " },
+    { (char *)"AT^PPPDIAGNOSEIPCP", at_ppp_diagnose_ipcp, (char *)" " },
+    { (char *)"AT^PPPFORCENETIFUP", at_ppp_force_netif_up, (char *)" " },
+    { (char *)"AT^PPPFORCEIPCPRENEGOTIATION", at_ppp_force_ipcp_renegotiation, (char *)" " },
+    { (char *)"AT^PPPSENDTESTPACKET", at_ppp_send_test_packet, (char *)" " },
+    { (char *)"AT^PPPCHECKDATAFLOW", at_ppp_check_data_flow, (char *)" " },
+    { (char *)"AT^PPPTESTUARTCALLBACK", at_ppp_test_uart_callback, (char *)" " },
+    { (char *)"AT^PPPSENDTEST", at_ppp_test_send, (char *)" " },
+    { (char *)"AT^PPPTESTUARTDIRECT", at_ppp_test_uart_direct, (char *)" " },
+    { (char *)"AT^PPPTESTUARTATMODE", at_ppp_test_uart_at_mode, (char *)" " },
+    { (char *)"AT^PPPCHECKRXTHREAD", at_ppp_check_rx_thread, (char *)" " },
+    { (char *)"AT^PPPTESTUARTPERFORMANCE", at_ppp_test_uart_performance, (char *)" " },
 #ifdef SUPPORT_ZHIHUI_WEBSOCKET
     { (char *)"AT^WEBSOCKETTEST",   at_websocket_test_start, (char *)"serverip,port,test_time" },
     { (char *)"AT^STOPWEBSOCKET",   at_websocket_test_stop, (char *)" " },
index e8989e2..103bfc4 100644 (file)
@@ -35,17 +35,7 @@ errcode_t ppp_start_dial(void);
  */
 errcode_t ppp_stop_dial(void);
 
-/**
- * @brief 启动PPP数据接收线程
- * @return 错误码
- */
-ppp_error_t ppp_start_data_receive_thread(void);
-
-/**
- * @brief 停止PPP数据接收线程
- * @return 错误码
- */
-ppp_error_t ppp_stop_data_receive_thread(void);
+/* PPP数据接收线程函数已移至ppp_lwip_thread.c */
 
 /**
  * @brief 获取PPP连接状态
@@ -173,6 +163,103 @@ errcode_t ppp_api_update_sim_status(void);
  */
 errcode_t ppp_api_update_all_runtime_status(void);
 
+/**
+ * @brief 设置默认网卡
+ * @param netif_name 网卡名称
+ * @return 错误码
+ */
+errcode_t ppp_api_set_default_netif(char* netif_name);
+
+/**
+ * @brief 获取当前默认网络接口名称
+ * @param netif_name 输出缓冲区
+ * @param buffer_size 缓冲区大小
+ * @return 错误码
+ */
+errcode_t ppp_api_get_default_netif(char* netif_name, uint32_t buffer_size);
+
+/**
+ * @brief 列举所有可用的网络接口
+ * @param interfaces_info 输出缓冲区,包含所有接口信息
+ * @param buffer_size 缓冲区大小
+ * @return 错误码
+ */
+errcode_t ppp_api_list_network_interfaces(char* interfaces_info, uint32_t buffer_size);
+
+/**
+ * @brief 获取网络接口详细状态信息
+ * @param netif_name 网络接口名称
+ * @param status_info 输出缓冲区,包含状态信息
+ * @param buffer_size 缓冲区大小
+ * @return 错误码
+ */
+errcode_t ppp_api_get_netif_status(const char* netif_name, char* status_info, uint32_t buffer_size);
+
+/**
+ * @brief PPP IPCP诊断函数
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_diagnose_ipcp_status(void);
+
+/**
+ * @brief 检查PPP连接状态并返回详细信息
+ * @param status_info 输出缓冲区,包含连接状态信息
+ * @param buffer_size 缓冲区大小
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_api_check_connection(char* status_info, uint32_t buffer_size);
+
+/**
+ * @brief 强制激活PPP网络接口
+ * @param result_info 输出缓冲区,包含操作结果信息
+ * @param buffer_size 缓冲区大小
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_api_force_netif_up(char* result_info, uint32_t buffer_size);
+
+/**
+ * @brief 设置默认网络接口(带详细状态输出)
+ * @param netif_name 网络接口名称
+ * @param result_info 输出缓冲区,包含操作结果和接口状态
+ * @param buffer_size 缓冲区大小
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_api_set_default_netif_with_status(const char* netif_name, char* result_info, uint32_t buffer_size);
+
+/**
+ * @brief 获取当前默认网络接口(带详细状态输出)
+ * @param result_info 输出缓冲区,包含默认接口名称和状态
+ * @param buffer_size 缓冲区大小
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_api_get_default_netif_with_status(char* result_info, uint32_t buffer_size);
+
+/**
+ * @brief 强制重新协商IPCP以获取IP地址
+ * @param result_info 输出缓冲区,包含协商结果信息
+ * @param buffer_size 缓冲区大小
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_api_force_ipcp_renegotiation(char* result_info, uint32_t buffer_size);
+
+/**
+ * @brief 启动PPP接收线程 - 参考slipif_init方式
+ * @return PPP_ERR_OK-成功,其他-失败
+ */
+ppp_error_t ppp_lwip_start_receive_thread(void);
+
+/**
+ * @brief 停止PPP接收线程
+ * @return PPP_ERR_OK-成功,其他-失败
+ */
+ppp_error_t ppp_lwip_stop_receive_thread(void);
+
+/**
+ * @brief 检查PPP接收线程是否运行
+ * @return true-运行中,false-未运行
+ */
+bool ppp_lwip_is_receive_thread_running(void);
+
 #ifdef __cplusplus
 }
 #endif
index 0a4571f..a4fda20 100644 (file)
@@ -23,6 +23,9 @@ extern "C" {
 #ifndef SIO_UART_BUS
 #define SIO_UART_BUS                UART_BUS_0          // UART总线
 #endif
+#ifndef SIO_UART_IRQ_NUM
+#define SIO_UART_IRQ_NUM            UART_0_IRQN         // UART IRQ引脚
+#endif
 
 /* 支持的波特率列表(自适应模式) */
 #define PPP_BAUDRATE_AUTO_LIST      {2000000, 9600, 57600, 115200 }
@@ -49,7 +52,8 @@ extern "C" {
 #define PPP_TX_BUFFER_SIZE          2048                // 发送缓冲区大小
 
 /* PPP数据接收线程配置 */
-#define PPP_RX_THREAD_STACK_SIZE    4096                // PPP数据接收线程栈大小
+#define PPP_RX_THREAD_STACK_SIZE        4096                // 接收线程栈大小
+#define PPP_RX_THREAD_PRIORITY          osPriorityNormal    // 接收线程优先级
 
 /* PPP网络配置 */
 #define PPP_MTU_SIZE                1500                // PPP MTU大小
@@ -66,7 +70,8 @@ typedef enum {
     PPP_STATE_INIT,                                     // 初始化状态
     PPP_STATE_AT_HANDSHAKE,                            // AT握手状态
     PPP_STATE_SET_BAUDRATE,                            // 设置波特率状态
-    PPP_STATE_DIALING,                                 // 拨号状态
+    PPP_STATE_DIALING,  
+    PPP_STATE_CONNECTING,                               // 拨号状态
     PPP_STATE_CONNECTED,                               // 已连接状态
     PPP_STATE_DISCONNECTING,                           // 断开连接状态
     PPP_STATE_ERROR                                    // 错误状态
index 4296a19..65aff75 100644 (file)
@@ -28,6 +28,7 @@ typedef enum {
  */
 typedef struct {
     uint8_t uart_bus;                                   // UART总线号
+    uint8_t irq_num;                                    // UART IRQ引脚
     uint32_t baudrate;                                  // 波特率
     uint8_t tx_pin;                                     // 发送引脚
     uint8_t rx_pin;                                     // 接收引脚
index 59311ee..20459dc 100644 (file)
 #include "schedule/osal_task.h"
 #include "securec.h"
 #include "ppp_log.h"
-#include "ppp_types.h"       // 添加类型定义头文件
+
+// lwIP头文件,用于访问netif结构体和系统抽象层
+#ifdef LWIP_PPP_SUPPORT
+#include "lwip/netif.h"
+#include "lwip/sys.h"  /* lwIP系统抽象层,参考slipif_init方式 */
+#endif
+
 // PPP连接状态
 static ppp_state_t g_ppp_state = PPP_STATE_IDLE;
 
@@ -28,6 +34,7 @@ uint8_t g_ppp_enable_debug = PPP_LOG_LEVEL_INFO;
 // 外部声明cat1_api_enable_cat1函数(在ppp_cat1_api.c中实现)
 extern void cat1_api_enable_cat1(bool isopen);
 
+static errcode_t ppp_api_get_ppp_netif_name(char* netif_name, uint32_t buffer_size);
 /**
  * @brief 初始化PPP模块
  */
@@ -100,6 +107,7 @@ errcode_t zhihui_ppp_init(const ppp_config_t *config)
     PPP_DEBUG_PRINT("Step 3: Initializing UART for AT mode\n");
     ppp_serial_config_t serial_config = {
         .uart_bus = SIO_UART_BUS,
+        .irq_num = SIO_UART_IRQ_NUM,
         .baudrate = g_ppp_config.baudrate,
         .tx_pin = SIO_UART_TX_PIN,
         .rx_pin = SIO_UART_RX_PIN,
@@ -107,8 +115,7 @@ errcode_t zhihui_ppp_init(const ppp_config_t *config)
         .tx_buffer_size = PPP_TX_BUFFER_SIZE,
         .rx_callback = NULL,
         .rx_callback_arg = NULL
-    };
-    
+    };  
     ppp_error_t ret = ppp_serial_init(&serial_config);
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_PRINT("Failed to initialize serial for AT mode: %d\n", ret);
@@ -167,7 +174,101 @@ init_failed:
 
 static void ppp_lwip_event_callback(const ppp_lwip_event_t *event, void *arg)
 {
+    (void)arg;
+    
     PPP_DEBUG_PRINT("PPP lwIP event: %d\n", event->type);
+    
+    switch (event->type) {
+        case PPP_LWIP_EVENT_CONNECTED:
+            PPP_DEBUG_INFO("PPP connection established successfully");
+            
+            // 设置PPP状态为已连接
+            g_ppp_state = PPP_STATE_CONNECTED;
+            PPP_DEBUG_INFO("PPP state updated to CONNECTED");
+            
+            // 等待一小段时间让IPCP协商完成
+            osal_msleep(1000);
+            
+            // 多次重试检查网络信息,直到获取到有效IP
+            int retry_count = 0;
+            const int max_retries = 10;
+            bool ip_acquired = false;
+            
+            while (retry_count < max_retries && !ip_acquired) {
+                // 重新检查网络信息
+                ppp_lwip_network_info_t lwip_info;
+                ppp_error_t lwip_ret = ppp_lwip_get_network_info(&lwip_info);
+                
+                if (lwip_ret == PPP_ERR_OK && lwip_info.local_ip != 0) {
+                    PPP_DEBUG_INFO("PPP network info acquired after %d retries - Local IP: %u.%u.%u.%u", 
+                                  retry_count,
+                                  (lwip_info.local_ip >> 0) & 0xFF,
+                                  (lwip_info.local_ip >> 8) & 0xFF,
+                                  (lwip_info.local_ip >> 16) & 0xFF,
+                                  (lwip_info.local_ip >> 24) & 0xFF);
+                    ip_acquired = true;
+                } else {
+                    retry_count++;
+                    PPP_DEBUG_WARN("PPP network info not ready, retry %d/%d", retry_count, max_retries);
+                    osal_msleep(500); // 等待500ms再重试
+                }
+            }
+            
+            if (!ip_acquired) {
+                PPP_DEBUG_ERROR("Failed to acquire IP address after %d retries", max_retries);
+                PPP_DEBUG_INFO("Forcing netif up and trying manual IP check...");
+                
+                // 强制激活网络接口
+                struct netif *ppp_netif = ppp_lwip_get_netif();
+                if (ppp_netif) {
+                    netif_set_up(ppp_netif);
+                    netif_set_link_up(ppp_netif);
+                    PPP_DEBUG_INFO("Forced netif up, flags: 0x%02x", ppp_netif->flags);
+                }
+            }
+            
+            // 获取实际的PPP网络接口名称
+            char ppp_netif_name[16];
+            errcode_t ret = ppp_api_get_ppp_netif_name(ppp_netif_name, sizeof(ppp_netif_name));
+            if (ret != ERRCODE_SUCC) {
+                // 如果获取失败,使用默认名称
+                strncpy_s(ppp_netif_name, sizeof(ppp_netif_name), "pp0", sizeof(ppp_netif_name) - 1);
+                PPP_DEBUG_WARN("Failed to get PPP netif name, using default: pp0");
+            }
+            
+            // 自动设置PPP接口为默认网卡
+            ret = ppp_api_set_default_netif(ppp_netif_name);
+            if (ret == ERRCODE_SUCC) {
+                PPP_DEBUG_INFO("PPP interface (%s) automatically set as default network interface", ppp_netif_name);
+            } else {
+                PPP_DEBUG_WARN("Failed to set PPP interface (%s) as default: %d", ppp_netif_name, ret);
+            }
+            break;
+            
+        case PPP_LWIP_EVENT_DISCONNECTED:
+            PPP_DEBUG_INFO("PPP connection disconnected");
+            
+            // 设置PPP状态为已初始化(可以重新拨号)
+            g_ppp_state = PPP_STATE_INITIALIZED;
+            PPP_DEBUG_INFO("PPP state updated to INITIALIZED");
+            
+            // PPP断开时,自动切换回回环接口作为默认网卡
+            ret = ppp_api_set_default_netif("lo");
+            if (ret == ERRCODE_SUCC) {
+                PPP_DEBUG_INFO("Automatically switched back to loopback interface (lo) as default");
+            } else {
+                PPP_DEBUG_WARN("Failed to set loopback interface as default: %d", ret);
+            }
+            break;
+            
+        case PPP_LWIP_EVENT_ERROR:
+            PPP_DEBUG_ERROR("PPP connection error: %d", event->error_code);
+            break;
+            
+        default:
+            PPP_DEBUG_DEBUG("PPP lwIP event: %d", event->type);
+            break;
+    }
 }
 
 /**
@@ -206,8 +307,46 @@ errcode_t ppp_start_dial(void)
         goto error_recovery_at_mode;
     }
 
+    // 8.5. 验证调制解调器是否真正进入PPP数据模式
+    PPP_DEBUG_PRINT("Verifying modem is in PPP data mode...\n");
+    osal_msleep(1000);  // 等待1秒让调制解调器稳定
+    
+    // 尝试读取一些数据,检查是否还有AT响应
+    uint8_t verify_buffer[64];
+    uint32_t bytes_read = 0;
+    ppp_error_t verify_ret = ppp_serial_read(verify_buffer, sizeof(verify_buffer), &bytes_read);
+    
+    if (verify_ret == PPP_ERR_OK && bytes_read > 0) {
+        PPP_DEBUG_PRINT("Read %u bytes after mode switch, checking for AT responses...\n", bytes_read);
+        
+        // 检查是否包含AT响应(如"OK", "ERROR"等)
+        bool has_at_response = false;
+        for (uint32_t i = 0; i < bytes_read - 1; i++) {
+            if ((verify_buffer[i] == 'O' && verify_buffer[i+1] == 'K') ||
+                (verify_buffer[i] == 'E' && i < bytes_read - 4 && 
+                 strncmp((char*)&verify_buffer[i], "ERROR", 5) == 0)) {
+                has_at_response = true;
+                break;
+            }
+        }
+        
+        if (has_at_response) {
+            PPP_DEBUG_ERROR("Modem still sending AT responses - not in PPP data mode!\n");
+            PPP_DEBUG_PRINT("Received data: ");
+            for (uint32_t i = 0; i < bytes_read; i++) {
+                PPP_DEBUG_PRINT("%02X ", verify_buffer[i]);
+            }
+            PPP_DEBUG_PRINT("\n");
+            goto error_recovery_at_mode;
+        } else {
+            PPP_DEBUG_PRINT("Data looks like PPP frames - mode switch successful\n");
+        }
+    } else {
+        PPP_DEBUG_PRINT("No immediate data after mode switch - this is normal\n");
+    }
+
     // 9. 启动PPP数据接收处理(在lwIP连接之前启动)
-    ret = ppp_start_data_receive_thread();
+            ret = ppp_lwip_start_receive_thread();
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_PRINT("Failed to start PPP data receive thread: %d\n", ret);
         goto error_recovery_at_mode;
@@ -223,7 +362,7 @@ errcode_t ppp_start_dial(void)
     ret = ppp_lwip_init(&lwip_config);  // 使用默认配置
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_PRINT("Failed to initialize lwIP PPP: %d\n", ret);
-        ppp_stop_data_receive_thread();
+        ppp_lwip_stop_receive_thread();
         goto error_recovery_at_mode;
     }
 
@@ -232,12 +371,15 @@ errcode_t ppp_start_dial(void)
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_PRINT("Failed to start PPP connection: %d\n", ret);
         ppp_lwip_deinit();
-        ppp_stop_data_receive_thread();
+        ppp_lwip_stop_receive_thread();
         goto error_recovery_at_mode;
     }
 
-    g_ppp_state = PPP_STATE_CONNECTED;
+    // 注意:不要立即设置为CONNECTED,等待PPP协商完成
+    // g_ppp_state将在ppp_lwip_event_callback中设置为CONNECTED
+    g_ppp_state = PPP_STATE_CONNECTING;
     PPP_DEBUG_PRINT("PPP dial completed successfully - now in data mode\n");
+    PPP_DEBUG_PRINT("PPP negotiation will start automatically...\n");
 
     return ERRCODE_SUCC;
 
@@ -277,7 +419,7 @@ errcode_t ppp_stop_dial(void)
     }
 
     // 1. 停止PPP数据接收线程
-    ppp_stop_data_receive_thread();
+    ppp_lwip_stop_receive_thread();
 
     // 2. 断开lwIP PPP连接
     ppp_lwip_disconnect();
@@ -349,10 +491,40 @@ errcode_t ppp_get_connection_info(ppp_connection_info_t *info)
         return ERRCODE_INVALID_PARAM;
     }
 
-    // TODO: 实现连接信息获取
+    // 初始化结构体
     (void)memset_s(info, sizeof(ppp_connection_info_t), 0, sizeof(ppp_connection_info_t));
 
-    PPP_DEBUG_PRINT("PPP connection info retrieved\n");
+    // 检查PPP连接状态
+    if (g_ppp_state != PPP_STATE_CONNECTED) {
+        PPP_DEBUG_PRINT("PPP not connected, state: %d\n", g_ppp_state);
+        return ERRCODE_FAIL;
+    }
+
+    // 从lwIP获取网络信息
+    ppp_lwip_network_info_t lwip_info;
+    ppp_error_t ret = ppp_lwip_get_network_info(&lwip_info);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("Failed to get lwIP network info: %d", ret);
+        return ERRCODE_FAIL;
+    }
+
+    // 复制网络信息
+    info->local_ip = lwip_info.local_ip;
+    info->remote_ip = lwip_info.remote_ip;
+    info->primary_dns = lwip_info.primary_dns;
+    info->secondary_dns = lwip_info.secondary_dns;
+    info->mtu = lwip_info.mtu;
+    info->connected = lwip_info.connected;
+    
+    // 设置连接时间(这里简化处理,可以后续完善)
+    info->connect_time = 0;
+
+    PPP_DEBUG_INFO("PPP connection info retrieved successfully");
+    PPP_DEBUG_INFO("Local IP: %u.%u.%u.%u", 
+                   (info->local_ip >> 0) & 0xFF,
+                   (info->local_ip >> 8) & 0xFF,
+                   (info->local_ip >> 16) & 0xFF,
+                   (info->local_ip >> 24) & 0xFF);
 
     return ERRCODE_SUCC;
 }
@@ -370,7 +542,7 @@ errcode_t ppp_reset_from_error(void)
     PPP_DEBUG_PRINT("Resetting PPP from error state\n");
 
     // 1. 停止所有可能的活动
-    ppp_stop_data_receive_thread();
+    ppp_lwip_stop_receive_thread();
     ppp_lwip_deinit();
 
     // 2. 尝试恢复到AT模式
@@ -439,86 +611,7 @@ errcode_t zhihui_ppp_deinit(void)
     return ERRCODE_SUCC;
 } 
 
-/* PPP数据接收线程相关 */
-static osal_task *g_ppp_rx_task = NULL;
-static bool g_ppp_rx_thread_running = false;
-
-/**
- * @brief PPP数据接收线程
- */
-static void ppp_data_receive_thread(void *arg)
-{
-    (void)arg;
-    
-    PPP_DEBUG_PRINT("PPP data receive thread started\n");
-    
-    uint8_t rx_buffer[PPP_RX_BUFFER_SIZE];
-    uint32_t bytes_read;
-    
-    while (g_ppp_rx_thread_running) {
-        // 从串口读取PPP数据
-        ppp_error_t ret = ppp_serial_read(rx_buffer, sizeof(rx_buffer), &bytes_read);
-        if (ret == PPP_ERR_OK && bytes_read > 0) {
-            // 将数据传递给lwIP PPP协议栈
-            ppp_lwip_input(rx_buffer, bytes_read);
-        }
-        
-        // 短暂延时,避免占用过多CPU
-        osal_msleep(1);
-    }
-    
-    PPP_DEBUG_PRINT("PPP data receive thread stopped\n");
-}
-
-/**
- * @brief 启动PPP数据接收线程
- */
-ppp_error_t ppp_start_data_receive_thread(void)
-{
-    if (g_ppp_rx_task != NULL) {
-        PPP_DEBUG_WARN("PPP data receive thread already running");
-        return PPP_ERR_OK;
-    }
-    
-    g_ppp_rx_thread_running = true;
-    
-    // 创建PPP数据接收线程
-    g_ppp_rx_task = osal_kthread_create((osal_kthread_handler)ppp_data_receive_thread, 
-                                        NULL, "ppp_rx_thread", PPP_RX_THREAD_STACK_SIZE);
-    if (g_ppp_rx_task == NULL) {
-        PPP_DEBUG_ERROR("Failed to create PPP data receive thread");
-        g_ppp_rx_thread_running = false;
-        return PPP_ERR_MEMORY;
-    }
-    
-    PPP_DEBUG_INFO("PPP data receive thread created successfully");
-    return PPP_ERR_OK;
-}
-
-/**
- * @brief 停止PPP数据接收线程
- */
-ppp_error_t ppp_stop_data_receive_thread(void)
-{
-    if (g_ppp_rx_task == NULL) {
-        return PPP_ERR_OK;
-    }
-    
-    PPP_DEBUG_INFO("Stopping PPP data receive thread");
-    
-    // 停止线程
-    g_ppp_rx_thread_running = false;
-    
-    // 等待线程结束
-    osal_msleep(100);
-    
-    // 销毁线程
-    osal_kthread_destroy(g_ppp_rx_task, 0);
-    g_ppp_rx_task = NULL;
-    
-    PPP_DEBUG_INFO("PPP data receive thread stopped");
-    return PPP_ERR_OK;
-}
+/* PPP数据接收线程已移至ppp_lwip_thread.c */
 
 /* ========== PPP测试接口实现 ========== */
 
@@ -1209,4 +1302,732 @@ errcode_t ppp_api_update_all_runtime_status(void)
     
     PPP_DEBUG_INFO("Runtime status update completed");
     return ret;
-} 
\ No newline at end of file
+} 
+
+/**
+ * @brief 设置默认网络接口
+ * @param netif_name 网络接口名称
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_api_set_default_netif(char* netif_name)
+{
+    if (netif_name == NULL) {
+        PPP_DEBUG_ERROR("Invalid netif name parameter");
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    PPP_DEBUG_INFO("Setting default network interface to: %s", netif_name);
+    
+    // 这里可以根据实际的网络接口管理需求来实现
+    // 由于lwIP的具体实现可能因系统而异,这里提供一个通用的框架
+    
+    // 示例实现:记录当前设置的默认网卡名称
+    static char current_default_netif[32] = {0};
+    
+    if (strlen(netif_name) >= sizeof(current_default_netif)) {
+        PPP_DEBUG_ERROR("Network interface name too long: %s", netif_name);
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    // 保存网卡名称
+    strncpy_s(current_default_netif, sizeof(current_default_netif), 
+              netif_name, sizeof(current_default_netif) - 1);
+    current_default_netif[sizeof(current_default_netif) - 1] = '\0';
+    
+    PPP_DEBUG_INFO("Default network interface set to: %s", current_default_netif);
+    
+    // 实际设置默认网络接口
+    if (strcmp(netif_name, "lo") == 0) {
+        // 设置回环接口为默认(这里简化处理)
+        PPP_DEBUG_INFO("Loopback interface set as default (no action needed)");
+    } else {
+        // 检查是否是PPP接口
+        char ppp_netif_name[16];
+        errcode_t name_ret = ppp_api_get_ppp_netif_name(ppp_netif_name, sizeof(ppp_netif_name));
+        
+        if ((name_ret == ERRCODE_SUCC && strcmp(netif_name, ppp_netif_name) == 0) ||
+            strcmp(netif_name, "pp0") == 0) {
+            // 设置PPP接口为默认
+            struct netif *ppp_netif = ppp_lwip_get_netif();
+            if (ppp_netif != NULL) {
+#ifdef LWIP_PPP_SUPPORT
+                netif_set_default(ppp_netif);
+                PPP_DEBUG_INFO("PPP netif set as default in lwIP");
+#endif
+            } else {
+                PPP_DEBUG_WARN("PPP netif not available for setting as default");
+            }
+        }
+    }
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 获取当前默认网络接口名称
+ * @param netif_name 输出缓冲区
+ * @param buffer_size 缓冲区大小
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_api_get_default_netif(char* netif_name, uint32_t buffer_size)
+{
+    if (netif_name == NULL || buffer_size == 0) {
+        PPP_DEBUG_ERROR("Invalid parameters");
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    static char current_default_netif[32] = {0};
+    
+    if (strlen(current_default_netif) == 0) {
+        // 如果没有设置过,返回默认值
+        strncpy_s(netif_name, buffer_size, "none", buffer_size - 1);
+    } else {
+        strncpy_s(netif_name, buffer_size, current_default_netif, buffer_size - 1);
+    }
+    
+    netif_name[buffer_size - 1] = '\0';
+    
+    PPP_DEBUG_INFO("Current default network interface: %s", netif_name);
+    return ERRCODE_SUCC;
+}
+
+// 重复函数定义已删除 - 使用后面的新实现
+
+// 重复函数定义已删除 - 使用后面的新实现 
+
+/**
+ * @brief 获取PPP网络接口的实际名称
+ * @param netif_name 输出缓冲区
+ * @param buffer_size 缓冲区大小
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+static errcode_t ppp_api_get_ppp_netif_name(char* netif_name, uint32_t buffer_size)
+{
+    if (netif_name == NULL || buffer_size == 0) {
+        PPP_DEBUG_ERROR("Invalid parameters");
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    // 获取PPP网络接口指针
+    struct netif *ppp_netif = ppp_lwip_get_netif();
+    if (ppp_netif == NULL) {
+        PPP_DEBUG_ERROR("PPP netif not available");
+        return ERRCODE_FAIL;
+    }
+    
+    // 构建网络接口名称
+    if (ppp_netif->name[0] != 0 && ppp_netif->name[1] != 0) {
+        // 如果有实际的名称,使用实际名称+编号
+        snprintf(netif_name, buffer_size, "%c%c%u", 
+                 ppp_netif->name[0], ppp_netif->name[1], ppp_netif->num);
+    } else {
+        // 如果没有名称,使用默认的pp0
+        snprintf(netif_name, buffer_size, "pp%u", ppp_netif->num);
+    }
+    
+    PPP_DEBUG_INFO("PPP netif name: %s", netif_name);
+    return ERRCODE_SUCC;
+} 
+
+/**
+ * @brief PPP IPCP诊断函数
+ */
+errcode_t ppp_diagnose_ipcp_status(void)
+{
+    PPP_DEBUG_INFO("=== PPP IPCP Diagnosis ===");
+    
+    if (g_ppp_state != PPP_STATE_CONNECTED) {
+        PPP_DEBUG_WARN("PPP not in connected state: %d", g_ppp_state);
+        return ERRCODE_FAIL;
+    }
+    
+    // 获取lwIP网络信息
+    ppp_lwip_network_info_t lwip_info;
+    ppp_error_t ret = ppp_lwip_get_network_info(&lwip_info);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("Failed to get lwIP network info: %d", ret);
+        return ERRCODE_FAIL;
+    }
+    
+    PPP_DEBUG_INFO("IPCP Status:");
+    PPP_DEBUG_INFO("  Connected: %s", lwip_info.connected ? "YES" : "NO");
+    PPP_DEBUG_INFO("  Local IP: %u.%u.%u.%u (0x%08x)", 
+                   (lwip_info.local_ip >> 0) & 0xFF,
+                   (lwip_info.local_ip >> 8) & 0xFF,
+                   (lwip_info.local_ip >> 16) & 0xFF,
+                   (lwip_info.local_ip >> 24) & 0xFF,
+                   lwip_info.local_ip);
+    PPP_DEBUG_INFO("  Remote IP: %u.%u.%u.%u (0x%08x)", 
+                   (lwip_info.remote_ip >> 0) & 0xFF,
+                   (lwip_info.remote_ip >> 8) & 0xFF,
+                   (lwip_info.remote_ip >> 16) & 0xFF,
+                   (lwip_info.remote_ip >> 24) & 0xFF,
+                   lwip_info.remote_ip);
+    PPP_DEBUG_INFO("  Primary DNS: %u.%u.%u.%u (0x%08x)", 
+                   (lwip_info.primary_dns >> 0) & 0xFF,
+                   (lwip_info.primary_dns >> 8) & 0xFF,
+                   (lwip_info.primary_dns >> 16) & 0xFF,
+                   (lwip_info.primary_dns >> 24) & 0xFF,
+                   lwip_info.primary_dns);
+    PPP_DEBUG_INFO("  Secondary DNS: %u.%u.%u.%u (0x%08x)", 
+                   (lwip_info.secondary_dns >> 0) & 0xFF,
+                   (lwip_info.secondary_dns >> 8) & 0xFF,
+                   (lwip_info.secondary_dns >> 16) & 0xFF,
+                   (lwip_info.secondary_dns >> 24) & 0xFF,
+                   lwip_info.secondary_dns);
+    PPP_DEBUG_INFO("  MTU: %u", lwip_info.mtu);
+    
+    // 检查网络接口状态
+    struct netif *ppp_netif = ppp_lwip_get_netif();
+    if (ppp_netif) {
+        PPP_DEBUG_INFO("Netif Status:");
+        PPP_DEBUG_INFO("  Flags: 0x%02x", ppp_netif->flags);
+        PPP_DEBUG_INFO("  Name: %c%c%u", ppp_netif->name[0], ppp_netif->name[1], ppp_netif->num);
+        PPP_DEBUG_INFO("  MTU: %u", ppp_netif->mtu);
+        PPP_DEBUG_INFO("  Link Up: %s", netif_is_link_up(ppp_netif) ? "YES" : "NO");
+        PPP_DEBUG_INFO("  Interface Up: %s", netif_is_up(ppp_netif) ? "YES" : "NO");
+    } else {
+        PPP_DEBUG_ERROR("PPP netif is NULL!");
+    }
+    
+    PPP_DEBUG_INFO("=== End PPP IPCP Diagnosis ===");
+    return ERRCODE_SUCC;
+} 
+
+/**
+ * @brief 检查PPP连接状态并返回详细信息
+ * @param status_info 输出缓冲区,包含连接状态信息
+ * @param buffer_size 缓冲区大小
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_api_check_connection(char* status_info, uint32_t buffer_size)
+{
+    if (status_info == NULL || buffer_size == 0) {
+        PPP_DEBUG_ERROR("Invalid parameters");
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    PPP_DEBUG_INFO("Checking PPP connection status");
+    
+    // 调用现有的状态获取函数
+    errcode_t ret = ppp_test_get_status(status_info, buffer_size);
+    if (ret != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to get PPP status");
+        return ret;
+    }
+    
+    PPP_DEBUG_INFO("PPP connection status retrieved successfully");
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 强制激活PPP网络接口
+ * @param result_info 输出缓冲区,包含操作结果信息
+ * @param buffer_size 缓冲区大小
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_api_force_netif_up(char* result_info, uint32_t buffer_size)
+{
+    if (result_info == NULL || buffer_size == 0) {
+        PPP_DEBUG_ERROR("Invalid parameters");
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    PPP_DEBUG_INFO("Forcing PPP network interface activation");
+    
+    // 初始化输出缓冲区
+    memset(result_info, 0, buffer_size);
+    
+    // 获取PPP网络接口
+    struct netif *ppp_netif = ppp_lwip_get_netif();
+    if (!ppp_netif) {
+        snprintf(result_info, buffer_size, "ERROR: PPP netif not available\n");
+        PPP_DEBUG_ERROR("PPP netif not available");
+        return ERRCODE_FAIL;
+    }
+    
+    // 记录激活前的状态
+    uint32_t flags_before = ppp_netif->flags;
+    uint32_t ip_before = ip4_addr_get_u32(&ppp_netif->ip_addr);
+    
+    // 强制激活网络接口
+#ifdef LWIP_PPP_SUPPORT
+    netif_set_up(ppp_netif);
+    netif_set_link_up(ppp_netif);
+    netif_set_default(ppp_netif);
+#endif
+    
+    // 记录激活后的状态
+    uint32_t flags_after = ppp_netif->flags;
+    uint32_t ip_after = ip4_addr_get_u32(&ppp_netif->ip_addr);
+    
+    // 生成结果信息
+    int ret_len = snprintf(result_info, buffer_size,
+        "=== PPP Network Interface Force Activation ===\n"
+        "Interface Name: %c%c%u\n"
+        "Flags Before:   0x%02x\n"
+        "Flags After:    0x%02x\n"
+        "IP Before:      %u.%u.%u.%u\n"
+        "IP After:       %u.%u.%u.%u\n"
+        "Status:         %s\n",
+        ppp_netif->name[0], ppp_netif->name[1], ppp_netif->num,
+        flags_before, flags_after,
+        (ip_before >> 0) & 0xFF, (ip_before >> 8) & 0xFF,
+        (ip_before >> 16) & 0xFF, (ip_before >> 24) & 0xFF,
+        (ip_after >> 0) & 0xFF, (ip_after >> 8) & 0xFF,
+        (ip_after >> 16) & 0xFF, (ip_after >> 24) & 0xFF,
+        (flags_after != flags_before || ip_after != ip_before) ? "CHANGED" : "NO CHANGE");
+    
+    if (ret_len > 0 && ret_len < (int)buffer_size) {
+        // 运行IPCP诊断
+        errcode_t diag_ret = ppp_diagnose_ipcp_status();
+        if (diag_ret != ERRCODE_SUCC) {
+            int remaining = buffer_size - ret_len;
+            if (remaining > 50) {
+                snprintf(result_info + ret_len, remaining, "\nWarning: IPCP diagnosis failed\n");
+            }
+        }
+        
+        PPP_DEBUG_INFO("PPP netif force activation completed");
+        return ERRCODE_SUCC;
+    } else {
+        PPP_DEBUG_ERROR("Failed to generate result info");
+        return ERRCODE_FAIL;
+    }
+}
+
+/**
+ * @brief 设置默认网络接口(带详细状态输出)
+ * @param netif_name 网络接口名称
+ * @param result_info 输出缓冲区,包含操作结果和接口状态
+ * @param buffer_size 缓冲区大小
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_api_set_default_netif_with_status(const char* netif_name, char* result_info, uint32_t buffer_size)
+{
+    if (netif_name == NULL || result_info == NULL || buffer_size == 0) {
+        PPP_DEBUG_ERROR("Invalid parameters");
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    PPP_DEBUG_INFO("Setting default network interface: %s", netif_name);
+    
+    // 初始化输出缓冲区
+    memset(result_info, 0, buffer_size);
+    
+    // 调用基础设置函数
+    errcode_t ret = ppp_api_set_default_netif((char*)netif_name);
+    if (ret != ERRCODE_SUCC) {
+        snprintf(result_info, buffer_size, 
+                "ERROR: Failed to set default interface to '%s'\n", netif_name);
+        return ret;
+    }
+    
+    // 生成成功信息
+    int info_len = snprintf(result_info, buffer_size,
+                           "SUCCESS: Set '%s' as default interface\n\n", netif_name);
+    
+    if (info_len > 0 && info_len < (int)buffer_size) {
+        // 获取接口详细状态
+        char status_info[1024];
+        ret = ppp_api_get_netif_status(netif_name, status_info, sizeof(status_info));
+        if (ret == ERRCODE_SUCC) {
+            int remaining = buffer_size - info_len;
+            if (remaining > 0) {
+                strncat(result_info, status_info, remaining - 1);
+            }
+        }
+    }
+    
+    PPP_DEBUG_INFO("Default network interface set successfully");
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 获取当前默认网络接口(带详细状态输出)
+ * @param result_info 输出缓冲区,包含默认接口名称和状态
+ * @param buffer_size 缓冲区大小
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_api_get_default_netif_with_status(char* result_info, uint32_t buffer_size)
+{
+    if (result_info == NULL || buffer_size == 0) {
+        PPP_DEBUG_ERROR("Invalid parameters");
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    PPP_DEBUG_INFO("Getting current default network interface");
+    
+    // 初始化输出缓冲区
+    memset(result_info, 0, buffer_size);
+    
+    // 获取默认接口名称
+    char netif_name[64];
+    errcode_t ret = ppp_api_get_default_netif(netif_name, sizeof(netif_name));
+    if (ret != ERRCODE_SUCC) {
+        snprintf(result_info, buffer_size, "ERROR: Failed to get default interface\n");
+        return ret;
+    }
+    
+    // 生成基础信息
+    int info_len = snprintf(result_info, buffer_size,
+                           "Current default interface: %s\n\n", netif_name);
+    
+    if (info_len > 0 && info_len < (int)buffer_size) {
+        if (strcmp(netif_name, "none") != 0) {
+            // 获取接口详细状态
+            char status_info[1024];
+            ret = ppp_api_get_netif_status(netif_name, status_info, sizeof(status_info));
+            if (ret == ERRCODE_SUCC) {
+                int remaining = buffer_size - info_len;
+                if (remaining > 0) {
+                    strncat(result_info, status_info, remaining - 1);
+                }
+            }
+        } else {
+            int remaining = buffer_size - info_len;
+            if (remaining > 30) {
+                strncat(result_info, "No default interface is currently set\n", remaining - 1);
+            }
+        }
+    }
+    
+    PPP_DEBUG_INFO("Default network interface info retrieved successfully");
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 列举所有可用的网络接口
+ * @param interfaces_info 输出缓冲区,包含所有接口信息
+ * @param buffer_size 缓冲区大小
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_api_list_network_interfaces(char* interfaces_info, uint32_t buffer_size)
+{
+    if (interfaces_info == NULL || buffer_size == 0) {
+        PPP_DEBUG_ERROR("Invalid parameters");
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    PPP_DEBUG_INFO("Listing network interfaces");
+    
+    // 初始化输出缓冲区
+    memset(interfaces_info, 0, buffer_size);
+    
+    int ret = snprintf(interfaces_info, buffer_size,
+                      "=== Network Interface List ===\n"
+                      "[0] lo (Loopback)\n"
+                      "    IP:      127.0.0.1\n"
+                      "    Status:  UP\n"
+                      "    Type:    Loopback\n\n");
+    
+    if (ret < 0 || ret >= (int)buffer_size) {
+        PPP_DEBUG_ERROR("Buffer too small for interface list");
+        return ERRCODE_FAIL;
+    }
+    
+    // 检查PPP接口状态
+    ppp_state_t ppp_state = ppp_get_state();
+    if (ppp_state == PPP_STATE_CONNECTED) {
+        // 获取PPP连接信息
+        ppp_connection_info_t network_info;
+        errcode_t info_ret = ppp_get_connection_info(&network_info);
+        
+        // 获取实际的PPP网络接口名称
+        char ppp_netif_name[16];
+        errcode_t name_ret = ppp_api_get_ppp_netif_name(ppp_netif_name, sizeof(ppp_netif_name));
+        if (name_ret != ERRCODE_SUCC) {
+            strncpy_s(ppp_netif_name, sizeof(ppp_netif_name), "pp0", sizeof(ppp_netif_name) - 1);
+        }
+        
+        int remaining = buffer_size - ret;
+        if (remaining > 0 && info_ret == ERRCODE_SUCC) {
+            ret += snprintf(interfaces_info + ret, remaining,
+                          "[1] %s (PPP Interface)\n"
+                          "    IP:      %u.%u.%u.%u\n"
+                          "    Remote:  %u.%u.%u.%u\n"
+                          "    DNS1:    %u.%u.%u.%u\n"
+                          "    DNS2:    %u.%u.%u.%u\n"
+                          "    MTU:     %u\n"
+                          "    Status:  UP CONNECTED\n"
+                          "    Type:    PPP\n\n",
+                          ppp_netif_name,
+                          (network_info.local_ip >> 0) & 0xFF,
+                          (network_info.local_ip >> 8) & 0xFF,
+                          (network_info.local_ip >> 16) & 0xFF,
+                          (network_info.local_ip >> 24) & 0xFF,
+                          (network_info.remote_ip >> 0) & 0xFF,
+                          (network_info.remote_ip >> 8) & 0xFF,
+                          (network_info.remote_ip >> 16) & 0xFF,
+                          (network_info.remote_ip >> 24) & 0xFF,
+                          (network_info.primary_dns >> 0) & 0xFF,
+                          (network_info.primary_dns >> 8) & 0xFF,
+                          (network_info.primary_dns >> 16) & 0xFF,
+                          (network_info.primary_dns >> 24) & 0xFF,
+                          (network_info.secondary_dns >> 0) & 0xFF,
+                          (network_info.secondary_dns >> 8) & 0xFF,
+                          (network_info.secondary_dns >> 16) & 0xFF,
+                          (network_info.secondary_dns >> 24) & 0xFF,
+                          network_info.mtu);
+        }
+    } else {
+        // 获取实际的PPP网络接口名称
+        char ppp_netif_name[16];
+        errcode_t name_ret = ppp_api_get_ppp_netif_name(ppp_netif_name, sizeof(ppp_netif_name));
+        if (name_ret != ERRCODE_SUCC) {
+            strncpy_s(ppp_netif_name, sizeof(ppp_netif_name), "pp0", sizeof(ppp_netif_name) - 1);
+        }
+        
+        int remaining = buffer_size - ret;
+        if (remaining > 0) {
+            ret += snprintf(interfaces_info + ret, remaining,
+                          "[1] %s (PPP Interface)\n"
+                          "    Status:  DOWN\n"
+                          "    Type:    PPP\n\n",
+                          ppp_netif_name);
+        }
+    }
+    
+    // 添加总结信息
+    int remaining = buffer_size - ret;
+    if (remaining > 0) {
+        ret += snprintf(interfaces_info + ret, remaining,
+                      "Total interfaces: %d\n"
+                      "Use ppp_api_set_default_netif() to set default interface\n",
+                      (ppp_state == PPP_STATE_CONNECTED) ? 2 : 2);
+    }
+    
+    PPP_DEBUG_INFO("Network interfaces listed successfully");
+    return (ret > 0 && ret < (int)buffer_size) ? ERRCODE_SUCC : ERRCODE_FAIL;
+}
+
+/**
+ * @brief 获取网络接口详细状态信息
+ * @param netif_name 网络接口名称
+ * @param status_info 输出缓冲区,包含状态信息
+ * @param buffer_size 缓冲区大小
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_api_get_netif_status(const char* netif_name, char* status_info, uint32_t buffer_size)
+{
+    if (netif_name == NULL || status_info == NULL || buffer_size == 0) {
+        PPP_DEBUG_ERROR("Invalid parameters");
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    PPP_DEBUG_INFO("Getting status for network interface: %s", netif_name);
+    
+    // 初始化输出缓冲区
+    memset(status_info, 0, buffer_size);
+    
+    if (strcmp(netif_name, "lo") == 0) {
+        // 回环接口状态
+        snprintf(status_info, buffer_size,
+                "=== Interface Status: %s ===\n"
+                "Name:     lo\n"
+                "Type:     Loopback\n"
+                "IP:       127.0.0.1\n"
+                "Netmask:  255.0.0.0\n"
+                "Status:   UP\n"
+                "MTU:      65536\n", netif_name);
+    } else {
+        // 检查是否是PPP接口
+        // 获取实际的PPP网络接口名称
+        char ppp_netif_name[16];
+        errcode_t name_ret = ppp_api_get_ppp_netif_name(ppp_netif_name, sizeof(ppp_netif_name));
+        bool is_ppp_interface = false;
+        
+        if (name_ret == ERRCODE_SUCC && strcmp(netif_name, ppp_netif_name) == 0) {
+            is_ppp_interface = true;
+        } else if (strcmp(netif_name, "pp0") == 0) {
+            // 兼容性:如果用户查询pp0,也认为是PPP接口
+            is_ppp_interface = true;
+            strncpy_s(ppp_netif_name, sizeof(ppp_netif_name), "pp0", sizeof(ppp_netif_name) - 1);
+        }
+        
+        if (is_ppp_interface) {
+            // PPP接口状态
+            ppp_state_t ppp_state = ppp_get_state();
+            
+            if (ppp_state == PPP_STATE_CONNECTED) {
+                ppp_connection_info_t network_info;
+                errcode_t ret = ppp_get_connection_info(&network_info);
+                
+                if (ret == ERRCODE_SUCC) {
+                    snprintf(status_info, buffer_size,
+                            "=== Interface Status: %s ===\n"
+                            "Name:     %s\n"
+                            "Type:     PPP\n"
+                            "IP:       %u.%u.%u.%u\n"
+                            "Remote:   %u.%u.%u.%u\n"
+                            "DNS1:     %u.%u.%u.%u\n"
+                            "DNS2:     %u.%u.%u.%u\n"
+                            "MTU:      %u\n"
+                            "Status:   UP CONNECTED\n", 
+                            netif_name, ppp_netif_name,
+                            (network_info.local_ip >> 0) & 0xFF,
+                            (network_info.local_ip >> 8) & 0xFF,
+                            (network_info.local_ip >> 16) & 0xFF,
+                            (network_info.local_ip >> 24) & 0xFF,
+                            (network_info.remote_ip >> 0) & 0xFF,
+                            (network_info.remote_ip >> 8) & 0xFF,
+                            (network_info.remote_ip >> 16) & 0xFF,
+                            (network_info.remote_ip >> 24) & 0xFF,
+                            (network_info.primary_dns >> 0) & 0xFF,
+                            (network_info.primary_dns >> 8) & 0xFF,
+                            (network_info.primary_dns >> 16) & 0xFF,
+                            (network_info.primary_dns >> 24) & 0xFF,
+                            (network_info.secondary_dns >> 0) & 0xFF,
+                            (network_info.secondary_dns >> 8) & 0xFF,
+                            (network_info.secondary_dns >> 16) & 0xFF,
+                            (network_info.secondary_dns >> 24) & 0xFF,
+                            network_info.mtu);
+                } else {
+                    snprintf(status_info, buffer_size,
+                            "=== Interface Status: %s ===\n"
+                            "Name:     %s\n"
+                            "Type:     PPP\n"
+                            "Status:   UP (No network info available)\n", 
+                            netif_name, ppp_netif_name);
+                }
+            } else {
+                snprintf(status_info, buffer_size,
+                        "=== Interface Status: %s ===\n"
+                        "Name:     %s\n"
+                        "Type:     PPP\n"
+                        "Status:   DOWN\n", 
+                        netif_name, ppp_netif_name);
+            }
+        } else {
+            // 未知接口
+            snprintf(status_info, buffer_size,
+                    "=== Interface Status: %s ===\n"
+                    "Error:    Interface not found\n"
+                    "Available interfaces: lo, %s\n", 
+                    netif_name, 
+                    (name_ret == ERRCODE_SUCC) ? ppp_netif_name : "pp0");
+        }
+    }
+    
+    PPP_DEBUG_INFO("Interface status retrieved successfully");
+    return ERRCODE_SUCC;
+} 
+
+/**
+ * @brief 强制重新协商IPCP以获取IP地址
+ * @param result_info 输出缓冲区,包含协商结果信息
+ * @param buffer_size 缓冲区大小
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_api_force_ipcp_renegotiation(char* result_info, uint32_t buffer_size)
+{
+    if (result_info == NULL || buffer_size == 0) {
+        PPP_DEBUG_ERROR("Invalid parameters");
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    PPP_DEBUG_INFO("Forcing IPCP renegotiation...");
+    
+    // 初始化输出缓冲区
+    memset(result_info, 0, buffer_size);
+    
+    // 获取PPP网络接口
+    struct netif *ppp_netif = ppp_lwip_get_netif();
+    if (!ppp_netif) {
+        snprintf(result_info, buffer_size, "ERROR: PPP netif not available\n");
+        PPP_DEBUG_ERROR("PPP netif not available");
+        return ERRCODE_FAIL;
+    }
+    
+    // 检查PPP连接状态
+    ppp_state_t ppp_state = ppp_get_state();
+    if (ppp_state != PPP_STATE_CONNECTED) {
+        snprintf(result_info, buffer_size, "ERROR: PPP not connected (state: %d)\n", ppp_state);
+        PPP_DEBUG_ERROR("PPP not connected");
+        return ERRCODE_FAIL;
+    }
+    
+    int info_len = snprintf(result_info, buffer_size,
+        "=== IPCP Renegotiation ===\n"
+        "PPP State: CONNECTED\n"
+        "IP Before: %u.%u.%u.%u\n",
+        (ppp_netif->ip_addr.addr >> 0) & 0xFF,
+        (ppp_netif->ip_addr.addr >> 8) & 0xFF,
+        (ppp_netif->ip_addr.addr >> 16) & 0xFF,
+        (ppp_netif->ip_addr.addr >> 24) & 0xFF);
+    
+    if (info_len < 0 || info_len >= (int)buffer_size) {
+        PPP_DEBUG_ERROR("Buffer too small for result info");
+        return ERRCODE_FAIL;
+    }
+    
+    // 强制重新激活网络接口
+    PPP_DEBUG_INFO("Forcing netif activation...");
+    netif_set_up(ppp_netif);
+    netif_set_link_up(ppp_netif);
+    
+    // 等待IPCP协商完成
+    bool ip_acquired = false;
+    for (int retry = 0; retry < 20; retry++) {
+        // 等待250ms
+        osal_msleep(250);
+        
+        // 检查IP地址是否已分配
+        if (ppp_netif->ip_addr.addr != 0) {
+            ip_acquired = true;
+            PPP_DEBUG_INFO("IP address acquired after %d retries", retry + 1);
+            break;
+        }
+        
+        PPP_DEBUG_INFO("IPCP renegotiation retry %d/20", retry + 1);
+        
+        // 每5次重试强制重新激活
+        if ((retry + 1) % 5 == 0) {
+            PPP_DEBUG_INFO("Forcing netif reactivation (retry %d)", retry + 1);
+            netif_set_up(ppp_netif);
+            netif_set_link_up(ppp_netif);
+        }
+    }
+    
+    // 生成结果信息
+    int remaining = buffer_size - info_len;
+    if (remaining > 0) {
+        if (ip_acquired) {
+            info_len += snprintf(result_info + info_len, remaining,
+                "IP After:  %u.%u.%u.%u\n"
+                "Gateway:   %u.%u.%u.%u\n"
+                "Netmask:   %u.%u.%u.%u\n"
+                "Flags:     0x%02x\n"
+                "Status:    SUCCESS - IP address acquired\n",
+                (ppp_netif->ip_addr.addr >> 0) & 0xFF,
+                (ppp_netif->ip_addr.addr >> 8) & 0xFF,
+                (ppp_netif->ip_addr.addr >> 16) & 0xFF,
+                (ppp_netif->ip_addr.addr >> 24) & 0xFF,
+                (ppp_netif->gw.addr >> 0) & 0xFF,
+                (ppp_netif->gw.addr >> 8) & 0xFF,
+                (ppp_netif->gw.addr >> 16) & 0xFF,
+                (ppp_netif->gw.addr >> 24) & 0xFF,
+                (ppp_netif->netmask.addr >> 0) & 0xFF,
+                (ppp_netif->netmask.addr >> 8) & 0xFF,
+                (ppp_netif->netmask.addr >> 16) & 0xFF,
+                (ppp_netif->netmask.addr >> 24) & 0xFF,
+                ppp_netif->flags);
+            
+            // 设置为默认网络接口
+            netif_set_default(ppp_netif);
+            
+            remaining = buffer_size - info_len;
+            if (remaining > 50) {
+                snprintf(result_info + info_len, remaining, "\nSet as default network interface\n");
+            }
+        } else {
+            snprintf(result_info + info_len, remaining,
+                "IP After:  0.0.0.0 (FAILED)\n"
+                "Status:    FAILED - IPCP negotiation timeout\n"
+                "Suggestion: Check network provider settings\n");
+        }
+    }
+    
+    PPP_DEBUG_INFO("IPCP renegotiation %s", ip_acquired ? "succeeded" : "failed");
+    return ip_acquired ? ERRCODE_SUCC : ERRCODE_FAIL;
+}
\ No newline at end of file
index a3acb22..854101c 100644 (file)
@@ -421,20 +421,48 @@ ppp_error_t ppp_at_complete_dial_sequence(const char *apn)
     }
     PPP_DEBUG_INFO("AT handshake successful");
     
+    // 2.5. 禁用回显以防止PPP数据被回显 - 强制执行
+    ret = ppp_at_send_command("ATE0", "OK", 5000, &response);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("Failed to disable echo - this is critical for PPP");
+        return ret;  // 改为致命错误,必须成功
+    } else {
+        PPP_DEBUG_INFO("Echo disabled successfully");
+    }
+    
+    // 移除ATQ0和ATV1命令,因为它们在某些调制解调器上不被支持
+    // 且对PPP连接不是必需的
+    
     // 3. 设置固定波特率 (AT+IPR=2000000,掉电保持)
     // 获取当前波特率并设置为固定波特率
     uint32_t current_baudrate = ppp_at_get_current_baudrate();
     if (current_baudrate > 0) {
         PPP_DEBUG_INFO("Setting fixed baudrate to %u (power-off persistent)", current_baudrate);
-        ret = ppp_at_send_command("AT+IPR=2000000", "OK", 5000, &response);
+        
+        char ipr_cmd[32];
+        snprintf_s(ipr_cmd, sizeof(ipr_cmd), sizeof(ipr_cmd) - 1, "AT+IPR=%u", current_baudrate);
+        
+        ret = ppp_at_send_command(ipr_cmd, "OK", 5000, &response);
         if (ret != PPP_ERR_OK) {
-            PPP_DEBUG_WARN("Failed to set fixed baudrate AT+IPR=2000000, continuing with current rate");
-            // 不作为致命错误,继续执行
+            PPP_DEBUG_WARN("Failed to set fixed baudrate %s, continuing with current rate", ipr_cmd);
+            // 不返回错误,继续执行
         } else {
-            PPP_DEBUG_INFO("Fixed baudrate 2000000 set successfully (power-off persistent)");
-            // 注意:这里不立即更改串口波特率,因为模块需要时间应用设置
-            // 下次开机时模块将自动使用2M波特率
+            PPP_DEBUG_INFO("Fixed baudrate set successfully");
         }
+    } else {
+        PPP_DEBUG_WARN("Could not determine current baudrate, skipping AT+IPR");
+    }
+    
+    // 3.5. 确保调制解调器完全退出AT命令模式
+    PPP_DEBUG_INFO("Ensuring modem is ready for PPP data mode...");
+    
+    // 发送一个简单的AT命令确认调制解调器状态
+    ret = ppp_at_send_command("AT", "OK", 3000, &response);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("Modem not responding to AT - may already be in data mode");
+        // 这可能是正常的,如果调制解调器已经在数据模式
+    } else {
+        PPP_DEBUG_INFO("Modem still in AT mode, proceeding with dial sequence");
     }
     
     // 4. 设置PDP上下文 (对应chat文件: OK 'AT+CGDCONT=3,"IP"')
@@ -454,14 +482,86 @@ ppp_error_t ppp_at_complete_dial_sequence(const char *apn)
     }
     PPP_DEBUG_INFO("PDP context set successfully");
     
+    // 4.5. 设置网络注册模式(确保网络连接稳定)
+    ret = ppp_at_send_command("AT+CREG=1", "OK", 5000, &response);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_WARN("Failed to set network registration mode, continuing anyway");
+    } else {
+        PPP_DEBUG_INFO("Network registration mode set successfully");
+    }
+    
+    // 4.6. 设置GPRS附着模式
+    ret = ppp_at_send_command("AT+CGATT=1", "OK", 10000, &response);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_WARN("Failed to attach to GPRS, continuing anyway");
+    } else {
+        PPP_DEBUG_INFO("GPRS attach successful");
+    }
+    
+    // 4.7. 检查网络状态
+    ret = ppp_at_send_command("AT+CREG?", "OK", 5000, &response);
+    if (ret == PPP_ERR_OK) {
+        PPP_DEBUG_INFO("Network registration status: %s", response.response);
+    }
+    
     // 5. 发送PPP拨号指令 (对应chat文件: OK 'ATD*99***2#' -> CONNECTED)
     ret = ppp_at_send_command("ATD*99***2#", "CONNECT", 30000, &response);
     if (ret != PPP_ERR_OK) {
-        PPP_DEBUG_ERROR("PPP dial failed");
+        PPP_DEBUG_ERROR("PPP dial command failed");
         return ret;
     }
-    
     PPP_DEBUG_INFO("PPP dial sequence completed successfully - entering data mode");
+    
+    // 6.5. 关键修复:确保调制解调器完全进入数据模式
+    PPP_DEBUG_INFO("Ensuring modem is fully in PPP data mode...");
+    
+    // 等待调制解调器稳定
+    osal_msleep(1000);
+    
+    // 发送一个空的AT命令来测试是否还在AT模式
+    // 如果还在AT模式,会有响应;如果在PPP模式,不会有响应
+    uint8_t test_cmd[] = "AT\r\n";
+    uint32_t bytes_written = 0;
+    ppp_error_t test_ret = ppp_serial_write(test_cmd, sizeof(test_cmd)-1, &bytes_written);
+    
+    if (test_ret == PPP_ERR_OK) {
+        // 等待可能的AT响应
+        osal_msleep(500);
+        
+        uint8_t response_buffer[64];
+        uint32_t bytes_read = 0;
+        ppp_error_t read_ret = ppp_serial_read(response_buffer, sizeof(response_buffer), &bytes_read);
+        
+        if (read_ret == PPP_ERR_OK && bytes_read > 0) {
+            PPP_DEBUG_WARN("Modem still responding to AT commands after CONNECT!");
+            PPP_DEBUG_WARN("Received %u bytes: %.*s", bytes_read, bytes_read, response_buffer);
+            
+            // 尝试强制进入数据模式
+            PPP_DEBUG_INFO("Forcing modem into data mode...");
+            
+            // 发送ATE0再次确保回显关闭
+            uint8_t ate0_cmd[] = "ATE0\r\n";
+            ppp_serial_write(ate0_cmd, sizeof(ate0_cmd)-1, &bytes_written);
+            osal_msleep(500);
+            
+            // 清理任何响应
+            ppp_serial_read(response_buffer, sizeof(response_buffer), &bytes_read);
+            
+            // 再次拨号
+            PPP_DEBUG_INFO("Re-dialing to ensure proper PPP mode...");
+            ret = ppp_at_send_command("ATD*99***2#", "CONNECT", 30000, &response);
+            if (ret != PPP_ERR_OK) {
+                PPP_DEBUG_ERROR("Re-dial failed");
+                return ret;
+            }
+            
+            osal_msleep(2000);  // 更长的等待时间
+        } else {
+            PPP_DEBUG_INFO("Modem correctly in PPP data mode - no AT response");
+        }
+    }
+
+    PPP_DEBUG_INFO("Modem data mode verification completed");
     return PPP_ERR_OK;
 }
 
index 5f529f3..29a21d1 100644 (file)
@@ -79,9 +79,9 @@ typedef struct {
     int sim;
     int signal;
     char opera[64];
-    char imei[20];
-    char pyVer[20];
-    char iccid[20];
+    char imei[32];
+    char pyVer[32];
+    char iccid[32];
     char modemVer[64];
 } ppp_cat1_runtime_status_t;
 
index 521d9e4..97aca6a 100644 (file)
@@ -60,6 +60,13 @@ ppp_error_t ppp_lwip_init(const ppp_lwip_config_t *config)
 
     PPP_DEBUG_INFO("Initializing PPP lwIP integration");
 
+    /* 重置连接状态 */
+    g_lwip_ctx.connected = false;
+    g_lwip_ctx.local_ip = 0;
+    g_lwip_ctx.remote_ip = 0;
+    g_lwip_ctx.primary_dns = 0;
+    g_lwip_ctx.secondary_dns = 0;
+
     /* 分配网络接口 */
     g_lwip_ctx.netif = (struct netif *)osal_kmalloc(sizeof(struct netif));
     if (!g_lwip_ctx.netif) {
@@ -85,11 +92,45 @@ ppp_error_t ppp_lwip_init(const ppp_lwip_config_t *config)
     if (config->username && config->password) {
         ppp_set_auth(g_lwip_ctx.ppp_pcb, PPPAUTHTYPE_PAP, config->username, config->password);
         PPP_DEBUG_INFO("PPP authentication configured (PAP)");
+    } else {
+        /* 如果没有用户名密码,设置为无认证 */
+        ppp_set_auth(g_lwip_ctx.ppp_pcb, PPPAUTHTYPE_NONE, "", "");
+        PPP_DEBUG_INFO("PPP authentication disabled (NONE)");
     }
 
+    /* 配置IPCP选项 - 启用IP地址协商 */
+    PPP_DEBUG_INFO("Configuring IPCP options...");
+    
+    /* 请求对端分配IP地址 (0.0.0.0表示请求分配) */
+    ppp_set_ipcp_ouraddr(g_lwip_ctx.ppp_pcb, IP4_ADDR_ANY);
+    
+    /* 接受对端提供的任何IP地址 */
+    ppp_set_ipcp_hisaddr(g_lwip_ctx.ppp_pcb, IP4_ADDR_ANY);
+    
+    /* 启用DNS协商 */
+    ppp_set_usepeerdns(g_lwip_ctx.ppp_pcb, 1);
+    
+    /* 使用标准IPCP协商选项 */
+    PPP_DEBUG_INFO("Setting standard IPCP negotiation options...");
+    
+    /* 启用基本的IP地址协商 */
+    g_lwip_ctx.ppp_pcb->ipcp_wantoptions.neg_addr = 1;
+    g_lwip_ctx.ppp_pcb->ipcp_allowoptions.neg_addr = 1;
+    
+#if LWIP_DNS
+    /* 请求DNS服务器地址 */
+    g_lwip_ctx.ppp_pcb->ipcp_wantoptions.req_dns1 = 1;
+    g_lwip_ctx.ppp_pcb->ipcp_wantoptions.req_dns2 = 1;
+#endif
+    
+    PPP_DEBUG_INFO("IPCP configuration completed with standard options");
+
     /* 设置状态回调 */
     ppp_set_notify_phase_callback(g_lwip_ctx.ppp_pcb, ppp_lwip_status_callback);
 
+    /* 使用标准PPP/LCP配置 */
+    PPP_DEBUG_INFO("Using standard PPP/LCP configuration...");
+
     /* 保存回调函数 */
     g_lwip_ctx.event_callback = config->event_callback;
     g_lwip_ctx.event_callback_arg = config->event_callback_arg;
@@ -144,39 +185,36 @@ ppp_error_t ppp_lwip_connect(void)
     return PPP_ERR_INVALID_PARAM;
 #else
     if (!g_lwip_ctx.initialized) {
+        PPP_DEBUG_ERROR("PPP lwIP not initialized");
         return PPP_ERR_INVALID_PARAM;
     }
 
+    /* 注释掉"already connected"检查,允许重新连接 */
     if (g_lwip_ctx.connected) {
-        PPP_DEBUG_WARN("PPP already connected");
-        return PPP_ERR_OK;
+        PPP_DEBUG_WARN("PPP was previously connected, will restart negotiation");
+        g_lwip_ctx.connected = false;  /* 重置连接状态 */
     }
 
-    PPP_DEBUG_INFO("Connecting PPP using custom serial interface");
-
-    /* 创建PPPoS连接,使用自定义输出回调 */
-    g_lwip_ctx.ppp_pcb = pppos_create(&g_lwip_ctx.netif,
-                                      ppp_lwip_output_callback,  // 自定义输出回调
-                                      ppp_lwip_status_callback,
-                                      &g_lwip_ctx);
-    if (g_lwip_ctx.ppp_pcb == NULL) {
-        PPP_DEBUG_ERROR("Failed to create PPPoS connection");
-        return PPP_ERR_MEMORY;
+    if (!g_lwip_ctx.ppp_pcb) {
+        PPP_DEBUG_ERROR("PPP control block not available");
+        return PPP_ERR_INVALID_PARAM;
     }
 
-    /* 设置认证信息 */
-    ppp_set_auth(g_lwip_ctx.ppp_pcb, PPPAUTHTYPE_NONE, "", "");
+    PPP_DEBUG_PRINT("=== Starting PPP Protocol Negotiation ===\n");
+    PPP_DEBUG_PRINT("Initiating PPP connection with lwIP...\n");
+    PPP_DEBUG_PRINT("This will trigger LCP and IPCP negotiation\n");
 
     /* 启动PPP连接 */
     err_t err = ppp_connect(g_lwip_ctx.ppp_pcb, 0);
     if (err != ERR_OK) {
         PPP_DEBUG_ERROR("Failed to start PPP connection: %d", err);
-        ppp_free(g_lwip_ctx.ppp_pcb);
-        g_lwip_ctx.ppp_pcb = NULL;
+        PPP_DEBUG_PRINT("=== PPP Connection FAILED ===\n");
         return PPP_ERR_DIAL_FAILED;
     }
 
-    PPP_DEBUG_INFO("PPP connection initiated with custom serial interface");
+    PPP_DEBUG_PRINT("PPP connection initiated successfully\n");
+    PPP_DEBUG_PRINT("Watch for PPP Protocol Output/Input logs below...\n");
+    PPP_DEBUG_PRINT("=== PPP Negotiation Started ===\n");
     return PPP_ERR_OK;
 #endif
 }
@@ -212,7 +250,8 @@ ppp_error_t ppp_lwip_disconnect(void)
     return PPP_ERR_OK;
 #endif
 }
-
+static const char* ppp_get_lcp_code_name(uint8_t code);
+static const char* ppp_get_protocol_name(uint16_t protocol);
 /**
  * @brief 输入PPP数据
  */
@@ -225,12 +264,89 @@ ppp_error_t ppp_lwip_input(const uint8_t *data, uint32_t length)
         return PPP_ERR_INVALID_PARAM;
     }
 
-    PPP_DEBUG_DEBUG("PPP input %u bytes", length);
-    PPP_DEBUG_HEXDUMP(data, length);
+    PPP_DEBUG_PRINT("=== PPP Protocol Input ===\n");
+    PPP_DEBUG_PRINT("PPP RX: %u bytes\n", length);
+    
+    /* 解析PPP协议包 */
+    if (length >= 4) {
+        /* 跳过PPP Flag (0x7E) 如果存在 */
+        uint32_t offset = 0;
+        if (data[0] == 0x7E) {
+            offset = 1;
+        }
+        
+        /* 检查Address/Control字段 */
+        if (offset + 3 < length && data[offset] == 0xFF && data[offset + 1] == 0x03) {
+            offset += 2;  /* 跳过Address/Control */
+            
+            /* 解析协议字段 */
+            if (offset + 1 < length) {
+                uint16_t protocol = (data[offset] << 8) | data[offset + 1];
+                offset += 2;
+                
+                PPP_DEBUG_PRINT("Protocol: 0x%04X (%s)\n", protocol, ppp_get_protocol_name(protocol));
+                
+                /* 解析LCP/IPCP包 */
+                if ((protocol == 0xC021 || protocol == 0x8021) && offset + 3 < length) {
+                    uint8_t code = data[offset];
+                    uint8_t id = data[offset + 1];
+                    uint16_t pkt_length = (data[offset + 2] << 8) | data[offset + 3];
+                    
+                    PPP_DEBUG_PRINT("  Code: %u (%s)\n", code, ppp_get_lcp_code_name(code));
+                    PPP_DEBUG_PRINT("  ID: %u\n", id);
+                    PPP_DEBUG_PRINT("  Length: %u\n", pkt_length);
+                    
+                    /* 解析Configure-Request/Ack/Nak的选项 */
+                    if ((code >= 1 && code <= 4) && offset + 4 < length) {  /* Configure packets */
+                        uint32_t opt_offset = offset + 4;
+                        PPP_DEBUG_PRINT("  Options:\n");
+                        
+                        while (opt_offset + 1 < length && opt_offset < offset + pkt_length) {
+                            uint8_t opt_type = data[opt_offset];
+                            uint8_t opt_len = data[opt_offset + 1];
+                            
+                            if (opt_len < 2 || opt_offset + opt_len > length) break;
+                            
+                            PPP_DEBUG_PRINT("    Type: %u, Length: %u", opt_type, opt_len);
+                            
+                            /* 解析常见选项 */
+                            if (protocol == 0x8021 && opt_type == 3 && opt_len == 6) {  /* IPCP IP Address */
+                                PPP_DEBUG_PRINT(" (IP Address: %u.%u.%u.%u)", 
+                                               data[opt_offset + 2], data[opt_offset + 3],
+                                               data[opt_offset + 4], data[opt_offset + 5]);
+                            } else if (protocol == 0x8021 && opt_type == 129 && opt_len == 6) {  /* Primary DNS */
+                                PPP_DEBUG_PRINT(" (Primary DNS: %u.%u.%u.%u)", 
+                                               data[opt_offset + 2], data[opt_offset + 3],
+                                               data[opt_offset + 4], data[opt_offset + 5]);
+                            } else if (protocol == 0x8021 && opt_type == 131 && opt_len == 6) {  /* Secondary DNS */
+                                PPP_DEBUG_PRINT(" (Secondary DNS: %u.%u.%u.%u)", 
+                                               data[opt_offset + 2], data[opt_offset + 3],
+                                               data[opt_offset + 4], data[opt_offset + 5]);
+                            }
+                            
+                            PPP_DEBUG_PRINT("\n");
+                            opt_offset += opt_len;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    /* 打印原始数据 */
+    PPP_DEBUG_PRINT("Raw Data: ");
+    for (uint32_t i = 0; i < length && i < 32; i++) {
+        PPP_DEBUG_PRINT("%02X ", data[i]);
+    }
+    if (length > 32) {
+        PPP_DEBUG_PRINT("... (total %u bytes)", length);
+    }
+    PPP_DEBUG_PRINT("\n");
 
     /* 将数据传递给PPPoS */
     pppos_input(g_lwip_ctx.ppp_pcb, (u8_t *)data, length);
 
+    PPP_DEBUG_PRINT("=== PPP Input Processed ===\n");
     return PPP_ERR_OK;
 #endif
 }
@@ -291,6 +407,26 @@ static void ppp_lwip_status_callback(ppp_pcb *pcb, int err_code, void *ctx)
     (void)ctx;
 
     PPP_DEBUG_INFO("PPP status callback: err_code=%d", err_code);
+    
+    /* 打印PPP阶段信息 */
+    const char* phase_str = "UNKNOWN";
+    switch (err_code) {
+        case PPPERR_NONE: phase_str = "CONNECTED"; break;
+        case PPPERR_PARAM: phase_str = "PARAM_ERROR"; break;
+        case PPPERR_OPEN: phase_str = "OPEN_ERROR"; break;
+        case PPPERR_DEVICE: phase_str = "DEVICE_ERROR"; break;
+        case PPPERR_ALLOC: phase_str = "ALLOC_ERROR"; break;
+        case PPPERR_USER: phase_str = "USER_ERROR"; break;
+        case PPPERR_CONNECT: phase_str = "CONNECT_ERROR"; break;
+        case PPPERR_AUTHFAIL: phase_str = "AUTH_FAIL"; break;
+        case PPPERR_PROTOCOL: phase_str = "PROTOCOL_ERROR"; break;
+        case PPPERR_PEERDEAD: phase_str = "PEER_DEAD"; break;
+        case PPPERR_IDLETIMEOUT: phase_str = "IDLE_TIMEOUT"; break;
+        case PPPERR_CONNECTTIME: phase_str = "CONNECT_TIMEOUT"; break;
+        case PPPERR_LOOPBACK: phase_str = "LOOPBACK"; break;
+        default: phase_str = "OTHER"; break;
+    }
+    PPP_DEBUG_INFO("PPP Phase: %s (%d)", phase_str, err_code);
 
     ppp_lwip_event_t event;
     memset_s(&event, sizeof(event), 0, sizeof(event));
@@ -303,6 +439,12 @@ static void ppp_lwip_status_callback(ppp_pcb *pcb, int err_code, void *ctx)
             
             /* 获取IP地址信息 */
             if (g_lwip_ctx.netif) {
+                PPP_DEBUG_INFO("PPP netif available, checking IP addresses...");
+                PPP_DEBUG_INFO("netif->ip_addr: 0x%08x", ip4_addr_get_u32(&g_lwip_ctx.netif->ip_addr));
+                PPP_DEBUG_INFO("netif->gw: 0x%08x", ip4_addr_get_u32(&g_lwip_ctx.netif->gw));
+                PPP_DEBUG_INFO("netif->netmask: 0x%08x", ip4_addr_get_u32(&g_lwip_ctx.netif->netmask));
+                PPP_DEBUG_INFO("netif flags: 0x%02x", g_lwip_ctx.netif->flags);
+                
                 g_lwip_ctx.local_ip = ip4_addr_get_u32(&g_lwip_ctx.netif->ip_addr);
                 g_lwip_ctx.remote_ip = ip4_addr_get_u32(&g_lwip_ctx.netif->gw);
                 
@@ -311,9 +453,11 @@ static void ppp_lwip_status_callback(ppp_pcb *pcb, int err_code, void *ctx)
                 const ip_addr_t *dns2 = dns_getserver(1);
                 if (dns1) {
                     g_lwip_ctx.primary_dns = ip4_addr_get_u32(ip_2_ip4(dns1));
+                    PPP_DEBUG_INFO("DNS1: 0x%08x", g_lwip_ctx.primary_dns);
                 }
                 if (dns2) {
                     g_lwip_ctx.secondary_dns = ip4_addr_get_u32(ip_2_ip4(dns2));
+                    PPP_DEBUG_INFO("DNS2: 0x%08x", g_lwip_ctx.secondary_dns);
                 }
                 
                 PPP_DEBUG_INFO("PPP connected - Local IP: %u.%u.%u.%u", 
@@ -321,6 +465,64 @@ static void ppp_lwip_status_callback(ppp_pcb *pcb, int err_code, void *ctx)
                               (g_lwip_ctx.local_ip >> 8) & 0xFF,
                               (g_lwip_ctx.local_ip >> 16) & 0xFF,
                               (g_lwip_ctx.local_ip >> 24) & 0xFF);
+                PPP_DEBUG_INFO("PPP connected - Remote IP: %u.%u.%u.%u", 
+                              (g_lwip_ctx.remote_ip >> 0) & 0xFF,
+                              (g_lwip_ctx.remote_ip >> 8) & 0xFF,
+                              (g_lwip_ctx.remote_ip >> 16) & 0xFF,
+                              (g_lwip_ctx.remote_ip >> 24) & 0xFF);
+                
+                /* 设置PPP接口为默认网络接口 */
+                if (g_lwip_ctx.netif->ip_addr.addr != 0) {
+                    PPP_DEBUG_INFO("Setting PPP interface as default...");
+                    netif_set_default(g_lwip_ctx.netif);
+                    PPP_DEBUG_INFO("PPP interface set as default network interface");
+                } else {
+                    PPP_DEBUG_WARN("PPP IP address is 0, IPCP negotiation may not be complete yet");
+                    PPP_DEBUG_INFO("Attempting to force IPCP completion...");
+                    
+                    /* 强制激活网络接口 */
+                    netif_set_up(g_lwip_ctx.netif);
+                    netif_set_link_up(g_lwip_ctx.netif);
+                    
+                    /* 等待IPCP协商完成的重试机制 */
+                    for (int retry = 0; retry < 10; retry++) {
+                        /* 等待500ms */
+                        osal_msleep(500);
+                        
+                        /* 检查IP地址是否已分配 */
+                        if (g_lwip_ctx.netif->ip_addr.addr != 0) {
+                            PPP_DEBUG_INFO("IPCP negotiation completed after %d retries", retry + 1);
+                            PPP_DEBUG_INFO("Final IP: %u.%u.%u.%u", 
+                                          (g_lwip_ctx.netif->ip_addr.addr >> 0) & 0xFF,
+                                          (g_lwip_ctx.netif->ip_addr.addr >> 8) & 0xFF,
+                                          (g_lwip_ctx.netif->ip_addr.addr >> 16) & 0xFF,
+                                          (g_lwip_ctx.netif->ip_addr.addr >> 24) & 0xFF);
+                            
+                            /* 更新本地IP地址 */
+                            g_lwip_ctx.local_ip = ip4_addr_get_u32(&g_lwip_ctx.netif->ip_addr);
+                            
+                            /* 设置为默认网络接口 */
+                            netif_set_default(g_lwip_ctx.netif);
+                            PPP_DEBUG_INFO("PPP interface set as default network interface");
+                            break;
+                        }
+                        
+                        PPP_DEBUG_INFO("IPCP retry %d/10 - IP still 0.0.0.0", retry + 1);
+                        
+                        /* 强制重新激活 */
+                        if (retry == 5) {
+                            PPP_DEBUG_INFO("Mid-retry: forcing netif up again");
+                            netif_set_up(g_lwip_ctx.netif);
+                            netif_set_link_up(g_lwip_ctx.netif);
+                        }
+                    }
+                    
+                    if (g_lwip_ctx.netif->ip_addr.addr == 0) {
+                        PPP_DEBUG_ERROR("IPCP negotiation failed after 10 retries - IP still 0.0.0.0");
+                    }
+                }
+            } else {
+                PPP_DEBUG_ERROR("PPP netif is NULL!");
             }
             break;
 
@@ -367,7 +569,20 @@ static void ppp_lwip_link_status_callback(ppp_pcb *pcb, int err_code, void *ctx)
     PPP_DEBUG_INFO("PPP link status callback: err_code=%d", err_code);
 
     if (err_code == PPPERR_NONE) {
-        PPP_DEBUG_INFO("PPP link up");
+        PPP_DEBUG_INFO("PPP link up - checking IPCP status...");
+        
+        // 检查网络接口状态
+        if (g_lwip_ctx.netif) {
+            PPP_DEBUG_INFO("Link up - netif flags: 0x%02x", g_lwip_ctx.netif->flags);
+            PPP_DEBUG_INFO("Link up - IP: 0x%08x", ip4_addr_get_u32(&g_lwip_ctx.netif->ip_addr));
+            
+            // 如果IP地址还是0,强制激活接口
+            if (g_lwip_ctx.netif->ip_addr.addr == 0) {
+                PPP_DEBUG_WARN("IP still 0 after link up, forcing netif activation");
+                netif_set_up(g_lwip_ctx.netif);
+                netif_set_link_up(g_lwip_ctx.netif);
+            }
+        }
     } else {
         PPP_DEBUG_WARN("PPP link down: %d", err_code);
         g_lwip_ctx.connected = false;
@@ -383,6 +598,39 @@ static void ppp_lwip_link_status_callback(ppp_pcb *pcb, int err_code, void *ctx)
     }
 }
 
+/* PPP协议解析辅助函数 */
+static const char* ppp_get_protocol_name(uint16_t protocol)
+{
+    switch (protocol) {
+        case 0xC021: return "LCP";
+        case 0x8021: return "IPCP";
+        case 0xC023: return "PAP";
+        case 0xC223: return "CHAP";
+        case 0x0021: return "IP";
+        case 0x002D: return "VJ_COMP_TCP";
+        case 0x002F: return "VJ_UNCOMP_TCP";
+        default: return "UNKNOWN";
+    }
+}
+
+static const char* ppp_get_lcp_code_name(uint8_t code)
+{
+    switch (code) {
+        case 1: return "Configure-Request";
+        case 2: return "Configure-Ack";
+        case 3: return "Configure-Nak";
+        case 4: return "Configure-Reject";
+        case 5: return "Terminate-Request";
+        case 6: return "Terminate-Ack";
+        case 7: return "Code-Reject";
+        case 8: return "Protocol-Reject";
+        case 9: return "Echo-Request";
+        case 10: return "Echo-Reply";
+        case 11: return "Discard-Request";
+        default: return "Unknown";
+    }
+}
+
 /**
  * @brief PPP输出回调函数 - 使用自定义串口接口,不依赖SIO
  */
@@ -391,16 +639,94 @@ static u32_t ppp_lwip_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void
     (void)pcb;
     (void)ctx;
 
-    PPP_DEBUG_DEBUG("PPP output %u bytes", len);
-    PPP_DEBUG_HEXDUMP(data, len);
+    PPP_DEBUG_PRINT("=== PPP Protocol Output ===\n");
+    PPP_DEBUG_PRINT("PPP TX: %u bytes\n", len);
+    
+    /* 解析PPP协议包 */
+    if (len >= 4) {
+        /* 跳过PPP Flag (0x7E) 如果存在 */
+        uint32_t offset = 0;
+        if (data[0] == 0x7E) {
+            offset = 1;
+        }
+        
+        /* 检查Address/Control字段 */
+        if (offset + 3 < len && data[offset] == 0xFF && data[offset + 1] == 0x03) {
+            offset += 2;  /* 跳过Address/Control */
+            
+            /* 解析协议字段 */
+            if (offset + 1 < len) {
+                uint16_t protocol = (data[offset] << 8) | data[offset + 1];
+                offset += 2;
+                
+                PPP_DEBUG_PRINT("Protocol: 0x%04X (%s)\n", protocol, ppp_get_protocol_name(protocol));
+                
+                /* 解析LCP/IPCP包 */
+                if ((protocol == 0xC021 || protocol == 0x8021) && offset + 3 < len) {
+                    uint8_t code = data[offset];
+                    uint8_t id = data[offset + 1];
+                    uint16_t length = (data[offset + 2] << 8) | data[offset + 3];
+                    
+                    PPP_DEBUG_PRINT("  Code: %u (%s)\n", code, ppp_get_lcp_code_name(code));
+                    PPP_DEBUG_PRINT("  ID: %u\n", id);
+                    PPP_DEBUG_PRINT("  Length: %u\n", length);
+                    
+                    /* 解析Configure-Request的选项 */
+                    if (code == 1 && offset + 4 < len) {  /* Configure-Request */
+                        uint32_t opt_offset = offset + 4;
+                        PPP_DEBUG_PRINT("  Options:\n");
+                        
+                        while (opt_offset + 1 < len && opt_offset < offset + length) {
+                            uint8_t opt_type = data[opt_offset];
+                            uint8_t opt_len = data[opt_offset + 1];
+                            
+                            if (opt_len < 2 || opt_offset + opt_len > len) break;
+                            
+                            PPP_DEBUG_PRINT("    Type: %u, Length: %u", opt_type, opt_len);
+                            
+                            /* 解析常见选项 */
+                            if (protocol == 0x8021 && opt_type == 3 && opt_len == 6) {  /* IPCP IP Address */
+                                PPP_DEBUG_PRINT(" (IP Address: %u.%u.%u.%u)", 
+                                               data[opt_offset + 2], data[opt_offset + 3],
+                                               data[opt_offset + 4], data[opt_offset + 5]);
+                            } else if (protocol == 0x8021 && opt_type == 129 && opt_len == 6) {  /* Primary DNS */
+                                PPP_DEBUG_PRINT(" (Primary DNS: %u.%u.%u.%u)", 
+                                               data[opt_offset + 2], data[opt_offset + 3],
+                                               data[opt_offset + 4], data[opt_offset + 5]);
+                            } else if (protocol == 0x8021 && opt_type == 131 && opt_len == 6) {  /* Secondary DNS */
+                                PPP_DEBUG_PRINT(" (Secondary DNS: %u.%u.%u.%u)", 
+                                               data[opt_offset + 2], data[opt_offset + 3],
+                                               data[opt_offset + 4], data[opt_offset + 5]);
+                            }
+                            
+                            PPP_DEBUG_PRINT("\n");
+                            opt_offset += opt_len;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    /* 打印原始数据 */
+    PPP_DEBUG_PRINT("Raw Data: ");
+    for (uint32_t i = 0; i < len && i < 32; i++) {
+        PPP_DEBUG_PRINT("%02X ", data[i]);
+    }
+    if (len > 32) {
+        PPP_DEBUG_PRINT("... (total %u bytes)", len);
+    }
+    PPP_DEBUG_PRINT("\n");
 
     /* 直接使用我们自己的串口写函数,不依赖SIO */
     ppp_error_t ret = ppp_serial_write(data, len);
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_ERROR("Failed to send PPP data via custom serial: %d", ret);
+        PPP_DEBUG_PRINT("=== PPP Output FAILED ===\n");
         return 0;
     }
 
+    PPP_DEBUG_PRINT("=== PPP Output SUCCESS ===\n");
     return len;
 }
 #endif /* LWIP_PPP_SUPPORT */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/src/ppp_lwip_thread.c b/code/sdk/zhihui/ppp/src/ppp_lwip_thread.c
new file mode 100644 (file)
index 0000000..116151e
--- /dev/null
@@ -0,0 +1,202 @@
+/**
+ * @file ppp_lwip_thread.c
+ * @brief PPP接收线程实现 - 参考lwIP slipif_init方式
+ */
+
+#include "ppp_api.h"
+#include "ppp_config.h"
+#include "ppp_debug.h"
+#include "ppp_serial.h"
+#include "ppp_lwip.h"
+#include "soc_osal.h"
+#include "schedule/osal_task.h"
+#include <stdlib.h>
+#include <string.h>
+
+/* PPP接收线程相关 - 参考slipif_init方式 */
+static osal_task *g_ppp_rx_thread = NULL;
+static volatile bool g_ppp_rx_thread_running = false;
+
+/**
+ * @brief PPP数据接收线程 - 参考slipif_init实现
+ * 
+ * 这个实现参考了lwIP中slipif_init的线程创建方式:
+ * 1. 使用标准的线程函数签名
+ * 2. 实现流数据处理和PPP帧重组
+ * 3. 直接调用lwIP的输入函数
+ */
+static void ppp_lwip_receive_thread(void *arg)
+{
+    (void)arg;
+    
+    PPP_DEBUG_INFO("PPP lwIP receive thread started (slipif-style)");
+    
+    /* 动态分配接收缓冲区以避免栈溢出 */
+    uint8_t *rx_buffer = (uint8_t *)malloc(PPP_RX_BUFFER_SIZE);
+    if (!rx_buffer) {
+        PPP_DEBUG_ERROR("Failed to allocate RX buffer for PPP thread");
+        return;
+    }
+    
+    /* 动态分配PPP流处理缓冲区 */
+    uint8_t *stream_buffer = (uint8_t *)malloc(PPP_RX_BUFFER_SIZE * 2);
+    if (!stream_buffer) {
+        PPP_DEBUG_ERROR("Failed to allocate stream buffer for PPP thread");
+        free(rx_buffer);
+        return;
+    }
+    
+    uint32_t bytes_read;
+    uint32_t total_packets = 0;
+    uint32_t total_bytes = 0;
+    
+    /* PPP流处理状态 */
+    uint32_t stream_pos = 0;          /* 流缓冲区当前位置 */
+    bool in_frame = false;            /* 是否正在接收PPP帧 */
+    uint32_t frame_start = 0;         /* 当前帧开始位置 */
+    uint32_t complete_frames = 0;     /* 完整帧计数 */
+    
+    PPP_DEBUG_INFO("PPP lwIP thread: allocated %d bytes RX buffer + %d bytes stream buffer", 
+                   PPP_RX_BUFFER_SIZE, PPP_RX_BUFFER_SIZE * 2);
+    
+    /* 主接收循环 - 参考slipif的实现方式 */
+    while (g_ppp_rx_thread_running) {
+        // 从串口读取PPP数据
+        ppp_error_t ret = ppp_serial_read(rx_buffer, PPP_RX_BUFFER_SIZE, &bytes_read);
+        
+        if (ret == PPP_ERR_OK && bytes_read > 0) {
+            total_packets++;
+            total_bytes += bytes_read;
+            
+            PPP_DEBUG_DEBUG("PPP lwIP RX: Fragment #%u, %u bytes", total_packets, bytes_read);
+            
+            // 将新数据添加到流缓冲区
+            if (stream_pos + bytes_read < PPP_RX_BUFFER_SIZE * 2) {
+                memcpy(stream_buffer + stream_pos, rx_buffer, bytes_read);
+                stream_pos += bytes_read;
+                
+                // 处理流缓冲区中的数据,查找完整的PPP帧
+                uint32_t processed = 0;
+                while (processed < stream_pos) {
+                    uint8_t byte = stream_buffer[processed];
+                    
+                    if (byte == 0x7E) {  /* PPP帧标志 */
+                        if (in_frame && processed > frame_start) {
+                            /* 找到完整帧的结束 */
+                            uint32_t frame_len = processed - frame_start + 1;
+                            complete_frames++;
+                            
+                            PPP_DEBUG_DEBUG("PPP lwIP Complete Frame #%u: %u bytes", 
+                                          complete_frames, frame_len);
+                            
+                            // 将完整帧传递给lwIP PPP协议栈
+                            ppp_error_t input_ret = ppp_lwip_input(stream_buffer + frame_start, frame_len);
+                            if (input_ret != PPP_ERR_OK) {
+                                PPP_DEBUG_ERROR("Failed to input PPP frame to lwIP: %d", input_ret);
+                            }
+                        }
+                        
+                        /* 开始新帧 */
+                        frame_start = processed;
+                        in_frame = true;
+                    }
+                    
+                    processed++;
+                }
+                
+                // 如果有未完成的帧,将其移到缓冲区开头
+                if (in_frame && frame_start > 0) {
+                    uint32_t remaining = stream_pos - frame_start;
+                    memmove(stream_buffer, stream_buffer + frame_start, remaining);
+                    stream_pos = remaining;
+                    frame_start = 0;
+                } else if (!in_frame) {
+                    // 没有正在处理的帧,清空缓冲区
+                    stream_pos = 0;
+                    frame_start = 0;
+                }
+            } else {
+                PPP_DEBUG_WARN("Stream buffer overflow, resetting");
+                stream_pos = 0;
+                frame_start = 0;
+                in_frame = false;
+            }
+        } else if (ret != PPP_ERR_OK) {
+            PPP_DEBUG_ERROR("PPP serial read error: %d", ret);
+        }
+        
+        // 统计信息输出 - 每2000次循环输出一次
+        if ((total_packets % 2000) == 0 && total_packets > 0) {
+            PPP_DEBUG_INFO("PPP lwIP RX: %u fragments, %u complete frames, %u total bytes", 
+                          total_packets, complete_frames, total_bytes);
+        }
+        
+        // 短暂休眠以避免CPU占用过高 - 参考slipif的做法
+        osal_msleep(10);
+    }
+    
+    /* 清理资源 */
+    free(rx_buffer);
+    free(stream_buffer);
+    
+    PPP_DEBUG_INFO("PPP lwIP receive thread terminated (processed %u frames)", complete_frames);
+}
+
+/**
+ * @brief 启动PPP接收线程 - 参考slipif_init方式
+ */
+ppp_error_t ppp_lwip_start_receive_thread(void)
+{
+    if (g_ppp_rx_thread != NULL) {
+        PPP_DEBUG_WARN("PPP lwIP receive thread already running");
+        return PPP_ERR_OK;
+    }
+    
+    g_ppp_rx_thread_running = true;
+    
+    // 创建PPP数据接收线程 - 参考slipif_init方式
+    // slipif使用sys_thread_new,我们使用等效的osal_kthread_create
+    g_ppp_rx_thread = osal_kthread_create((osal_kthread_handler)ppp_lwip_receive_thread, 
+                                          NULL, "ppp_lwip_rx", PPP_RX_THREAD_STACK_SIZE);
+    if (g_ppp_rx_thread == NULL) {
+        PPP_DEBUG_ERROR("Failed to create PPP lwIP receive thread");
+        g_ppp_rx_thread_running = false;
+        return PPP_ERR_MEMORY;
+    }
+    
+    PPP_DEBUG_INFO("PPP lwIP receive thread created successfully (slipif-style)");
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 停止PPP接收线程
+ */
+ppp_error_t ppp_lwip_stop_receive_thread(void)
+{
+    if (g_ppp_rx_thread == NULL) {
+        return PPP_ERR_OK;
+    }
+    
+    PPP_DEBUG_INFO("Stopping PPP lwIP receive thread");
+    
+    // 停止线程
+    g_ppp_rx_thread_running = false;
+    
+    // 等待线程结束
+    osal_msleep(100);
+    
+    // 销毁线程
+    osal_kthread_destroy(g_ppp_rx_thread, 0);
+    g_ppp_rx_thread = NULL;
+    
+    PPP_DEBUG_INFO("PPP lwIP receive thread stopped");
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 检查PPP接收线程是否运行
+ */
+bool ppp_lwip_is_receive_thread_running(void)
+{
+    return g_ppp_rx_thread_running && (g_ppp_rx_thread != NULL);
+} 
\ No newline at end of file
index b871f2b..73b7d69 100644 (file)
 #include "soc_osal.h"
 #include "securec.h"
 #include <string.h>
+#include "arch_port.h"
 
 /* 串口上下文结构 - 优化缓存机制 */
 typedef struct {
     bool initialized;
     ppp_serial_mode_t current_mode;
     uint8_t uart_bus;
+    uint8_t irq_num;
     
     /* UART配置参数 */
     uart_pin_config_t pin_config;
@@ -69,6 +71,10 @@ static ppp_error_t ppp_serial_flush_tx_buffer_internal(void);
 static bool ppp_serial_is_ppp_control_packet(const uint8_t *data, uint32_t length);
 static bool ppp_serial_should_immediate_flush(const uint8_t *data, uint32_t length, uint32_t buffered_count);
 static uint32_t ppp_serial_get_current_time_ms(void);
+static ppp_error_t ppp_serial_register_irq(void);
+static ppp_error_t ppp_serial_unregister_irq(void);
+
+/* IRQ相关代码已移除 - 使用简化的直接UART读取方式 */
 
 /**
  * @brief 初始化PPP串口 - 统一缓冲区管理
@@ -85,6 +91,7 @@ ppp_error_t ppp_serial_init(const ppp_serial_config_t *config)
     /* 打印配置参数 */
     PPP_DEBUG_INFO("Configuration parameters:");
     PPP_DEBUG_INFO("  - UART Bus: %u", config->uart_bus);
+    PPP_DEBUG_INFO("  - IRQ Num: %u", config->irq_num);
     PPP_DEBUG_INFO("  - Baudrate: %u", config->baudrate);
     PPP_DEBUG_INFO("  - TX Pin: %u", config->tx_pin);
     PPP_DEBUG_INFO("  - RX Pin: %u", config->rx_pin);
@@ -94,6 +101,7 @@ ppp_error_t ppp_serial_init(const ppp_serial_config_t *config)
 
     /* 配置UART参数 */
     g_serial_ctx.uart_bus = config->uart_bus;
+    g_serial_ctx.irq_num = config->irq_num;
     g_serial_ctx.pin_config.tx_pin = config->tx_pin;
     g_serial_ctx.pin_config.rx_pin = config->rx_pin;
     g_serial_ctx.uart_attr.baud_rate = config->baudrate;
@@ -275,22 +283,9 @@ ppp_error_t ppp_serial_switch_to_ppp_mode(void)
     osal_mutex_unlock(&g_serial_ctx.tx_mutex);
     PPP_DEBUG_INFO("TX buffer cleared for mode switch");
 
-    /* 注册UART接收回调,启用软件缓冲区管理 */
-    PPP_DEBUG_INFO("Registering UART RX callback...");
-    PPP_DEBUG_INFO("  - Bus: %u", g_serial_ctx.uart_bus);
-    PPP_DEBUG_INFO("  - Condition: UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE");
-    PPP_DEBUG_INFO("  - Buffer size: %u", g_serial_ctx.rx_buffer_size);
-    PPP_DEBUG_INFO("  - Callback function: %p", ppp_serial_rx_callback);
-    
-    errcode_t ret = uapi_uart_register_rx_callback(g_serial_ctx.uart_bus, 
-                                                   UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE,
-                                                   g_serial_ctx.rx_buffer_size,
-                                                   ppp_serial_rx_callback);
-    if (ret != ERRCODE_SUCC) {
-        PPP_DEBUG_ERROR("Failed to register UART RX callback: error code = %d (0x%x)", ret, ret);
-        return PPP_ERR_UART;
-    }
-    PPP_DEBUG_INFO("UART RX callback registered successfully");
+    /* PPP数据模式:使用优化的直接UART读取,增加超时时间获取完整数据 */
+    PPP_DEBUG_INFO("PPP Data Mode: Using optimized direct UART read with longer timeout");
+    PPP_DEBUG_INFO("This approach is more reliable than callback mechanism");
     
     g_serial_ctx.current_mode = PPP_SERIAL_MODE_PPP_DATA;
     PPP_DEBUG_INFO("Mode switched to PPP_DATA (%d)", g_serial_ctx.current_mode);
@@ -317,11 +312,6 @@ ppp_error_t ppp_serial_switch_to_at_mode(void)
     PPP_DEBUG_INFO("Current mode: %d (PPP_DATA) -> %d (AT)", g_serial_ctx.current_mode, PPP_SERIAL_MODE_AT);
     PPP_DEBUG_INFO("UART Bus: %u", g_serial_ctx.uart_bus);
 
-    /* 取消注册UART接收回调,回到直接UART读取模式 */
-    PPP_DEBUG_INFO("Unregistering UART RX callback...");
-    uapi_uart_unregister_rx_callback(g_serial_ctx.uart_bus);
-    PPP_DEBUG_INFO("UART RX callback unregistered");
-
     /* 清空接收缓冲区 */
     PPP_DEBUG_INFO("Clearing RX buffer...");
     osal_mutex_lock(&g_serial_ctx.rx_mutex);
@@ -342,6 +332,12 @@ ppp_error_t ppp_serial_switch_to_at_mode(void)
     osal_mutex_unlock(&g_serial_ctx.tx_mutex);
     PPP_DEBUG_INFO("TX buffer cleared (discarded %u bytes)", old_tx_count);
 
+    /* 从PPP数据模式切换回AT模式 */
+    if (g_serial_ctx.current_mode == PPP_SERIAL_MODE_PPP_DATA) {
+        PPP_DEBUG_INFO("Switching from PPP data mode to AT mode");
+        PPP_DEBUG_INFO("No callback cleanup needed (using direct UART read)");
+    }
+
     g_serial_ctx.current_mode = PPP_SERIAL_MODE_AT;
     PPP_DEBUG_INFO("Mode switched to AT (%d)", g_serial_ctx.current_mode);
     PPP_DEBUG_INFO("=== AT Mode Switch Complete ===");
@@ -364,7 +360,7 @@ ppp_error_t ppp_serial_write(const uint8_t *data, uint32_t length)
     PPP_DEBUG_INFO("UART Bus: %u", g_serial_ctx.uart_bus);
 
     ppp_error_t result = PPP_ERR_OK;
-
+    int32_t write_result = 0;
     switch (g_serial_ctx.current_mode) {
         case PPP_SERIAL_MODE_AT:
             /* AT命令模式:直接使用UART发送 */
@@ -374,7 +370,7 @@ ppp_error_t ppp_serial_write(const uint8_t *data, uint32_t length)
             PPP_DEBUG_INFO("Calling uapi_uart_write(bus=%u, data=%p, len=%u, timeout=1000)...", 
                           g_serial_ctx.uart_bus, data, length);
             
-            int32_t write_result = uapi_uart_write(g_serial_ctx.uart_bus, data, length, 1000);
+            write_result = uapi_uart_write(g_serial_ctx.uart_bus, data, length, 1000);
             PPP_DEBUG_INFO("uapi_uart_write returned: %d (expected: %u)", write_result, length);
             
             if (write_result != (int32_t)length) {
@@ -390,60 +386,34 @@ ppp_error_t ppp_serial_write(const uint8_t *data, uint32_t length)
             break;
 
         case PPP_SERIAL_MODE_PPP_DATA:
-            /* PPP数据模式:使用缓冲发送 */
-            PPP_DEBUG_INFO("Buffering %u bytes for PPP data mode", length);
-            // PPP_DEBUG_HEXDUMP(data, length);
+            /* PPP数据模式:直接使用UART发送(与AT模式一致) */
+            PPP_DEBUG_INFO("Sending %u bytes via UART (PPP data mode)", length);
             
-            osal_mutex_lock(&g_serial_ctx.tx_mutex);
-            
-            /* 检查缓冲区空间 */
-            uint32_t available_space = ppp_serial_tx_buffer_available_space();
-            if (available_space < length) {
-                PPP_DEBUG_WARN("TX buffer insufficient space: need %u, available %u", length, available_space);
-                
-                /* 先尝试发送现有缓冲区数据 */
-                osal_mutex_unlock(&g_serial_ctx.tx_mutex);
-                ppp_error_t flush_result = ppp_serial_flush_tx();
-                if (flush_result != PPP_ERR_OK) {
-                    PPP_DEBUG_ERROR("Failed to flush TX buffer before new write");
-                    result = flush_result;
-                    break;
-                }
-                osal_mutex_lock(&g_serial_ctx.tx_mutex);
-                
-                /* 重新检查空间 */
-                available_space = ppp_serial_tx_buffer_available_space();
-                if (available_space < length) {
-                    PPP_DEBUG_ERROR("TX buffer still insufficient after flush: need %u, available %u", 
-                                   length, available_space);
-                    osal_mutex_unlock(&g_serial_ctx.tx_mutex);
-                    g_serial_ctx.tx_errors++;
-                    result = PPP_ERR_UART;
-                    break;
-                }
+            // 打印PPP数据包内容用于调试
+            PPP_DEBUG_PRINT("PPP TX Data: ");
+            for (uint32_t i = 0; i < length && i < 16; i++) {
+                PPP_DEBUG_PRINT("%02X ", data[i]);
             }
-            
-            /* 将数据复制到发送缓冲区 */
-            for (uint32_t i = 0; i < length; i++) {
-                g_serial_ctx.tx_buffer[g_serial_ctx.tx_head] = data[i];
-                g_serial_ctx.tx_head = (g_serial_ctx.tx_head + 1) % g_serial_ctx.tx_buffer_size;
-                g_serial_ctx.tx_count++;
+            if (length > 16) {
+                PPP_DEBUG_PRINT("... (total %u bytes)", length);
             }
+            PPP_DEBUG_PRINT("\n");
             
-            uint32_t buffered_count = g_serial_ctx.tx_count;
-            osal_mutex_unlock(&g_serial_ctx.tx_mutex);
+            PPP_DEBUG_INFO("Calling uapi_uart_write(bus=%u, data=%p, len=%u, timeout=1000)...", 
+                          g_serial_ctx.uart_bus, data, length);
             
-            PPP_DEBUG_INFO("Buffered %u bytes (total buffered: %u bytes)", length, buffered_count);
+            write_result = uapi_uart_write(g_serial_ctx.uart_bus, data, length, 1000);
+            PPP_DEBUG_INFO("uapi_uart_write returned: %d (expected: %u)", write_result, length);
             
-            /* 智能flush策略:根据PPP协议特性决定是否立即发送 */
-            if (ppp_serial_should_immediate_flush(data, length, buffered_count)) {
-                PPP_DEBUG_INFO("Smart flush triggered (buffered: %u, packet: %u bytes)", 
-                              buffered_count, length);
-                result = ppp_serial_flush_tx();
-                g_serial_ctx.last_tx_time = ppp_serial_get_current_time_ms();
+            if (write_result != (int32_t)length) {
+                PPP_DEBUG_ERROR("UART write failed in PPP data mode: returned %d, expected %u", write_result, length);
+                PPP_DEBUG_ERROR("Possible causes: UART not initialized, hardware error, or timeout");
+                g_serial_ctx.tx_errors++;
+                result = PPP_ERR_UART;
             } else {
                 g_serial_ctx.tx_bytes += length;
-                PPP_DEBUG_INFO("Data buffered smartly (total: %u bytes, will flush when appropriate)", buffered_count);
+                PPP_DEBUG_INFO("Sent %u bytes successfully via UART (PPP mode, total tx: %u bytes)", 
+                              length, g_serial_ctx.tx_bytes);
             }
             break;
 
@@ -475,22 +445,51 @@ ppp_error_t ppp_serial_read(uint8_t *buffer, uint32_t buffer_size, uint32_t *byt
 
     switch (g_serial_ctx.current_mode) {
         case PPP_SERIAL_MODE_AT:
-            /* AT命令模式:直接从UART读取 */
+        /* AT命令模式:直接从UART读取 */
             {
                 int32_t read_result = uapi_uart_read(g_serial_ctx.uart_bus, buffer, buffer_size, 100);
                 if (read_result > 0) {
                     *bytes_read = (uint32_t)read_result;
                     g_serial_ctx.rx_bytes += *bytes_read;
                     PPP_DEBUG_DEBUG("Read %u bytes via UART (AT mode)", *bytes_read);
-                    // PPP_DEBUG_HEXDUMP(buffer, *bytes_read);
                 } else if (read_result < 0) {
-                    PPP_DEBUG_ERROR("UART read error in AT mode: %d", read_result);
+                    PPP_DEBUG_ERROR("UART read error: %d", read_result);
                     g_serial_ctx.rx_errors++;
                     result = PPP_ERR_UART;
                 }
             }
             break;
 
+        case PPP_SERIAL_MODE_PPP_DATA:
+        /* PPP数据模式:使用优化的直接UART读取,增加超时时间 */
+            {
+                /* 使用更长的超时时间来获取更完整的数据包 */
+                int32_t read_result = uapi_uart_read(g_serial_ctx.uart_bus, buffer, buffer_size, 500);
+                if (read_result > 0) {
+                    *bytes_read = (uint32_t)read_result;
+                    g_serial_ctx.rx_bytes += *bytes_read;
+                    
+                    PPP_DEBUG_INFO("PPP UART Read: Received %u bytes (optimized mode)", *bytes_read);
+                    PPP_DEBUG_PRINT("PPP RX Data: ");
+                    for (uint32_t i = 0; i < *bytes_read && i < 16; i++) {
+                        PPP_DEBUG_PRINT("%02X ", buffer[i]);
+                    }
+                    if (*bytes_read > 16) {
+                        PPP_DEBUG_PRINT("... (total %u bytes)", *bytes_read);
+                    }
+                    PPP_DEBUG_PRINT("\n");
+                } else if (read_result < 0) {
+                    PPP_DEBUG_ERROR("UART read error in PPP mode: %d", read_result);
+                    g_serial_ctx.rx_errors++;
+                    result = PPP_ERR_UART;
+                } else {
+                    /* read_result == 0, 超时但无错误 */
+                    *bytes_read = 0;
+                    result = PPP_ERR_OK;
+                }
+            }
+            break;
+#if 0
         case PPP_SERIAL_MODE_PPP_DATA:
             /* PPP数据模式:从软件环形缓冲区读取 */
             osal_mutex_lock(&g_serial_ctx.rx_mutex);
@@ -515,7 +514,7 @@ ppp_error_t ppp_serial_read(uint8_t *buffer, uint32_t buffer_size, uint32_t *byt
             PPP_DEBUG_DEBUG("Read %u bytes from software buffer (PPP data mode)", to_read);
             // PPP_DEBUG_HEXDUMP(buffer, to_read);
             break;
-
+#endif
         default:
             PPP_DEBUG_ERROR("Invalid serial mode: %d", g_serial_ctx.current_mode);
             result = PPP_ERR_INVALID_PARAM;
@@ -793,6 +792,9 @@ static void ppp_serial_rx_callback(const void *buffer, uint16_t length, bool rem
 {
     (void)remaining;
     
+    /* UART接收回调函数:将数据存储到环形缓冲区 */
+    PPP_DEBUG_INFO("UART Callback: Received %u bytes", length);
+    
     if (!buffer || length == 0) {
         return;
     }
@@ -828,7 +830,17 @@ static void ppp_serial_rx_callback(const void *buffer, uint16_t length, bool rem
         g_serial_ctx.rx_callback(data, length, g_serial_ctx.rx_callback_arg);
     }
 
-    PPP_DEBUG_DEBUG("Received %u bytes", length);
+    PPP_DEBUG_INFO("UART Callback: Received %u bytes", length);
+    
+    // 打印前8字节用于调试
+    PPP_DEBUG_PRINT("UART RX Data: ");
+    for (uint16_t i = 0; i < length && i < 8; i++) {
+        PPP_DEBUG_PRINT("%02X ", data[i]);
+    }
+    if (length > 8) {
+        PPP_DEBUG_PRINT("... (total %u bytes)", length);
+    }
+    PPP_DEBUG_PRINT("\n");
 }
 
 /**
@@ -1021,4 +1033,55 @@ uint32_t ppp_serial_tx_available(void)
     osal_mutex_unlock(&g_serial_ctx.tx_mutex);
 
     return count;
-} 
\ No newline at end of file
+}
+
+/*
+ * 注意:以下IRQ处理函数暂时不使用,因为UART回调机制已经包含了中断处理
+ * 如果需要更底层的中断控制,可以取消注释并调试IRQ冲突问题
+ */
+
+#if 0
+/**
+ * @brief UART中断处理函数
+ */
+static void _ppp_serial_irq_handler(uint32_t irq_num, void *arg)
+{
+    (void)irq_num;
+    (void)arg;
+    
+    /* 调用HAL层的UART中断处理函数 */
+    hal_uart_irq_handler(g_serial_ctx.uart_bus);
+}
+
+/**
+ * @brief 注册UART中断
+ */
+static ppp_error_t ppp_serial_register_irq(void)
+{
+    PPP_DEBUG_INFO("Registering UART IRQ %d for bus %u", SIO_UART_IRQ_NUM, g_serial_ctx.uart_bus);
+    
+    int32_t ret = osal_irq_request(SIO_UART_IRQ_NUM, _ppp_serial_irq_handler, NULL, "ppp_uart", 0);
+    if (ret != 0) {
+        PPP_DEBUG_ERROR("Failed to register UART IRQ %d: %d", SIO_UART_IRQ_NUM, ret);
+        return PPP_ERR_UART;
+    }
+    
+    PPP_DEBUG_INFO("UART IRQ %d registered successfully", SIO_UART_IRQ_NUM);
+
+    osal_irq_set_priority(SIO_UART_IRQ_NUM, irq_prio(SIO_UART_IRQ_NUM));
+    osal_irq_enable(SIO_UART_IRQ_NUM);
+
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 注销UART中断
+ */
+static ppp_error_t ppp_serial_unregister_irq(void)
+{
+    osal_irq_free(SIO_UART_IRQ_NUM, NULL);
+    osal_irq_disable(SIO_UART_IRQ_NUM);
+    PPP_DEBUG_INFO("UART IRQ %d unregistered successfully", SIO_UART_IRQ_NUM);
+    return PPP_ERR_OK;
+}
+#endif 
\ No newline at end of file