更新ppp 实现
author孙春阳 <snickersun@163.com>
Thu, 11 Sep 2025 08:43:21 +0000 (16:43 +0800)
committer孙春阳 <snickersun@163.com>
Thu, 11 Sep 2025 08:43:21 +0000 (16:43 +0800)
14 files changed:
code/sdk/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/arch/sio.c
code/sdk/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/test/slip_test.c
code/sdk/zhihui/ppp/CMakeLists.txt
code/sdk/zhihui/ppp/example/ppp_example.c
code/sdk/zhihui/ppp/include/ppp_api.h
code/sdk/zhihui/ppp/include/ppp_at_handler.h
code/sdk/zhihui/ppp/include/ppp_config.h
code/sdk/zhihui/ppp/include/ppp_power_ctl.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_lwip.c
code/sdk/zhihui/ppp/src/ppp_power_ctl.c
code/sdk/zhihui/ppp/src/ppp_serial.c

index fae1e89..5505950 100644 (file)
@@ -76,7 +76,7 @@ static bool g_sio_uart_initialized = false;
 static uint8_t g_sio_write_buffer[SIO_WRITE_BUFFER_SIZE];
 static uint32_t g_sio_write_buffer_pos = 0;
 
-extern void uart_slip_read_int_handler(const void *buffer, uint16_t length, bool error);
+extern void uart_read_data_int_handler(const void *buffer, uint16_t length, bool error);
 
 /**
  * Initialize SIO UART
@@ -98,7 +98,7 @@ static errcode_t sio_uart_init(void)
     }
 
     ret = uapi_uart_register_rx_callback(SIO_UART_BUS, UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE,
-        SIO_UART_RX_BUFFER_SIZE, uart_slip_read_int_handler);
+        SIO_UART_RX_BUFFER_SIZE, uart_read_data_int_handler);
 
     printf("uapi_uart_register_rx_callback ret=%x\r\n", ret);
 
index 6a7ade6..31432c2 100644 (file)
@@ -100,7 +100,7 @@ void slip_test_send(void)
     }
 }
 
-void uart_slip_read_int_handler(const void *buffer, uint16_t length, bool error)
+void uart_read_data_int_handler(const void *buffer, uint16_t length, bool error)
 {
     if (slipif_initialled == true)
     {
index eedeb85..996c72a 100644 (file)
@@ -68,6 +68,7 @@ set(PUBLIC_DEFINES
     PRINTPKT_SUPPORT=1
     PPP_DEBUG=LWIP_DBG_ON
     PPP_INPROC_IRQ_SAFE=0
+    PPP_OPTIONS=1 
     SUPPORT_PPP_SERVICE
     SUPPORT_AT_PPP
 )
index aa0cd09..f1b8264 100644 (file)
@@ -26,16 +26,22 @@ int ppp_example_main(void)
 
     /* 配置PPP拨号参数 */
     ppp_config_t config = {
-        .apn = "cmnet",                     // 中国移动APN
+        .apn = "cmnet",                     // 中国移动APN (对应AT+CGDCONT中的APN)
         .username = "",                     // 用户名(通常为空)
         .password = "",                     // 密码(通常为空)
-        .baudrate = 2000000,                // 2M波特率
-        .auto_baudrate = true,              // 启用自动波特率检测
-        .dial_timeout = 30000,              // 30秒拨号超时
+        .baudrate = 2000000,                // 2M波特率 (对应AT+IPR=2000000)
+        .auto_baudrate = true,              // 启用自动波特率检测 (对应chat文件中的AT握手)
+        .dial_timeout = 30000,              // 30秒拨号超时 (对应chat文件TIMEOUT 5)
         .retry_count = 3                    // 重试3次
         };
 
     /* 初始化PPP拨号系统 */
+    /* 这将执行完整的chat文件流程:
+     * 1. 跳过开机日志 (对应 '' \rAT)
+     * 2. AT握手 (对应 AT -> OK)  
+     * 3. 设置PDP上下文 (对应 AT+CGDCONT=3,"IP")
+     * 4. PPP拨号 (对应 ATD*99***2# -> CONNECTED)
+     */
     errcode_t ret = zhihui_ppp_init(&config);
 
     if (ret != ERRCODE_SUCC) {
index 92ec12c..8c02107 100644 (file)
@@ -35,6 +35,18 @@ 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);
+
 /**
  * @brief 获取PPP连接状态
  * @return PPP状态
index 50f9341..a11586d 100644 (file)
@@ -52,6 +52,13 @@ ppp_error_t ppp_at_set_baudrate(uint32_t baudrate);
  */
 ppp_error_t ppp_at_auto_detect_baudrate(void);
 
+/**
+ * @brief 完整的PPP拨号序列 (对应chat文件的完整流程)
+ * @param apn APN接入点名称
+ * @return 错误码
+ */
+ppp_error_t ppp_at_complete_dial_sequence(const char *apn);
+
 #ifdef __cplusplus
 }
 #endif
index b9dce07..0149970 100644 (file)
@@ -10,6 +10,20 @@ extern "C" {
 
 /* PPP配置参数 - UART配置统一使用SIO (在lwipopts_default.h中定义) */
 
+/* SIO设备号配置 - 与SLIP区分开 */
+#define PPP_IFNUM                   1                   // PPP使用的SIO设备号,与SLIP_IFNUM(0)区分
+
+/* UART引脚配置 - 对应SIO配置 */
+#ifndef SIO_UART_TX_PIN
+#define SIO_UART_TX_PIN             S_AGPIO_L25         // UART TX引脚
+#endif
+#ifndef SIO_UART_RX_PIN  
+#define SIO_UART_RX_PIN             S_AGPIO_L26         // UART RX引脚
+#endif
+#ifndef SIO_UART_BUS
+#define SIO_UART_BUS                UART_BUS_1          // UART总线
+#endif
+
 /* 支持的波特率列表(自适应模式) */
 #define PPP_BAUDRATE_AUTO_LIST      {9600, 57600, 115200}
 #define PPP_BAUDRATE_AUTO_COUNT     3
@@ -31,7 +45,10 @@ extern "C" {
 
 /* 缓冲区大小配置 */
 #define PPP_RX_BUFFER_SIZE          2048                // 接收缓冲区大小
-#define PPP_TX_BUFFER_SIZE          1024                // 发送缓冲区大小
+#define PPP_TX_BUFFER_SIZE          2048                // 发送缓冲区大小
+
+/* PPP数据接收线程配置 */
+#define PPP_RX_THREAD_STACK_SIZE    4096                // PPP数据接收线程栈大小
 
 /* PPP网络配置 */
 #define PPP_MTU_SIZE                1500                // PPP MTU大小
index c1851fb..487bf0b 100644 (file)
@@ -122,6 +122,11 @@ void ppp_ring_isr_callback(pin_t pin, uintptr_t param);
  */
 void ppp_api_enable_cat1(bool isopen);
 
+/**
+ * @brief PPP模块反初始化
+ */
+void ppp_api_deinit(void);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 1a2c334..75655c2 100644 (file)
@@ -94,6 +94,13 @@ ppp_error_t ppp_serial_set_baudrate(uint32_t baudrate);
  */
 void ppp_serial_get_stats(ppp_serial_stats_t *stats);
 
+/**
+ * @brief 获取PPP模块SIO句柄
+ * @return SIO句柄,如果未初始化则返回NULL
+ */
+#include "lwip/sio.h"
+sio_fd_t ppp_get_sio_fd(void);
+
 #ifdef __cplusplus
 }
 #endif
index c6df73c..8ccff1c 100644 (file)
@@ -1,6 +1,8 @@
 #include "ppp_api.h"
 #include "ppp_debug.h"
 #include "ppp_power_ctl.h"
+#include "ppp_at_handler.h"  // 添加AT处理头文件
+#include "ppp_serial.h"      // 添加串口处理头文件
 #include "osal_debug.h"
 #include "schedule/osal_task.h"
 #include "securec.h"
@@ -58,14 +60,83 @@ errcode_t ppp_start_dial(void)
     // 2. 等待4G模块启动
     osal_msleep(2000);
 
-    // 3. 初始化AT命令处理
-    // TODO: 实现AT命令初始化
+    // 3. 初始化AT命令处理(AT命令模式)
+    ppp_error_t ret = ppp_at_handler_init(SIO_UART_BUS);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_PRINT("Failed to initialize AT handler: %d\n", ret);
+        return ERRCODE_FAIL;
+    }
 
-    // 4. 启动PPP协议栈
-    // TODO: 实现PPP协议栈启动
+    // 4. 执行波特率握手(如果启用自动波特率)
+    if (g_ppp_config.auto_baudrate) {
+        ret = ppp_at_baudrate_handshake();
+        if (ret != PPP_ERR_OK) {
+            PPP_DEBUG_PRINT("Baudrate handshake failed: %d\n", ret);
+            return ERRCODE_FAIL;
+        }
+    }
 
-    g_ppp_state = PPP_STATE_DIALING;
-    PPP_DEBUG_PRINT("PPP dial started\n");
+    // 5. 执行完整的AT指令序列(对应chat文件)
+    ret = ppp_at_complete_dial_sequence(g_ppp_config.apn);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_PRINT("PPP dial sequence failed: %d\n", ret);
+        g_ppp_state = PPP_STATE_ERROR;
+        return ERRCODE_FAIL;
+    }
+
+    PPP_DEBUG_PRINT("AT dial sequence completed - switching to PPP data mode\n");
+
+    // 6. 关闭AT命令处理器(释放UART资源)
+    ppp_at_handler_deinit();
+    PPP_DEBUG_PRINT("AT handler deinitialized - UART released\n");
+
+    // 7. 初始化SIO串口(PPP数据模式)
+    ppp_serial_config_t serial_config = {
+        .uart_bus = SIO_UART_BUS,
+        .baudrate = g_ppp_config.baudrate,
+        .tx_pin = SIO_UART_TX_PIN,
+        .rx_pin = SIO_UART_RX_PIN,
+        .rx_buffer_size = PPP_RX_BUFFER_SIZE,
+        .tx_buffer_size = PPP_TX_BUFFER_SIZE,
+        .rx_callback = NULL,  // 将在PPP数据接收线程中设置
+        .rx_callback_arg = NULL
+    };
+    
+    ret = ppp_serial_init(&serial_config);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_PRINT("Failed to initialize serial for PPP data mode: %d\n", ret);
+        return ERRCODE_FAIL;
+    }
+
+    // 8. 初始化lwIP PPP协议栈
+    ret = ppp_lwip_init();
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_PRINT("Failed to initialize lwIP PPP: %d\n", ret);
+        ppp_serial_deinit();
+        return ERRCODE_FAIL;
+    }
+
+    // 9. 启动PPP连接
+    ret = ppp_lwip_connect();
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_PRINT("Failed to start PPP connection: %d\n", ret);
+        ppp_lwip_deinit();
+        ppp_serial_deinit();
+        return ERRCODE_FAIL;
+    }
+
+    // 10. 启动PPP数据接收处理
+    ret = ppp_start_data_receive_thread();
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_PRINT("Failed to start PPP data receive thread: %d\n", ret);
+        ppp_lwip_disconnect();
+        ppp_lwip_deinit();
+        ppp_serial_deinit();
+        return ERRCODE_FAIL;
+    }
+
+    g_ppp_state = PPP_STATE_CONNECTED;
+    PPP_DEBUG_PRINT("PPP dial completed successfully - now in data mode\n");
 
     return ERRCODE_SUCC;
 }
@@ -77,14 +148,47 @@ errcode_t ppp_stop_dial(void)
 {
     PPP_DEBUG_PRINT("Stopping PPP connection\n");
 
-    // 1. 停止PPP协议栈
-    // TODO: 实现PPP协议栈停止
+    if (g_ppp_state != PPP_STATE_CONNECTED) {
+        PPP_DEBUG_WARN("PPP not connected, current state: %d", g_ppp_state);
+        return ERRCODE_SUCC;
+    }
+
+    // 1. 停止PPP数据接收线程
+    ppp_stop_data_receive_thread();
+
+    // 2. 断开lwIP PPP连接
+    ppp_lwip_disconnect();
+
+    // 3. 清理lwIP PPP资源
+    ppp_lwip_deinit();
+
+    // 4. 关闭SIO串口(释放串口资源)
+    ppp_serial_deinit();
+    PPP_DEBUG_PRINT("SIO serial deinitialized - switching back to AT mode\n");
+
+    // 5. 重新初始化AT命令处理器(切换回AT命令模式)
+    ppp_error_t ret = ppp_at_handler_init(SIO_UART_BUS);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("Failed to reinitialize AT handler: %d", ret);
+        g_ppp_state = PPP_STATE_ERROR;
+        return ERRCODE_FAIL;
+    }
+
+    // 6. 发送PPP挂断命令(切换回命令模式)
+    ret = ppp_at_hangup_ppp();
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_WARN("Failed to send hangup command: %d", ret);
+        // 继续执行,不返回错误
+    }
+
+    // 7. 关闭AT命令处理器
+    ppp_at_handler_deinit();
 
-    // 2. 关闭4G电源(通过兼容接口)
+    // 8. 关闭4G电源
     cat1_api_enable_cat1(false);
 
-    g_ppp_state = PPP_STATE_IDLE;
-    PPP_DEBUG_PRINT("PPP connection stopped\n");
+    g_ppp_state = PPP_STATE_INITIALIZED;
+    PPP_DEBUG_PRINT("PPP connection stopped successfully\n");
 
     return ERRCODE_SUCC;
 }
@@ -148,4 +252,85 @@ errcode_t zhihui_ppp_deinit(void)
     PPP_DEBUG_PRINT("PPP module deinitialized\n");
 
     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;
 } 
\ No newline at end of file
index 827fde9..970af19 100644 (file)
@@ -237,6 +237,94 @@ ppp_error_t ppp_at_send_command(const char *command, const char *expected_respon
     return ret;
 }
 
+/**
+ * @brief 跳过开机日志 (对应chat文件中的 '' \rAT)
+ */
+static ppp_error_t ppp_at_skip_startup_logs(void)
+{
+    PPP_DEBUG_INFO("Skipping startup logs...");
+    
+    // 清空接收缓冲区,跳过开机时的各种日志输出
+    uint8_t dummy_buffer[256];
+    uint32_t bytes_read;
+    
+    // 连续读取并丢弃开机日志,直到没有更多数据
+    int retry_count = 0;
+    const int max_retries = 10;
+    
+    do {
+        ppp_error_t ret = ppp_serial_read(dummy_buffer, sizeof(dummy_buffer), &bytes_read);
+        if (ret != PPP_ERR_OK) {
+            break;
+        }
+        
+        if (bytes_read > 0) {
+            PPP_DEBUG_DEBUG("Skipped %u bytes of startup logs", bytes_read);
+            retry_count = 0; // 重置重试计数
+        } else {
+            retry_count++;
+        }
+        
+        osal_msleep(100);
+    } while (retry_count < max_retries);
+    
+    PPP_DEBUG_INFO("Startup logs skipped");
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 完整的PPP拨号序列 (对应chat文件的完整流程)
+ */
+ppp_error_t ppp_at_complete_dial_sequence(const char *apn)
+{
+    ppp_at_response_t response;
+    ppp_error_t ret;
+    
+    PPP_DEBUG_INFO("Starting complete PPP dial sequence");
+    
+    // 1. 跳过开机日志 (对应chat文件: '' \rAT)
+    ret = ppp_at_skip_startup_logs();
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("Failed to skip startup logs");
+        return ret;
+    }
+    
+    // 2. 发送AT测试连接 (对应chat文件: '' \rAT -> OK)
+    ret = ppp_at_send_command("AT", "OK", 5000, &response);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("AT handshake failed");
+        return ret;
+    }
+    PPP_DEBUG_INFO("AT handshake successful");
+    
+    // 3. 设置PDP上下文 (对应chat文件: OK 'AT+CGDCONT=3,"IP"')
+    char cgdcont_cmd[128];
+    if (apn && strlen(apn) > 0) {
+        snprintf_s(cgdcont_cmd, sizeof(cgdcont_cmd), sizeof(cgdcont_cmd) - 1, 
+                   "AT+CGDCONT=3,\"IP\",\"%s\"", apn);
+    } else {
+        snprintf_s(cgdcont_cmd, sizeof(cgdcont_cmd), sizeof(cgdcont_cmd) - 1, 
+                   "AT+CGDCONT=3,\"IP\"");
+    }
+    
+    ret = ppp_at_send_command(cgdcont_cmd, "OK", 5000, &response);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("Failed to set PDP context: %s", cgdcont_cmd);
+        return ret;
+    }
+    PPP_DEBUG_INFO("PDP context set successfully");
+    
+    // 4. 发送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");
+        return ret;
+    }
+    
+    PPP_DEBUG_INFO("PPP dial sequence completed successfully - entering data mode");
+    return PPP_ERR_OK;
+}
+
 /**
  * @brief 发送PPP拨号命令
  */
@@ -319,11 +407,24 @@ bool ppp_at_is_auto_baudrate_mode(void)
  */
 static bool ppp_at_parse_response(const char *response, const char *expected)
 {
-    if (!response || !expected) {
+    if (!response) {
+        return false;
+    }
+
+    // 检查ABORT条件 (对应chat文件中的ABORT指令)
+    if (strstr(response, "BUSY") || 
+        strstr(response, "ERROR") || 
+        strstr(response, "NO CARRIER")) {
+        PPP_DEBUG_ERROR("AT command aborted: %s", response);
         return false;
     }
 
-    return strstr(response, expected) != NULL;
+    // 检查期望响应
+    if (expected && strstr(response, expected)) {
+        return true;
+    }
+
+    return false;
 }
 
 /**
index c513de1..845c056 100644 (file)
@@ -3,6 +3,7 @@
 #include "ppp_types.h"
 #include "ppp_debug.h"
 #include "ppp_serial.h"
+#include "ppp_power_ctl.h"  // 添加电源控制头文件
 #include "securec.h"
 #include <string.h>
 
@@ -14,6 +15,7 @@
 #include "lwip/dns.h"
 #include "netif/ppp/ppp.h"
 #include "netif/ppp/pppos.h"
+#include "lwip/sio.h"  // 添加SIO头文件
 #endif
 
 /* PPP lwIP上下文 */
@@ -367,7 +369,7 @@ static void ppp_lwip_link_status_callback(ppp_pcb *pcb, int err_code, void *ctx)
 }
 
 /**
- * @brief PPP输出回调函数
+ * @brief PPP输出回调函数 - 使用SIO接口,像SLIP一样
  */
 static u32_t ppp_lwip_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx)
 {
@@ -377,13 +379,19 @@ static u32_t ppp_lwip_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void
     PPP_DEBUG_DEBUG("PPP output %u bytes", len);
     PPP_DEBUG_HEXDUMP(data, len);
 
-    /* 通过串口发送数据 */
-    ppp_error_t ret = ppp_serial_write(data, len);
-    if (ret != PPP_ERR_OK) {
-        PPP_DEBUG_ERROR("Failed to send PPP data: %d", ret);
+    /* 通过SIO接口发送数据,像SLIP一样 */
+    sio_fd_t sio_fd = ppp_get_sio_fd();
+    if (sio_fd == NULL) {
+        PPP_DEBUG_ERROR("SIO interface not initialized");
         return 0;
     }
 
-    return len;
+    u32_t sent = sio_write(sio_fd, data, len);
+    if (sent != len) {
+        PPP_DEBUG_ERROR("Failed to send PPP data via SIO: %u/%u", sent, len);
+        return 0;
+    }
+
+    return sent;
 }
 #endif /* LWIP_PPP_SUPPORT */ 
\ No newline at end of file
index 923a524..e553420 100644 (file)
@@ -125,8 +125,8 @@ void ppp_api_gpio_init(void)
  */
 void ppp_api_uart_init(void)
 {
-    PPP_DEBUG_PRINT("PPP UART init\n");
-    // UARTå\88\9då§\8bå\8c\96é\80»è¾\91å\8f¯ä»¥å\9c¨è¿\99é\87\8cæ·»å\8a 
+    PPP_DEBUG_PRINT("PPP UART init - delegated to ppp_serial module\n");
+    // UARTå\88\9då§\8bå\8c\96é\80»è¾\91已移è\87³ppp_serial.c中
 }
 
 /**
@@ -411,4 +411,17 @@ void ppp_api_enable_cat1(bool isopen)
         // 可以在这里添加PPP特定的清理逻辑
         // 例如:停止PPP协议栈等
     }
+}
+
+/**
+ * @brief PPP模块反初始化
+ */
+void ppp_api_deinit(void)
+{
+    PPP_DEBUG_PRINT("PPP: deinit\n");
+    
+    // 关闭电源
+    ppp_api_cat1_power_on(0);
+    
+    g_ppp_cat1_power_status = false;
 }
\ No newline at end of file
index bedea5f..449a74e 100644 (file)
 #include "securec.h"
 #include <string.h>
 
+// 添加SIO相关头文件,让PPP像SLIP一样使用SIO接口
+#include "lwip/sio.h"
+#include "lwip/opt.h"
+
 /* 串口上下文结构 */
 typedef struct {
     bool initialized;
@@ -19,6 +23,9 @@ typedef struct {
     uart_attr_t uart_attr;
     uart_buffer_config_t buffer_config;
     
+    /* SIO接口句柄 */
+    sio_fd_t sio_fd;
+    
     /* 接收缓冲区 */
     uint8_t *rx_buffer;
     uint32_t rx_buffer_size;
@@ -61,103 +68,22 @@ ppp_error_t ppp_serial_init(const ppp_serial_config_t *config)
         return PPP_ERR_INVALID_PARAM;
     }
 
-    PPP_DEBUG_INFO("Initializing PPP serial on UART%d", config->uart_bus);
-
-    /* 分配接收缓冲区 */
-    g_serial_ctx.rx_buffer = (uint8_t *)osal_kmalloc(config->rx_buffer_size, OSAL_GFP_KERNEL);
-    if (!g_serial_ctx.rx_buffer) {
-        PPP_DEBUG_ERROR("Failed to allocate RX buffer");
-        return PPP_ERR_MEMORY;
-    }
-
-    /* 分配发送缓冲区 */
-    g_serial_ctx.tx_buffer = (uint8_t *)osal_kmalloc(config->tx_buffer_size, OSAL_GFP_KERNEL);
-    if (!g_serial_ctx.tx_buffer) {
-        PPP_DEBUG_ERROR("Failed to allocate TX buffer");
-        osal_kfree(g_serial_ctx.rx_buffer);
-        return PPP_ERR_MEMORY;
-    }
+    PPP_DEBUG_INFO("Initializing PPP serial using SIO interface like SLIP");
 
-    /* 创建互斥锁 */
-    if (osal_mutex_init(&g_serial_ctx.rx_mutex) != OSAL_SUCCESS) {
-        PPP_DEBUG_ERROR("Failed to create RX mutex");
-        osal_kfree(g_serial_ctx.rx_buffer);
-        osal_kfree(g_serial_ctx.tx_buffer);
-        return PPP_ERR_MEMORY;
-    }
-
-    /* 创建信号量 */
-    if (osal_sem_init(&g_serial_ctx.rx_semaphore, 0) != OSAL_SUCCESS) {
-        PPP_DEBUG_ERROR("Failed to create RX semaphore");
-        osal_mutex_destroy(g_serial_ctx.rx_mutex);
-        osal_kfree(g_serial_ctx.rx_buffer);
-        osal_kfree(g_serial_ctx.tx_buffer);
-        return PPP_ERR_MEMORY;
+    /* 打开SIO接口,使用与SLIP相同的方式但不同的设备号 */
+    g_serial_ctx.sio_fd = sio_open(PPP_IFNUM);
+    if (g_serial_ctx.sio_fd == NULL) {
+        PPP_DEBUG_ERROR("Failed to open SIO interface for PPP, device=%d", PPP_IFNUM);
+        return PPP_ERR_UART;
     }
 
-    /* 配置串口参数 */
+    /* 配置基本参数 */
     g_serial_ctx.uart_bus = config->uart_bus;
     g_serial_ctx.rx_buffer_size = config->rx_buffer_size;
     g_serial_ctx.tx_buffer_size = config->tx_buffer_size;
     g_serial_ctx.rx_callback = config->rx_callback;
     g_serial_ctx.rx_callback_arg = config->rx_callback_arg;
 
-    /* 配置串口引脚 */
-    g_serial_ctx.pin_config.tx_pin = config->tx_pin;
-    g_serial_ctx.pin_config.rx_pin = config->rx_pin;
-    g_serial_ctx.pin_config.cts_pin = PIN_NONE;
-    g_serial_ctx.pin_config.rts_pin = PIN_NONE;
-
-    /* 配置串口属性 */
-    g_serial_ctx.uart_attr.baud_rate = config->baudrate;
-    g_serial_ctx.uart_attr.data_bits = UART_DATA_BIT_8;
-    g_serial_ctx.uart_attr.parity = UART_PARITY_NONE;
-    g_serial_ctx.uart_attr.stop_bits = UART_STOP_BIT_1;
-
-    /* 配置串口缓冲区 */
-    g_serial_ctx.buffer_config.rx_buffer_size = 256; // 硬件缓冲区
-    g_serial_ctx.buffer_config.rx_buffer = (uint8_t *)osal_kmalloc(256, OSAL_GFP_KERNEL);
-    if (!g_serial_ctx.buffer_config.rx_buffer) {
-        PPP_DEBUG_ERROR("Failed to allocate UART RX buffer");
-        osal_sem_destroy(g_serial_ctx.rx_semaphore);
-        osal_mutex_destroy(g_serial_ctx.rx_mutex);
-        osal_kfree(g_serial_ctx.rx_buffer);
-        osal_kfree(g_serial_ctx.tx_buffer);
-        return PPP_ERR_MEMORY;
-    }
-
-    /* 初始化串口 */
-    errcode_t ret = uapi_uart_init(g_serial_ctx.uart_bus, 
-                                   &g_serial_ctx.pin_config,
-                                   &g_serial_ctx.uart_attr,
-                                   NULL,
-                                   &g_serial_ctx.buffer_config);
-    if (ret != ERRCODE_SUCC) {
-        PPP_DEBUG_ERROR("Failed to initialize UART: %d", ret);
-        osal_kfree(g_serial_ctx.buffer_config.rx_buffer);
-        osal_sem_destroy(g_serial_ctx.rx_semaphore);
-        osal_mutex_destroy(g_serial_ctx.rx_mutex);
-        osal_kfree(g_serial_ctx.rx_buffer);
-        osal_kfree(g_serial_ctx.tx_buffer);
-        return PPP_ERR_UART;
-    }
-
-    /* 注册接收回调 */
-    ret = uapi_uart_register_rx_callback(g_serial_ctx.uart_bus,
-                                         UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE,
-                                         1, // 接收到1个字节就触发回调
-                                         ppp_serial_rx_callback);
-    if (ret != ERRCODE_SUCC) {
-        PPP_DEBUG_ERROR("Failed to register UART RX callback: %d", ret);
-        uapi_uart_deinit(g_serial_ctx.uart_bus);
-        osal_kfree(g_serial_ctx.buffer_config.rx_buffer);
-        osal_sem_destroy(g_serial_ctx.rx_semaphore);
-        osal_mutex_destroy(g_serial_ctx.rx_mutex);
-        osal_kfree(g_serial_ctx.rx_buffer);
-        osal_kfree(g_serial_ctx.tx_buffer);
-        return PPP_ERR_UART;
-    }
-
     /* 初始化缓冲区状态 */
     g_serial_ctx.rx_head = 0;
     g_serial_ctx.rx_tail = 0;
@@ -174,7 +100,10 @@ ppp_error_t ppp_serial_init(const ppp_serial_config_t *config)
 
     return PPP_ERR_OK;
 }
-
+void uart_read_data_int_handler(const void *buffer, uint16_t length, bool error)
+{
+    ppp_serial_rx_callback(buffer, length,error);
+}
 /**
  * @brief 反初始化PPP串口
  */
@@ -186,28 +115,10 @@ void ppp_serial_deinit(void)
 
     PPP_DEBUG_INFO("Deinitializing PPP serial");
 
-    /* 反初始化串口 */
-    uapi_uart_deinit(g_serial_ctx.uart_bus);
-
-    /* 释放资源 */
-    if (g_serial_ctx.buffer_config.rx_buffer) {
-        osal_kfree(g_serial_ctx.buffer_config.rx_buffer);
-    }
-    
-    if (g_serial_ctx.rx_semaphore) {
-        osal_sem_destroy(g_serial_ctx.rx_semaphore);
-    }
-    
-    if (g_serial_ctx.rx_mutex) {
-        osal_mutex_destroy(g_serial_ctx.rx_mutex);
-    }
-    
-    if (g_serial_ctx.rx_buffer) {
-        osal_kfree(g_serial_ctx.rx_buffer);
-    }
-    
-    if (g_serial_ctx.tx_buffer) {
-        osal_kfree(g_serial_ctx.tx_buffer);
+    /* 关闭SIO接口 */
+    if (g_serial_ctx.sio_fd != NULL) {
+        sio_close(g_serial_ctx.sio_fd);
+        g_serial_ctx.sio_fd = NULL;
     }
 
     memset_s(&g_serial_ctx, sizeof(g_serial_ctx), 0, sizeof(g_serial_ctx));
@@ -223,34 +134,25 @@ ppp_error_t ppp_serial_write(const uint8_t *data, uint32_t length)
         return PPP_ERR_INVALID_PARAM;
     }
 
-    if (length > g_serial_ctx.tx_buffer_size) {
-        PPP_DEBUG_ERROR("Data length exceeds TX buffer size");
-        return PPP_ERR_INVALID_PARAM;
+    if (g_serial_ctx.sio_fd == NULL) {
+        PPP_DEBUG_ERROR("SIO interface not initialized");
+        return PPP_ERR_UART;
     }
 
-    PPP_DEBUG_DEBUG("Sending %u bytes", length);
+    PPP_DEBUG_DEBUG("Sending %u bytes via SIO", length);
     PPP_DEBUG_HEXDUMP(data, length);
 
-    /* 复制数据到发送缓冲区 */
-    memcpy_s(g_serial_ctx.tx_buffer, g_serial_ctx.tx_buffer_size, data, length);
-
-    /* 发送数据 */
-    int32_t bytes_written = uapi_uart_write(g_serial_ctx.uart_bus, g_serial_ctx.tx_buffer, length, 1000);
+    /* 通过SIO接口发送数据,像SLIP一样 */
+    u32_t bytes_written = sio_write(g_serial_ctx.sio_fd, (u8_t*)data, length);
     
-    if (bytes_written < 0) {
-        PPP_DEBUG_ERROR("UART write failed: %d", bytes_written);
-        g_serial_ctx.tx_errors++;
-        return PPP_ERR_UART;
-    }
-
-    if ((uint32_t)bytes_written != length) {
-        PPP_DEBUG_WARN("Partial write: %d/%u bytes", bytes_written, length);
+    if (bytes_written != length) {
+        PPP_DEBUG_ERROR("SIO write failed: %u/%u bytes", bytes_written, length);
         g_serial_ctx.tx_errors++;
         return PPP_ERR_UART;
     }
 
-    g_serial_ctx.tx_bytes += (uint32_t)bytes_written;
-    PPP_DEBUG_DEBUG("Sent %u bytes successfully", bytes_written);
+    g_serial_ctx.tx_bytes += bytes_written;
+    PPP_DEBUG_DEBUG("Sent %u bytes successfully via SIO", bytes_written);
 
     return PPP_ERR_OK;
 }
@@ -453,4 +355,13 @@ static uint32_t ppp_serial_buffer_available_space(void)
 static uint32_t ppp_serial_buffer_data_count(void)
 {
     return g_serial_ctx.rx_count;
+}
+
+/**
+ * @brief 获取PPP模块SIO句柄
+ * @return SIO句柄,如果未初始化则返回NULL
+ */
+sio_fd_t ppp_get_sio_fd(void)
+{
+    return g_serial_ctx.sio_fd;
 } 
\ No newline at end of file