pppc测试相关更新,目前主要问题在串口数据接收 2451/2 2451/head 2452/target/1
author孙春阳 <snickersun@163.com>
Tue, 30 Sep 2025 07:23:38 +0000 (15:23 +0800)
committer孙春阳 <snickersun@163.com>
Tue, 30 Sep 2025 07:23:38 +0000 (15:23 +0800)
31 files changed:
code/sdk/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/include/lwip/lwipopts_default.h
code/sdk/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include/netif/ppp/pppdebug.h
code/sdk/zhihui/ai_stub/src/ppp_stub_functions.c
code/sdk/zhihui/ppp/CMakeLists.txt
code/sdk/zhihui/ppp/example/ppp_at_cmd.c
code/sdk/zhihui/ppp/include/ppp_config.h
code/sdk/zhihui/ppp/include/ppp_interrupt.h [new file with mode: 0644]
code/sdk/zhihui/ppp/include/ppp_lwip.h
code/sdk/zhihui/ppp/include/ppp_serial.h
code/sdk/zhihui/ppp/ppp_dec_test/performance_test.c [new file with mode: 0644]
code/sdk/zhihui/ppp/ppp_dec_test/ppp_analyzer.py [new file with mode: 0644]
code/sdk/zhihui/ppp/ppp_dec_test/ppp_file_reader.c [new file with mode: 0644]
code/sdk/zhihui/ppp/ppp_dec_test/ppp_packet_analyzer.c [new file with mode: 0644]
code/sdk/zhihui/ppp/ppp_dec_test/ppp_packet_analyzer.h [new file with mode: 0644]
code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser.c [new file with mode: 0644]
code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser.h [new file with mode: 0644]
code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser_configurable.h [new file with mode: 0644]
code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser_dynamic.c [new file with mode: 0644]
code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser_dynamic.h [new file with mode: 0644]
code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser_streaming.h [new file with mode: 0644]
code/sdk/zhihui/ppp/ppp_dec_test/ppp_stream_parser.c [new file with mode: 0644]
code/sdk/zhihui/ppp/ppp_dec_test/ppp_stream_parser.h [new file with mode: 0644]
code/sdk/zhihui/ppp/ppp_dec_test/ppp_stream_test [new file with mode: 0644]
code/sdk/zhihui/ppp/ppp_dec_test/ppp_stream_test.c [new file with mode: 0644]
code/sdk/zhihui/ppp/src/ppp_api.c
code/sdk/zhihui/ppp/src/ppp_interrupt.c [new file with mode: 0644]
code/sdk/zhihui/ppp/src/ppp_lwip.c
code/sdk/zhihui/ppp/src/ppp_lwip_thread.c
code/sdk/zhihui/ppp/src/ppp_serial.c
code/sdk/zhihui/tcptest/include/zhihui_tcp_test.h
code/sdk/zhihui/tcptest/src/zhihui_tcp_test.c

index f48813e..0ec4bb5 100644 (file)
@@ -55,9 +55,16 @@ extern "C" {
 #ifndef LWIP_DISABLE_TCP_SANITY_CHECKS
 #define LWIP_DISABLE_TCP_SANITY_CHECKS  1
 #endif
-#define LWIP_DEBUG              0
-#define LWIP_DBG_TYPES_ON       LWIP_DBG_OFF
-#define SOCKETS_DEBUG           LWIP_DBG_OFF 
+
+#if 0
+#define LWIP_DEBUG                      LWIP_DBG_ON
+#define LWIP_DBG_TYPES_ON               LWIP_DBG_ON
+#define SOCKETS_DEBUG                   LWIP_DBG_ON 
+#define TCP_DEBUG                       LWIP_DBG_ON
+#define TCP_INPUT_DEBUG                 LWIP_DBG_ON
+#define TCP_OUTPUT_DEBUG                LWIP_DBG_ON
+#define TCP_INPKT_DEBUG                 LWIP_DBG_ON
+#endif
 
 #ifndef LWIP_SLIP
 #define LWIP_SLIP 0
@@ -136,6 +143,17 @@ extern "C" {
 #define PPP_INPROC_IRQ_SAFE 0
 #endif
 
+/* PPP MRU配置控制 - 用于防止发送分片 */
+#ifndef PPP_ENABLE_LARGE_MRU
+#define PPP_ENABLE_LARGE_MRU        0                   // 0=禁用1500字节MRU(防止分片), 1=启用1500字节MRU
+#endif
+
+#if PPP_ENABLE_LARGE_MRU
+#define PPP_MRU_SIZE                1500                // PPP MRU大小 - 启用大MRU
+#else
+#define PPP_MRU_SIZE                1500                 // PPP MRU大小 - 限制为128字节防止分片
+#endif
+
 #elif defined(SLIP_MODULE_ENABLED) && !defined(PPP_MODULE_ENABLED)
 /* SLIP模式配置 */
 #ifndef LWIP_SLIP
@@ -1342,11 +1360,11 @@ extern "C" {
  * debug messages of certain types.
  */
 #ifndef LWIP_DBG_TYPES_ON
-#define LWIP_DBG_TYPES_ON               LWIP_DBG_OFF
+#define LWIP_DBG_TYPES_ON               LWIP_DBG_ON
 #endif
 
 #ifndef IP_DEBUG
-#define IP_DEBUG                        LWIP_DBG_OFF
+#define IP_DEBUG                        LWIP_DBG_ON
 #endif
 
 #ifndef ETHARP_DEBUG
@@ -1354,7 +1372,7 @@ extern "C" {
 #endif
 
 #ifndef NETIF_DEBUG
-#define NETIF_DEBUG                     LWIP_DBG_OFF
+#define NETIF_DEBUG                     LWIP_DBG_ON
 #endif
 
 #ifndef L3_EVENT_MSG_DEBUG
@@ -2122,7 +2140,7 @@ upto 255 interfaces . New versions donot have these restrictions but we stick to
  * messages are written.
  */
 #ifndef LWIP_DBG_MIN_LEVEL
-#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_OFF
+#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_ALL
 #endif
 
 #ifndef LWIP_SOCKET_POLL
index 36ee4f9..1a1c6bd 100644 (file)
@@ -49,7 +49,7 @@ extern "C" {
 #define LOG_ERR       (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE)
 #define LOG_NOTICE    (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING)
 #define LOG_WARNING   (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING)
-#define LOG_INFO      (PPP_DEBUG)
+#define LOG_INFO      (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING)
 #define LOG_DETAIL    (PPP_DEBUG)
 #define LOG_DEBUG     (PPP_DEBUG)
 
index cc4caa5..4ac37f2 100644 (file)
@@ -28,63 +28,9 @@ int httpc_get_file_dns_to_disk(const char *url, const char *file_path, int timeo
     return -1;
 }
 #endif
-/**
- * @brief AI流式录音发送桩函数
- * @param data 音频数据
- * @param len 数据长度
- * @param session_id 会话ID
- * @return 总是返回失败(-1)
- */
-int streamingRecordAndSend_AI(void *data, int len, const char *session_id)
-{
-    (void)data;
-    (void)len;
-    (void)session_id;
-    
-    // 桩函数 - 不实现实际功能
-    return -1;
-}
 
-/**
- * @brief AI消息队列发送桩函数
- * @param msg_data 消息数据
- * @param data_len 数据长度
- * @param type 消息类型
- * @return 总是返回失败(-1)
- */
-int send_msg_data_into_Ai_msg_queue(void *msg_data, uint16_t data_len, uint16_t type)
-{
-    (void)msg_data;
-    (void)data_len;
-    (void)type;
-    
-    // 桩函数 - 不实现实际功能
-    return -1;
-}
 
-/**
- * @brief 蓝牙设置AI回答字符串桩函数
- * @param answer_str AI回答字符串
- * @param type 消息类型
- */
-void ble_set_ai_Answer_str(char *answer_str, uint8_t type)
-{
-    (void)answer_str;
-    (void)type;
-    
-    // 桩函数 - 不实现实际功能
-}
 
-/**
- * @brief 蓝牙设置AI问题字符串桩函数
- * @param question_str AI问题字符串
- */
-void ble_set_ai_Question_str(char *question_str)
-{
-    (void)question_str;
-    
-    // 桩函数 - 不实现实际功能
-}
 
 #ifdef SUPPORT_CAT1_SERVICE
 
index bd03b93..8095031 100644 (file)
@@ -13,15 +13,16 @@ set(PPP_AT_CMD_SOURCE
 )
 # 源文件列表
 set(SOURCES
-    src/ppp_api.c
-    src/ppp_at_handler.c
-    src/ppp_serial.c
-    src/ppp_lwip.c
-    src/ppp_lwip_thread.c
-    src/ppp_debug.c
-    src/ppp_debug_manager.c
-    src/ppp_power_ctl.c
-    src/ppp_cat1_api.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ppp_api.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ppp_at_handler.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ppp_serial.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ppp_lwip.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ppp_lwip_thread.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ppp_debug.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ppp_debug_manager.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ppp_power_ctl.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ppp_cat1_api.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ppp_interrupt.c
     ${PPP_AT_CMD_SOURCE}
 )
 
@@ -62,7 +63,7 @@ set(PUBLIC_DEFINES
     PPP_USE_PBUF_RAM=1
     PPP_FCS_TABLE=1
     PRINTPKT_SUPPORT=1
-    PPP_DEBUG=LWIP_DBG_ON
+    PPP_DEBUG=0x80U
     PPP_INPROC_IRQ_SAFE=0
     # 添加IPCP相关配置
     IPCP_SUPPORT=1
@@ -70,7 +71,7 @@ set(PUBLIC_DEFINES
     LWIP_DNS=1
     DNS_TABLE_SIZE=2
     # 启用IPCP调试
-    IPCP_DEBUG=LWIP_DBG_ON
+    IPCP_DEBUG=0x80U
     # 确保IPCP功能完全启用
     PPP_IPV4_SUPPORT=1
     # 启用LCP相关功能
index 8442a88..e8aff5d 100644 (file)
@@ -1796,7 +1796,7 @@ static errcode_t at_ppp_tcp_performance_test(uint8_t *para, uint32_t paraLen)
     config.test_duration = (uint32_t)test_time;
     config.connection_count = (uint16_t)connections;
     config.verbose = true; // AT命令模式不使用详细输出
-    config.send_interval_ms = 100; // 100ms间隔,适合AT命令模式
+    config.send_interval_ms = 500; // 500ms间隔,给其他进程更多CPU时间
     config.data_min_size = 1024;    // 较小的数据包
     config.data_max_size = 4096;  // 适中的最大包
     config.recv_timeout_ms = (uint32_t)recv_timeout_ms; // 可配置的接收超时
index d4c15cf..1bad803 100644 (file)
@@ -49,6 +49,23 @@ extern "C" {
 #define PPP_DIAL_RETRY_COUNT        3                   // 拨号重试次数
 #define PPP_KEEPALIVE_INTERVAL      30                  // 保活间隔(秒)
 
+/* PPP接收模式配置 */
+#ifndef PPP_USE_INTERRUPT_MODE
+#define PPP_USE_INTERRUPT_MODE      1                   // 1=中断模式(UART中断接收), 0=轮询模式(线程轮询)
+#endif
+
+/* PPP线程模式配置(仅轮询模式有效) */
+#ifndef PPP_USE_DUAL_THREAD
+#define PPP_USE_DUAL_THREAD         1                   // 1=双线程模式(接收+处理), 0=单线程模式(接收直接处理)
+#endif
+
+/* PPP性能优化配置 - 解决接收阻塞问题 */
+#define PPP_LWIP_PBUF_POOL_SIZE     32                  // 增加pbuf池大小,默认16太小
+#define PPP_LWIP_TCPIP_MSG_INPKT    64                  // 增加输入消息数量,默认32太小
+#define PPP_LWIP_TCPIP_MBOX_SIZE    128                 // 增加TCPIP邮箱大小,默认64太小
+#define PPP_LWIP_TCP_RECVMBOX_SIZE  256                 // 增加TCP接收邮箱大小,默认128太小
+#define PPP_LWIP_TCP_WND_SIZE       65536               // 增加TCP接收窗口,默认32KB太小
+
 /* 缓冲区大小配置 */
 #define PPP_RX_BUFFER_SIZE          2048                // 接收缓冲区大小
 #define PPP_TX_BUFFER_SIZE          2048                // 发送缓冲区大小
@@ -57,10 +74,6 @@ extern "C" {
 #define PPP_RX_THREAD_STACK_SIZE        4096                // 接收线程栈大小
 #define PPP_RX_THREAD_PRIORITY          osPriorityNormal    // 接收线程优先级
 
-/* PPP网络配置 */
-#define PPP_MTU_SIZE                1500                // PPP MTU大小
-#define PPP_MRU_SIZE                1500                // PPP MRU大小
-
 /* 调试配置 */
 #define PPP_DEBUG_ENABLE            1                   // 启用调试输出
 #define PPP_DEBUG_LEVEL             PPP_DEBUG_LEVEL_INFO // 默认只显示警告和错误 (1=ERROR, 2=WARN, 3=INFO, 4=DEBUG)
diff --git a/code/sdk/zhihui/ppp/include/ppp_interrupt.h b/code/sdk/zhihui/ppp/include/ppp_interrupt.h
new file mode 100644 (file)
index 0000000..19bdd8f
--- /dev/null
@@ -0,0 +1,93 @@
+/**
+ * @file ppp_interrupt.h
+ * @brief PPP UART中断接收处理头文件
+ */
+
+#ifndef PPP_INTERRUPT_H
+#define PPP_INTERRUPT_H
+
+#include "ppp_types.h"
+#include "uart.h"
+#include "pinctrl.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief PPP中断统计信息
+ */
+typedef struct {
+    uint32_t total_interrupts;           // 总中断次数
+    uint32_t success_count;              // 成功处理次数
+    uint32_t error_count;                // 错误次数
+    uint32_t lwip_error_count;           // lwIP错误次数
+    
+    uint32_t total_bytes_received;       // 总接收字节数
+    uint32_t total_bytes_sent_to_lwip;   // 发送到lwIP的字节数
+    
+    uint32_t dropped_not_initialized;    // 因PPP未初始化丢弃的字节数
+    uint32_t dropped_lwip_error;         // 因lwIP错误丢弃的字节数
+} ppp_interrupt_stats_t;
+
+/**
+ * @brief UART接收中断回调函数(由UART驱动调用)
+ * @param buffer 接收数据缓冲区
+ * @param length 数据长度
+ * @param error 是否有错误
+ */
+void ppp_uart_rx_interrupt_handler(const void *buffer, uint16_t length, bool error);
+
+/**
+ * @brief 获取UART硬件缓冲区配置(供外部UART初始化使用)
+ * @param rx_buffer 返回接收缓冲区指针
+ * @param buffer_size 返回缓冲区大小
+ */
+void ppp_interrupt_get_buffer_config(void **rx_buffer, uint32_t *buffer_size);
+
+/**
+ * @brief 启用PPP UART中断接收
+ * @return PPP_ERR_OK 成功,其他值失败
+ * 
+ * @note 调用此函数前:
+ *       1. ppp_serial必须已初始化(UART总线号从ppp_serial_get_uart_bus()获取)
+ *       2. UART必须已经初始化并配置了硬件缓冲区
+ *       3. 使用 ppp_interrupt_get_buffer_config() 获取缓冲区配置
+ */
+ppp_error_t ppp_interrupt_enable(void);
+
+/**
+ * @brief 禁用PPP UART中断接收
+ * @return PPP_ERR_OK 成功,其他值失败
+ */
+ppp_error_t ppp_interrupt_disable(void);
+
+/**
+ * @brief 检查中断是否已启用
+ * @return true 已启用,false 未启用
+ */
+bool ppp_interrupt_is_enabled(void);
+
+/**
+ * @brief 获取中断统计信息
+ * @param stats 统计信息输出缓冲区
+ */
+void ppp_interrupt_get_stats(ppp_interrupt_stats_t *stats);
+
+/**
+ * @brief 重置中断统计信息
+ */
+void ppp_interrupt_reset_stats(void);
+
+/**
+ * @brief 打印中断统计信息
+ */
+void ppp_interrupt_print_stats(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPP_INTERRUPT_H */ 
\ No newline at end of file
index 8c91bd8..40acb8e 100644 (file)
@@ -159,6 +159,23 @@ ppp_error_t ppp_lwip_trigger_keepalive(void);
  */
 ppp_error_t ppp_lwip_get_output_stats(ppp_lwip_output_stats_t *stats);
 
+// /**
+//  * @brief 获取PPP控制块(供中断处理模块使用)
+//  * @return PPP控制块指针,如果未初始化则返回NULL
+//  */
+// ppp_pcb* ppp_lwip_get_pcb(void);
+
+/**
+ * @brief 检查PPP lwIP是否已初始化(供中断处理模块使用)
+ * @return true 已初始化,false 未初始化
+ */
+bool ppp_lwip_is_initialized(void);
+
+/**
+ * @brief 打印lwIP内存使用情况(用于诊断)
+ */
+void ppp_lwip_print_memory_stats(void);
+
 #ifdef __cplusplus
 }
 #endif
index 8763396..2d7f2b5 100644 (file)
@@ -99,6 +99,15 @@ ppp_error_t ppp_serial_write(const uint8_t *data, uint32_t length);
  */
 ppp_error_t ppp_serial_read(uint8_t *buffer, uint32_t buffer_size, uint32_t *bytes_read);
 
+/**
+ * @brief PPP快速尝试读取 - 类似SLIP的sio_tryread,使用1ms超时
+ * @param buffer 接收缓冲区
+ * @param buffer_size 缓冲区大小
+ * @param bytes_read 实际读取字节数
+ * @return 错误码
+ */
+ppp_error_t ppp_serial_tryread(uint8_t *buffer, uint32_t buffer_size, uint32_t *bytes_read);
+
 /**
  * @brief 等待数据接收
  * @param timeout_ms 超时时间(毫秒)
@@ -150,8 +159,33 @@ ppp_error_t ppp_serial_set_rx_callback(ppp_serial_rx_callback_t callback, void *
 
 /**
  * @brief 获取串口统计信息
+ * @param stats 统计信息结构指针
+ * @return 错误码
+ */
+ppp_error_t ppp_serial_get_stats(ppp_serial_stats_t *stats);
+
+/**
+ * @brief 获取UART总线号
+ * @return UART总线号,如果未初始化返回UART_BUS_0
+ */
+uint8_t ppp_serial_get_uart_bus(void);
+
+/**
+ * @brief PPP中断接收回调函数 - 用于高效数据接收
+ * @param buffer 接收到的数据缓冲区
+ * @param length 数据长度
+ * @param error 是否有错误
+ * @note 此函数应该在UART中断回调中调用,类似SLIP的uart_read_data_int_handler
+ */
+void ppp_uart_rx_interrupt_handler(const void *buffer, uint16_t length, bool error);
+
+/**
+ * @brief 获取中断接收队列统计信息
+ * @param queue_count 队列中的数据块数量
+ * @param bytes_queued 队列中的字节数
+ * @param chunks_dropped 丢弃的数据块数量
  */
-uint32_t ppp_serial_get_stats(ppp_serial_stats_t *stats);
+void ppp_get_interrupt_rx_stats(uint32_t *queue_count, uint32_t *bytes_queued, uint32_t *chunks_dropped);
 
 /**
  * @brief 重置串口状态
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/performance_test.c b/code/sdk/zhihui/ppp/ppp_dec_test/performance_test.c
new file mode 100644 (file)
index 0000000..64972aa
--- /dev/null
@@ -0,0 +1,318 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "ppp_parser.h"
+#include "ppp_packet_analyzer.h"
+#include "ppp_stream_parser.h"
+
+/* 配置常量 */
+#define MAX_FILE_SIZE           (1024 * 1024)  /* 最大文件大小1MB */
+#define MAX_FRAMES              10000          /* 最大帧数量 */
+#define CHUNK_SIZE              256            /* 流式处理块大小 */
+
+/* 全局变量 */
+static uint8_t g_hex_data[MAX_FILE_SIZE];      /* 十六进制数据缓冲区 */
+static ppp_frame_t g_frames[MAX_FRAMES];       /* PPP帧数组 */
+static packet_analysis_result_t g_results[MAX_FRAMES]; /* 分析结果数组 */
+
+/**
+ * 获取当前时间(微秒)
+ */
+static uint64_t get_time_us(void)
+{
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
+}
+
+/**
+ * 从十六进制字符串转换为字节值
+ */
+static int hex_char_to_byte(char hex_char)
+{
+    if (hex_char >= '0' && hex_char <= '9') {
+        return hex_char - '0';
+    } else if (hex_char >= 'A' && hex_char <= 'F') {
+        return hex_char - 'A' + 10;
+    } else if (hex_char >= 'a' && hex_char <= 'f') {
+        return hex_char - 'a' + 10;
+    }
+    return -1;
+}
+
+/**
+ * 从文件中读取十六进制数据
+ */
+static uint32_t read_hex_file(const char *file_path, uint8_t *data, uint32_t max_size)
+{
+    if (!file_path || !data || max_size == 0) {
+        return 0;
+    }
+    
+    FILE *file = fopen(file_path, "r");
+    if (!file) {
+        printf("错误: 无法打开文件 %s: %s\n", file_path, strerror(errno));
+        return 0;
+    }
+    
+    char line[256];
+    uint32_t data_len = 0;
+    
+    while (fgets(line, sizeof(line), file) && data_len < max_size) {
+        /* 移除行尾的换行符和空白字符 */
+        char *end = line + strlen(line) - 1;
+        while (end >= line && isspace(*end)) {
+            *end-- = '\0';
+        }
+        
+        /* 跳过空行 */
+        if (strlen(line) == 0) {
+            continue;
+        }
+        
+        /* 处理每行的十六进制字符串 */
+        char *ptr = line;
+        while (*ptr && data_len < max_size) {
+            /* 跳过空白字符 */
+            while (*ptr && isspace(*ptr)) {
+                ptr++;
+            }
+            
+            if (!*ptr) break;
+            
+            /* 读取两个十六进制字符组成一个字节 */
+            if (strlen(ptr) >= 2) {
+                int high = hex_char_to_byte(ptr[0]);
+                int low = hex_char_to_byte(ptr[1]);
+                
+                if (high >= 0 && low >= 0) {
+                    data[data_len++] = (high << 4) | low;
+                    ptr += 2;
+                } else {
+                    ptr += 2;
+                }
+            } else if (strlen(ptr) == 1) {
+                /* 单个十六进制字符,当作一个字节处理 */
+                int value = hex_char_to_byte(ptr[0]);
+                if (value >= 0) {
+                    data[data_len++] = value;
+                    ptr++;
+                } else {
+                    ptr++;
+                }
+            }
+        }
+    }
+    
+    fclose(file);
+    return data_len;
+}
+
+/**
+ * 传统解析器性能测试
+ */
+static void test_traditional_parser(const char *file_path, uint32_t data_len)
+{
+    printf("\n=== 传统解析器性能测试 ===\n");
+    
+    uint64_t start_time = get_time_us();
+    
+    /* 初始化解析器 */
+    ppp_parser_t parser;
+    ppp_parser_init(&parser);
+    
+    uint64_t init_time = get_time_us();
+    
+    /* 解析PPP帧 */
+    uint32_t frame_count = ppp_parser_process_data(&parser, g_hex_data, data_len, 
+                                                  g_frames, MAX_FRAMES);
+    
+    uint64_t parse_time = get_time_us();
+    
+    /* 包内容分析 */
+    packet_stats_t packet_stats;
+    uint32_t analyzed_count = analyze_ppp_frames(g_frames, frame_count, 
+                                                g_results, &packet_stats);
+    
+    uint64_t analyze_time = get_time_us();
+    
+    /* 打印性能统计 */
+    printf("文件: %s\n", file_path);
+    printf("数据大小: %u 字节\n", data_len);
+    printf("解析帧数: %u\n", frame_count);
+    printf("分析帧数: %u\n", analyzed_count);
+    printf("时间统计:\n");
+    printf("  初始化时间: %lu 微秒\n", init_time - start_time);
+    printf("  解析时间: %lu 微秒\n", parse_time - init_time);
+    printf("  分析时间: %lu 微秒\n", analyze_time - parse_time);
+    printf("  总时间: %lu 微秒\n", analyze_time - start_time);
+    printf("性能指标:\n");
+    printf("  解析速度: %.2f MB/s\n", 
+           (double)data_len / (parse_time - init_time) * 1000000 / (1024 * 1024));
+    printf("  分析速度: %.2f 帧/秒\n", 
+           (double)frame_count / (analyze_time - parse_time) * 1000000);
+    printf("  总体速度: %.2f MB/s\n", 
+           (double)data_len / (analyze_time - start_time) * 1000000 / (1024 * 1024));
+    
+    /* 内存使用估算 */
+    size_t memory_usage = sizeof(ppp_parser_t) + 
+                         sizeof(ppp_frame_t) * MAX_FRAMES + 
+                         sizeof(packet_analysis_result_t) * MAX_FRAMES;
+    printf("内存使用: %.2f KB (估算)\n", (double)memory_usage / 1024);
+}
+
+/**
+ * 流式解析器性能测试
+ */
+static void test_streaming_parser(const char *file_path, uint32_t data_len)
+{
+    printf("\n=== 流式解析器性能测试 ===\n");
+    
+    uint64_t start_time = get_time_us();
+    
+    /* 初始化帧收集器 */
+    ppp_frame_collector_t collector;
+    if (!ppp_frame_collector_init(&collector, MAX_FRAMES)) {
+        printf("错误: 无法初始化帧收集器\n");
+        return;
+    }
+    
+    /* 初始化流式解析器 */
+    ppp_stream_parser_t parser;
+    if (!ppp_stream_parser_init(&parser, 
+                               0,  /* 使用默认最大帧大小 */
+                               ppp_collector_start_callback,
+                               ppp_collector_data_callback,
+                               ppp_collector_complete_callback,
+                               ppp_collector_error_callback,
+                               &collector)) {
+        printf("错误: 无法初始化流式解析器\n");
+        ppp_frame_collector_free(&collector);
+        return;
+    }
+    
+    uint64_t init_time = get_time_us();
+    
+    /* 分块处理数据 */
+    uint32_t total_processed = 0;
+    uint32_t chunk_count = 0;
+    
+    for (uint32_t offset = 0; offset < data_len; offset += CHUNK_SIZE) {
+        uint32_t chunk_size = (offset + CHUNK_SIZE > data_len) ? 
+                             (data_len - offset) : CHUNK_SIZE;
+        
+        chunk_count++;
+        uint32_t processed = ppp_stream_parser_process(&parser, 
+                                                      g_hex_data + offset, 
+                                                      chunk_size);
+        total_processed += processed;
+    }
+    
+    uint64_t parse_time = get_time_us();
+    
+    /* 分析收集到的帧 */
+    uint32_t analyzed_count = 0;
+    for (uint32_t i = 0; i < collector.frame_count; i++) {
+        const uint8_t *frame_data;
+        uint32_t frame_len;
+        
+        if (ppp_frame_collector_get_frame(&collector, i, &frame_data, &frame_len)) {
+            ppp_frame_t temp_frame;
+            temp_frame.payload_len = frame_len;
+            memcpy(temp_frame.payload, frame_data, 
+                   (frame_len > PPP_MAX_FRAME_SIZE) ? PPP_MAX_FRAME_SIZE : frame_len);
+            
+            packet_analysis_result_t result;
+            if (analyze_ppp_frame(&temp_frame, &result)) {
+                analyzed_count++;
+            }
+        }
+    }
+    
+    uint64_t analyze_time = get_time_us();
+    
+    /* 打印性能统计 */
+    printf("文件: %s\n", file_path);
+    printf("数据大小: %u 字节\n", data_len);
+    printf("处理块数: %u (块大小: %d 字节)\n", chunk_count, CHUNK_SIZE);
+    printf("解析帧数: %u\n", collector.frame_count);
+    printf("分析帧数: %u\n", analyzed_count);
+    printf("时间统计:\n");
+    printf("  初始化时间: %lu 微秒\n", init_time - start_time);
+    printf("  解析时间: %lu 微秒\n", parse_time - init_time);
+    printf("  分析时间: %lu 微秒\n", analyze_time - parse_time);
+    printf("  总时间: %lu 微秒\n", analyze_time - start_time);
+    printf("性能指标:\n");
+    printf("  解析速度: %.2f MB/s\n", 
+           (double)data_len / (parse_time - init_time) * 1000000 / (1024 * 1024));
+    printf("  分析速度: %.2f 帧/秒\n", 
+           (double)collector.frame_count / (analyze_time - parse_time) * 1000000);
+    printf("  总体速度: %.2f MB/s\n", 
+           (double)data_len / (analyze_time - start_time) * 1000000 / (1024 * 1024));
+    
+    /* 内存使用估算 */
+    size_t base_memory = sizeof(ppp_stream_parser_t) + sizeof(ppp_frame_collector_t);
+    size_t dynamic_memory = 0;
+    for (uint32_t i = 0; i < collector.frame_count; i++) {
+        dynamic_memory += collector.frame_lengths[i];
+    }
+    printf("内存使用: %.2f KB (基础) + %.2f KB (动态) = %.2f KB (总计)\n", 
+           (double)base_memory / 1024, 
+           (double)dynamic_memory / 1024,
+           (double)(base_memory + dynamic_memory) / 1024);
+    
+    /* 清理资源 */
+    ppp_frame_collector_free(&collector);
+}
+
+/**
+ * 主函数
+ */
+int main(int argc, char *argv[])
+{
+    printf("PPP解析器性能测试工具\n");
+    printf("对比传统解析器和流式解析器的性能\n\n");
+    
+    /* 确定要测试的文件 */
+    const char *test_file = (argc > 1) ? argv[1] : "out0.txt";
+    
+    /* 读取测试数据 */
+    printf("读取测试文件: %s\n", test_file);
+    uint32_t data_len = read_hex_file(test_file, g_hex_data, MAX_FILE_SIZE);
+    if (data_len == 0) {
+        printf("错误: 无法读取测试文件\n");
+        return 1;
+    }
+    
+    printf("成功读取 %u 字节数据\n", data_len);
+    
+    /* 运行性能测试 */
+    test_traditional_parser(test_file, data_len);
+    test_streaming_parser(test_file, data_len);
+    
+    /* 打印对比总结 */
+    printf("\n=== 性能对比总结 ===\n");
+    printf("传统解析器特点:\n");
+    printf("  - 一次性加载所有数据到内存\n");
+    printf("  - 固定大小的缓冲区\n");
+    printf("  - 简单的线性处理\n");
+    printf("  - 内存使用可预测\n\n");
+    
+    printf("流式解析器特点:\n");
+    printf("  - 分块处理数据,内存占用固定\n");
+    printf("  - 支持任意大小的PPP帧\n");
+    printf("  - 回调机制,灵活的数据处理\n");
+    printf("  - 适合实时数据流处理\n");
+    printf("  - 动态内存分配,按需使用\n\n");
+    
+    printf("推荐使用场景:\n");
+    printf("  传统解析器: 小文件、批处理、内存充足\n");
+    printf("  流式解析器: 大文件、实时处理、内存受限、嵌入式系统\n");
+    
+    return 0;
+} 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/ppp_analyzer.py b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_analyzer.py
new file mode 100644 (file)
index 0000000..6d11c3a
--- /dev/null
@@ -0,0 +1,514 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+PPP协议解析工具
+用于解析out.txt和in.txt中的十六进制数据,识别TCP/UDP包并提取基本信息
+"""
+import struct
+import os
+import binascii
+
+class PPPFrameParser:
+    """PPP帧解析器,处理帧边界检测、字节填充和数据验证"""
+    def __init__(self):
+        self.buffer = bytearray()  # 帧数据缓冲区
+        self.in_frame = False      # 是否处于帧接收状态
+        self.dropped_data = []     # 记录丢弃的数据
+        self.last_dropped_position = -1  # 上一次丢弃数据的位置
+        self.fragmented_frames = {}  # 存储分片的PPP帧 {frame_id: fragmented_data}
+
+    def process_byte(self, byte, position=None):
+        """处理单个字节,返回完整PPP帧(包含头尾0x7E)"""
+        if byte == 0x7E:  # PPP帧标志位
+            if self.in_frame and len(self.buffer) > 0:
+                # 帧结束:添加结束标志并处理缓冲区数据
+                self.buffer.append(byte)  # 添加结束0x7E
+                frame = self._parse_buffer_with_flags()
+                self.buffer.clear()
+                self.in_frame = False
+                return frame
+            else:
+                # 帧开始:初始化缓冲区并添加开始标志
+                # 如果有未处理的缓冲区数据,记录为丢弃数据
+                if self.in_frame and len(self.buffer) > 0:
+                    self._record_dropped_data(self.buffer, position - len(self.buffer))
+                self.in_frame = True
+                self.buffer.clear()
+                self.buffer.append(byte)  # 添加开始0x7E
+        else:
+            if self.in_frame:
+                self.buffer.append(byte)
+        return None
+
+    def _parse_buffer_with_flags(self):
+        """处理包含头尾0x7E的完整PPP帧,返回原始帧数据"""
+        # 验证帧头尾标志
+        if len(self.buffer) < 6:  # 最小:0x7E + 地址1 + 控制1 + 协议2 + 0x7E = 6字节
+            self._record_dropped_data(self.buffer, None)
+            return None
+            
+        if self.buffer[0] != 0x7E or self.buffer[-1] != 0x7E:
+            self._record_dropped_data(self.buffer, None)
+            return None
+        
+        # 返回完整帧数据(包含头尾0x7E),转义字符处理将在分析阶段进行
+        return bytes(self.buffer)
+    
+    def _unescape_ppp_frame(self, frame_content):
+        """处理PPP转义字符,输入是去掉头尾0x7E的帧内容"""
+        processed = bytearray()
+        i = 0
+        while i < len(frame_content):
+            if frame_content[i] == 0x7D:  # 转义字符
+                if i + 1 < len(frame_content):
+                    processed.append(frame_content[i+1] ^ 0x20)
+                    i += 2
+                else:
+                    # 不完整的转义序列
+                    return None
+            else:
+                processed.append(frame_content[i])
+                i += 1
+        return processed
+
+    def _parse_buffer_simple(self):
+        """简化版缓冲区处理,只还原字节填充,不进行FCS校验"""
+        # 还原字节填充(0x7D后字节异或0x20)
+        processed = bytearray()
+        i = 0
+        while i < len(self.buffer):
+            if self.buffer[i] == 0x7D:  # 转义字符
+                if i + 1 < len(self.buffer):
+                    processed.append(self.buffer[i+1] ^ 0x20)
+                    i += 2
+                else:
+                    # 不完整的转义序列,记录为丢弃数据
+                    self.dropped_data.append({
+                        'reason': '不完整的转义序列',
+                        'data': bytes(self.buffer),
+                        'position': self.last_dropped_position
+                    })
+                    return None
+            else:
+                processed.append(self.buffer[i])
+                i += 1
+
+        # 校验帧长度(最小:地址1 + 控制1 + 协议2 = 4字节)
+        if len(processed) < 4:
+            # 帧长度不足,记录为丢弃数据
+            self.dropped_data.append({
+                'reason': '帧长度不足4字节',
+                'data': bytes(self.buffer),
+                'position': self.last_dropped_position
+            })
+            return None
+
+        # 返回处理后的数据
+        return processed
+
+    def _record_dropped_data(self, data, position):
+        """记录丢弃的数据"""
+        self.dropped_data.append({
+            'reason': '帧同步丢失或格式错误',
+            'data': bytes(data),
+            'position': position
+        })
+        self.last_dropped_position = position
+
+    def get_dropped_data_count(self):
+        """获取丢弃的数据数量"""
+        return len(self.dropped_data)
+
+    def print_dropped_data(self):
+        """打印所有丢弃的数据"""
+        if not self.dropped_data:
+            print("  没有丢弃的数据")
+            return
+        
+        print(f"  丢弃的数据总数: {len(self.dropped_data)}")
+        # 只打印前5条丢弃的数据,避免输出过多
+        for i, dropped in enumerate(self.dropped_data[:5]):
+            print(f"  丢弃数据 #{i+1}:")
+            print(f"    原因: {dropped['reason']}")
+            print(f"    位置: {dropped['position']}")
+            print(f"    数据: {dropped['data'].hex().upper()}")
+        
+        if len(self.dropped_data) > 5:
+            print(f"  ... 还有{len(self.dropped_data) - 5}条丢弃的数据未显示")
+
+    def reassemble_fragment(self, frame):
+        """尝试重组分片的PPP帧
+        在PPP中,分片是通过MP(多链路PPP)协议实现的,但这里我们使用简化的方式
+        实际应用中可能需要根据具体的PPP扩展协议实现更复杂的重组逻辑
+        """
+        # 这个简化版本假设所有帧都是完整的,不处理分片
+        # 如果需要处理实际的PPP分片,需要根据具体的PPP扩展协议实现
+        return frame
+
+    def get_fragmented_frame_count(self):
+        """获取当前缓存的分片帧数量"""
+        return len(self.fragmented_frames)
+
+
+def calculate_ip_checksum(ip_header):
+    """计算IP头部校验和"""
+    # 将IP头部视为16位字的序列
+    words = [struct.unpack('!H', ip_header[i:i+2])[0] for i in range(0, len(ip_header), 2)]
+    
+    # 如果头部长度为奇数,最后一个字节补零
+    if len(ip_header) % 2 == 1:
+        words.append(ip_header[-1] << 8)
+    
+    # 计算校验和
+    checksum = sum(words)
+    # 将溢出的部分加到低16位
+    checksum = (checksum >> 16) + (checksum & 0xffff)
+    checksum += (checksum >> 16)  # 再次处理溢出
+    # 取反得到最终校验和
+    return ~checksum & 0xffff
+
+
+def verify_ip_packet(ip_data):
+    """验证IP数据包的完整性和正确性"""
+    # 检查最小长度
+    if len(ip_data) < 20:
+        return False, "IP数据包长度不足20字节"
+    
+    # 验证版本号(应为4)
+    version = (ip_data[0] >> 4) & 0x0F
+    if version != 4:
+        return False, f"非IPv4数据包,版本号: {version}"
+    
+    # 验证头部长度
+    ihl = ip_data[0] & 0x0F
+    if ihl < 5 or ihl > 15:
+        return False, f"无效的IP头部长度: {ihl}"
+    
+    # 检查总长度是否合理
+    total_length = (ip_data[2] << 8) | ip_data[3]
+    # 允许实际长度比声明长度多2字节(可能是PPP填充)
+    if not (total_length == len(ip_data) or total_length == len(ip_data) - 2):
+        return False, f"IP数据包长度不匹配: 头部声明{total_length}字节,实际{len(ip_data)}字节"
+    
+    # 保存原始校验和
+    original_checksum = (ip_data[10] << 8) | ip_data[11]
+    
+    # 清零校验和字段后重新计算
+    ip_header_copy = bytearray(ip_data[:ihl*4])
+    ip_header_copy[10] = 0
+    ip_header_copy[11] = 0
+    
+    # 计算校验和
+    calculated_checksum = calculate_ip_checksum(ip_header_copy)
+    
+    # 验证校验和
+    if original_checksum != calculated_checksum:
+        return False, f"IP校验和错误: 接收{original_checksum:04X},计算{calculated_checksum:04X}"
+    
+    return True, "IP数据包验证通过"
+
+
+def parse_ip_packet(ip_data):
+    """解析IP数据包,提取基本信息"""
+    if len(ip_data) < 20:  # IP头部最小长度为20字节
+        return None
+    
+    # 解析IP头部(不考虑选项字段)
+    ip_header = struct.unpack('!BBHHHBBH4s4s', ip_data[:20])
+    version_ihl = ip_header[0]
+    protocol = ip_header[6]  # 协议类型
+    src_ip = '.'.join(map(str, ip_header[8]))  # 源IP地址
+    dst_ip = '.'.join(map(str, ip_header[9]))  # 目标IP地址
+    
+    # 计算IP数据部分的偏移量
+    ihl = (version_ihl & 0x0F) * 4
+    payload = ip_data[ihl:]
+    
+    result = {
+        'src_ip': src_ip,
+        'dst_ip': dst_ip,
+        'protocol': protocol
+    }
+    
+    # 根据协议类型解析传输层数据
+    if protocol == 6:  # TCP协议
+        result['protocol_name'] = 'TCP'
+        tcp_info = parse_tcp_packet(payload)
+        if tcp_info:
+            result.update(tcp_info)
+    elif protocol == 17:  # UDP协议
+        result['protocol_name'] = 'UDP'
+        udp_info = parse_udp_packet(payload)
+        if udp_info:
+            result.update(udp_info)
+    else:
+        result['protocol_name'] = f'Unknown({protocol})'
+    
+    return result
+
+def parse_tcp_packet(tcp_data):
+    """解析TCP数据包,提取端口信息"""
+    if len(tcp_data) < 20:  # TCP头部最小长度为20字节
+        return None
+    
+    # 解析TCP头部
+    tcp_header = struct.unpack('!HHLLBBHHH', tcp_data[:20])
+    src_port = tcp_header[0]  # 源端口
+    dst_port = tcp_header[1]  # 目标端口
+    
+    return {
+        'src_port': src_port,
+        'dst_port': dst_port
+    }
+
+def parse_udp_packet(udp_data):
+    """解析UDP数据包,提取端口信息"""
+    if len(udp_data) < 8:  # UDP头部固定为8字节
+        return None
+    
+    # 解析UDP头部
+    udp_header = struct.unpack('!HHHH', udp_data[:8])
+    src_port = udp_header[0]  # 源端口
+    dst_port = udp_header[1]  # 目标端口
+    
+    return {
+        'src_port': src_port,
+        'dst_port': dst_port
+    }
+
+def read_hex_file(file_path):
+    """从文件中读取十六进制数据"""
+    try:
+        with open(file_path, 'r', encoding='utf-8') as f:
+            lines = f.readlines()
+            # 移除每行的换行符并转换为字节
+            bytes_data = []
+            for i, line in enumerate(lines):
+                stripped_line = line.strip()
+                if stripped_line:
+                    try:
+                        # 转换十六进制字符串为整数
+                        byte_value = int(stripped_line, 16)
+                        if 0 <= byte_value <= 255:
+                            bytes_data.append(byte_value)
+                        else:
+                            print(f"警告: 文件{file_path}第{i+1}行值{stripped_line}超出字节范围")
+                    except ValueError:
+                        print(f"警告: 文件{file_path}第{i+1}行'{stripped_line}'不是有效的十六进制字符串")
+            print(f"成功读取文件{file_path}: {len(bytes_data)}字节")
+            return bytearray(bytes_data)
+    except Exception as e:
+        print(f"读取文件{file_path}错误: {e}")
+        return None
+
+
+def group_ppp_frames(frames):
+    """对PPP帧进行组包处理,目前主要是简单的收集,后续可以扩展更复杂的组包逻辑"""
+    # 按协议类型对帧进行分组
+    grouped_frames = {}
+    for frame in frames:
+        if len(frame) >= 4:
+            protocol = (frame[2] << 8) | frame[3]
+            if protocol not in grouped_frames:
+                grouped_frames[protocol] = []
+            grouped_frames[protocol].append(frame)
+        else:
+            # 帧长度不足,无法解析协议
+            if 'invalid' not in grouped_frames:
+                grouped_frames['invalid'] = []
+            grouped_frames['invalid'].append(frame)
+    
+    return grouped_frames
+
+def analyze_ppp_file(file_path):
+    """分析PPP文件并输出TCP/UDP包信息"""
+    print(f"\n开始分析文件: {file_path}")
+    
+    # 读取文件数据
+    data = read_hex_file(file_path)
+    if not data:
+        return
+    
+    parser = PPPFrameParser()
+    tcp_count = 0
+    udp_count = 0
+    other_count = 0
+    ppp_frame_count = 0
+    reassembled_count = 0  # 重组的帧数量
+    protocol_counts = {}
+    frames = []  # 存储所有解析出的PPP帧
+    ip_validation_results = []  # 存储IP帧验证结果
+    
+    # 处理每个字节
+    for i, byte in enumerate(data):
+        frame = parser.process_byte(byte, position=i)
+        if frame:
+            # frame现在包含完整PPP帧(包含头尾0x7E)
+            # 尝试重组分片帧(暂时跳过重组,直接处理单个帧)
+            raw_frame = frame  # 完整帧数据(包含头尾0x7E)
+            frames.append(raw_frame)
+            ppp_frame_count += 1
+            
+            # 打印PPP帧信息(显示完整帧长度)
+            print(f"PPP帧 #{ppp_frame_count}: 长度={len(raw_frame)}字节, 起始位置={i-len(raw_frame)+1}")
+            print(f"  内容: {raw_frame.hex().upper()}")
+            
+            # 验证帧头尾标志
+            if len(raw_frame) >= 6 and raw_frame[0] == 0x7E and raw_frame[-1] == 0x7E:
+                # 提取帧内容(去掉头尾0x7E)
+                frame_content = raw_frame[1:-1]
+                
+                # 处理转义字符
+                processed_frame = parser._unescape_ppp_frame(frame_content)
+                if processed_frame and len(processed_frame) >= 4:
+                    # 解析PPP头部
+                    address = processed_frame[0]
+                    control = processed_frame[1]
+                    # 协议字段是大端模式的两字节
+                    protocol = (processed_frame[2] << 8) | processed_frame[3]
+                    
+                    # 更新协议计数
+                    if protocol not in protocol_counts:
+                        protocol_counts[protocol] = 0
+                    protocol_counts[protocol] += 1
+                    
+                    payload = processed_frame[4:]
+                    
+                    print(f"  协议: 0x{protocol:04X}, 地址: 0x{address:02X}, 控制: 0x{control:02X}, 负载长度: {len(payload)}字节")
+                    
+                    # 检查是否为IP协议或其他常见PPP协议
+                    if protocol == 0x0021:  # IP协议
+                        # 验证IP数据包完整性
+                        is_valid, validation_msg = verify_ip_packet(payload)
+                        ip_validation_results.append({
+                            'frame_number': ppp_frame_count,
+                            'is_valid': is_valid,
+                            'message': validation_msg
+                        })
+                        
+                        print(f"  IP验证: {'通过' if is_valid else '失败'} - {validation_msg}")
+                        
+                        if is_valid:
+                            # 解析IP数据包
+                            ip_info = parse_ip_packet(payload)
+                            if ip_info:
+                                # 输出TCP/UDP包信息
+                                if ip_info['protocol'] == 6:  # TCP
+                                    tcp_count += 1
+                                    print(f"  TCP #{tcp_count}: {ip_info['src_ip']}:{ip_info['src_port']} -> {ip_info['dst_ip']}:{ip_info['dst_port']}")
+                                elif ip_info['protocol'] == 17:  # UDP
+                                    udp_count += 1
+                                    print(f"  UDP #{udp_count}: {ip_info['src_ip']}:{ip_info['src_port']} -> {ip_info['dst_ip']}:{ip_info['dst_port']}")
+                                else:
+                                    other_count += 1
+                            else:
+                                other_count += 1
+                        else:
+                            other_count += 1
+                    elif protocol == 0xC021:  # LCP协议
+                        # LCP协议不需要进一步分析
+                        print(f"  LCP协议帧")
+                    elif protocol == 0x8021:  # IPCP协议
+                        print(f"  IPCP协议帧")
+                    else:
+                        print(f"  其他PPP协议: 0x{protocol:04X}")
+                else:
+                    print(f"  警告: 帧长度不足4字节,无法解析PPP头部")
+    
+    # 打印PPP帧组包结果
+    if frames:
+        print(f"\nPPP帧组包结果:")
+        grouped_frames = group_ppp_frames(frames)
+        for proto, proto_frames in grouped_frames.items():
+            if proto == 'invalid':
+                print(f"  无效帧: {len(proto_frames)}个")
+            else:
+                protocol_name = "未知"
+                if proto == 0x0021:
+                    protocol_name = "IP (IPv4)"
+                elif proto == 0xC021:
+                    protocol_name = "LCP (链路控制协议)"
+                elif proto == 0x8021:
+                    protocol_name = "IPCP (IP控制协议)"
+                print(f"  0x{proto:04X} ({protocol_name}): {len(proto_frames)}个帧")
+        
+        # 验证组包结果是否正确
+        total_grouped = sum(len(frames) for frames in grouped_frames.values())
+        if total_grouped == len(frames):
+            print(f"  组包验证: 成功,所有{total_grouped}个帧都已正确分组")
+        else:
+            print(f"  组包验证: 警告,分组总数({total_grouped})与原始帧总数({len(frames)})不匹配")
+    
+    # 打印分片重组统计
+    fragmented_count = parser.get_fragmented_frame_count()
+    print(f"\nPPP帧分片重组统计:")
+    print(f"  解析的原始帧数量: {ppp_frame_count}")
+    print(f"  成功重组的帧数量: {reassembled_count}")
+    print(f"  当前缓存的分片数量: {fragmented_count}")
+    
+    # 打印IP帧验证统计
+    if ip_validation_results:
+        valid_ip_count = sum(1 for result in ip_validation_results if result['is_valid'])
+        print(f"\nIP帧验证统计:")
+        print(f"  总共验证IP帧: {len(ip_validation_results)}")
+        print(f"  验证通过: {valid_ip_count}")
+        print(f"  验证失败: {len(ip_validation_results) - valid_ip_count}")
+        
+        # 打印前几个验证失败的详细信息
+        failed_results = [r for r in ip_validation_results if not r['is_valid']][:3]
+        for result in failed_results:
+            print(f"  帧 #{result['frame_number']} 验证失败: {result['message']}")
+    
+    # 打印丢弃的数据信息
+    print(f"\n丢弃的数据信息:")
+    parser.print_dropped_data()
+    
+    # 打印协议统计信息
+    print(f"\n文件分析完成: {file_path}")
+    print(f"总共发现 PPP 帧: {ppp_frame_count}")
+    print(f"发现 TCP 包: {tcp_count}")
+    print(f"发现 UDP 包: {udp_count}")
+    print(f"其他/未知包: {other_count}")
+    
+    # 打印协议分布
+    print("\nPPP协议分布:")
+    for proto, count in sorted(protocol_counts.items()):
+        protocol_name = "未知"
+        if proto == 0x0021:
+            protocol_name = "IP (IPv4)"
+        elif proto == 0xC021:
+            protocol_name = "LCP (链路控制协议)"
+        elif proto == 0x8021:
+            protocol_name = "IPCP (IP控制协议)"
+        print(f"  0x{proto:04X} ({protocol_name}): {count}个帧")
+    
+
+def main():
+    """主函数"""
+    import sys
+    
+    # 检查是否有命令行参数指定要分析的文件
+    if len(sys.argv) > 1:
+        # 使用命令行参数中的文件列表
+        files_to_analyze = sys.argv[1:]
+    else:
+        # 默认分析out.txt和in.txt
+        files_to_analyze = ['out.txt', 'in.txt']
+    
+    # 遍历并分析每个文件
+    for file_name in files_to_analyze:
+        # 构建完整的文件路径
+        if os.path.isabs(file_name):
+            file_path = file_name
+        else:
+            file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), file_name)
+        
+        if os.path.exists(file_path):
+            print(f"\n=== 开始分析文件: {file_path} ===")
+            analyze_ppp_file(file_path)
+        else:
+            print(f"文件不存在: {file_path}")
+
+
+if __name__ == "__main__":
+    main()
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/ppp_file_reader.c b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_file_reader.c
new file mode 100644 (file)
index 0000000..ae01ea0
--- /dev/null
@@ -0,0 +1,330 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include "ppp_parser.h"
+#include "ppp_packet_analyzer.h"
+
+/* 配置常量 */
+#define MAX_FILE_SIZE           (1024 * 1024)  /* 最大文件大小1MB */
+#define MAX_FRAMES              1000           /* 最大帧数量 */
+#define MAX_RESULTS             1000           /* 最大分析结果数量 */
+#define HEX_BUFFER_SIZE         16384          /* 十六进制读取缓冲区大小 */
+#define MAX_LINE_LENGTH         256            /* 最大行长度 */
+
+/* 全局变量 */
+static uint8_t g_hex_data[MAX_FILE_SIZE];      /* 十六进制数据缓冲区 */
+static ppp_frame_t g_frames[MAX_FRAMES];       /* PPP帧数组 */
+static packet_analysis_result_t g_results[MAX_RESULTS]; /* 分析结果数组 */
+
+/**
+ * 从十六进制字符串转换为字节值
+ * @param hex_char 十六进制字符
+ * @return 字节值,失败返回-1
+ */
+static int hex_char_to_byte(char hex_char)
+{
+    if (hex_char >= '0' && hex_char <= '9') {
+        return hex_char - '0';
+    } else if (hex_char >= 'A' && hex_char <= 'F') {
+        return hex_char - 'A' + 10;
+    } else if (hex_char >= 'a' && hex_char <= 'f') {
+        return hex_char - 'a' + 10;
+    }
+    return -1;
+}
+
+/**
+ * 从文件中读取十六进制数据
+ * @param file_path 文件路径
+ * @param data 输出数据缓冲区
+ * @param max_size 最大数据大小
+ * @return 实际读取的字节数,失败返回0
+ */
+static uint32_t read_hex_file(const char *file_path, uint8_t *data, uint32_t max_size)
+{
+    if (!file_path || !data || max_size == 0) {
+        printf("错误: 无效的参数\n");
+        return 0;
+    }
+    
+    FILE *file = fopen(file_path, "r");
+    if (!file) {
+        printf("错误: 无法打开文件 %s: %s\n", file_path, strerror(errno));
+        return 0;
+    }
+    
+    char line[MAX_LINE_LENGTH];
+    uint32_t data_len = 0;
+    uint32_t line_number = 0;
+    
+    printf("开始读取文件: %s\n", file_path);
+    
+    while (fgets(line, sizeof(line), file) && data_len < max_size) {
+        line_number++;
+        
+        /* 移除行尾的换行符和空白字符 */
+        char *end = line + strlen(line) - 1;
+        while (end >= line && isspace(*end)) {
+            *end-- = '\0';
+        }
+        
+        /* 跳过空行 */
+        if (strlen(line) == 0) {
+            continue;
+        }
+        
+        /* 处理每行的十六进制字符串 */
+        char *ptr = line;
+        while (*ptr && data_len < max_size) {
+            /* 跳过空白字符 */
+            while (*ptr && isspace(*ptr)) {
+                ptr++;
+            }
+            
+            if (!*ptr) break;
+            
+            /* 读取两个十六进制字符组成一个字节 */
+            if (strlen(ptr) >= 2) {
+                int high = hex_char_to_byte(ptr[0]);
+                int low = hex_char_to_byte(ptr[1]);
+                
+                if (high >= 0 && low >= 0) {
+                    data[data_len++] = (high << 4) | low;
+                    ptr += 2;
+                } else {
+                    printf("警告: 文件%s第%u行包含无效的十六进制字符: %c%c\n", 
+                           file_path, line_number, ptr[0], ptr[1]);
+                    ptr += 2;
+                }
+            } else if (strlen(ptr) == 1) {
+                /* 单个十六进制字符,当作一个字节处理 */
+                int value = hex_char_to_byte(ptr[0]);
+                if (value >= 0) {
+                    data[data_len++] = value;
+                    ptr++;
+                } else {
+                    printf("警告: 文件%s第%u行包含无效的十六进制字符: %c\n", 
+                           file_path, line_number, ptr[0]);
+                    ptr++;
+                }
+            }
+        }
+    }
+    
+    fclose(file);
+    
+    if (data_len >= max_size) {
+        printf("警告: 文件%s数据量超过缓冲区大小,只读取了前%u字节\n", file_path, max_size);
+    }
+    
+    printf("成功读取文件%s: %u字节\n", file_path, data_len);
+    return data_len;
+}
+
+/**
+ * 分析PPP文件并输出详细信息
+ * @param file_path 文件路径
+ */
+static void analyze_ppp_file(const char *file_path)
+{
+    printf("\n=== 开始分析文件: %s ===\n", file_path);
+    
+    /* 读取文件数据 */
+    uint32_t data_len = read_hex_file(file_path, g_hex_data, MAX_FILE_SIZE);
+    if (data_len == 0) {
+        printf("文件读取失败,跳过分析\n");
+        return;
+    }
+    
+    /* 初始化PPP解析器 */
+    ppp_parser_t parser;
+    ppp_parser_init(&parser);
+    
+    /* 解析PPP帧 */
+    printf("\n--- PPP帧解析阶段 ---\n");
+    uint32_t frame_count = ppp_parser_process_data(&parser, g_hex_data, data_len, 
+                                                  g_frames, MAX_FRAMES);
+    
+    printf("解析完成,共发现 %u 个PPP帧\n", frame_count);
+    
+    /* 打印解析器统计信息 */
+    ppp_parser_print_stats(&parser);
+    ppp_parser_print_dropped_data(&parser);
+    
+    if (frame_count == 0) {
+        printf("未发现有效的PPP帧\n");
+        return;
+    }
+    
+    /* 打印前几个PPP帧的详细信息 */
+    printf("\n--- PPP帧详细信息 ---\n");
+    uint32_t print_count = (frame_count > 5) ? 5 : frame_count;
+    for (uint32_t i = 0; i < print_count; i++) {
+        ppp_print_frame_info(&g_frames[i], i + 1);
+    }
+    
+    if (frame_count > 5) {
+        printf("... 还有%u个帧未显示详细信息\n", frame_count - 5);
+    }
+    
+    /* 包内容分析 */
+    printf("\n--- 包内容分析阶段 ---\n");
+    packet_stats_t packet_stats;
+    uint32_t analyzed_count = analyze_ppp_frames(g_frames, frame_count, 
+                                               g_results, &packet_stats);
+    
+    /* PPP帧组包分析(在analyzer处理后进行,这样协议信息已经解析) */
+    printf("\n--- PPP帧组包分析 ---\n");
+    ppp_group_result_t group_result;
+    ppp_classify_frames(g_frames, frame_count, &group_result);
+    ppp_print_group_result(&group_result);
+    
+    printf("包分析完成,成功分析 %u 个包\n", analyzed_count);
+    
+    /* 打印包统计信息 */
+    print_packet_stats(&packet_stats);
+    
+    /* 打印前几个包的详细分析结果 */
+    printf("\n--- 包详细分析结果 ---\n");
+    uint32_t detail_count = (analyzed_count > 3) ? 3 : analyzed_count;
+    for (uint32_t i = 0; i < detail_count; i++) {
+        if (g_results[i].has_ip) {
+            print_packet_analysis_result(&g_results[i], i + 1);
+        }
+    }
+    
+    if (analyzed_count > 3) {
+        printf("... 还有%u个包未显示详细分析结果\n", analyzed_count - 3);
+    }
+    
+    /* 简化的TCP/UDP包统计输出 */
+    printf("\n--- TCP/UDP包简要统计 ---\n");
+    uint32_t tcp_count = 0, udp_count = 0;
+    for (uint32_t i = 0; i < analyzed_count; i++) {
+        if (g_results[i].has_tcp) {
+            tcp_count++;
+            if (tcp_count <= 10) {  /* 只显示前10个 */
+                char src_ip[16], dst_ip[16];
+                format_ip_address(&g_results[i].ip_info.src_ip, src_ip, sizeof(src_ip));
+                format_ip_address(&g_results[i].ip_info.dst_ip, dst_ip, sizeof(dst_ip));
+                printf("  TCP #%u: %s:%u -> %s:%u\n", tcp_count,
+                       src_ip, g_results[i].tcp_info.src_port,
+                       dst_ip, g_results[i].tcp_info.dst_port);
+            }
+        } else if (g_results[i].has_udp) {
+            udp_count++;
+            if (udp_count <= 10) {  /* 只显示前10个 */
+                char src_ip[16], dst_ip[16];
+                format_ip_address(&g_results[i].ip_info.src_ip, src_ip, sizeof(src_ip));
+                format_ip_address(&g_results[i].ip_info.dst_ip, dst_ip, sizeof(dst_ip));
+                printf("  UDP #%u: %s:%u -> %s:%u\n", udp_count,
+                       src_ip, g_results[i].udp_info.src_port,
+                       dst_ip, g_results[i].udp_info.dst_port);
+            }
+        }
+    }
+    
+    if (tcp_count > 10) {
+        printf("  ... 还有%u个TCP包未显示\n", tcp_count - 10);
+    }
+    if (udp_count > 10) {
+        printf("  ... 还有%u个UDP包未显示\n", udp_count - 10);
+    }
+    
+    printf("\n=== 文件分析完成: %s ===\n", file_path);
+    printf("总结: 发现PPP帧%u个, TCP包%u个, UDP包%u个, 其他包%u个\n", 
+           frame_count, packet_stats.tcp_packets, packet_stats.udp_packets, 
+           packet_stats.other_packets);
+}
+
+/**
+ * 打印使用说明
+ */
+static void print_usage(const char *program_name)
+{
+    printf("PPP协议解析工具 (C语言版本)\n");
+    printf("用于解析十六进制文件中的PPP协议数据,识别TCP/UDP包并提取基本信息\n\n");
+    printf("使用方法:\n");
+    printf("  %s [文件1] [文件2] ...\n\n", program_name);
+    printf("参数说明:\n");
+    printf("  文件1, 文件2, ... : 要分析的十六进制数据文件\n");
+    printf("                      如果不指定文件,默认分析 out.txt 和 in.txt\n\n");
+    printf("文件格式:\n");
+    printf("  每行包含十六进制数据,可以是单个字节或多个字节\n");
+    printf("  例如: 7E FF 03 00 21 45 00 00 1C 7E\n");
+    printf("  或者: 7E\n");
+    printf("        FF\n");
+    printf("        03\n\n");
+    printf("示例:\n");
+    printf("  %s out.txt in.txt\n", program_name);
+    printf("  %s data1.hex data2.hex data3.hex\n", program_name);
+}
+
+/**
+ * 主函数
+ */
+int main(int argc, char *argv[])
+{
+    printf("PPP协议解析工具 (C语言版本) - 启动\n");
+    printf("版本: 1.0\n");
+    printf("功能: PPP帧解析、IP包分析、TCP/UDP包识别\n\n");
+    
+    /* 检查命令行参数 */
+    if (argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) {
+        print_usage(argv[0]);
+        return 0;
+    }
+    
+    /* 确定要分析的文件列表 */
+    const char **files_to_analyze;
+    int file_count;
+    const char *default_files[] = {"out.txt", "in.txt"};
+    
+    if (argc > 1) {
+        /* 使用命令行参数中的文件列表 */
+        files_to_analyze = (const char **)&argv[1];
+        file_count = argc - 1;
+    } else {
+        /* 使用默认文件列表 */
+        files_to_analyze = default_files;
+        file_count = 2;
+        printf("未指定文件,使用默认文件: out.txt, in.txt\n");
+    }
+    
+    /* 遍历并分析每个文件 */
+    int success_count = 0;
+    for (int i = 0; i < file_count; i++) {
+        const char *file_path = files_to_analyze[i];
+        
+        /* 检查文件是否存在 */
+        FILE *test_file = fopen(file_path, "r");
+        if (test_file) {
+            fclose(test_file);
+            analyze_ppp_file(file_path);
+            success_count++;
+        } else {
+            printf("\n错误: 文件不存在或无法访问: %s\n", file_path);
+        }
+    }
+    
+    /* 打印总结信息 */
+    printf("\n============================================================\n");
+    printf("分析总结:\n");
+    printf("  指定文件数量: %d\n", file_count);
+    printf("  成功分析文件: %d\n", success_count);
+    printf("  失败文件数量: %d\n", file_count - success_count);
+    
+    if (success_count == 0) {
+        printf("\n警告: 没有成功分析任何文件\n");
+        printf("请检查:\n");
+        printf("1. 文件是否存在\n");
+        printf("2. 文件格式是否正确(十六进制数据)\n");
+        printf("3. 文件权限是否允许读取\n");
+        return 1;
+    }
+    
+    printf("\nPPP协议解析工具运行完成\n");
+    return 0;
+} 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/ppp_packet_analyzer.c b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_packet_analyzer.c
new file mode 100644 (file)
index 0000000..28500ce
--- /dev/null
@@ -0,0 +1,519 @@
+#include "ppp_packet_analyzer.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* 内部辅助函数声明 */
+static bool ppp_unescape_frame(const uint8_t *raw_data, uint16_t raw_len, 
+                              uint8_t *processed_data, uint16_t *processed_len);
+
+/**
+ * PPP转义字符处理:还原字节填充
+ * @param raw_data 原始帧数据(包含转义字符)
+ * @param raw_len 原始数据长度
+ * @param processed_data 输出的处理后数据
+ * @param processed_len 输出的处理后数据长度
+ * @return 处理是否成功
+ */
+static bool ppp_unescape_frame(const uint8_t *raw_data, uint16_t raw_len, 
+                              uint8_t *processed_data, uint16_t *processed_len)
+{
+    if (!raw_data || !processed_data || !processed_len || raw_len == 0) {
+        return false;
+    }
+    
+    uint16_t out_len = 0;
+    
+    /* 还原字节填充(0x7D后字节异或0x20) */
+    for (uint16_t i = 0; i < raw_len; i++) {
+        if (raw_data[i] == 0x7D) {  /* PPP转义字符 */
+            /* 转义字符 */
+            if (i + 1 < raw_len) {
+                processed_data[out_len++] = raw_data[i + 1] ^ 0x20;
+                i++; /* 跳过下一个字节 */
+            } else {
+                /* 不完整的转义序列 */
+                return false;
+            }
+        } else {
+            processed_data[out_len++] = raw_data[i];
+        }
+        
+        /* 防止输出缓冲区溢出 */
+        if (out_len >= PPP_MAX_FRAME_SIZE) {
+            return false;
+        }
+    }
+    
+    *processed_len = out_len;
+    return true;
+}
+
+/**
+ * 计算IP头部校验和
+ */
+uint16_t calculate_ip_checksum(const uint8_t *ip_header, uint8_t header_len)
+{
+    if (!ip_header || header_len < IP_MIN_HEADER_SIZE || header_len % 2 != 0) {
+        return 0;
+    }
+    
+    uint32_t sum = 0;
+    
+    /* 将IP头部视为16位字的序列进行累加 */
+    for (uint8_t i = 0; i < header_len; i += 2) {
+        uint16_t word = (ip_header[i] << 8) | ip_header[i + 1];
+        sum += word;
+    }
+    
+    /* 处理进位 */
+    while (sum >> 16) {
+        sum = (sum & 0xFFFF) + (sum >> 16);
+    }
+    
+    /* 取反得到校验和 */
+    return ~sum & 0xFFFF;
+}
+
+/**
+ * 验证IP数据包的完整性和正确性
+ */
+bool verify_ip_packet(const uint8_t *ip_data, uint16_t data_len, ip_validation_result_t *result)
+{
+    if (!ip_data || !result) {
+        *result = IP_ERROR_TOO_SHORT;
+        return false;
+    }
+    
+    /* 检查最小长度 */
+    if (data_len < IP_MIN_HEADER_SIZE) {
+        *result = IP_ERROR_TOO_SHORT;
+        return false;
+    }
+    
+    /* 验证版本号(应为4) */
+    uint8_t version = (ip_data[0] >> 4) & 0x0F;
+    if (version != IP_VERSION_4) {
+        *result = IP_ERROR_INVALID_VERSION;
+        return false;
+    }
+    
+    /* 验证头部长度 */
+    uint8_t ihl = (ip_data[0] & 0x0F) * 4;
+    if (ihl < IP_MIN_HEADER_SIZE || ihl > IP_MAX_HEADER_SIZE || ihl > data_len) {
+        *result = IP_ERROR_INVALID_HEADER_LEN;
+        return false;
+    }
+    
+    /* 检查总长度是否合理 */
+    uint16_t total_length = (ip_data[2] << 8) | ip_data[3];
+    /* 允许实际长度比声明长度多几个字节(可能是PPP填充),或者实际长度大于等于声明长度 */
+    if (total_length > data_len || (data_len - total_length) > 4) {
+        *result = IP_ERROR_LENGTH_MISMATCH;
+        return false;
+    }
+    
+    /* 验证校验和 */
+    uint16_t original_checksum = (ip_data[10] << 8) | ip_data[11];
+    
+    /* 创建头部副本并清零校验和字段 */
+    uint8_t header_copy[IP_MAX_HEADER_SIZE];
+    memcpy(header_copy, ip_data, ihl);
+    header_copy[10] = 0;
+    header_copy[11] = 0;
+    
+    uint16_t calculated_checksum = calculate_ip_checksum(header_copy, ihl);
+    
+    if (original_checksum != calculated_checksum) {
+        *result = IP_ERROR_CHECKSUM_FAILED;
+        return false;
+    }
+    
+    *result = IP_VALID;
+    return true;
+}
+
+/**
+ * 解析IP数据包,提取基本信息
+ */
+bool parse_ip_packet(const uint8_t *ip_data, uint16_t data_len, ip_packet_info_t *ip_info)
+{
+    if (!ip_data || !ip_info || data_len < IP_MIN_HEADER_SIZE) {
+        return false;
+    }
+    
+    memset(ip_info, 0, sizeof(ip_packet_info_t));
+    
+    /* 解析IP头部字段 */
+    ip_info->version = (ip_data[0] >> 4) & 0x0F;
+    ip_info->header_len = (ip_data[0] & 0x0F) * 4;
+    ip_info->tos = ip_data[1];
+    ip_info->total_len = (ip_data[2] << 8) | ip_data[3];
+    ip_info->id = (ip_data[4] << 8) | ip_data[5];
+    ip_info->flags_frag = (ip_data[6] << 8) | ip_data[7];
+    ip_info->ttl = ip_data[8];
+    ip_info->protocol = ip_data[9];
+    ip_info->checksum = (ip_data[10] << 8) | ip_data[11];
+    
+    /* 解析IP地址 */
+    memcpy(ip_info->src_ip.addr, &ip_data[12], 4);
+    memcpy(ip_info->dst_ip.addr, &ip_data[16], 4);
+    
+    /* 计算负载信息 */
+    if (ip_info->header_len <= data_len) {
+        ip_info->payload = ip_data + ip_info->header_len;
+        ip_info->payload_len = data_len - ip_info->header_len;
+    }
+    
+    /* 验证IP包 */
+    bool is_valid = verify_ip_packet(ip_data, data_len, &ip_info->validation);
+    ip_info->validation_msg = get_ip_validation_message(ip_info->validation);
+    
+    return true;  /* 总是返回true,即使验证失败也要解析IP包信息 */
+}
+
+/**
+ * 解析TCP数据包,提取端口和基本信息
+ */
+bool parse_tcp_packet(const uint8_t *tcp_data, uint16_t data_len, tcp_packet_info_t *tcp_info)
+{
+    if (!tcp_data || !tcp_info || data_len < TCP_MIN_HEADER_SIZE) {
+        return false;
+    }
+    
+    memset(tcp_info, 0, sizeof(tcp_packet_info_t));
+    
+    /* 解析TCP头部字段 */
+    tcp_info->src_port = (tcp_data[0] << 8) | tcp_data[1];
+    tcp_info->dst_port = (tcp_data[2] << 8) | tcp_data[3];
+    tcp_info->seq_num = (tcp_data[4] << 24) | (tcp_data[5] << 16) | 
+                        (tcp_data[6] << 8) | tcp_data[7];
+    tcp_info->ack_num = (tcp_data[8] << 24) | (tcp_data[9] << 16) | 
+                        (tcp_data[10] << 8) | tcp_data[11];
+    
+    uint8_t data_offset = (tcp_data[12] >> 4) & 0x0F;
+    tcp_info->header_len = data_offset * 4;
+    tcp_info->flags = tcp_data[13];
+    tcp_info->window = (tcp_data[14] << 8) | tcp_data[15];
+    tcp_info->checksum = (tcp_data[16] << 8) | tcp_data[17];
+    tcp_info->urgent_ptr = (tcp_data[18] << 8) | tcp_data[19];
+    
+    /* 计算负载信息 */
+    if (tcp_info->header_len <= data_len) {
+        tcp_info->payload = tcp_data + tcp_info->header_len;
+        tcp_info->payload_len = data_len - tcp_info->header_len;
+    }
+    
+    return true;
+}
+
+/**
+ * 解析UDP数据包,提取端口和基本信息
+ */
+bool parse_udp_packet(const uint8_t *udp_data, uint16_t data_len, udp_packet_info_t *udp_info)
+{
+    if (!udp_data || !udp_info || data_len < UDP_HEADER_SIZE) {
+        return false;
+    }
+    
+    memset(udp_info, 0, sizeof(udp_packet_info_t));
+    
+    /* 解析UDP头部字段 */
+    udp_info->src_port = (udp_data[0] << 8) | udp_data[1];
+    udp_info->dst_port = (udp_data[2] << 8) | udp_data[3];
+    udp_info->length = (udp_data[4] << 8) | udp_data[5];
+    udp_info->checksum = (udp_data[6] << 8) | udp_data[7];
+    
+    /* 计算负载信息 */
+    udp_info->payload = udp_data + UDP_HEADER_SIZE;
+    udp_info->payload_len = data_len - UDP_HEADER_SIZE;
+    
+    return true;
+}
+
+/**
+ * 分析PPP帧内容,解析其中的IP/TCP/UDP包
+ */
+bool analyze_ppp_frame(const ppp_frame_t *frame, packet_analysis_result_t *result)
+{
+    if (!frame || !result) {
+        return false;
+    }
+    
+    memset(result, 0, sizeof(packet_analysis_result_t));
+    result->ppp_frame = frame;
+    
+    /* 检查原始帧长度 */
+    if (frame->raw_frame_len < 6) {  /* 最小:0x7E + 地址1 + 控制1 + 协议2 + 0x7E = 6字节 */
+        result->protocol_name = "PPP Frame Too Short";
+        return false;
+    }
+    
+    /* 验证帧头尾标志 */
+    if (frame->raw_frame[0] != PPP_FLAG_BYTE || 
+        frame->raw_frame[frame->raw_frame_len - 1] != PPP_FLAG_BYTE) {
+        result->protocol_name = "Invalid PPP Frame Flags";
+        return false;
+    }
+    
+    /* 提取帧内容(去掉头尾0x7E) */
+    const uint8_t *frame_content = &frame->raw_frame[1];
+    uint16_t frame_content_len = frame->raw_frame_len - 2;
+    
+    /* 处理PPP转义字符 */
+    uint8_t processed_data[PPP_MAX_FRAME_SIZE];
+    uint16_t processed_len;
+    
+    if (!ppp_unescape_frame(frame_content, frame_content_len, processed_data, &processed_len)) {
+        result->protocol_name = "Invalid PPP Frame";
+        return false;
+    }
+    
+    /* 检查处理后的帧长度 */
+    if (processed_len < 4) {  /* 最小:地址1 + 控制1 + 协议2 = 4字节 */
+        result->protocol_name = "PPP Frame Too Short";
+        return false;
+    }
+    
+    /* 解析PPP帧头部 */
+    uint8_t address = processed_data[0];
+    uint8_t control = processed_data[1];
+    uint16_t protocol = (processed_data[2] << 8) | processed_data[3];
+    
+    /* 更新frame结构中的协议信息(用于组包统计) */
+    ((ppp_frame_t*)frame)->address = address;
+    ((ppp_frame_t*)frame)->control = control;
+    ((ppp_frame_t*)frame)->protocol = protocol;
+    
+    /* 复制处理后的负载数据 */
+    ((ppp_frame_t*)frame)->payload_len = processed_len;
+    memcpy(((ppp_frame_t*)frame)->payload, processed_data, processed_len);
+    
+    /* 获取IP负载数据 */
+    const uint8_t *ip_payload = &processed_data[4];
+    uint16_t ip_payload_len = processed_len - 4;
+    
+    /* 检查是否为IP协议 */
+    if (protocol == PPP_PROTOCOL_IP && ip_payload_len > 0) {
+        /* 解析IP包 */
+        result->has_ip = parse_ip_packet(ip_payload, ip_payload_len, &result->ip_info);
+        
+        if (result->has_ip) {
+            if (result->ip_info.validation == IP_VALID) {
+                /* 根据IP协议类型解析传输层 */
+                if (result->ip_info.protocol == IP_PROTOCOL_TCP && result->ip_info.payload_len > 0) {
+                    result->has_tcp = parse_tcp_packet(result->ip_info.payload, 
+                                                     result->ip_info.payload_len, &result->tcp_info);
+                    result->protocol_name = "TCP";
+                } else if (result->ip_info.protocol == IP_PROTOCOL_UDP && result->ip_info.payload_len > 0) {
+                    result->has_udp = parse_udp_packet(result->ip_info.payload, 
+                                                     result->ip_info.payload_len, &result->udp_info);
+                    result->protocol_name = "UDP";
+                } else if (result->ip_info.protocol == IP_PROTOCOL_ICMP) {
+                    result->protocol_name = "ICMP";
+                } else {
+                    result->protocol_name = "Other IP";
+                }
+            } else {
+                result->protocol_name = "Invalid IP";
+            }
+        }
+    } else {
+        /* 非IP协议 */
+        result->protocol_name = ppp_get_protocol_name(protocol);
+    }
+    
+    return true;
+}
+
+/**
+ * 批量分析PPP帧
+ */
+uint32_t analyze_ppp_frames(const ppp_frame_t *frames, uint32_t frame_count,
+                           packet_analysis_result_t *results, packet_stats_t *stats)
+{
+    if (!frames || !results || !stats || frame_count == 0) {
+        return 0;
+    }
+    
+    init_packet_stats(stats);
+    uint32_t success_count = 0;
+    
+    for (uint32_t i = 0; i < frame_count; i++) {
+        if (analyze_ppp_frame(&frames[i], &results[i])) {
+            success_count++;
+            stats->total_packets++;
+            
+            /* 更新统计信息 */
+            if (results[i].has_ip) {
+                stats->ip_packets++;
+                
+                /* 更新IP验证统计 */
+                ip_validation_result_t validation = results[i].ip_info.validation;
+                if (validation < 6) {
+                    stats->ip_validation_counts[validation]++;
+                }
+                
+                if (validation != IP_VALID) {
+                    stats->invalid_ip_packets++;
+                }
+                
+                /* 更新传输层统计 */
+                if (results[i].has_tcp) {
+                    stats->tcp_packets++;
+                } else if (results[i].has_udp) {
+                    stats->udp_packets++;
+                } else {
+                    stats->other_packets++;
+                }
+            } else {
+                stats->other_packets++;
+            }
+        }
+    }
+    
+    return success_count;
+}
+
+/**
+ * 获取IP验证结果的描述字符串
+ */
+const char* get_ip_validation_message(ip_validation_result_t result)
+{
+    switch (result) {
+        case IP_VALID:
+            return "IP数据包验证通过";
+        case IP_ERROR_TOO_SHORT:
+            return "IP数据包长度不足20字节";
+        case IP_ERROR_INVALID_VERSION:
+            return "非IPv4数据包";
+        case IP_ERROR_INVALID_HEADER_LEN:
+            return "无效的IP头部长度";
+        case IP_ERROR_LENGTH_MISMATCH:
+            return "IP数据包长度不匹配";
+        case IP_ERROR_CHECKSUM_FAILED:
+            return "IP校验和错误";
+        default:
+            return "未知错误";
+    }
+}
+
+/**
+ * 格式化IP地址为字符串
+ */
+void format_ip_address(const ip_addr_t *ip_addr, char *buffer, size_t buffer_size)
+{
+    if (!ip_addr || !buffer || buffer_size < 16) {
+        return;
+    }
+    
+    snprintf(buffer, buffer_size, "%u.%u.%u.%u",
+             ip_addr->addr[0], ip_addr->addr[1], 
+             ip_addr->addr[2], ip_addr->addr[3]);
+}
+
+/**
+ * 打印IP包信息
+ */
+void print_ip_packet_info(const ip_packet_info_t *ip_info)
+{
+    if (!ip_info) return;
+    
+    char src_ip_str[16], dst_ip_str[16];
+    format_ip_address(&ip_info->src_ip, src_ip_str, sizeof(src_ip_str));
+    format_ip_address(&ip_info->dst_ip, dst_ip_str, sizeof(dst_ip_str));
+    
+    printf("  IP验证: %s - %s\n", 
+           (ip_info->validation == IP_VALID) ? "通过" : "失败",
+           ip_info->validation_msg);
+    
+    if (ip_info->validation == IP_VALID) {
+        printf("  IP信息: %s -> %s, 协议=%u, 长度=%u, TTL=%u\n",
+               src_ip_str, dst_ip_str, ip_info->protocol, 
+               ip_info->total_len, ip_info->ttl);
+    }
+}
+
+/**
+ * 打印TCP包信息
+ */
+void print_tcp_packet_info(const tcp_packet_info_t *tcp_info)
+{
+    if (!tcp_info) return;
+    
+    printf("  TCP: 端口 %u -> %u, 序列号=%u, 确认号=%u, 标志=0x%02X\n",
+           tcp_info->src_port, tcp_info->dst_port, 
+           tcp_info->seq_num, tcp_info->ack_num, tcp_info->flags);
+}
+
+/**
+ * 打印UDP包信息
+ */
+void print_udp_packet_info(const udp_packet_info_t *udp_info)
+{
+    if (!udp_info) return;
+    
+    printf("  UDP: 端口 %u -> %u, 长度=%u\n",
+           udp_info->src_port, udp_info->dst_port, udp_info->length);
+}
+
+/**
+ * 打印包分析结果
+ */
+void print_packet_analysis_result(const packet_analysis_result_t *result, uint32_t packet_number)
+{
+    if (!result || !result->ppp_frame) return;
+    
+    printf("\n=== 包 #%u 分析结果 ===\n", packet_number);
+    
+    /* 打印PPP帧基本信息 */
+    printf("PPP帧: 协议=0x%04X (%s), 负载长度=%u字节\n",
+           result->ppp_frame->protocol, result->protocol_name, 
+           result->ppp_frame->payload_len);
+    
+    /* 打印IP包信息 */
+    if (result->has_ip) {
+        print_ip_packet_info(&result->ip_info);
+        
+        /* 打印传输层信息 */
+        if (result->has_tcp) {
+            print_tcp_packet_info(&result->tcp_info);
+        } else if (result->has_udp) {
+            print_udp_packet_info(&result->udp_info);
+        }
+    }
+}
+
+/**
+ * 打印包统计信息
+ */
+void print_packet_stats(const packet_stats_t *stats)
+{
+    if (!stats) return;
+    
+    printf("\n=== 包分析统计信息 ===\n");
+    printf("总包数: %u\n", stats->total_packets);
+    printf("IP包数: %u\n", stats->ip_packets);
+    printf("TCP包数: %u\n", stats->tcp_packets);
+    printf("UDP包数: %u\n", stats->udp_packets);
+    printf("其他包数: %u\n", stats->other_packets);
+    printf("无效IP包数: %u\n", stats->invalid_ip_packets);
+    
+    printf("\nIP验证结果统计:\n");
+    printf("  验证通过: %u\n", stats->ip_validation_counts[IP_VALID]);
+    printf("  长度不足: %u\n", stats->ip_validation_counts[IP_ERROR_TOO_SHORT]);
+    printf("  版本错误: %u\n", stats->ip_validation_counts[IP_ERROR_INVALID_VERSION]);
+    printf("  头部长度错误: %u\n", stats->ip_validation_counts[IP_ERROR_INVALID_HEADER_LEN]);
+    printf("  长度不匹配: %u\n", stats->ip_validation_counts[IP_ERROR_LENGTH_MISMATCH]);
+    printf("  校验和错误: %u\n", stats->ip_validation_counts[IP_ERROR_CHECKSUM_FAILED]);
+}
+
+/**
+ * 初始化包统计信息
+ */
+void init_packet_stats(packet_stats_t *stats)
+{
+    if (!stats) return;
+    
+    memset(stats, 0, sizeof(packet_stats_t));
+} 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/ppp_packet_analyzer.h b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_packet_analyzer.h
new file mode 100644 (file)
index 0000000..b09b24e
--- /dev/null
@@ -0,0 +1,236 @@
+#ifndef PPP_PACKET_ANALYZER_H
+#define PPP_PACKET_ANALYZER_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ppp_parser.h"
+
+/* IP协议常量定义 */
+#define IP_VERSION_4            4       /* IPv4版本号 */
+#define IP_MIN_HEADER_SIZE      20      /* IP头部最小长度 */
+#define IP_MAX_HEADER_SIZE      60      /* IP头部最大长度 */
+#define IP_PROTOCOL_TCP         6       /* TCP协议 */
+#define IP_PROTOCOL_UDP         17      /* UDP协议 */
+#define IP_PROTOCOL_ICMP        1       /* ICMP协议 */
+
+/* TCP/UDP常量定义 */
+#define TCP_MIN_HEADER_SIZE     20      /* TCP头部最小长度 */
+#define UDP_HEADER_SIZE         8       /* UDP头部固定长度 */
+
+/* IP验证结果枚举 */
+typedef enum {
+    IP_VALID = 0,                       /* IP包有效 */
+    IP_ERROR_TOO_SHORT,                 /* 包长度不足 */
+    IP_ERROR_INVALID_VERSION,           /* 版本号错误 */
+    IP_ERROR_INVALID_HEADER_LEN,        /* 头部长度错误 */
+    IP_ERROR_LENGTH_MISMATCH,           /* 长度不匹配 */
+    IP_ERROR_CHECKSUM_FAILED            /* 校验和错误 */
+} ip_validation_result_t;
+
+/* IP地址结构 */
+typedef struct {
+    uint8_t addr[4];                    /* IP地址字节数组 */
+} ip_addr_t;
+
+/* IP包信息结构 */
+typedef struct {
+    uint8_t version;                    /* IP版本 */
+    uint8_t header_len;                 /* 头部长度(字节) */
+    uint8_t tos;                        /* 服务类型 */
+    uint16_t total_len;                 /* 总长度 */
+    uint16_t id;                        /* 标识符 */
+    uint16_t flags_frag;                /* 标志和片偏移 */
+    uint8_t ttl;                        /* 生存时间 */
+    uint8_t protocol;                   /* 协议类型 */
+    uint16_t checksum;                  /* 头部校验和 */
+    ip_addr_t src_ip;                   /* 源IP地址 */
+    ip_addr_t dst_ip;                   /* 目标IP地址 */
+    
+    /* 负载信息 */
+    const uint8_t *payload;             /* 负载数据指针 */
+    uint16_t payload_len;               /* 负载长度 */
+    
+    /* 验证结果 */
+    ip_validation_result_t validation;  /* 验证结果 */
+    const char *validation_msg;         /* 验证消息 */
+} ip_packet_info_t;
+
+/* TCP包信息结构 */
+typedef struct {
+    uint16_t src_port;                  /* 源端口 */
+    uint16_t dst_port;                  /* 目标端口 */
+    uint32_t seq_num;                   /* 序列号 */
+    uint32_t ack_num;                   /* 确认号 */
+    uint8_t header_len;                 /* 头部长度(字节) */
+    uint8_t flags;                      /* 控制标志 */
+    uint16_t window;                    /* 窗口大小 */
+    uint16_t checksum;                  /* 校验和 */
+    uint16_t urgent_ptr;                /* 紧急指针 */
+    
+    /* 负载信息 */
+    const uint8_t *payload;             /* 负载数据指针 */
+    uint16_t payload_len;               /* 负载长度 */
+} tcp_packet_info_t;
+
+/* UDP包信息结构 */
+typedef struct {
+    uint16_t src_port;                  /* 源端口 */
+    uint16_t dst_port;                  /* 目标端口 */
+    uint16_t length;                    /* UDP长度 */
+    uint16_t checksum;                  /* 校验和 */
+    
+    /* 负载信息 */
+    const uint8_t *payload;             /* 负载数据指针 */
+    uint16_t payload_len;               /* 负载长度 */
+} udp_packet_info_t;
+
+/* 包分析结果结构 */
+typedef struct {
+    /* PPP帧信息 */
+    const ppp_frame_t *ppp_frame;      /* PPP帧指针 */
+    
+    /* IP包信息 */
+    bool has_ip;                        /* 是否包含IP包 */
+    ip_packet_info_t ip_info;           /* IP包信息 */
+    
+    /* 传输层信息 */
+    bool has_tcp;                       /* 是否包含TCP包 */
+    bool has_udp;                       /* 是否包含UDP包 */
+    tcp_packet_info_t tcp_info;         /* TCP包信息 */
+    udp_packet_info_t udp_info;         /* UDP包信息 */
+    
+    /* 协议名称 */
+    const char *protocol_name;          /* 协议名称字符串 */
+} packet_analysis_result_t;
+
+/* 包统计信息结构 */
+typedef struct {
+    uint32_t total_packets;             /* 总包数 */
+    uint32_t ip_packets;                /* IP包数 */
+    uint32_t tcp_packets;               /* TCP包数 */
+    uint32_t udp_packets;               /* UDP包数 */
+    uint32_t other_packets;             /* 其他包数 */
+    uint32_t invalid_ip_packets;        /* 无效IP包数 */
+    
+    /* IP验证统计 */
+    uint32_t ip_validation_counts[6];   /* 各种验证结果的计数 */
+} packet_stats_t;
+
+/* 函数声明 */
+
+/**
+ * 计算IP头部校验和
+ * @param ip_header IP头部数据
+ * @param header_len 头部长度
+ * @return 计算出的校验和
+ */
+uint16_t calculate_ip_checksum(const uint8_t *ip_header, uint8_t header_len);
+
+/**
+ * 验证IP数据包的完整性和正确性
+ * @param ip_data IP数据包
+ * @param data_len 数据长度
+ * @param result 验证结果
+ * @return 验证是否通过
+ */
+bool verify_ip_packet(const uint8_t *ip_data, uint16_t data_len, ip_validation_result_t *result);
+
+/**
+ * 解析IP数据包,提取基本信息
+ * @param ip_data IP数据包
+ * @param data_len 数据长度
+ * @param ip_info 输出的IP包信息
+ * @return 解析是否成功
+ */
+bool parse_ip_packet(const uint8_t *ip_data, uint16_t data_len, ip_packet_info_t *ip_info);
+
+/**
+ * 解析TCP数据包,提取端口和基本信息
+ * @param tcp_data TCP数据包
+ * @param data_len 数据长度
+ * @param tcp_info 输出的TCP包信息
+ * @return 解析是否成功
+ */
+bool parse_tcp_packet(const uint8_t *tcp_data, uint16_t data_len, tcp_packet_info_t *tcp_info);
+
+/**
+ * 解析UDP数据包,提取端口和基本信息
+ * @param udp_data UDP数据包
+ * @param data_len 数据长度
+ * @param udp_info 输出的UDP包信息
+ * @return 解析是否成功
+ */
+bool parse_udp_packet(const uint8_t *udp_data, uint16_t data_len, udp_packet_info_t *udp_info);
+
+/**
+ * 分析PPP帧内容,解析其中的IP/TCP/UDP包
+ * @param frame PPP帧
+ * @param result 分析结果
+ * @return 分析是否成功
+ */
+bool analyze_ppp_frame(const ppp_frame_t *frame, packet_analysis_result_t *result);
+
+/**
+ * 批量分析PPP帧
+ * @param frames PPP帧数组
+ * @param frame_count 帧数量
+ * @param results 分析结果数组
+ * @param stats 统计信息
+ * @return 成功分析的帧数量
+ */
+uint32_t analyze_ppp_frames(const ppp_frame_t *frames, uint32_t frame_count,
+                           packet_analysis_result_t *results, packet_stats_t *stats);
+
+/**
+ * 获取IP验证结果的描述字符串
+ * @param result 验证结果
+ * @return 描述字符串
+ */
+const char* get_ip_validation_message(ip_validation_result_t result);
+
+/**
+ * 格式化IP地址为字符串
+ * @param ip_addr IP地址结构
+ * @param buffer 输出缓冲区
+ * @param buffer_size 缓冲区大小
+ */
+void format_ip_address(const ip_addr_t *ip_addr, char *buffer, size_t buffer_size);
+
+/**
+ * 打印IP包信息
+ * @param ip_info IP包信息
+ */
+void print_ip_packet_info(const ip_packet_info_t *ip_info);
+
+/**
+ * 打印TCP包信息
+ * @param tcp_info TCP包信息
+ */
+void print_tcp_packet_info(const tcp_packet_info_t *tcp_info);
+
+/**
+ * 打印UDP包信息
+ * @param udp_info UDP包信息
+ */
+void print_udp_packet_info(const udp_packet_info_t *udp_info);
+
+/**
+ * 打印包分析结果
+ * @param result 分析结果
+ * @param packet_number 包序号
+ */
+void print_packet_analysis_result(const packet_analysis_result_t *result, uint32_t packet_number);
+
+/**
+ * 打印包统计信息
+ * @param stats 统计信息
+ */
+void print_packet_stats(const packet_stats_t *stats);
+
+/**
+ * 初始化包统计信息
+ * @param stats 统计信息结构
+ */
+void init_packet_stats(packet_stats_t *stats);
+
+#endif /* PPP_PACKET_ANALYZER_H */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser.c b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser.c
new file mode 100644 (file)
index 0000000..a2f3c54
--- /dev/null
@@ -0,0 +1,383 @@
+#include "ppp_parser.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* 内部辅助函数声明 */
+static bool ppp_parse_buffer(ppp_parser_t *parser, ppp_frame_t *frame);
+static void ppp_record_dropped_data(ppp_parser_t *parser, ppp_drop_reason_t reason, 
+                                   const uint8_t *data, uint16_t data_len);
+static const char* ppp_get_drop_reason_string(ppp_drop_reason_t reason);
+
+/**
+ * 初始化PPP解析器
+ */
+void ppp_parser_init(ppp_parser_t *parser)
+{
+    if (!parser) return;
+    
+    memset(parser, 0, sizeof(ppp_parser_t));
+    parser->in_frame = false;
+    parser->buffer_len = 0;
+    parser->current_position = 0;
+    parser->dropped_data_head = 0;
+    parser->dropped_data_tail = 0;
+}
+
+/**
+ * 重置PPP解析器状态
+ */
+void ppp_parser_reset(ppp_parser_t *parser)
+{
+    if (!parser) return;
+    
+    parser->buffer_len = 0;
+    parser->in_frame = false;
+    /* 保留统计信息,只重置解析状态 */
+}
+
+/**
+ * 处理单个字节,返回是否解析出完整PPP帧
+ */
+bool ppp_parser_process_byte(ppp_parser_t *parser, uint8_t byte, ppp_frame_t *frame)
+{
+    if (!parser || !frame) return false;
+    
+    parser->total_bytes_processed++;
+    parser->current_position++;
+    
+    if (byte == PPP_FLAG_BYTE) {
+        /* PPP帧标志位 */
+        if (parser->in_frame && parser->buffer_len > 0) {
+            /* 帧结束:添加结束标志并处理缓冲区数据 */
+            if (parser->buffer_len < PPP_MAX_BUFFER_SIZE) {
+                parser->buffer[parser->buffer_len++] = byte; /* 添加结束0x7E */
+            }
+            bool result = ppp_parse_buffer(parser, frame);
+            parser->buffer_len = 0;
+            parser->in_frame = false;
+            return result;
+        } else {
+            /* 帧开始:初始化缓冲区并添加开始标志 */
+            if (parser->in_frame && parser->buffer_len > 0) {
+                /* 记录丢弃的数据 */
+                ppp_record_dropped_data(parser, PPP_DROP_REASON_FRAME_SYNC_LOST,
+                                      parser->buffer, parser->buffer_len);
+            }
+            parser->in_frame = true;
+            parser->buffer_len = 0;
+            parser->buffer[parser->buffer_len++] = byte; /* 添加开始0x7E */
+        }
+    } else {
+        if (parser->in_frame) {
+            /* 检查缓冲区溢出 */
+            if (parser->buffer_len >= PPP_MAX_BUFFER_SIZE) {
+                ppp_record_dropped_data(parser, PPP_DROP_REASON_BUFFER_OVERFLOW,
+                                      parser->buffer, parser->buffer_len);
+                parser->buffer_len = 0;
+                parser->in_frame = false;
+                return false;
+            }
+            parser->buffer[parser->buffer_len++] = byte;
+        }
+    }
+    
+    return false;
+}
+
+/**
+ * 批量处理字节数据
+ */
+uint32_t ppp_parser_process_data(ppp_parser_t *parser, const uint8_t *data, 
+                                uint32_t data_len, ppp_frame_t *frames, uint32_t max_frames)
+{
+    if (!parser || !data || !frames || max_frames == 0) return 0;
+    
+    uint32_t frame_count = 0;
+    
+    for (uint32_t i = 0; i < data_len && frame_count < max_frames; i++) {
+        if (ppp_parser_process_byte(parser, data[i], &frames[frame_count])) {
+            frame_count++;
+        }
+    }
+    
+    return frame_count;
+}
+
+/**
+ * 解析缓冲区数据,保留完整PPP帧(包含头尾0x7E),不处理转义字符
+ */
+static bool ppp_parse_buffer(ppp_parser_t *parser, ppp_frame_t *frame)
+{
+    if (!parser || !frame || parser->buffer_len == 0) return false;
+    
+    /* 校验帧长度(最小:0x7E + 地址1 + 控制1 + 协议2 + 0x7E = 6字节) */
+    if (parser->buffer_len < (PPP_MIN_FRAME_SIZE + 2)) {
+        ppp_record_dropped_data(parser, PPP_DROP_REASON_FRAME_TOO_SHORT,
+                              parser->buffer, parser->buffer_len);
+        return false;
+    }
+    
+    /* 检查帧长度是否超过最大限制 */
+    if (parser->buffer_len > (PPP_MAX_FRAME_SIZE + 2)) {
+        ppp_record_dropped_data(parser, PPP_DROP_REASON_FRAME_TOO_LONG,
+                              parser->buffer, parser->buffer_len);
+        return false;
+    }
+    
+    /* 验证帧头尾标志 */
+    if (parser->buffer[0] != PPP_FLAG_BYTE || 
+        parser->buffer[parser->buffer_len - 1] != PPP_FLAG_BYTE) {
+        ppp_record_dropped_data(parser, PPP_DROP_REASON_FRAME_SYNC_LOST,
+                              parser->buffer, parser->buffer_len);
+        return false;
+    }
+    
+    /* 复制完整PPP帧数据(包含头尾0x7E和转义字符) */
+    frame->raw_frame_len = parser->buffer_len;
+    memcpy(frame->raw_frame, parser->buffer, parser->buffer_len);
+    
+    /* 暂时将其他字段设为0,由analyzer处理转义后再解析 */
+    frame->address = 0;
+    frame->control = 0;
+    frame->protocol = 0;
+    frame->payload_len = 0;
+    
+    parser->total_frames_parsed++;
+    return true;
+}
+
+/**
+ * 记录丢弃的数据
+ */
+static void ppp_record_dropped_data(ppp_parser_t *parser, ppp_drop_reason_t reason,
+                                   const uint8_t *data, uint16_t data_len)
+{
+    if (!parser || !data) return;
+    
+    /* 计算下一个写入位置 */
+    uint8_t next_tail = (parser->dropped_data_tail + 1) % 32;
+    
+    /* 如果缓冲区满了,覆盖最旧的数据 */
+    if (next_tail == parser->dropped_data_head) {
+        parser->dropped_data_head = (parser->dropped_data_head + 1) % 32;
+    }
+    
+    /* 记录丢弃数据 */
+    ppp_dropped_data_t *dropped = &parser->dropped_data[parser->dropped_data_tail];
+    dropped->reason = reason;
+    dropped->position = parser->current_position;
+    dropped->data_len = (data_len > 256) ? 256 : data_len;
+    memcpy(dropped->data, data, dropped->data_len);
+    
+    parser->dropped_data_tail = next_tail;
+    parser->dropped_data_count++;
+}
+
+/**
+ * 对PPP帧进行组包处理
+ */
+void ppp_classify_frames(const ppp_frame_t *frames, uint32_t frame_count, ppp_group_result_t *result)
+{
+    if (!frames || !result || frame_count == 0) return;
+    
+    memset(result, 0, sizeof(ppp_group_result_t));
+    result->total_frames = frame_count;
+    
+    for (uint32_t i = 0; i < frame_count; i++) {
+        const ppp_frame_t *frame = &frames[i];
+        
+        /* 查找是否已存在该协议的统计 */
+        int protocol_index = -1;
+        for (int j = 0; j < result->protocol_count; j++) {
+            if (result->protocols[j].protocol == frame->protocol) {
+                protocol_index = j;
+                break;
+            }
+        }
+        
+        if (protocol_index >= 0) {
+            /* 更新现有协议统计 */
+            result->protocols[protocol_index].frame_count++;
+        } else if (result->protocol_count < 16) {
+            /* 添加新协议统计 */
+            protocol_index = result->protocol_count++;
+            result->protocols[protocol_index].protocol = frame->protocol;
+            result->protocols[protocol_index].frame_count = 1;
+            result->protocols[protocol_index].protocol_name = ppp_get_protocol_name(frame->protocol);
+        } else {
+            /* 协议种类超过限制,计入无效帧 */
+            result->invalid_frames++;
+        }
+    }
+}
+
+/**
+ * 获取协议名称
+ */
+const char* ppp_get_protocol_name(uint16_t protocol)
+{
+    switch (protocol) {
+        case PPP_PROTOCOL_IP:
+            return "IP (IPv4)";
+        case PPP_PROTOCOL_LCP:
+            return "LCP (链路控制协议)";
+        case PPP_PROTOCOL_IPCP:
+            return "IPCP (IP控制协议)";
+        default:
+            return "未知协议";
+    }
+}
+
+/**
+ * 获取丢弃原因字符串
+ */
+static const char* ppp_get_drop_reason_string(ppp_drop_reason_t reason)
+{
+    switch (reason) {
+        case PPP_DROP_REASON_FRAME_SYNC_LOST:
+            return "帧同步丢失或格式错误";
+        case PPP_DROP_REASON_INCOMPLETE_ESCAPE:
+            return "不完整的转义序列";
+        case PPP_DROP_REASON_FRAME_TOO_SHORT:
+            return "帧长度不足4字节";
+        case PPP_DROP_REASON_FRAME_TOO_LONG:
+            return "帧长度过长";
+        case PPP_DROP_REASON_BUFFER_OVERFLOW:
+            return "缓冲区溢出";
+        default:
+            return "未知原因";
+    }
+}
+
+/**
+ * 打印PPP解析器统计信息
+ */
+void ppp_parser_print_stats(const ppp_parser_t *parser)
+{
+    if (!parser) return;
+    
+    printf("\nPPP解析器统计信息:\n");
+    printf("  处理的总字节数: %u\n", parser->total_bytes_processed);
+    printf("  解析的总帧数: %u\n", parser->total_frames_parsed);
+    printf("  丢弃数据次数: %u\n", parser->dropped_data_count);
+}
+
+/**
+ * 打印丢弃数据信息
+ */
+void ppp_parser_print_dropped_data(const ppp_parser_t *parser)
+{
+    if (!parser) return;
+    
+    printf("\n丢弃的数据信息:\n");
+    
+    if (parser->dropped_data_count == 0) {
+        printf("  没有丢弃的数据\n");
+        return;
+    }
+    
+    printf("  丢弃的数据总数: %u\n", parser->dropped_data_count);
+    
+    /* 计算要显示的数据数量(最多5条) */
+    uint8_t count = 0;
+    uint8_t current = parser->dropped_data_head;
+    
+    while (current != parser->dropped_data_tail && count < 5) {
+        const ppp_dropped_data_t *dropped = &parser->dropped_data[current];
+        
+        printf("  丢弃数据 #%d:\n", count + 1);
+        printf("    原因: %s\n", ppp_get_drop_reason_string(dropped->reason));
+        printf("    位置: %u\n", dropped->position);
+        printf("    数据: ");
+        for (uint16_t i = 0; i < dropped->data_len && i < 32; i++) {
+            printf("%02X", dropped->data[i]);
+        }
+        if (dropped->data_len > 32) {
+            printf("...");
+        }
+        printf("\n");
+        
+        current = (current + 1) % 32;
+        count++;
+    }
+    
+    if (parser->dropped_data_count > 5) {
+        printf("  ... 还有%u条丢弃的数据未显示\n", parser->dropped_data_count - 5);
+    }
+}
+
+/**
+ * 打印PPP帧信息
+ */
+void ppp_print_frame_info(const ppp_frame_t *frame, uint32_t frame_number)
+{
+    if (!frame) return;
+    
+    printf("PPP帧 #%u: 完整长度=%u字节 (包含头尾0x7E)\n", frame_number, frame->raw_frame_len);
+    
+    /* 显示完整PPP帧数据 */
+    printf("  完整帧数据: ");
+    for (uint16_t i = 0; i < frame->raw_frame_len && i < 32; i++) {
+        printf("%02X", frame->raw_frame[i]);
+    }
+    if (frame->raw_frame_len > 32) {
+        printf("...");
+    }
+    printf("\n");
+    
+    /* 如果已经解析过,显示解析后的信息 */
+    if (frame->payload_len > 0) {
+        printf("  协议: 0x%04X, 地址: 0x%02X, 控制: 0x%02X\n",
+               frame->protocol, frame->address, frame->control);
+        printf("  处理后负载长度: %u字节 (已处理转义字符)\n", frame->payload_len);
+        
+        /* 显示处理后的负载数据(最多显示前32字节) */
+        printf("  处理后负载: ");
+        uint16_t print_len = (frame->payload_len > 32) ? 32 : frame->payload_len;
+        for (uint16_t i = 0; i < print_len; i++) {
+            printf("%02X", frame->payload[i]);
+        }
+        if (frame->payload_len > 32) {
+            printf("...");
+        }
+        printf("\n");
+    } else {
+        printf("  (未解析 - 需要通过analyzer处理转义字符)\n");
+    }
+}
+
+/**
+ * 打印组包结果
+ */
+void ppp_print_group_result(const ppp_group_result_t *result)
+{
+    if (!result) return;
+    
+    printf("\nPPP帧组包结果:\n");
+    printf("  总帧数: %u\n", result->total_frames);
+    printf("  协议种类: %u\n", result->protocol_count);
+    
+    for (uint8_t i = 0; i < result->protocol_count; i++) {
+        const ppp_protocol_stats_t *stats = &result->protocols[i];
+        printf("  0x%04X (%s): %u个帧\n", 
+               stats->protocol, stats->protocol_name, stats->frame_count);
+    }
+    
+    if (result->invalid_frames > 0) {
+        printf("  无效帧: %u个\n", result->invalid_frames);
+    }
+    
+    /* 验证组包结果 */
+    uint32_t total_grouped = result->invalid_frames;
+    for (uint8_t i = 0; i < result->protocol_count; i++) {
+        total_grouped += result->protocols[i].frame_count;
+    }
+    
+    if (total_grouped == result->total_frames) {
+        printf("  组包验证: 成功,所有%u个帧都已正确分组\n", total_grouped);
+    } else {
+        printf("  组包验证: 警告,分组总数(%u)与原始帧总数(%u)不匹配\n", 
+               total_grouped, result->total_frames);
+    }
+} 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser.h b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser.h
new file mode 100644 (file)
index 0000000..0453da5
--- /dev/null
@@ -0,0 +1,158 @@
+#ifndef PPP_PARSER_H
+#define PPP_PARSER_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+/* PPP协议常量定义 */
+#define PPP_FLAG_BYTE           0x7E    /* PPP帧标志位 */
+#define PPP_ESCAPE_BYTE         0x7D    /* PPP转义字符 */
+#define PPP_ESCAPE_XOR          0x20    /* PPP转义异或值 */
+#define PPP_MIN_FRAME_SIZE      4       /* PPP帧最小长度(地址+控制+协议) */
+#define PPP_MAX_FRAME_SIZE      1500    /* PPP帧最大长度 */
+#define PPP_MAX_BUFFER_SIZE     2048    /* 解析缓冲区最大长度 */
+
+/* PPP协议类型定义 */
+#define PPP_PROTOCOL_IP         0x0021  /* IPv4协议 */
+#define PPP_PROTOCOL_LCP        0xC021  /* 链路控制协议 */
+#define PPP_PROTOCOL_IPCP       0x8021  /* IP控制协议 */
+
+/* 丢弃数据原因枚举 */
+typedef enum {
+    PPP_DROP_REASON_NONE = 0,
+    PPP_DROP_REASON_FRAME_SYNC_LOST,    /* 帧同步丢失 */
+    PPP_DROP_REASON_INCOMPLETE_ESCAPE,  /* 不完整的转义序列 */
+    PPP_DROP_REASON_FRAME_TOO_SHORT,    /* 帧长度不足 */
+    PPP_DROP_REASON_FRAME_TOO_LONG,     /* 帧长度过长 */
+    PPP_DROP_REASON_BUFFER_OVERFLOW     /* 缓冲区溢出 */
+} ppp_drop_reason_t;
+
+/* 丢弃数据记录结构 */
+typedef struct {
+    ppp_drop_reason_t reason;           /* 丢弃原因 */
+    uint8_t data[256];                  /* 丢弃的数据(最多256字节) */
+    uint16_t data_len;                  /* 丢弃数据长度 */
+    uint32_t position;                  /* 丢弃位置 */
+} ppp_dropped_data_t;
+
+/* PPP帧结构 */
+typedef struct {
+    uint8_t address;                    /* 地址字段 */
+    uint8_t control;                    /* 控制字段 */
+    uint16_t protocol;                  /* 协议字段 */
+    uint8_t raw_frame[PPP_MAX_FRAME_SIZE + 2]; /* 完整PPP帧数据(包含头尾0x7E) */
+    uint16_t raw_frame_len;             /* 完整帧长度 */
+    uint8_t payload[PPP_MAX_FRAME_SIZE]; /* 负载数据(处理转义后) */
+    uint16_t payload_len;               /* 负载长度 */
+} ppp_frame_t;
+
+/* PPP帧解析器状态结构 */
+typedef struct {
+    uint8_t buffer[PPP_MAX_BUFFER_SIZE]; /* 帧数据缓冲区 */
+    uint16_t buffer_len;                /* 缓冲区当前长度 */
+    bool in_frame;                      /* 是否处于帧接收状态 */
+    uint32_t current_position;          /* 当前处理位置 */
+    
+    /* 统计信息 */
+    uint32_t total_frames_parsed;       /* 解析的总帧数 */
+    uint32_t total_bytes_processed;     /* 处理的总字节数 */
+    uint32_t dropped_data_count;        /* 丢弃数据次数 */
+    
+    /* 丢弃数据记录(环形缓冲区) */
+    ppp_dropped_data_t dropped_data[32]; /* 最多记录32条丢弃数据 */
+    uint8_t dropped_data_head;          /* 丢弃数据头指针 */
+    uint8_t dropped_data_tail;          /* 丢弃数据尾指针 */
+} ppp_parser_t;
+
+/* PPP协议统计结构 */
+typedef struct {
+    uint16_t protocol;                  /* 协议类型 */
+    uint32_t frame_count;               /* 帧数量 */
+    const char *protocol_name;          /* 协议名称 */
+} ppp_protocol_stats_t;
+
+/* PPP帧组包结果结构 */
+typedef struct {
+    ppp_protocol_stats_t protocols[16]; /* 最多支持16种协议统计 */
+    uint8_t protocol_count;             /* 协议种类数量 */
+    uint32_t total_frames;              /* 总帧数 */
+    uint32_t invalid_frames;            /* 无效帧数 */
+} ppp_group_result_t;
+
+/* 函数声明 */
+
+/**
+ * 初始化PPP解析器
+ * @param parser PPP解析器指针
+ */
+void ppp_parser_init(ppp_parser_t *parser);
+
+/**
+ * 重置PPP解析器状态
+ * @param parser PPP解析器指针
+ */
+void ppp_parser_reset(ppp_parser_t *parser);
+
+/**
+ * 处理单个字节,返回是否解析出完整PPP帧
+ * @param parser PPP解析器指针
+ * @param byte 输入字节
+ * @param frame 输出的PPP帧指针
+ * @return true表示解析出完整帧,false表示需要更多数据
+ */
+bool ppp_parser_process_byte(ppp_parser_t *parser, uint8_t byte, ppp_frame_t *frame);
+
+/**
+ * 批量处理字节数据
+ * @param parser PPP解析器指针
+ * @param data 输入数据指针
+ * @param data_len 输入数据长度
+ * @param frames 输出帧数组
+ * @param max_frames 最大帧数量
+ * @return 实际解析出的帧数量
+ */
+uint32_t ppp_parser_process_data(ppp_parser_t *parser, const uint8_t *data, 
+                                uint32_t data_len, ppp_frame_t *frames, uint32_t max_frames);
+
+/**
+ * 对PPP帧进行组包处理
+ * @param frames PPP帧数组
+ * @param frame_count 帧数量
+ * @param result 组包结果
+ */
+void ppp_classify_frames(const ppp_frame_t *frames, uint32_t frame_count, ppp_group_result_t *result);
+
+/**
+ * 获取协议名称
+ * @param protocol 协议类型
+ * @return 协议名称字符串
+ */
+const char* ppp_get_protocol_name(uint16_t protocol);
+
+/**
+ * 打印PPP解析器统计信息
+ * @param parser PPP解析器指针
+ */
+void ppp_parser_print_stats(const ppp_parser_t *parser);
+
+/**
+ * 打印丢弃数据信息
+ * @param parser PPP解析器指针
+ */
+void ppp_parser_print_dropped_data(const ppp_parser_t *parser);
+
+/**
+ * 打印PPP帧信息
+ * @param frame PPP帧指针
+ * @param frame_number 帧序号
+ */
+void ppp_print_frame_info(const ppp_frame_t *frame, uint32_t frame_number);
+
+/**
+ * 打印组包结果
+ * @param result 组包结果指针
+ */
+void ppp_print_group_result(const ppp_group_result_t *result);
+
+#endif /* PPP_PARSER_H */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser_configurable.h b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser_configurable.h
new file mode 100644 (file)
index 0000000..79450da
--- /dev/null
@@ -0,0 +1,158 @@
+#ifndef PPP_PARSER_CONFIGURABLE_H
+#define PPP_PARSER_CONFIGURABLE_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+/* PPP协议常量定义 */
+#define PPP_FLAG_BYTE           0x7E    /* PPP帧标志位 */
+#define PPP_ESCAPE_BYTE         0x7D    /* PPP转义字符 */
+#define PPP_ESCAPE_XOR          0x20    /* PPP转义异或值 */
+#define PPP_MIN_FRAME_SIZE      4       /* PPP帧最小长度(地址+控制+协议) */
+
+/* 可配置的缓冲区大小 */
+#ifndef PPP_MAX_BUFFER_SIZE
+#define PPP_MAX_BUFFER_SIZE     2048    /* 默认解析缓冲区最大长度 */
+#endif
+
+#ifndef PPP_MAX_FRAME_SIZE
+#define PPP_MAX_FRAME_SIZE      1500    /* 默认PPP帧最大长度 */
+#endif
+
+/* 编译时检查 */
+#if PPP_MAX_BUFFER_SIZE < PPP_MIN_FRAME_SIZE
+#error "PPP_MAX_BUFFER_SIZE must be at least PPP_MIN_FRAME_SIZE"
+#endif
+
+#if PPP_MAX_FRAME_SIZE > PPP_MAX_BUFFER_SIZE
+#error "PPP_MAX_FRAME_SIZE cannot be larger than PPP_MAX_BUFFER_SIZE"
+#endif
+
+/* 运行时配置结构 */
+typedef struct {
+    uint32_t max_buffer_size;           /* 最大缓冲区大小 */
+    uint32_t max_frame_size;            /* 最大帧大小 */
+    bool enable_size_warnings;         /* 启用大小警告 */
+    bool auto_drop_oversized;          /* 自动丢弃超大帧 */
+} ppp_parser_config_t;
+
+/* PPP帧结构(可配置版本) */
+typedef struct {
+    uint8_t address;                    /* 地址字段 */
+    uint8_t control;                    /* 控制字段 */
+    uint16_t protocol;                  /* 协议字段 */
+    uint8_t *payload;                   /* 负载数据指针 */
+    uint32_t payload_len;               /* 负载长度 */
+    uint32_t payload_capacity;          /* 负载容量 */
+} ppp_frame_configurable_t;
+
+/* PPP解析器状态结构(可配置版本) */
+typedef struct {
+    /* 配置信息 */
+    ppp_parser_config_t config;
+    
+    /* 缓冲区 */
+    uint8_t *buffer;                    /* 动态分配的缓冲区 */
+    uint32_t buffer_len;                /* 缓冲区当前长度 */
+    uint32_t buffer_capacity;           /* 缓冲区容量 */
+    bool in_frame;                      /* 是否处于帧接收状态 */
+    uint32_t current_position;          /* 当前处理位置 */
+    
+    /* 统计信息 */
+    uint32_t total_frames_parsed;       /* 解析的总帧数 */
+    uint32_t total_bytes_processed;     /* 处理的总字节数 */
+    uint32_t dropped_data_count;        /* 丢弃数据次数 */
+    uint32_t oversized_frames_dropped;  /* 丢弃的超大帧数 */
+    uint32_t max_frame_size_seen;       /* 见过的最大帧大小 */
+} ppp_parser_configurable_t;
+
+/* 默认配置 */
+extern const ppp_parser_config_t PPP_DEFAULT_CONFIG;
+
+/* 大缓冲区配置(用于处理大帧) */
+extern const ppp_parser_config_t PPP_LARGE_BUFFER_CONFIG;
+
+/* 嵌入式配置(内存受限) */
+extern const ppp_parser_config_t PPP_EMBEDDED_CONFIG;
+
+/* 函数声明 */
+
+/**
+ * 创建配置
+ * @param max_buffer_size 最大缓冲区大小
+ * @param max_frame_size 最大帧大小
+ * @param enable_warnings 启用警告
+ * @param auto_drop 自动丢弃超大帧
+ * @return 配置结构
+ */
+ppp_parser_config_t ppp_create_config(uint32_t max_buffer_size, uint32_t max_frame_size,
+                                      bool enable_warnings, bool auto_drop);
+
+/**
+ * 初始化可配置PPP解析器
+ * @param parser PPP解析器指针
+ * @param config 配置指针(NULL使用默认配置)
+ * @return 成功返回true
+ */
+bool ppp_parser_configurable_init(ppp_parser_configurable_t *parser, 
+                                  const ppp_parser_config_t *config);
+
+/**
+ * 释放可配置PPP解析器
+ * @param parser PPP解析器指针
+ */
+void ppp_parser_configurable_free(ppp_parser_configurable_t *parser);
+
+/**
+ * 处理单个字节(可配置版本)
+ * @param parser PPP解析器指针
+ * @param byte 输入字节
+ * @param frame 输出的PPP帧指针
+ * @return true表示解析出完整帧
+ */
+bool ppp_parser_configurable_process_byte(ppp_parser_configurable_t *parser, uint8_t byte, 
+                                          ppp_frame_configurable_t *frame);
+
+/**
+ * 批量处理字节数据(可配置版本)
+ * @param parser PPP解析器指针
+ * @param data 输入数据指针
+ * @param data_len 输入数据长度
+ * @param frames 输出帧数组
+ * @param max_frames 最大帧数量
+ * @return 实际解析出的帧数量
+ */
+uint32_t ppp_parser_configurable_process_data(ppp_parser_configurable_t *parser, 
+                                              const uint8_t *data, uint32_t data_len, 
+                                              ppp_frame_configurable_t *frames, 
+                                              uint32_t max_frames);
+
+/**
+ * 释放PPP帧资源(可配置版本)
+ * @param frame PPP帧指针
+ */
+void ppp_frame_configurable_free(ppp_frame_configurable_t *frame);
+
+/**
+ * 打印配置信息
+ * @param config 配置指针
+ */
+void ppp_print_config(const ppp_parser_config_t *config);
+
+/**
+ * 打印解析器统计信息(可配置版本)
+ * @param parser 解析器指针
+ */
+void ppp_parser_configurable_print_stats(const ppp_parser_configurable_t *parser);
+
+/* 便利宏定义 */
+#define PPP_CONFIG_DEFAULT()        (&PPP_DEFAULT_CONFIG)
+#define PPP_CONFIG_LARGE_BUFFER()   (&PPP_LARGE_BUFFER_CONFIG)
+#define PPP_CONFIG_EMBEDDED()       (&PPP_EMBEDDED_CONFIG)
+
+/* 自定义配置宏 */
+#define PPP_CONFIG_CUSTOM(buf_size, frame_size, warnings, auto_drop) \
+    ppp_create_config(buf_size, frame_size, warnings, auto_drop)
+
+#endif /* PPP_PARSER_CONFIGURABLE_H */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser_dynamic.c b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser_dynamic.c
new file mode 100644 (file)
index 0000000..f7cae64
--- /dev/null
@@ -0,0 +1,272 @@
+#include "ppp_parser_dynamic.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * 初始化动态缓冲区
+ */
+bool ppp_dynamic_buffer_init(ppp_dynamic_buffer_t *buffer, uint32_t initial_size)
+{
+    if (!buffer) return false;
+    
+    memset(buffer, 0, sizeof(ppp_dynamic_buffer_t));
+    
+    if (initial_size == 0) {
+        initial_size = PPP_INITIAL_BUFFER_SIZE;
+    }
+    
+    buffer->data = malloc(initial_size);
+    if (!buffer->data) {
+        return false;
+    }
+    
+    buffer->capacity = initial_size;
+    buffer->len = 0;
+    buffer->size = initial_size;
+    
+    return true;
+}
+
+/**
+ * 释放动态缓冲区
+ */
+void ppp_dynamic_buffer_free(ppp_dynamic_buffer_t *buffer)
+{
+    if (!buffer) return;
+    
+    if (buffer->data) {
+        free(buffer->data);
+        buffer->data = NULL;
+    }
+    
+    buffer->capacity = 0;
+    buffer->len = 0;
+    buffer->size = 0;
+}
+
+/**
+ * 确保缓冲区有足够空间
+ */
+bool ppp_dynamic_buffer_ensure_space(ppp_dynamic_buffer_t *buffer, uint32_t required_size)
+{
+    if (!buffer) return false;
+    
+    if (buffer->capacity >= required_size) {
+        return true; /* 已有足够空间 */
+    }
+    
+    /* 检查是否超过最大限制 */
+    if (required_size > PPP_MAX_BUFFER_SIZE) {
+        printf("错误: 请求的缓冲区大小(%u)超过最大限制(%u)\n", 
+               required_size, PPP_MAX_BUFFER_SIZE);
+        return false;
+    }
+    
+    /* 计算新的容量(按步长增长) */
+    uint32_t new_capacity = buffer->capacity;
+    while (new_capacity < required_size) {
+        new_capacity += PPP_BUFFER_GROW_STEP;
+        if (new_capacity > PPP_MAX_BUFFER_SIZE) {
+            new_capacity = PPP_MAX_BUFFER_SIZE;
+            break;
+        }
+    }
+    
+    /* 重新分配内存 */
+    uint8_t *new_data = realloc(buffer->data, new_capacity);
+    if (!new_data) {
+        printf("错误: 无法重新分配缓冲区内存(大小: %u)\n", new_capacity);
+        return false;
+    }
+    
+    buffer->data = new_data;
+    buffer->capacity = new_capacity;
+    
+    printf("缓冲区扩展: %u -> %u 字节\n", buffer->size, new_capacity);
+    buffer->size = new_capacity;
+    
+    return true;
+}
+
+/**
+ * 向缓冲区添加数据
+ */
+bool ppp_dynamic_buffer_append(ppp_dynamic_buffer_t *buffer, const uint8_t *data, uint32_t len)
+{
+    if (!buffer || !data || len == 0) return false;
+    
+    if (!ppp_dynamic_buffer_ensure_space(buffer, buffer->len + len)) {
+        return false;
+    }
+    
+    memcpy(buffer->data + buffer->len, data, len);
+    buffer->len += len;
+    
+    return true;
+}
+
+/**
+ * 向缓冲区添加单个字节
+ */
+bool ppp_dynamic_buffer_append_byte(ppp_dynamic_buffer_t *buffer, uint8_t byte)
+{
+    return ppp_dynamic_buffer_append(buffer, &byte, 1);
+}
+
+/**
+ * 清空缓冲区(不释放内存)
+ */
+void ppp_dynamic_buffer_clear(ppp_dynamic_buffer_t *buffer)
+{
+    if (!buffer) return;
+    buffer->len = 0;
+}
+
+/**
+ * 初始化动态PPP解析器
+ */
+bool ppp_parser_dynamic_init(ppp_parser_dynamic_t *parser)
+{
+    if (!parser) return false;
+    
+    memset(parser, 0, sizeof(ppp_parser_dynamic_t));
+    
+    if (!ppp_dynamic_buffer_init(&parser->buffer, PPP_INITIAL_BUFFER_SIZE)) {
+        return false;
+    }
+    
+    parser->in_frame = false;
+    parser->current_position = 0;
+    
+    return true;
+}
+
+/**
+ * 释放动态PPP解析器
+ */
+void ppp_parser_dynamic_free(ppp_parser_dynamic_t *parser)
+{
+    if (!parser) return;
+    
+    ppp_dynamic_buffer_free(&parser->buffer);
+    memset(parser, 0, sizeof(ppp_parser_dynamic_t));
+}
+
+/**
+ * 处理单个字节(动态版本)
+ */
+bool ppp_parser_dynamic_process_byte(ppp_parser_dynamic_t *parser, uint8_t byte, 
+                                    ppp_frame_dynamic_t *frame)
+{
+    if (!parser || !frame) return false;
+    
+    parser->total_bytes_processed++;
+    parser->current_position++;
+    
+    if (byte == PPP_FLAG_BYTE) {
+        /* PPP帧标志位 */
+        if (parser->in_frame && parser->buffer.len > 0) {
+            /* 帧结束:处理缓冲区数据 */
+            bool result = ppp_parse_buffer_dynamic(parser, frame);
+            ppp_dynamic_buffer_clear(&parser->buffer);
+            parser->in_frame = false;
+            return result;
+        } else {
+            /* 帧开始:初始化缓冲区 */
+            if (parser->in_frame && parser->buffer.len > 0) {
+                /* 记录丢弃的数据 */
+                parser->dropped_data_count++;
+                printf("警告: 丢弃未完成的帧数据(%u字节)\n", parser->buffer.len);
+            }
+            parser->in_frame = true;
+            ppp_dynamic_buffer_clear(&parser->buffer);
+        }
+    } else {
+        if (parser->in_frame) {
+            /* 添加字节到缓冲区 */
+            if (!ppp_dynamic_buffer_append_byte(&parser->buffer, byte)) {
+                /* 缓冲区添加失败,可能是内存不足 */
+                printf("错误: 无法添加字节到缓冲区,丢弃当前帧\n");
+                parser->dropped_data_count++;
+                parser->in_frame = false;
+                ppp_dynamic_buffer_clear(&parser->buffer);
+                return false;
+            }
+        }
+    }
+    
+    return false;
+}
+
+/**
+ * 解析缓冲区数据(动态版本)
+ */
+static bool ppp_parse_buffer_dynamic(ppp_parser_dynamic_t *parser, ppp_frame_dynamic_t *frame)
+{
+    if (!parser || !frame || parser->buffer.len == 0) return false;
+    
+    /* 校验帧长度 */
+    if (parser->buffer.len < PPP_MIN_FRAME_SIZE) {
+        printf("警告: 帧长度不足(%u字节)\n", parser->buffer.len);
+        parser->dropped_data_count++;
+        return false;
+    }
+    
+    /* 更新最大帧大小统计 */
+    if (parser->buffer.len > parser->max_frame_size_seen) {
+        parser->max_frame_size_seen = parser->buffer.len;
+        printf("发现更大的帧: %u字节\n", parser->buffer.len);
+    }
+    
+    /* 初始化帧结构 */
+    memset(frame, 0, sizeof(ppp_frame_dynamic_t));
+    
+    /* 初始化动态负载缓冲区 */
+    if (!ppp_dynamic_buffer_init(&frame->payload, parser->buffer.len)) {
+        printf("错误: 无法为帧负载分配内存\n");
+        return false;
+    }
+    
+    /* 复制原始帧数据 */
+    if (!ppp_dynamic_buffer_append(&frame->payload, parser->buffer.data, parser->buffer.len)) {
+        printf("错误: 无法复制帧数据\n");
+        ppp_dynamic_buffer_free(&frame->payload);
+        return false;
+    }
+    
+    /* 暂时将协议字段设为0,由analyzer处理 */
+    frame->address = 0;
+    frame->control = 0;
+    frame->protocol = 0;
+    
+    parser->total_frames_parsed++;
+    return true;
+}
+
+/**
+ * 释放PPP帧资源
+ */
+void ppp_frame_dynamic_free(ppp_frame_dynamic_t *frame)
+{
+    if (!frame) return;
+    
+    ppp_dynamic_buffer_free(&frame->payload);
+    memset(frame, 0, sizeof(ppp_frame_dynamic_t));
+}
+
+/**
+ * 打印动态解析器统计信息
+ */
+void ppp_parser_dynamic_print_stats(const ppp_parser_dynamic_t *parser)
+{
+    if (!parser) return;
+    
+    printf("\n动态PPP解析器统计信息:\n");
+    printf("  处理的总字节数: %u\n", parser->total_bytes_processed);
+    printf("  解析的总帧数: %u\n", parser->total_frames_parsed);
+    printf("  丢弃数据次数: %u\n", parser->dropped_data_count);
+    printf("  缓冲区重分配次数: %u\n", parser->buffer_reallocations);
+    printf("  最大帧大小: %u字节\n", parser->max_frame_size_seen);
+    printf("  当前缓冲区容量: %u字节\n", parser->buffer.capacity);
+} 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser_dynamic.h b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser_dynamic.h
new file mode 100644 (file)
index 0000000..c580aaa
--- /dev/null
@@ -0,0 +1,125 @@
+#ifndef PPP_PARSER_DYNAMIC_H
+#define PPP_PARSER_DYNAMIC_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+/* PPP协议常量定义 */
+#define PPP_FLAG_BYTE           0x7E    /* PPP帧标志位 */
+#define PPP_ESCAPE_BYTE         0x7D    /* PPP转义字符 */
+#define PPP_ESCAPE_XOR          0x20    /* PPP转义异或值 */
+#define PPP_MIN_FRAME_SIZE      4       /* PPP帧最小长度(地址+控制+协议) */
+
+/* 动态缓冲区配置 */
+#define PPP_INITIAL_BUFFER_SIZE 1500    /* 初始缓冲区大小 */
+#define PPP_MAX_BUFFER_SIZE     65536   /* 最大缓冲区大小 */
+#define PPP_BUFFER_GROW_STEP    1024    /* 缓冲区增长步长 */
+
+/* 动态缓冲区结构 */
+typedef struct {
+    uint8_t *data;                      /* 缓冲区数据指针 */
+    uint32_t size;                      /* 缓冲区总大小 */
+    uint32_t len;                       /* 当前数据长度 */
+    uint32_t capacity;                  /* 当前容量 */
+} ppp_dynamic_buffer_t;
+
+/* PPP帧结构(动态版本) */
+typedef struct {
+    uint8_t address;                    /* 地址字段 */
+    uint8_t control;                    /* 控制字段 */
+    uint16_t protocol;                  /* 协议字段 */
+    ppp_dynamic_buffer_t payload;       /* 动态负载数据 */
+} ppp_frame_dynamic_t;
+
+/* PPP解析器状态结构(动态版本) */
+typedef struct {
+    ppp_dynamic_buffer_t buffer;        /* 动态帧数据缓冲区 */
+    bool in_frame;                      /* 是否处于帧接收状态 */
+    uint32_t current_position;          /* 当前处理位置 */
+    
+    /* 统计信息 */
+    uint32_t total_frames_parsed;       /* 解析的总帧数 */
+    uint32_t total_bytes_processed;     /* 处理的总字节数 */
+    uint32_t dropped_data_count;        /* 丢弃数据次数 */
+    uint32_t buffer_reallocations;      /* 缓冲区重分配次数 */
+    uint32_t max_frame_size_seen;       /* 见过的最大帧大小 */
+} ppp_parser_dynamic_t;
+
+/* 函数声明 */
+
+/**
+ * 初始化动态缓冲区
+ * @param buffer 缓冲区指针
+ * @param initial_size 初始大小
+ * @return 成功返回true
+ */
+bool ppp_dynamic_buffer_init(ppp_dynamic_buffer_t *buffer, uint32_t initial_size);
+
+/**
+ * 释放动态缓冲区
+ * @param buffer 缓冲区指针
+ */
+void ppp_dynamic_buffer_free(ppp_dynamic_buffer_t *buffer);
+
+/**
+ * 确保缓冲区有足够空间
+ * @param buffer 缓冲区指针
+ * @param required_size 需要的大小
+ * @return 成功返回true
+ */
+bool ppp_dynamic_buffer_ensure_space(ppp_dynamic_buffer_t *buffer, uint32_t required_size);
+
+/**
+ * 向缓冲区添加数据
+ * @param buffer 缓冲区指针
+ * @param data 要添加的数据
+ * @param len 数据长度
+ * @return 成功返回true
+ */
+bool ppp_dynamic_buffer_append(ppp_dynamic_buffer_t *buffer, const uint8_t *data, uint32_t len);
+
+/**
+ * 向缓冲区添加单个字节
+ * @param buffer 缓冲区指针
+ * @param byte 要添加的字节
+ * @return 成功返回true
+ */
+bool ppp_dynamic_buffer_append_byte(ppp_dynamic_buffer_t *buffer, uint8_t byte);
+
+/**
+ * 清空缓冲区(不释放内存)
+ * @param buffer 缓冲区指针
+ */
+void ppp_dynamic_buffer_clear(ppp_dynamic_buffer_t *buffer);
+
+/**
+ * 初始化动态PPP解析器
+ * @param parser PPP解析器指针
+ * @return 成功返回true
+ */
+bool ppp_parser_dynamic_init(ppp_parser_dynamic_t *parser);
+
+/**
+ * 释放动态PPP解析器
+ * @param parser PPP解析器指针
+ */
+void ppp_parser_dynamic_free(ppp_parser_dynamic_t *parser);
+
+/**
+ * 处理单个字节(动态版本)
+ * @param parser PPP解析器指针
+ * @param byte 输入字节
+ * @param frame 输出的PPP帧指针
+ * @return true表示解析出完整帧
+ */
+bool ppp_parser_dynamic_process_byte(ppp_parser_dynamic_t *parser, uint8_t byte, 
+                                    ppp_frame_dynamic_t *frame);
+
+/**
+ * 释放PPP帧资源
+ * @param frame PPP帧指针
+ */
+void ppp_frame_dynamic_free(ppp_frame_dynamic_t *frame);
+
+#endif /* PPP_PARSER_DYNAMIC_H */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser_streaming.h b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_parser_streaming.h
new file mode 100644 (file)
index 0000000..c199213
--- /dev/null
@@ -0,0 +1,164 @@
+#ifndef PPP_PARSER_STREAMING_H
+#define PPP_PARSER_STREAMING_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+/* PPP协议常量定义 */
+#define PPP_FLAG_BYTE           0x7E    /* PPP帧标志位 */
+#define PPP_ESCAPE_BYTE         0x7D    /* PPP转义字符 */
+#define PPP_ESCAPE_XOR          0x20    /* PPP转义异或值 */
+#define PPP_MIN_FRAME_SIZE      4       /* PPP帧最小长度(地址+控制+协议) */
+
+/* 流式处理配置 */
+#define PPP_STREAM_BUFFER_SIZE  512     /* 流式缓冲区大小 */
+#define PPP_MAX_FRAME_SIZE      65536   /* 最大支持的帧大小 */
+
+/* 流式处理状态 */
+typedef enum {
+    PPP_STREAM_STATE_IDLE,              /* 空闲状态 */
+    PPP_STREAM_STATE_IN_FRAME,          /* 帧内状态 */
+    PPP_STREAM_STATE_FRAME_COMPLETE,    /* 帧完成状态 */
+    PPP_STREAM_STATE_FRAME_TOO_LARGE,   /* 帧过大状态 */
+    PPP_STREAM_STATE_ERROR              /* 错误状态 */
+} ppp_stream_state_t;
+
+/* 流式处理回调函数类型 */
+typedef struct ppp_stream_parser ppp_stream_parser_t;
+
+/**
+ * 帧数据回调函数
+ * @param parser 解析器指针
+ * @param data 帧数据
+ * @param len 数据长度
+ * @param user_data 用户数据
+ * @return 处理是否成功
+ */
+typedef bool (*ppp_frame_data_callback_t)(ppp_stream_parser_t *parser, 
+                                          const uint8_t *data, uint32_t len, 
+                                          void *user_data);
+
+/**
+ * 帧完成回调函数
+ * @param parser 解析器指针
+ * @param total_len 帧总长度
+ * @param user_data 用户数据
+ * @return 处理是否成功
+ */
+typedef bool (*ppp_frame_complete_callback_t)(ppp_stream_parser_t *parser, 
+                                              uint32_t total_len, 
+                                              void *user_data);
+
+/**
+ * 错误处理回调函数
+ * @param parser 解析器指针
+ * @param error_code 错误代码
+ * @param user_data 用户数据
+ */
+typedef void (*ppp_error_callback_t)(ppp_stream_parser_t *parser, 
+                                     int error_code, 
+                                     void *user_data);
+
+/* 流式PPP解析器结构 */
+struct ppp_stream_parser {
+    /* 状态信息 */
+    ppp_stream_state_t state;           /* 当前状态 */
+    uint32_t current_frame_len;         /* 当前帧长度 */
+    uint32_t total_frames_parsed;       /* 解析的总帧数 */
+    uint32_t total_bytes_processed;     /* 处理的总字节数 */
+    uint32_t dropped_frames;            /* 丢弃的帧数 */
+    uint32_t oversized_frames;          /* 超大帧数 */
+    
+    /* 缓冲区(用于小块数据暂存) */
+    uint8_t buffer[PPP_STREAM_BUFFER_SIZE];
+    uint32_t buffer_len;
+    
+    /* 回调函数 */
+    ppp_frame_data_callback_t data_callback;
+    ppp_frame_complete_callback_t complete_callback;
+    ppp_error_callback_t error_callback;
+    void *user_data;
+};
+
+/* 错误代码定义 */
+#define PPP_ERROR_FRAME_TOO_LARGE   1   /* 帧过大 */
+#define PPP_ERROR_INVALID_STATE     2   /* 无效状态 */
+#define PPP_ERROR_CALLBACK_FAILED   3   /* 回调函数失败 */
+
+/* 函数声明 */
+
+/**
+ * 初始化流式PPP解析器
+ * @param parser 解析器指针
+ * @param data_callback 数据回调函数
+ * @param complete_callback 完成回调函数
+ * @param error_callback 错误回调函数
+ * @param user_data 用户数据
+ * @return 成功返回true
+ */
+bool ppp_stream_parser_init(ppp_stream_parser_t *parser,
+                           ppp_frame_data_callback_t data_callback,
+                           ppp_frame_complete_callback_t complete_callback,
+                           ppp_error_callback_t error_callback,
+                           void *user_data);
+
+/**
+ * 处理输入数据
+ * @param parser 解析器指针
+ * @param data 输入数据
+ * @param len 数据长度
+ * @return 处理的字节数
+ */
+uint32_t ppp_stream_parser_process(ppp_stream_parser_t *parser, 
+                                  const uint8_t *data, uint32_t len);
+
+/**
+ * 重置解析器状态
+ * @param parser 解析器指针
+ */
+void ppp_stream_parser_reset(ppp_stream_parser_t *parser);
+
+/**
+ * 获取解析器统计信息
+ * @param parser 解析器指针
+ */
+void ppp_stream_parser_print_stats(const ppp_stream_parser_t *parser);
+
+/* 示例:文件输出处理器 */
+typedef struct {
+    FILE *output_file;
+    uint32_t frame_count;
+    uint8_t *frame_buffer;
+    uint32_t frame_buffer_size;
+    uint32_t frame_buffer_pos;
+} ppp_file_output_t;
+
+/**
+ * 初始化文件输出处理器
+ * @param output 输出处理器
+ * @param filename 输出文件名
+ * @return 成功返回true
+ */
+bool ppp_file_output_init(ppp_file_output_t *output, const char *filename);
+
+/**
+ * 释放文件输出处理器
+ * @param output 输出处理器
+ */
+void ppp_file_output_free(ppp_file_output_t *output);
+
+/* 文件输出回调函数 */
+bool ppp_file_output_data_callback(ppp_stream_parser_t *parser, 
+                                  const uint8_t *data, uint32_t len, 
+                                  void *user_data);
+
+bool ppp_file_output_complete_callback(ppp_stream_parser_t *parser, 
+                                      uint32_t total_len, 
+                                      void *user_data);
+
+void ppp_file_output_error_callback(ppp_stream_parser_t *parser, 
+                                   int error_code, 
+                                   void *user_data);
+
+#endif /* PPP_PARSER_STREAMING_H */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/ppp_stream_parser.c b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_stream_parser.c
new file mode 100644 (file)
index 0000000..8b076d9
--- /dev/null
@@ -0,0 +1,397 @@
+#include "ppp_stream_parser.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * 初始化流式PPP解析器
+ */
+bool ppp_stream_parser_init(ppp_stream_parser_t *parser,
+                           uint32_t max_frame_size,
+                           ppp_frame_start_callback_t start_callback,
+                           ppp_frame_data_callback_t data_callback,
+                           ppp_frame_complete_callback_t complete_callback,
+                           ppp_error_callback_t error_callback,
+                           void *user_data)
+{
+    if (!parser || !data_callback || !complete_callback) {
+        return false;
+    }
+    
+    memset(parser, 0, sizeof(ppp_stream_parser_t));
+    
+    parser->state = PPP_STREAM_STATE_IDLE;
+    parser->max_frame_size = (max_frame_size > 0) ? max_frame_size : PPP_MAX_FRAME_SIZE;
+    parser->start_callback = start_callback;
+    parser->data_callback = data_callback;
+    parser->complete_callback = complete_callback;
+    parser->error_callback = error_callback;
+    parser->user_data = user_data;
+    
+    return true;
+}
+
+/**
+ * 处理输入数据
+ */
+uint32_t ppp_stream_parser_process(ppp_stream_parser_t *parser, 
+                                  const uint8_t *data, uint32_t len)
+{
+    if (!parser || !data || len == 0) {
+        return 0;
+    }
+    
+    uint32_t processed = 0;
+    
+    for (uint32_t i = 0; i < len; i++) {
+        uint8_t byte = data[i];
+        parser->total_bytes_processed++;
+        processed++;
+        
+        switch (parser->state) {
+            case PPP_STREAM_STATE_IDLE:
+                if (byte == PPP_FLAG_BYTE) {
+                    /* 帧开始 */
+                    parser->state = PPP_STREAM_STATE_IN_FRAME;
+                    parser->current_frame_len = 1;  /* 包含开始的0x7E */
+                    parser->buffer_len = 0;
+                    
+                    /* 将开始标志添加到缓冲区 */
+                    parser->buffer[parser->buffer_len++] = byte;
+                    
+                    /* 调用帧开始回调 */
+                    if (parser->start_callback) {
+                        if (!parser->start_callback(parser, parser->user_data)) {
+                            if (parser->error_callback) {
+                                parser->error_callback(parser, PPP_ERROR_CALLBACK_FAILED,
+                                                     "帧开始回调失败", parser->user_data);
+                            }
+                            parser->state = PPP_STREAM_STATE_ERROR;
+                        }
+                    }
+                }
+                /* 其他字节在空闲状态下被忽略 */
+                break;
+                
+            case PPP_STREAM_STATE_IN_FRAME:
+                if (byte == PPP_FLAG_BYTE) {
+                    /* 帧结束 - 添加结束标志 */
+                    parser->current_frame_len++;
+                    
+                    /* 将结束标志添加到缓冲区 */
+                    parser->buffer[parser->buffer_len++] = byte;
+                    
+                    if (parser->current_frame_len >= (PPP_MIN_FRAME_SIZE + 2)) {  /* 包含头尾0x7E */
+                        /* 处理缓冲区中的剩余数据 */
+                        if (parser->buffer_len > 0) {
+                            if (!parser->data_callback(parser, parser->buffer, 
+                                                     parser->buffer_len, parser->user_data)) {
+                                if (parser->error_callback) {
+                                    parser->error_callback(parser, PPP_ERROR_CALLBACK_FAILED,
+                                                         "数据回调失败", parser->user_data);
+                                }
+                                parser->state = PPP_STREAM_STATE_ERROR;
+                                break;
+                            }
+                        }
+                        
+                        /* 调用帧完成回调 */
+                        if (parser->complete_callback(parser, parser->current_frame_len, 
+                                                    parser->user_data)) {
+                            parser->total_frames_parsed++;
+                            parser->state = PPP_STREAM_STATE_FRAME_COMPLETE;
+                            
+                            /* 更新最大帧大小统计 */
+                            if (parser->current_frame_len > parser->max_frame_size_seen) {
+                                parser->max_frame_size_seen = parser->current_frame_len;
+                            }
+                        } else {
+                            if (parser->error_callback) {
+                                parser->error_callback(parser, PPP_ERROR_CALLBACK_FAILED,
+                                                     "帧完成回调失败", parser->user_data);
+                            }
+                            parser->state = PPP_STREAM_STATE_ERROR;
+                        }
+                    } else {
+                        /* 帧太短,丢弃 */
+                        parser->dropped_frames++;
+                        if (parser->error_callback) {
+                            char msg[64];
+                            snprintf(msg, sizeof(msg), "帧长度不足(%u字节)", parser->current_frame_len);
+                            parser->error_callback(parser, PPP_ERROR_FRAME_TOO_LARGE, msg, parser->user_data);
+                        }
+                    }
+                    
+                    /* 重置状态,准备下一帧 */
+                    parser->state = PPP_STREAM_STATE_IDLE;
+                    parser->current_frame_len = 0;
+                    parser->buffer_len = 0;
+                } else {
+                    /* 帧内数据 */
+                    parser->current_frame_len++;
+                    
+                    /* 检查帧大小限制 */
+                    if (parser->current_frame_len > parser->max_frame_size) {
+                        parser->oversized_frames++;
+                        parser->dropped_frames++;
+                        if (parser->error_callback) {
+                            char msg[64];
+                            snprintf(msg, sizeof(msg), "帧过大(%u字节)", parser->current_frame_len);
+                            parser->error_callback(parser, PPP_ERROR_FRAME_TOO_LARGE, msg, parser->user_data);
+                        }
+                        parser->state = PPP_STREAM_STATE_FRAME_TOO_LARGE;
+                        break;
+                    }
+                    
+                    /* 将数据添加到缓冲区 */
+                    parser->buffer[parser->buffer_len++] = byte;
+                    
+                    /* 如果缓冲区满了,调用数据回调 */
+                    if (parser->buffer_len >= PPP_STREAM_BUFFER_SIZE) {
+                        if (!parser->data_callback(parser, parser->buffer, 
+                                                 parser->buffer_len, parser->user_data)) {
+                            if (parser->error_callback) {
+                                parser->error_callback(parser, PPP_ERROR_CALLBACK_FAILED,
+                                                     "数据回调失败", parser->user_data);
+                            }
+                            parser->state = PPP_STREAM_STATE_ERROR;
+                            break;
+                        }
+                        parser->buffer_len = 0;
+                    }
+                }
+                break;
+                
+            case PPP_STREAM_STATE_FRAME_TOO_LARGE:
+                /* 等待帧结束标志 */
+                if (byte == PPP_FLAG_BYTE) {
+                    parser->state = PPP_STREAM_STATE_IDLE;
+                    parser->current_frame_len = 0;
+                    parser->buffer_len = 0;
+                }
+                break;
+                
+            case PPP_STREAM_STATE_FRAME_COMPLETE:
+                /* 帧完成后,重新开始处理 */
+                parser->state = PPP_STREAM_STATE_IDLE;
+                /* 重新处理当前字节 */
+                i--;
+                processed--;
+                parser->total_bytes_processed--;
+                break;
+                
+            case PPP_STREAM_STATE_ERROR:
+                /* 错误状态,等待重置 */
+                return processed;
+        }
+    }
+    
+    return processed;
+}
+
+/**
+ * 重置解析器状态
+ */
+void ppp_stream_parser_reset(ppp_stream_parser_t *parser)
+{
+    if (!parser) return;
+    
+    parser->state = PPP_STREAM_STATE_IDLE;
+    parser->current_frame_len = 0;
+    parser->buffer_len = 0;
+}
+
+/**
+ * 获取解析器统计信息
+ */
+void ppp_stream_parser_print_stats(const ppp_stream_parser_t *parser)
+{
+    if (!parser) return;
+    
+    printf("\n流式PPP解析器统计信息:\n");
+    printf("  当前状态: %s\n", ppp_stream_state_name(parser->state));
+    printf("  处理的总字节数: %u\n", parser->total_bytes_processed);
+    printf("  解析的总帧数: %u\n", parser->total_frames_parsed);
+    printf("  丢弃的帧数: %u\n", parser->dropped_frames);
+    printf("  超大帧数: %u\n", parser->oversized_frames);
+    printf("  最大帧大小: %u字节\n", parser->max_frame_size_seen);
+    printf("  最大允许帧大小: %u字节\n", parser->max_frame_size);
+}
+
+/**
+ * 获取状态名称
+ */
+const char* ppp_stream_state_name(ppp_stream_state_t state)
+{
+    switch (state) {
+        case PPP_STREAM_STATE_IDLE:
+            return "空闲";
+        case PPP_STREAM_STATE_IN_FRAME:
+            return "帧内";
+        case PPP_STREAM_STATE_FRAME_COMPLETE:
+            return "帧完成";
+        case PPP_STREAM_STATE_FRAME_TOO_LARGE:
+            return "帧过大";
+        case PPP_STREAM_STATE_ERROR:
+            return "错误";
+        default:
+            return "未知";
+    }
+}
+
+/* 帧收集器实现 */
+
+/**
+ * 初始化帧收集器
+ */
+bool ppp_frame_collector_init(ppp_frame_collector_t *collector, uint32_t max_frames)
+{
+    if (!collector || max_frames == 0) {
+        return false;
+    }
+    
+    memset(collector, 0, sizeof(ppp_frame_collector_t));
+    
+    collector->frames = malloc(max_frames * sizeof(uint8_t*));
+    collector->frame_lengths = malloc(max_frames * sizeof(uint32_t));
+    
+    if (!collector->frames || !collector->frame_lengths) {
+        free(collector->frames);
+        free(collector->frame_lengths);
+        return false;
+    }
+    
+    collector->max_frames = max_frames;
+    collector->frame_count = 0;
+    
+    return true;
+}
+
+/**
+ * 释放帧收集器
+ */
+void ppp_frame_collector_free(ppp_frame_collector_t *collector)
+{
+    if (!collector) return;
+    
+    /* 释放所有帧数据 */
+    for (uint32_t i = 0; i < collector->frame_count; i++) {
+        free(collector->frames[i]);
+    }
+    
+    /* 释放当前帧数据 */
+    free(collector->current_frame_data);
+    
+    /* 释放数组 */
+    free(collector->frames);
+    free(collector->frame_lengths);
+    
+    memset(collector, 0, sizeof(ppp_frame_collector_t));
+}
+
+/**
+ * 获取收集到的帧数据
+ */
+bool ppp_frame_collector_get_frame(const ppp_frame_collector_t *collector, 
+                                  uint32_t frame_index,
+                                  const uint8_t **frame_data, 
+                                  uint32_t *frame_len)
+{
+    if (!collector || !frame_data || !frame_len || frame_index >= collector->frame_count) {
+        return false;
+    }
+    
+    *frame_data = collector->frames[frame_index];
+    *frame_len = collector->frame_lengths[frame_index];
+    
+    return true;
+}
+
+/* 帧收集器的回调函数实现 */
+
+bool ppp_collector_start_callback(ppp_stream_parser_t *parser, void *user_data)
+{
+    ppp_frame_collector_t *collector = (ppp_frame_collector_t*)user_data;
+    
+    if (!collector) return false;
+    
+    /* 检查是否还能收集更多帧 */
+    if (collector->frame_count >= collector->max_frames) {
+        return false;
+    }
+    
+    /* 初始化当前帧 */
+    collector->current_frame_capacity = 1024; /* 初始容量 */
+    collector->current_frame_data = malloc(collector->current_frame_capacity);
+    collector->current_frame_len = 0;
+    
+    return (collector->current_frame_data != NULL);
+}
+
+bool ppp_collector_data_callback(ppp_stream_parser_t *parser, 
+                                const uint8_t *data, uint32_t len, void *user_data)
+{
+    ppp_frame_collector_t *collector = (ppp_frame_collector_t*)user_data;
+    
+    if (!collector || !data || len == 0) return false;
+    
+    /* 确保有足够空间 */
+    uint32_t required_size = collector->current_frame_len + len;
+    if (required_size > collector->current_frame_capacity) {
+        /* 扩展容量 */
+        uint32_t new_capacity = collector->current_frame_capacity;
+        while (new_capacity < required_size) {
+            new_capacity *= 2;
+        }
+        
+        uint8_t *new_data = realloc(collector->current_frame_data, new_capacity);
+        if (!new_data) {
+            return false;
+        }
+        
+        collector->current_frame_data = new_data;
+        collector->current_frame_capacity = new_capacity;
+    }
+    
+    /* 复制数据 */
+    memcpy(collector->current_frame_data + collector->current_frame_len, data, len);
+    collector->current_frame_len += len;
+    
+    return true;
+}
+
+bool ppp_collector_complete_callback(ppp_stream_parser_t *parser, 
+                                    uint32_t total_len, void *user_data)
+{
+    ppp_frame_collector_t *collector = (ppp_frame_collector_t*)user_data;
+    
+    if (!collector) return false;
+    
+    /* 将当前帧添加到收集器 */
+    collector->frames[collector->frame_count] = collector->current_frame_data;
+    collector->frame_lengths[collector->frame_count] = collector->current_frame_len;
+    collector->frame_count++;
+    
+    /* 重置当前帧 */
+    collector->current_frame_data = NULL;
+    collector->current_frame_len = 0;
+    collector->current_frame_capacity = 0;
+    
+    return true;
+}
+
+void ppp_collector_error_callback(ppp_stream_parser_t *parser, 
+                                 int error_code, const char *error_msg, void *user_data)
+{
+    ppp_frame_collector_t *collector = (ppp_frame_collector_t*)user_data;
+    
+    printf("帧收集器错误 [%d]: %s\n", error_code, error_msg ? error_msg : "未知错误");
+    
+    /* 清理当前帧数据 */
+    if (collector && collector->current_frame_data) {
+        free(collector->current_frame_data);
+        collector->current_frame_data = NULL;
+        collector->current_frame_len = 0;
+        collector->current_frame_capacity = 0;
+    }
+} 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/ppp_stream_parser.h b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_stream_parser.h
new file mode 100644 (file)
index 0000000..b710094
--- /dev/null
@@ -0,0 +1,206 @@
+#ifndef PPP_STREAM_PARSER_H
+#define PPP_STREAM_PARSER_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+/* PPP协议常量定义 */
+#define PPP_FLAG_BYTE           0x7E    /* PPP帧标志位 */
+#define PPP_ESCAPE_BYTE         0x7D    /* PPP转义字符 */
+#define PPP_ESCAPE_XOR          0x20    /* PPP转义异或值 */
+#define PPP_MIN_FRAME_SIZE      4       /* PPP帧最小长度(地址+控制+协议) */
+
+/* 流式处理配置 */
+#define PPP_STREAM_BUFFER_SIZE  1024    /* 流式缓冲区大小 */
+#ifndef PPP_MAX_FRAME_SIZE
+#define PPP_MAX_FRAME_SIZE      65536   /* 最大支持的帧大小 */
+#endif
+
+/* 流式处理状态 */
+typedef enum {
+    PPP_STREAM_STATE_IDLE,              /* 空闲状态 */
+    PPP_STREAM_STATE_IN_FRAME,          /* 帧内状态 */
+    PPP_STREAM_STATE_FRAME_COMPLETE,    /* 帧完成状态 */
+    PPP_STREAM_STATE_FRAME_TOO_LARGE,   /* 帧过大状态 */
+    PPP_STREAM_STATE_ERROR              /* 错误状态 */
+} ppp_stream_state_t;
+
+/* 错误代码定义 */
+#define PPP_ERROR_FRAME_TOO_LARGE   1   /* 帧过大 */
+#define PPP_ERROR_INVALID_STATE     2   /* 无效状态 */
+#define PPP_ERROR_CALLBACK_FAILED   3   /* 回调函数失败 */
+#define PPP_ERROR_OUT_OF_MEMORY     4   /* 内存不足 */
+
+/* 前向声明 */
+typedef struct ppp_stream_parser ppp_stream_parser_t;
+
+/* 回调函数类型定义 */
+
+/**
+ * 帧开始回调函数
+ * @param parser 解析器指针
+ * @param user_data 用户数据
+ * @return 处理是否成功
+ */
+typedef bool (*ppp_frame_start_callback_t)(ppp_stream_parser_t *parser, void *user_data);
+
+/**
+ * 帧数据回调函数
+ * @param parser 解析器指针
+ * @param data 帧数据块
+ * @param len 数据长度
+ * @param user_data 用户数据
+ * @return 处理是否成功
+ */
+typedef bool (*ppp_frame_data_callback_t)(ppp_stream_parser_t *parser, 
+                                          const uint8_t *data, uint32_t len, 
+                                          void *user_data);
+
+/**
+ * 帧完成回调函数
+ * @param parser 解析器指针
+ * @param total_len 帧总长度
+ * @param user_data 用户数据
+ * @return 处理是否成功
+ */
+typedef bool (*ppp_frame_complete_callback_t)(ppp_stream_parser_t *parser, 
+                                              uint32_t total_len, 
+                                              void *user_data);
+
+/**
+ * 错误处理回调函数
+ * @param parser 解析器指针
+ * @param error_code 错误代码
+ * @param error_msg 错误消息
+ * @param user_data 用户数据
+ */
+typedef void (*ppp_error_callback_t)(ppp_stream_parser_t *parser, 
+                                     int error_code, 
+                                     const char *error_msg,
+                                     void *user_data);
+
+/* 流式PPP解析器结构 */
+struct ppp_stream_parser {
+    /* 状态信息 */
+    ppp_stream_state_t state;           /* 当前状态 */
+    uint32_t current_frame_len;         /* 当前帧长度 */
+    uint32_t max_frame_size;            /* 最大允许帧大小 */
+    
+    /* 统计信息 */
+    uint32_t total_frames_parsed;       /* 解析的总帧数 */
+    uint32_t total_bytes_processed;     /* 处理的总字节数 */
+    uint32_t dropped_frames;            /* 丢弃的帧数 */
+    uint32_t oversized_frames;          /* 超大帧数 */
+    uint32_t max_frame_size_seen;       /* 见过的最大帧大小 */
+    
+    /* 小缓冲区(用于处理跨块的数据) */
+    uint8_t buffer[PPP_STREAM_BUFFER_SIZE];
+    uint32_t buffer_len;
+    
+    /* 回调函数 */
+    ppp_frame_start_callback_t start_callback;
+    ppp_frame_data_callback_t data_callback;
+    ppp_frame_complete_callback_t complete_callback;
+    ppp_error_callback_t error_callback;
+    void *user_data;
+};
+
+/* 函数声明 */
+
+/**
+ * 初始化流式PPP解析器
+ * @param parser 解析器指针
+ * @param max_frame_size 最大帧大小(0使用默认值)
+ * @param start_callback 帧开始回调函数
+ * @param data_callback 数据回调函数
+ * @param complete_callback 完成回调函数
+ * @param error_callback 错误回调函数
+ * @param user_data 用户数据
+ * @return 成功返回true
+ */
+bool ppp_stream_parser_init(ppp_stream_parser_t *parser,
+                           uint32_t max_frame_size,
+                           ppp_frame_start_callback_t start_callback,
+                           ppp_frame_data_callback_t data_callback,
+                           ppp_frame_complete_callback_t complete_callback,
+                           ppp_error_callback_t error_callback,
+                           void *user_data);
+
+/**
+ * 处理输入数据
+ * @param parser 解析器指针
+ * @param data 输入数据
+ * @param len 数据长度
+ * @return 处理的字节数
+ */
+uint32_t ppp_stream_parser_process(ppp_stream_parser_t *parser, 
+                                  const uint8_t *data, uint32_t len);
+
+/**
+ * 重置解析器状态
+ * @param parser 解析器指针
+ */
+void ppp_stream_parser_reset(ppp_stream_parser_t *parser);
+
+/**
+ * 获取解析器统计信息
+ * @param parser 解析器指针
+ */
+void ppp_stream_parser_print_stats(const ppp_stream_parser_t *parser);
+
+/**
+ * 获取状态名称
+ * @param state 状态值
+ * @return 状态名称字符串
+ */
+const char* ppp_stream_state_name(ppp_stream_state_t state);
+
+/* 便利函数:创建简单的帧收集器 */
+typedef struct {
+    uint8_t **frames;                   /* 帧数据数组 */
+    uint32_t *frame_lengths;            /* 帧长度数组 */
+    uint32_t frame_count;               /* 当前帧数量 */
+    uint32_t max_frames;                /* 最大帧数量 */
+    uint32_t current_frame_capacity;    /* 当前帧容量 */
+    uint8_t *current_frame_data;        /* 当前帧数据 */
+    uint32_t current_frame_len;         /* 当前帧长度 */
+} ppp_frame_collector_t;
+
+/**
+ * 初始化帧收集器
+ * @param collector 收集器指针
+ * @param max_frames 最大帧数量
+ * @return 成功返回true
+ */
+bool ppp_frame_collector_init(ppp_frame_collector_t *collector, uint32_t max_frames);
+
+/**
+ * 释放帧收集器
+ * @param collector 收集器指针
+ */
+void ppp_frame_collector_free(ppp_frame_collector_t *collector);
+
+/**
+ * 获取收集到的帧数据
+ * @param collector 收集器指针
+ * @param frame_index 帧索引
+ * @param frame_data 输出帧数据指针
+ * @param frame_len 输出帧长度
+ * @return 成功返回true
+ */
+bool ppp_frame_collector_get_frame(const ppp_frame_collector_t *collector, 
+                                  uint32_t frame_index,
+                                  const uint8_t **frame_data, 
+                                  uint32_t *frame_len);
+
+/* 帧收集器的回调函数 */
+bool ppp_collector_start_callback(ppp_stream_parser_t *parser, void *user_data);
+bool ppp_collector_data_callback(ppp_stream_parser_t *parser, 
+                                const uint8_t *data, uint32_t len, void *user_data);
+bool ppp_collector_complete_callback(ppp_stream_parser_t *parser, 
+                                    uint32_t total_len, void *user_data);
+void ppp_collector_error_callback(ppp_stream_parser_t *parser, 
+                                 int error_code, const char *error_msg, void *user_data);
+
+#endif /* PPP_STREAM_PARSER_H */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/ppp_stream_test b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_stream_test
new file mode 100644 (file)
index 0000000..d63d4e0
Binary files /dev/null and b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_stream_test differ
diff --git a/code/sdk/zhihui/ppp/ppp_dec_test/ppp_stream_test.c b/code/sdk/zhihui/ppp/ppp_dec_test/ppp_stream_test.c
new file mode 100644 (file)
index 0000000..b03bb95
--- /dev/null
@@ -0,0 +1,376 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include "ppp_stream_parser.h"
+#include "ppp_packet_analyzer.h"
+
+/* 配置常量 */
+#define MAX_FILE_SIZE           (1024 * 1024)  /* 最大文件大小1MB */
+#define MAX_FRAMES              1000           /* 最大帧数量 */
+#define CHUNK_SIZE              256            /* 流式处理块大小 */
+
+/* 全局变量 */
+static uint8_t g_hex_data[MAX_FILE_SIZE];      /* 十六进制数据缓冲区 */
+
+/**
+ * 从十六进制字符串转换为字节值
+ */
+static int hex_char_to_byte(char hex_char)
+{
+    if (hex_char >= '0' && hex_char <= '9') {
+        return hex_char - '0';
+    } else if (hex_char >= 'A' && hex_char <= 'F') {
+        return hex_char - 'A' + 10;
+    } else if (hex_char >= 'a' && hex_char <= 'f') {
+        return hex_char - 'a' + 10;
+    }
+    return -1;
+}
+
+/**
+ * 从文件中读取十六进制数据
+ */
+static uint32_t read_hex_file(const char *file_path, uint8_t *data, uint32_t max_size)
+{
+    if (!file_path || !data || max_size == 0) {
+        printf("错误: 无效的参数\n");
+        return 0;
+    }
+    
+    FILE *file = fopen(file_path, "r");
+    if (!file) {
+        printf("错误: 无法打开文件 %s: %s\n", file_path, strerror(errno));
+        return 0;
+    }
+    
+    char line[256];
+    uint32_t data_len = 0;
+    uint32_t line_number = 0;
+    
+    printf("开始读取文件: %s\n", file_path);
+    
+    while (fgets(line, sizeof(line), file) && data_len < max_size) {
+        line_number++;
+        
+        /* 移除行尾的换行符和空白字符 */
+        char *end = line + strlen(line) - 1;
+        while (end >= line && isspace(*end)) {
+            *end-- = '\0';
+        }
+        
+        /* 跳过空行 */
+        if (strlen(line) == 0) {
+            continue;
+        }
+        
+        /* 处理每行的十六进制字符串 */
+        char *ptr = line;
+        while (*ptr && data_len < max_size) {
+            /* 跳过空白字符 */
+            while (*ptr && isspace(*ptr)) {
+                ptr++;
+            }
+            
+            if (!*ptr) break;
+            
+            /* 读取两个十六进制字符组成一个字节 */
+            if (strlen(ptr) >= 2) {
+                int high = hex_char_to_byte(ptr[0]);
+                int low = hex_char_to_byte(ptr[1]);
+                
+                if (high >= 0 && low >= 0) {
+                    data[data_len++] = (high << 4) | low;
+                    ptr += 2;
+                } else {
+                    printf("警告: 文件%s第%u行包含无效的十六进制字符: %c%c\n", 
+                           file_path, line_number, ptr[0], ptr[1]);
+                    ptr += 2;
+                }
+            } else if (strlen(ptr) == 1) {
+                /* 单个十六进制字符,当作一个字节处理 */
+                int value = hex_char_to_byte(ptr[0]);
+                if (value >= 0) {
+                    data[data_len++] = value;
+                    ptr++;
+                } else {
+                    printf("警告: 文件%s第%u行包含无效的十六进制字符: %c\n", 
+                           file_path, line_number, ptr[0]);
+                    ptr++;
+                }
+            }
+        }
+    }
+    
+    fclose(file);
+    
+    if (data_len >= max_size) {
+        printf("警告: 文件%s数据量超过缓冲区大小,只读取了前%u字节\n", file_path, max_size);
+    }
+    
+    printf("成功读取文件%s: %u字节\n", file_path, data_len);
+    return data_len;
+}
+
+/**
+ * 流式分析PPP文件
+ */
+static void analyze_ppp_file_streaming(const char *file_path)
+{
+    printf("\n=== 流式分析文件: %s ===\n", file_path);
+    
+    /* 读取文件数据 */
+    uint32_t data_len = read_hex_file(file_path, g_hex_data, MAX_FILE_SIZE);
+    if (data_len == 0) {
+        printf("文件读取失败,跳过分析\n");
+        return;
+    }
+    
+    /* 初始化帧收集器 */
+    ppp_frame_collector_t collector;
+    if (!ppp_frame_collector_init(&collector, MAX_FRAMES)) {
+        printf("错误: 无法初始化帧收集器\n");
+        return;
+    }
+    
+    /* 初始化流式解析器 */
+    ppp_stream_parser_t parser;
+    if (!ppp_stream_parser_init(&parser, 
+                               0,  /* 使用默认最大帧大小 */
+                               ppp_collector_start_callback,
+                               ppp_collector_data_callback,
+                               ppp_collector_complete_callback,
+                               ppp_collector_error_callback,
+                               &collector)) {
+        printf("错误: 无法初始化流式解析器\n");
+        ppp_frame_collector_free(&collector);
+        return;
+    }
+    
+    printf("\n--- 流式PPP帧解析阶段 ---\n");
+    printf("使用块大小: %d字节\n", CHUNK_SIZE);
+    
+    /* 分块处理数据 */
+    uint32_t total_processed = 0;
+    uint32_t chunk_count = 0;
+    
+    for (uint32_t offset = 0; offset < data_len; offset += CHUNK_SIZE) {
+        uint32_t chunk_size = (offset + CHUNK_SIZE > data_len) ? 
+                             (data_len - offset) : CHUNK_SIZE;
+        
+        chunk_count++;
+        printf("处理块 #%u: 偏移=%u, 大小=%u字节\n", chunk_count, offset, chunk_size);
+        
+        uint32_t processed = ppp_stream_parser_process(&parser, 
+                                                      g_hex_data + offset, 
+                                                      chunk_size);
+        total_processed += processed;
+        
+        if (processed != chunk_size) {
+            printf("警告: 块 #%u 只处理了 %u/%u 字节\n", chunk_count, processed, chunk_size);
+        }
+    }
+    
+    printf("流式解析完成,总共处理 %u 字节,分 %u 个块\n", total_processed, chunk_count);
+    
+    /* 打印解析器统计信息 */
+    ppp_stream_parser_print_stats(&parser);
+    
+    /* 处理收集到的帧 */
+    printf("\n--- 收集到的PPP帧分析 ---\n");
+    printf("总共收集到 %u 个PPP帧\n", collector.frame_count);
+    
+    if (collector.frame_count > 0) {
+        /* 分析前几个帧 */
+        uint32_t analyze_count = (collector.frame_count > 5) ? 5 : collector.frame_count;
+        
+        for (uint32_t i = 0; i < analyze_count; i++) {
+            const uint8_t *frame_data;
+            uint32_t frame_len;
+            
+            if (ppp_frame_collector_get_frame(&collector, i, &frame_data, &frame_len)) {
+                printf("\n--- 帧 #%u 分析 (长度: %u字节) ---\n", i + 1, frame_len);
+                
+                /* 打印帧数据(前32字节) */
+                printf("帧数据: ");
+                uint32_t print_len = (frame_len > 32) ? 32 : frame_len;
+                for (uint32_t j = 0; j < print_len; j++) {
+                    printf("%02X", frame_data[j]);
+                }
+                if (frame_len > 32) {
+                    printf("...");
+                }
+                printf("\n");
+                
+                /* 使用packet analyzer分析帧内容 */
+                packet_analysis_result_t result;
+                
+                /* 创建临时的ppp_frame_t结构 */
+                ppp_frame_t temp_frame;
+                memset(&temp_frame, 0, sizeof(temp_frame));
+                
+                /* 设置原始帧数据(包含头尾0x7E) */
+                temp_frame.raw_frame_len = frame_len;
+                memcpy(temp_frame.raw_frame, frame_data, 
+                       (frame_len > (PPP_MAX_FRAME_SIZE + 2)) ? (PPP_MAX_FRAME_SIZE + 2) : frame_len);
+                
+                if (analyze_ppp_frame(&temp_frame, &result)) {
+                    printf("协议分析: %s\n", result.protocol_name);
+                    
+                    if (result.has_ip) {
+                        char src_ip[16], dst_ip[16];
+                        format_ip_address(&result.ip_info.src_ip, src_ip, sizeof(src_ip));
+                        format_ip_address(&result.ip_info.dst_ip, dst_ip, sizeof(dst_ip));
+                        
+                        printf("IP: %s -> %s, 验证: %s\n", 
+                               src_ip, dst_ip,
+                               (result.ip_info.validation == IP_VALID) ? "通过" : "失败");
+                        
+                        if (result.has_tcp) {
+                            printf("TCP: 端口 %u -> %u\n", 
+                                   result.tcp_info.src_port, result.tcp_info.dst_port);
+                        } else if (result.has_udp) {
+                            printf("UDP: 端口 %u -> %u\n", 
+                                   result.udp_info.src_port, result.udp_info.dst_port);
+                        }
+                    }
+                } else {
+                    printf("协议分析失败\n");
+                }
+            }
+        }
+        
+        if (collector.frame_count > 5) {
+            printf("\n... 还有 %u 个帧未显示详细分析\n", collector.frame_count - 5);
+        }
+        
+        /* 统计协议分布 */
+        printf("\n--- 协议统计 ---\n");
+        uint32_t ip_count = 0, tcp_count = 0, udp_count = 0, lcp_count = 0, other_count = 0;
+        
+        for (uint32_t i = 0; i < collector.frame_count; i++) {
+            const uint8_t *frame_data;
+            uint32_t frame_len;
+            
+            if (ppp_frame_collector_get_frame(&collector, i, &frame_data, &frame_len)) {
+                ppp_frame_t temp_frame;
+                memset(&temp_frame, 0, sizeof(temp_frame));
+                
+                /* 设置原始帧数据(包含头尾0x7E) */
+                temp_frame.raw_frame_len = frame_len;
+                memcpy(temp_frame.raw_frame, frame_data, 
+                       (frame_len > (PPP_MAX_FRAME_SIZE + 2)) ? (PPP_MAX_FRAME_SIZE + 2) : frame_len);
+                
+                packet_analysis_result_t result;
+                if (analyze_ppp_frame(&temp_frame, &result)) {
+                    if (result.has_ip) {
+                        ip_count++;
+                        if (result.has_tcp) tcp_count++;
+                        else if (result.has_udp) udp_count++;
+                    } else if (strstr(result.protocol_name, "LCP")) {
+                        lcp_count++;
+                    } else {
+                        other_count++;
+                    }
+                } else {
+                    other_count++;
+                }
+            }
+        }
+        
+        printf("IP包: %u\n", ip_count);
+        printf("TCP包: %u\n", tcp_count);
+        printf("UDP包: %u\n", udp_count);
+        printf("LCP包: %u\n", lcp_count);
+        printf("其他包: %u\n", other_count);
+    }
+    
+    /* 清理资源 */
+    ppp_frame_collector_free(&collector);
+    
+    printf("\n=== 流式分析完成: %s ===\n", file_path);
+}
+
+/**
+ * 打印使用说明
+ */
+static void print_usage(const char *program_name)
+{
+    printf("流式PPP协议解析工具\n");
+    printf("演示流式处理大型PPP数据文件的能力\n\n");
+    printf("使用方法:\n");
+    printf("  %s [文件1] [文件2] ...\n\n", program_name);
+    printf("特点:\n");
+    printf("  - 流式处理,内存占用固定\n");
+    printf("  - 支持任意大小的PPP帧\n");
+    printf("  - 分块处理,模拟实时数据流\n");
+    printf("  - 回调机制,灵活的数据处理\n\n");
+    printf("示例:\n");
+    printf("  %s out0.txt\n", program_name);
+    printf("  %s out0.txt out1.txt\n", program_name);
+}
+
+/**
+ * 主函数
+ */
+int main(int argc, char *argv[])
+{
+    printf("流式PPP协议解析工具 - 启动\n");
+    printf("版本: 1.0\n");
+    printf("特性: 流式处理、动态内存管理、回调机制\n\n");
+    
+    /* 检查命令行参数 */
+    if (argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) {
+        print_usage(argv[0]);
+        return 0;
+    }
+    
+    /* 确定要分析的文件列表 */
+    const char **files_to_analyze;
+    int file_count;
+    const char *default_files[] = {"out0.txt", "out1.txt"};
+    
+    if (argc > 1) {
+        /* 使用命令行参数中的文件列表 */
+        files_to_analyze = (const char **)&argv[1];
+        file_count = argc - 1;
+    } else {
+        /* 使用默认文件列表 */
+        files_to_analyze = default_files;
+        file_count = 2;
+        printf("未指定文件,使用默认文件: out0.txt, out1.txt\n");
+    }
+    
+    /* 遍历并分析每个文件 */
+    int success_count = 0;
+    for (int i = 0; i < file_count; i++) {
+        const char *file_path = files_to_analyze[i];
+        
+        /* 检查文件是否存在 */
+        FILE *test_file = fopen(file_path, "r");
+        if (test_file) {
+            fclose(test_file);
+            analyze_ppp_file_streaming(file_path);
+            success_count++;
+        } else {
+            printf("\n错误: 文件不存在或无法访问: %s\n", file_path);
+        }
+    }
+    
+    /* 打印总结信息 */
+    printf("\n============================================================\n");
+    printf("流式分析总结:\n");
+    printf("  指定文件数量: %d\n", file_count);
+    printf("  成功分析文件: %d\n", success_count);
+    printf("  失败文件数量: %d\n", file_count - success_count);
+    printf("  使用的块大小: %d字节\n", CHUNK_SIZE);
+    
+    if (success_count == 0) {
+        printf("\n警告: 没有成功分析任何文件\n");
+        return 1;
+    }
+    
+    printf("\n流式PPP协议解析工具运行完成\n");
+    return 0;
+} 
\ No newline at end of file
index f2ebc52..4e33027 100644 (file)
@@ -6,6 +6,7 @@
 #include "ppp_serial.h"      // 添加串口处理头文件
 #include "ppp_lwip.h"
 #include "ppp_cat1_api.h"
+#include "ppp_interrupt.h"   // 添加中断处理头文件
 #include "soc_osal.h"
 #include <string.h>
 #include <stdlib.h>          // 添加malloc/free支持
@@ -432,12 +433,26 @@ errcode_t ppp_start_dial(void)
         PPP_DEBUG_PRINT("No immediate data after mode switch - this is normal\n");
     }
 
-    // 9. 启动PPP数据接收处理(在lwIP连接之前启动)
-            ret = ppp_lwip_start_receive_thread();
+    // 9. 启动PPP数据接收处理(根据配置选择中断或轮询模式)
+#if PPP_USE_INTERRUPT_MODE
+    // 中断模式:注册UART中断回调(UART总线号从ppp_serial_get_uart_bus()获取)
+    PPP_DEBUG_PRINT("Enabling PPP interrupt mode...\n");
+    ret = ppp_interrupt_enable();
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_PRINT("Failed to enable PPP interrupt: %d\n", ret);
+        goto error_recovery_at_mode;
+    }
+    PPP_DEBUG_PRINT("PPP interrupt mode enabled successfully\n");
+#else
+    // 轮询模式:启动接收线程
+    PPP_DEBUG_PRINT("Starting PPP receive thread (polling mode)...\n");
+    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;
     }
+    PPP_DEBUG_PRINT("PPP receive thread started successfully\n");
+#endif
 
     ppp_lwip_config_t lwip_config = {
         .username = "",
@@ -568,14 +583,11 @@ errcode_t ppp_stop_dial(void)
     ppp_error_t ret = PPP_ERR_OK;  // 声明ret变量
     bool at_communication_ok = false;  // 声明AT通信状态变量
     
-    // 1. 首先停止PPP数据接收线程(在切换串口模式之前)
-    PPP_DEBUG_INFO("Stopping PPP receive thread...");
-    ppp_lwip_stop_receive_thread();
-    PPP_DEBUG_INFO("PPP receive thread stopped");
+
     
-    // 2. 强制等待确保线程完全退出
-    PPP_DEBUG_INFO("Waiting for thread cleanup...");
-    osal_msleep(200);  // 给线程足够时间完全退出
+    // 2. 强制等待确保完全退出
+    PPP_DEBUG_INFO("Waiting for cleanup...");
+    osal_msleep(200);  // 给足够时间完全退出
     
     // 3. 断开lwIP PPP连接
     PPP_DEBUG_INFO("Disconnecting lwIP PPP...");
@@ -591,6 +603,23 @@ errcode_t ppp_stop_dial(void)
     // 等待确保前面的操作完成
     osal_msleep(1000);
     
+
+         // 1. 停止PPP数据接收(根据配置选择中断或轮询模式)
+     #if PPP_USE_INTERRUPT_MODE
+     // 中断模式:禁用UART中断
+     PPP_DEBUG_INFO("Disabling PPP interrupt mode...");
+     ppp_interrupt_disable();
+     PPP_DEBUG_INFO("PPP interrupt mode disabled");
+ 
+     // 打印中断统计信息
+     ppp_interrupt_print_stats();
+     #else
+     // 轮询模式:停止接收线程
+     PPP_DEBUG_INFO("Stopping PPP receive thread...");
+     ppp_lwip_stop_receive_thread();
+     PPP_DEBUG_INFO("PPP receive thread stopped");
+     #endif
+
     // // 方法1:发送+++转义序列切换调制解调器到命令模式
     // PPP_DEBUG_INFO("Sending escape sequence (+++) to switch modem to command mode...");
     // const char escape_seq[] = "+++";
diff --git a/code/sdk/zhihui/ppp/src/ppp_interrupt.c b/code/sdk/zhihui/ppp/src/ppp_interrupt.c
new file mode 100644 (file)
index 0000000..1827c17
--- /dev/null
@@ -0,0 +1,257 @@
+/**
+ * @file ppp_interrupt.c
+ * @brief PPP UART中断接收处理 - 类似SLIP但更简单
+ * 
+ * 核心优势:
+ * - 使用512字节UART硬件缓冲区,防止数据丢失
+ * - 中断回调直接调用pppos_input_tcpip(),无需自己管理队列
+ * - lwIP TCPIP线程自动处理协议解析,无需loop线程
+ */
+
+#include "ppp_interrupt.h"
+#include "ppp_debug.h"
+#include "ppp_lwip.h"
+#include "ppp_serial.h"
+#include "uart.h"
+#include "hal_uart.h"
+#include "errcode.h"
+#include <string.h>
+#include <stdbool.h>
+
+/* lwIP相关头文件 */
+#include "lwip/err.h"
+#include "netif/ppp/ppp.h"
+#include "netif/ppp/pppos.h"
+
+/* UART硬件缓冲区配置 */
+#define PPP_UART_RX_BUFFER_SIZE    2048  // 硬件缓冲区大小(足够容纳MTU 1500 + PPP开销)
+
+/* 硬件缓冲区 */
+static uint8_t g_ppp_uart_rx_buffer[PPP_UART_RX_BUFFER_SIZE];
+
+/* 中断使能标志 */
+static bool g_ppp_interrupt_enabled = false;
+
+/* 统计信息 */
+static ppp_interrupt_stats_t g_ppp_interrupt_stats = {0};
+
+/* 外部函数声明(在ppp_lwip.c中实现) */
+extern ppp_pcb* ppp_lwip_get_pcb(void);
+extern bool ppp_lwip_is_initialized(void);
+
+/**
+ * @brief UART接收中断回调函数(中断上下文)
+ * @note 此函数在中断上下文中调用,必须快速返回
+ * 
+ * 数据流:
+ * 1. UART硬件接收数据 -> 512字节硬件缓冲区
+ * 2. 触发中断回调(本函数)
+ * 3. 直接调用pppos_input_tcpip() -> lwIP自动封装pbuf并发送到TCPIP线程
+ * 4. TCPIP线程自动调用pppos_input() -> ppp_input() -> IP层
+ * 
+ * 关键:pppos_input_tcpip()是lwIP提供的线程安全接口,
+ *      专门设计为可以在中断上下文调用!
+ */
+void ppp_uart_rx_interrupt_handler(const void *buffer, uint16_t length, bool error)
+{
+    // 快速路径:参数校验
+    if (error || !buffer || length == 0) {
+        if (error) {
+            g_ppp_interrupt_stats.error_count++;
+        }
+        return;
+    }
+    
+    // 更新接收统计
+    g_ppp_interrupt_stats.total_interrupts++;
+    g_ppp_interrupt_stats.total_bytes_received += length;
+    
+    // 打印接收数据大小(中断中只打印简要信息)
+    PPP_DEBUG_INFO("PPP IRQ RX: %u bytes", length);
+    
+    // 获取PPP控制块
+    ppp_pcb *ppp_pcb_ptr = ppp_lwip_get_pcb();
+    if (!ppp_pcb_ptr || !ppp_lwip_is_initialized()) {
+        // PPP未初始化,丢弃数据
+        g_ppp_interrupt_stats.dropped_not_initialized += length;
+        PPP_DEBUG_WARN("PPP IRQ: PPP not initialized, dropping %u bytes", length);
+        return;
+    }
+    
+    // 核心操作:直接调用lwIP的线程安全接口
+    // 这个函数会:
+    //   1. 分配pbuf
+    //   2. 复制数据到pbuf
+    //   3. 通过tcpip_inpkt()发送到TCPIP线程
+    //   4. TCPIP线程自动调用pppos_input()进行协议解析
+    err_t result = pppos_input_tcpip(ppp_pcb_ptr, (u8_t *)buffer, length);
+    
+    if (result != ERR_OK) {
+        // 发送失败(可能是内存不足或队列满)
+        g_ppp_interrupt_stats.dropped_lwip_error += length;
+        g_ppp_interrupt_stats.lwip_error_count++;
+        PPP_DEBUG_WARN("PPP IRQ: pppos_input_tcpip failed: %d, dropped %u bytes", result, length);
+    } else {
+        // 成功发送到lwIP
+        g_ppp_interrupt_stats.total_bytes_sent_to_lwip += length;
+        g_ppp_interrupt_stats.success_count++;
+    }
+}
+
+/**
+ * @brief 获取UART硬件缓冲区配置(供外部UART初始化使用)
+ * @param rx_buffer 返回接收缓冲区指针
+ * @param buffer_size 返回缓冲区大小
+ */
+void ppp_interrupt_get_buffer_config(void **rx_buffer, uint32_t *buffer_size)
+{
+    if (rx_buffer) {
+        *rx_buffer = g_ppp_uart_rx_buffer;
+    }
+    if (buffer_size) {
+        *buffer_size = PPP_UART_RX_BUFFER_SIZE;
+    }
+}
+
+/**
+ * @brief 启用PPP UART中断接收
+ * @return PPP_ERR_OK 成功,其他值失败
+ * 
+ * @note 调用此函数前:
+ *       1. ppp_serial必须已初始化(UART总线号从ppp_serial_get_uart_bus()获取)
+ *       2. UART必须已经初始化并配置了硬件缓冲区
+ *       3. 使用 ppp_interrupt_get_buffer_config() 获取缓冲区配置
+ */
+ppp_error_t ppp_interrupt_enable(void)
+{
+    if (g_ppp_interrupt_enabled) {
+        PPP_DEBUG_WARN("PPP interrupt already enabled");
+        return PPP_ERR_OK;  // 已启用
+    }
+    
+    // 从ppp_serial获取UART总线号(避免重复定义)
+    uint8_t uart_bus = ppp_serial_get_uart_bus();
+    
+    PPP_DEBUG_INFO("Enabling PPP UART interrupt (bus=%d)", uart_bus);
+    
+    // 注册UART中断回调
+    // UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE (0x07):
+    //   - 缓冲区满时触发(>= PPP_UART_RX_BUFFER_SIZE)
+    //   - UART空闲时触发(接收间隔超时,防止小包延迟)
+    // 
+    // 参数说明(参考SLIP的实现):
+    //   - 第2个参数:触发条件标志(0x07 = 满 OR 空闲)
+    //   - 第3个参数:缓冲区大小(2048字节,足够容纳1500 MTU + PPP开销)
+    // 
+    // 平衡设计:
+    //   - 2048字节缓冲区:可完整接收大包,避免溢出
+    //   - 空闲检测:小包(<2048字节)依赖UART空闲超时触发
+    //   - 参考SLIP使用256字节,PPP使用2048字节应对更大的MTU
+    errcode_t ret = uapi_uart_register_rx_callback(
+        uart_bus,
+        0x07,  // UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE
+        PPP_UART_RX_BUFFER_SIZE,  // 缓冲区大小:2048字节
+        ppp_uart_rx_interrupt_handler  // 回调函数
+    );
+    
+    if (ret != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to register UART RX callback: 0x%x", ret);
+        return PPP_ERR_UART;
+    }
+    
+    g_ppp_interrupt_enabled = true;
+    
+    PPP_DEBUG_INFO("PPP UART interrupt enabled successfully");
+    PPP_DEBUG_INFO("  RX buffer: %d bytes (balanced for MTU 1500)", PPP_UART_RX_BUFFER_SIZE);
+    PPP_DEBUG_INFO("  Trigger: buffer full OR UART idle");
+    PPP_DEBUG_INFO("  Data flow: UART IRQ -> pppos_input_tcpip() -> lwIP TCPIP thread");
+    
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 禁用PPP UART中断接收
+ * @return PPP_ERR_OK 成功,其他值失败
+ */
+ppp_error_t ppp_interrupt_disable(void)
+{
+    if (!g_ppp_interrupt_enabled) {
+        return PPP_ERR_OK;
+    }
+    
+    // 从ppp_serial获取UART总线号
+    uint8_t uart_bus = ppp_serial_get_uart_bus();
+    
+    PPP_DEBUG_INFO("Disabling PPP UART interrupt (bus=%d)", uart_bus);
+    
+    // 注销中断回调
+    uapi_uart_unregister_rx_callback(uart_bus);
+    
+    g_ppp_interrupt_enabled = false;
+    
+    PPP_DEBUG_INFO("PPP UART interrupt disabled");
+    
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 检查中断是否已启用
+ * @return true 已启用,false 未启用
+ */
+bool ppp_interrupt_is_enabled(void)
+{
+    return g_ppp_interrupt_enabled;
+}
+
+/**
+ * @brief 获取中断统计信息
+ * @param stats 统计信息输出缓冲区
+ */
+void ppp_interrupt_get_stats(ppp_interrupt_stats_t *stats)
+{
+    if (stats) {
+        memcpy(stats, &g_ppp_interrupt_stats, sizeof(ppp_interrupt_stats_t));
+    }
+}
+
+/**
+ * @brief 重置中断统计信息
+ */
+void ppp_interrupt_reset_stats(void)
+{
+    memset(&g_ppp_interrupt_stats, 0, sizeof(ppp_interrupt_stats_t));
+    PPP_DEBUG_INFO("PPP interrupt statistics reset");
+}
+
+/**
+ * @brief 打印中断统计信息
+ */
+void ppp_interrupt_print_stats(void)
+{
+    PPP_DEBUG_INFO("=== PPP Interrupt Statistics ===");
+    PPP_DEBUG_INFO("Interrupt Status: %s", g_ppp_interrupt_enabled ? "ENABLED" : "DISABLED");
+    PPP_DEBUG_INFO("Hardware Buffer: %d bytes", PPP_UART_RX_BUFFER_SIZE);
+    PPP_DEBUG_INFO("");
+    PPP_DEBUG_INFO("Total Interrupts: %u", g_ppp_interrupt_stats.total_interrupts);
+    PPP_DEBUG_INFO("  - Success: %u", g_ppp_interrupt_stats.success_count);
+    PPP_DEBUG_INFO("  - Error: %u", g_ppp_interrupt_stats.error_count);
+    PPP_DEBUG_INFO("  - lwIP Error: %u", g_ppp_interrupt_stats.lwip_error_count);
+    PPP_DEBUG_INFO("");
+    PPP_DEBUG_INFO("Total Bytes Received: %u", g_ppp_interrupt_stats.total_bytes_received);
+    PPP_DEBUG_INFO("Total Bytes Sent to lwIP: %u", g_ppp_interrupt_stats.total_bytes_sent_to_lwip);
+    PPP_DEBUG_INFO("");
+    PPP_DEBUG_INFO("Dropped Bytes:");
+    PPP_DEBUG_INFO("  - Not Initialized: %u", g_ppp_interrupt_stats.dropped_not_initialized);
+    PPP_DEBUG_INFO("  - lwIP Error: %u", g_ppp_interrupt_stats.dropped_lwip_error);
+    PPP_DEBUG_INFO("");
+    
+    // 计算丢包率
+    if (g_ppp_interrupt_stats.total_bytes_received > 0) {
+        uint32_t total_dropped = g_ppp_interrupt_stats.dropped_not_initialized + 
+                                 g_ppp_interrupt_stats.dropped_lwip_error;
+        uint32_t drop_rate = (total_dropped * 10000) / g_ppp_interrupt_stats.total_bytes_received;
+        PPP_DEBUG_INFO("Drop Rate: %u.%02u%%", drop_rate / 100, drop_rate % 100);
+    }
+    
+    PPP_DEBUG_INFO("================================");
+} 
\ No newline at end of file
index 619b358..b57fa1e 100644 (file)
@@ -64,7 +64,7 @@ typedef struct {
 
 static ppp_output_stats_t g_ppp_output_stats = {0};
 /* 内部函数声明 */
-static u32_t ppp_lwip_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx);
+static uint32_t ppp_lwip_output_callback(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *ctx);
 static void ppp_lwip_link_status_callback(ppp_pcb *pcb, int err_code, void *ctx);
 static void ppp_lwip_status_callback(ppp_pcb *pcb, int err_code, void *ctx);
 static void ppp_lwip_netif_status_callback(struct netif *netif);
@@ -293,16 +293,22 @@ ppp_error_t ppp_lwip_init(const ppp_lwip_config_t *config)
     g_lwip_ctx.ppp_pcb->lcp_wantoptions.neg_magicnumber = 0;
     g_lwip_ctx.ppp_pcb->lcp_allowoptions.neg_magicnumber = 0;
 
+    #if PPP_ENABLE_LARGE_MRU
     /* 启用并强制MRU协商 - 防止接收超大帧 */
     g_lwip_ctx.ppp_pcb->lcp_wantoptions.neg_mru = 1;
-    g_lwip_ctx.ppp_pcb->lcp_allowoptions.neg_mru = 1;
     g_lwip_ctx.ppp_pcb->lcp_wantoptions.mru = PPP_MRU_SIZE;  // 使用配置的1500字节
+    g_lwip_ctx.ppp_pcb->lcp_allowoptions.neg_mru = 1;
     g_lwip_ctx.ppp_pcb->lcp_allowoptions.mru = PPP_MRU_SIZE;
+    #else
+    g_lwip_ctx.ppp_pcb->lcp_wantoptions.neg_mru = 0;
+    g_lwip_ctx.ppp_pcb->lcp_wantoptions.mru = 0;  // 使用配置的1500字节
+    g_lwip_ctx.ppp_pcb->lcp_allowoptions.neg_mru = 0;
+    g_lwip_ctx.ppp_pcb->lcp_allowoptions.mru = 0;
+    #endif
     PPP_DEBUG_INFO("MRU negotiation enabled: want=%u, allow=%u", 
-                  g_lwip_ctx.ppp_pcb->lcp_wantoptions.mru,
-                  g_lwip_ctx.ppp_pcb->lcp_allowoptions.mru);
-
-    /* 启用IPCP接受选项 (对应 ipcp-accept-local/remote) */
+        g_lwip_ctx.ppp_pcb->lcp_wantoptions.mru,
+        g_lwip_ctx.ppp_pcb->lcp_allowoptions.mru);
+/* 启用IPCP接受选项 (对应 ipcp-accept-local/remote) */
     g_lwip_ctx.ppp_pcb->ipcp_wantoptions.accept_local = 1;
     g_lwip_ctx.ppp_pcb->ipcp_wantoptions.accept_remote = 1;
 
@@ -930,13 +936,22 @@ static void ppp_lwip_netif_status_callback(struct netif *netif)
  */
 static u32_t ppp_lwip_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx)
 {
-    (void)pcb;
-    (void)ctx;
+    /* 严格的参数检查 - 防止空指针访问 */
+    if (!pcb) {
+        PPP_DEBUG_ERROR("CRITICAL: ppp_pcb is NULL in output callback!");
+        return 0;
+    }
     
     if (!data || len == 0) {
         PPP_DEBUG_ERROR("Invalid output data: data=%p, len=%u", data, len);
         return 0;
     }
+    
+    /* 检查数据长度是否合理(PPP最大帧1500字节 + 头部) */
+    if (len > 2048) {
+        PPP_DEBUG_ERROR("Abnormal packet size: %u bytes (max expected 2048)", len);
+        return 0;
+    }
 
     /* 记录数据活动 */
     ppp_lwip_record_data_activity();
@@ -1309,5 +1324,78 @@ ppp_error_t ppp_lwip_get_output_stats(ppp_lwip_output_stats_t *stats)
     return PPP_ERR_OK;
 }
 
+/**
+ * @brief 获取PPP控制块(供中断处理模块使用)
+ * @return PPP控制块指针,如果未初始化则返回NULL
+ */
+ppp_pcb* ppp_lwip_get_pcb(void)
+{
+#ifdef LWIP_PPP_SUPPORT
+    return g_lwip_ctx.ppp_pcb;
+#else
+    return NULL;
+#endif
+}
+
+/**
+ * @brief 检查PPP lwIP是否已初始化(供中断处理模块使用)
+ * @return true 已初始化,false 未初始化
+ */
+bool ppp_lwip_is_initialized(void)
+{
+    return g_lwip_ctx.initialized;
+}
+
+/**
+ * @brief 打印lwIP内存使用情况(用于诊断)
+ */
+void ppp_lwip_print_memory_stats(void)
+{
+#ifdef LWIP_PPP_SUPPORT
+    PPP_DEBUG_PRINT("\n=== lwIP Memory Statistics ===\n");
+    
+    #if MEMP_STATS
+    // 打印pbuf池统计
+    PPP_DEBUG_PRINT("PBUF Pools:\n");
+    PPP_DEBUG_PRINT("  PBUF_POOL: used=%u, max=%u, avail=%u\n",
+                   lwip_stats.memp[MEMP_PBUF_POOL]->used,
+                   lwip_stats.memp[MEMP_PBUF_POOL]->max,
+                   lwip_stats.memp[MEMP_PBUF_POOL]->avail);
+    PPP_DEBUG_PRINT("  PBUF: used=%u, max=%u, avail=%u\n",
+                   lwip_stats.memp[MEMP_PBUF]->used,
+                   lwip_stats.memp[MEMP_PBUF]->max,
+                   lwip_stats.memp[MEMP_PBUF]->avail);
+    
+    // 打印TCP相关池统计
+    PPP_DEBUG_PRINT("TCP Pools:\n");
+    PPP_DEBUG_PRINT("  TCP_PCB: used=%u, max=%u, avail=%u\n",
+                   lwip_stats.memp[MEMP_TCP_PCB]->used,
+                   lwip_stats.memp[MEMP_TCP_PCB]->max,
+                   lwip_stats.memp[MEMP_TCP_PCB]->avail);
+    PPP_DEBUG_PRINT("  TCP_SEG: used=%u, max=%u, avail=%u\n",
+                   lwip_stats.memp[MEMP_TCP_SEG]->used,
+                   lwip_stats.memp[MEMP_TCP_SEG]->max,
+                   lwip_stats.memp[MEMP_TCP_SEG]->avail);
+    #else
+    PPP_DEBUG_PRINT("  MEMP_STATS not enabled in lwIP\n");
+    #endif
+    
+    #if MEM_STATS
+    // 打印堆内存统计
+    PPP_DEBUG_PRINT("Heap Memory:\n");
+    PPP_DEBUG_PRINT("  Used: %u bytes\n", lwip_stats.mem.used);
+    PPP_DEBUG_PRINT("  Max: %u bytes\n", lwip_stats.mem.max);
+    PPP_DEBUG_PRINT("  Available: %u bytes\n", lwip_stats.mem.avail);
+    PPP_DEBUG_PRINT("  Errors: %u\n", lwip_stats.mem.err);
+    #else
+    PPP_DEBUG_PRINT("  MEM_STATS not enabled in lwIP\n");
+    #endif
+    
+    PPP_DEBUG_PRINT("=================================\n\n");
+#else
+    PPP_DEBUG_PRINT("lwIP PPP support not compiled\n");
+#endif
+}
+
 
 #endif /* LWIP_PPP_SUPPORT */ 
\ No newline at end of file
index bf798ad..6610322 100644 (file)
@@ -1,6 +1,10 @@
 /**
  * @file ppp_lwip_thread.c
- * @brief PPP接收线程实现 - 双线程架构:接收线程拼包 + 处理线程处理
+ * @brief PPP接收线程实现 - 支持单线程和双线程模式
+ * 
+ * 线程模式配置:
+ * - PPP_USE_DUAL_THREAD=1: 双线程模式(接收线程拼包 + 处理线程处理)
+ * - PPP_USE_DUAL_THREAD=0: 单线程模式(接收线程直接处理)
  */
 
 #include "ppp_api.h"
 #include "soc_osal.h"
 #include "schedule/osal_task.h"
 #include "msgqueue/osal_msgqueue.h"
+#include "custom_utils.h"
 #include <stdlib.h>
 #include <string.h>
 
-/* PPP帧队列相关 */
+/* PPP接收模式配置(中断相关代码已移除,使用独立的ppp_interrupt模块) */
+
+/* PPP线程模式配置 */
+#ifndef PPP_USE_DUAL_THREAD
+#define PPP_USE_DUAL_THREAD     0       // 默认使用双线程模式
+#endif
+
+#if PPP_USE_DUAL_THREAD
+#define PPP_THREAD_MODE_STR     "DUAL_THREAD"
+#else
+#define PPP_THREAD_MODE_STR     "SINGLE_THREAD"
+#endif
+
+/* PPP帧队列相关(仅双线程模式使用) */
+#if PPP_USE_DUAL_THREAD
 #define PPP_FRAME_QUEUE_SIZE    32      // 队列大小
 #define PPP_MAX_FRAME_SIZE      2048    // 从1500增加到2048
 
-/* PPP帧结构 */
+/* PPP帧结构(仅双线程模式使用) */
 typedef struct {
     uint8_t *data;      // 帧数据
     uint32_t length;    // 帧长度
 } ppp_frame_t;
+#endif
 
 /* PPP字节丢弃统计结构已在ppp_types.h中定义 */
 
 /* PPP线程相关 */
-static osal_task *g_ppp_rx_thread = NULL;           // 接收线程
-static osal_task *g_ppp_process_thread = NULL;      // 处理线程
+static uint32_t g_ppp_rx_thread_handle = 0;         // 接收线程句柄
+#if PPP_USE_DUAL_THREAD
+static uint32_t g_ppp_process_thread_handle = 0;    // 处理线程句柄(仅双线程模式)
+#endif
 static volatile bool g_ppp_rx_thread_running = false;
+#if PPP_USE_DUAL_THREAD
 static volatile bool g_ppp_process_thread_running = false;
+#endif
 static volatile bool g_ppp_rx_thread_completed = false;
+#if PPP_USE_DUAL_THREAD
 static volatile bool g_ppp_process_thread_completed = false;
+#endif
 
-/* PPP帧队列 */
+/* PPP帧队列(仅双线程模式使用) */
+#if PPP_USE_DUAL_THREAD
 static unsigned long g_ppp_frame_queue = 0xFFFFFFFFu;
-
-/* PPP接收缓冲区 */
-static uint8_t g_ppp_rx_buffer[PPP_RX_BUFFER_SIZE * 2];  // 双倍缓冲区用于拼包
-static uint32_t g_buffer_pos = 0;       // 当前缓冲区位置
-
-/* PPP帧标志 */
-#define PPP_FLAG_CHAR           0x7E    // PPP帧标志字符
-#define PPP_ESCAPE_CHAR         0x7D    // PPP转义字符
-#define PPP_ESCAPE_MASK         0x20    // PPP转义掩码
+#endif
 
 /* PPP丢弃统计 */
 static ppp_discard_stats_t g_ppp_discard_stats = {0};
 
-/* PPP帧拼包状态 */
-typedef struct {
-    uint8_t *buffer;        // 拼包缓冲区
-    uint32_t buffer_size;   // 缓冲区大小
-    uint32_t data_len;      // 当前数据长度
-    bool in_frame;          // 是否在帧内
-    bool escaped;           // 是否转义状态
-} ppp_frame_assembler_t;
-
-static ppp_frame_assembler_t g_frame_assembler = {0};
+static ppp_error_t ppp_process_data_block(const uint8_t *data, uint32_t length);
 
 /**
- * @brief å\88\9då§\8bå\8c\96PPP帧æ\8b¼å\8c\85å\99¨
+ * @brief å¤\84ç\90\86PPPæ\95°æ\8d®å¹¶æ\89\93å\8d°è¯¦ç»\86ä¿¡æ\81¯ï¼\88å\8d\95线ç¨\8b模å¼\8fä¸\93ç\94¨ï¼\89
  */
-static ppp_error_t ppp_frame_assembler_init(void)
+static ppp_error_t ppp_process_and_print_data(const uint8_t *data, uint32_t length)
 {
-    g_frame_assembler.buffer_size = PPP_MAX_FRAME_SIZE;
-    g_frame_assembler.buffer = (uint8_t *)malloc(g_frame_assembler.buffer_size);
-    if (!g_frame_assembler.buffer) {
-        PPP_DEBUG_ERROR("Failed to allocate frame assembler buffer");
-        return PPP_ERR_MEMORY;
+    if (!data || length == 0) {
+        return PPP_ERR_INVALID_PARAM;
     }
     
-    g_frame_assembler.data_len = 0;
-    g_frame_assembler.in_frame = false;
-    g_frame_assembler.escaped = false;
+    // 打印详细的接收数据(在处理阶段,不影响接收效率)
+    PPP_DEBUG_INFO("PPP Processing: %u bytes", length);
+    PPP_DEBUG_PRINT("PPP RX Data: ");
+    for (uint32_t i = 0; i < length; i++) {
+        PPP_DEBUG_PRINT("%02X ", data[i]);
+        // 每16字节换行,便于阅读
+        if ((i + 1) % 16 == 0) {
+            PPP_DEBUG_PRINT("\n             ");
+        }
+    }
+    PPP_DEBUG_PRINT("\n");
     
-    PPP_DEBUG_INFO("PPP frame assembler initialized with %u bytes buffer", 
-                   g_frame_assembler.buffer_size);
-    return PPP_ERR_OK;
-}
-
-/**
- * @brief 清理PPP帧拼包器
- */
-static void ppp_frame_assembler_cleanup(void)
-{
-    if (g_frame_assembler.buffer) {
-        free(g_frame_assembler.buffer);
-        g_frame_assembler.buffer = NULL;
+    // 调用lwIP处理
+    ppp_error_t lwip_ret = ppp_lwip_input(data, length);
+    if (lwip_ret != PPP_ERR_OK) {
+        PPP_DEBUG_WARN("lwIP input failed: %d", lwip_ret);
+        return lwip_ret;
+    } else {
+        PPP_DEBUG_DEBUG("PPP data processed successfully by lwIP");
+        return PPP_ERR_OK;
     }
-    memset(&g_frame_assembler, 0, sizeof(g_frame_assembler));
-}
-
-/**
- * @brief 重置帧拼包状态
- */
-static void ppp_frame_assembler_reset(void)
-{
-    g_frame_assembler.data_len = 0;
-    g_frame_assembler.in_frame = false;
-    g_frame_assembler.escaped = false;
 }
 
+#if PPP_USE_DUAL_THREAD
 /**
- * @brief å\8f\91é\80\81å®\8cæ\95´PPP帧å\88°é\98\9få\88\97
+ * @brief å¤\84ç\90\86æ\8e¥æ\94¶å\88°ç\9a\84æ\95°æ\8d®å\9d\97ï¼\88å\8f\8c线ç¨\8b模å¼\8fï¼\89
  */
-static ppp_error_t ppp_send_frame_to_queue(const uint8_t *data, uint32_t length)
+static ppp_error_t ppp_process_data_block(const uint8_t *data, uint32_t length)
 {
-    if (!data || length == 0 || length > PPP_MAX_FRAME_SIZE) {
+    if (!data || length == 0) {
         return PPP_ERR_INVALID_PARAM;
     }
     
@@ -118,9 +118,8 @@ static ppp_error_t ppp_send_frame_to_queue(const uint8_t *data, uint32_t length)
         PPP_DEBUG_ERROR("Failed to allocate frame structure");
         
         // 统计内存分配失败丢弃
-        g_ppp_discard_stats.total_frames_discarded++;
-        g_ppp_discard_stats.malloc_fail_bytes += length;
         g_ppp_discard_stats.total_bytes_discarded += length;
+        g_ppp_discard_stats.malloc_fail_bytes += length;
         
         return PPP_ERR_MEMORY;
     }
@@ -131,9 +130,8 @@ static ppp_error_t ppp_send_frame_to_queue(const uint8_t *data, uint32_t length)
         PPP_DEBUG_ERROR("Failed to allocate frame data");
         
         // 统计内存分配失败丢弃
-        g_ppp_discard_stats.total_frames_discarded++;
-        g_ppp_discard_stats.malloc_fail_bytes += length;
         g_ppp_discard_stats.total_bytes_discarded += length;
+        g_ppp_discard_stats.malloc_fail_bytes += length;
         
         free(frame);
         return PPP_ERR_MEMORY;
@@ -146,100 +144,30 @@ static ppp_error_t ppp_send_frame_to_queue(const uint8_t *data, uint32_t length)
     // 发送到队列
     int ret = osal_msg_queue_write_copy(g_ppp_frame_queue, &frame, sizeof(ppp_frame_t *), 0);
     if (ret != OSAL_SUCCESS) {
-        PPP_DEBUG_WARN("Failed to send frame to queue: %d, dropping frame", ret);
+        PPP_DEBUG_WARN("Failed to send data to queue: %d, dropping data", ret);
         
         // 统计队列满丢弃
-        g_ppp_discard_stats.total_frames_discarded++;
-        g_ppp_discard_stats.queue_full_bytes += length;
         g_ppp_discard_stats.total_bytes_discarded += length;
+        g_ppp_discard_stats.queue_full_bytes += length;
         
         free(frame->data);
         free(frame);
-        return PPP_ERR_UNKNOWN;  // 使用已定义的错误码
-    }
-    
-    PPP_DEBUG_DEBUG("Sent complete PPP frame to queue: %u bytes", length);
-    
-    // 更新帧统计
-    g_ppp_discard_stats.total_frames_received++;
-    
-    return PPP_ERR_OK;
-}
-
-/**
- * @brief 处理接收到的字节,进行PPP帧拼包(保留完整帧格式)
- */
-static ppp_error_t ppp_process_received_byte(uint8_t byte)
-{
-    // PPP帧标志字符
-    if (byte == 0x7E) {
-        if (g_frame_assembler.in_frame && g_frame_assembler.data_len > 0) {
-            // 帧结束,添加结束标志并发送完整帧
-            if (g_frame_assembler.data_len < g_frame_assembler.buffer_size) {
-                g_frame_assembler.buffer[g_frame_assembler.data_len++] = 0x7E;
-                
-                PPP_DEBUG_DEBUG("Complete PPP frame assembled: %u bytes (with 0x7E flags)", g_frame_assembler.data_len);
-                
-                // 发送完整帧(包含首尾0x7E标志)
-                ppp_send_frame_to_queue(g_frame_assembler.buffer, g_frame_assembler.data_len);
-            } else {
-                // 缓冲区满,丢弃帧
-                PPP_DEBUG_WARN("Frame buffer full, dropping frame");
-                g_ppp_discard_stats.total_frames_discarded++;
-                g_ppp_discard_stats.oversized_frame_bytes += g_frame_assembler.data_len;
-                g_ppp_discard_stats.total_bytes_discarded += g_frame_assembler.data_len;
-            }
-        } else if (g_frame_assembler.in_frame && g_frame_assembler.data_len == 0) {
-            // 连续的0x7E标志,这是正常的
-            PPP_DEBUG_DEBUG("Consecutive 0x7E flag, continuing");
-        } else {
-            // 不在帧内收到0x7E,开始新帧
-            PPP_DEBUG_DEBUG("Starting new frame with 0x7E");
-        }
-        
-        // 开始新帧,首先添加起始0x7E标志
-        ppp_frame_assembler_reset();
-        g_frame_assembler.in_frame = true;
-        g_frame_assembler.buffer[g_frame_assembler.data_len++] = 0x7E;
-        return PPP_ERR_OK;
-    }
-    
-    // 如果不在帧内,忽略数据
-    if (!g_frame_assembler.in_frame) {
-        // 统计被忽略的数据
-        g_ppp_discard_stats.total_bytes_discarded++;
-        g_ppp_discard_stats.incomplete_frame_bytes++;
-        PPP_DEBUG_DEBUG("Ignoring byte 0x%02X outside frame", byte);
-        return PPP_ERR_OK;
-    }
-    
-    // 检查缓冲区空间(为结束0x7E预留1字节)
-    if (g_frame_assembler.data_len >= (g_frame_assembler.buffer_size - 1)) {
-        PPP_DEBUG_WARN("Frame too large (%u bytes), resetting assembler", g_frame_assembler.data_len);
-        
-        // 统计超大帧丢弃
-        g_ppp_discard_stats.total_frames_discarded++;
-        g_ppp_discard_stats.oversized_frame_bytes += g_frame_assembler.data_len;
-        g_ppp_discard_stats.total_bytes_discarded += g_frame_assembler.data_len;
-        
-        ppp_frame_assembler_reset();
         return PPP_ERR_UNKNOWN;
     }
     
-    // 直接添加字节到帧缓冲区(保留原始格式,包括转义字符)
-    g_frame_assembler.buffer[g_frame_assembler.data_len++] = byte;
-    
+    PPP_DEBUG_DEBUG("Sent data block to queue: %u bytes", length);
     return PPP_ERR_OK;
 }
+#endif
 
 /**
- * @brief PPP数据接收线程 - 只负责拼包
+ * @brief PPP数据接收线程 - 轮询模式(类似SLIP的高效策略)
  */
 static void ppp_lwip_receive_thread(void *arg)
 {
     (void)arg;
-
-    PPP_DEBUG_INFO("PPP receive thread started (frame assembly mode)");
+    
+    PPP_DEBUG_INFO("PPP receive thread started (polling mode)");
 
     // 分配串口接收缓冲区
     uint8_t *rx_buffer = (uint8_t *)malloc(PPP_RX_BUFFER_SIZE);
@@ -250,60 +178,88 @@ static void ppp_lwip_receive_thread(void *arg)
     }
 
     uint32_t bytes_read = 0;
-    uint32_t total_bytes = 0, total_frames = 0;
+    uint32_t total_bytes = 0;
+    uint32_t idle_count = 0;
 
-    PPP_DEBUG_DEBUG("PPP receive thread: allocated %d bytes RX buffer", PPP_RX_BUFFER_SIZE);
+    PPP_DEBUG_INFO("PPP receive thread: allocated %d bytes RX buffer", PPP_RX_BUFFER_SIZE);
 
-    // 主循环:从串口读取数据并拼包
+    // 主循环:类似SLIP的连续读取策略
     while (g_ppp_rx_thread_running) {
-        // 从串口读取数据
-        ppp_error_t ret = ppp_serial_read(rx_buffer, PPP_RX_BUFFER_SIZE, &bytes_read);
-
-        if (ret == PPP_ERR_OK && bytes_read > 0) {
-            total_bytes += bytes_read;
+        uint32_t batch_bytes = 0;
+        uint32_t read_count = 0;
+        
+        // 连续读取直到无数据,类似SLIP的slipif_poll
+        while (g_ppp_rx_thread_running) {
+            ppp_error_t ret = ppp_serial_tryread(rx_buffer, PPP_RX_BUFFER_SIZE, &bytes_read);
             
-            // 更新接收字节统计
-            g_ppp_discard_stats.total_bytes_received += bytes_read;
-
-            PPP_DEBUG_DEBUG("PPP RX: Got %u bytes (total: %u bytes)", bytes_read, total_bytes);
+            if (ret == PPP_ERR_OK && bytes_read > 0) {
+                total_bytes += bytes_read;
+                batch_bytes += bytes_read;
+                read_count++;
+                
+                // 更新接收字节统计
+                g_ppp_discard_stats.total_bytes_received += bytes_read;
+                
+                PPP_DEBUG_DEBUG("PPP RX: Got %u bytes (read #%u)", bytes_read, read_count);
 
-            // 逐字节处理,进行PPP帧拼包(保留完整帧格式)
-            for (uint32_t i = 0; i < bytes_read; i++) {
-                ppp_error_t process_ret = ppp_process_received_byte(rx_buffer[i]);
+#if PPP_USE_DUAL_THREAD
+                // 双线程模式:发送到队列由处理线程处理
+                ppp_error_t process_ret = ppp_process_data_block(rx_buffer, bytes_read);
                 if (process_ret != PPP_ERR_OK) {
-                    // 字节处理失败,统计丢弃
-                    g_ppp_discard_stats.total_bytes_discarded++;
-                    g_ppp_discard_stats.invalid_frame_bytes++;
+                    PPP_DEBUG_WARN("Failed to process data block: %d", process_ret);
                 }
-            }
-        } else if (ret != PPP_ERR_OK) {
-            // 读取错误
-            if (!g_ppp_rx_thread_running) {
-                PPP_DEBUG_DEBUG("PPP receive thread stopping, ignoring read error");
+#else
+                // 单线程模式:调用处理函数(包含详细数据打印)
+                ppp_error_t process_ret = ppp_process_and_print_data(rx_buffer, bytes_read);
+                if (process_ret != PPP_ERR_OK) {
+                    g_ppp_discard_stats.total_bytes_discarded += bytes_read;
+                } else {
+                    g_ppp_discard_stats.total_bytes_processed += bytes_read;
+                }
+#endif
+            } else if (ret != PPP_ERR_OK) {
+                // 读取错误
+                if (!g_ppp_rx_thread_running) {
+                    PPP_DEBUG_DEBUG("PPP receive thread stopping, ignoring read error");
+                    break;
+                }
+                PPP_DEBUG_ERROR("PPP serial tryread error: %d", ret);
+                break;
+            } else {
+                // 无数据,退出连续读取循环
                 break;
             }
-            PPP_DEBUG_ERROR("PPP serial read error: %d", ret);
-        } else {
-            // 没有数据,短暂休眠
+        }
+        
+        if (batch_bytes > 0) {
+            // 有数据处理,重置空闲计数器
+            idle_count = 0;
+            PPP_DEBUG_DEBUG("PPP batch: %u bytes in %u reads", batch_bytes, read_count);
+            
+            // 短暂休眠后继续,保持高响应性
             osal_msleep(1);
+        } else {
+            // 无数据时使用类似SLIP的休眠策略
+            idle_count++;
+            osal_msleep(20);  // 类似SLIP的20ms休眠,不打印避免日志干扰
         }
 
-        // 定期打印统计信息
-        if ((total_frames % 100) == 0 && total_frames > 0) {
-            PPP_DEBUG_DEBUG("PPP RX: %u frames assembled, %u total bytes", 
-                total_frames, total_bytes);
+        // 定期打印统计信息(减少频率)
+        if ((total_bytes % 4096) == 0 && total_bytes > 0) {
+            PPP_DEBUG_INFO("PPP RX: %u total bytes received", total_bytes);
         }
     }
 
     // 释放缓冲区
     free(rx_buffer);
 
-    PPP_DEBUG_INFO("PPP receive thread completed");
+    PPP_DEBUG_INFO("PPP receive thread completed (polling mode), processed %u bytes", total_bytes);
     g_ppp_rx_thread_completed = true;
 }
 
+#if PPP_USE_DUAL_THREAD
 /**
- * @brief PPP帧处理线程 - 从队列获取完整帧并处理
+ * @brief PPP数据处理线程 - 从队列获取数据块并处理(仅双线程模式)
  */
 static void ppp_lwip_process_thread(void *arg)
 {
@@ -311,45 +267,47 @@ static void ppp_lwip_process_thread(void *arg)
 
     PPP_DEBUG_INFO("PPP process thread started");
 
-    uint32_t processed_frames = 0;
+    uint32_t processed_blocks = 0;
     uint32_t processed_bytes = 0;
 
-    // 主循环:从队列获取完整PPP帧并处理
+    // 主循环:从队列获取数据块并处理
     while (g_ppp_process_thread_running) {
-        ppp_frame_t *frame = NULL;
+        ppp_frame_t *data_block = NULL;
         uint32_t msg_size = sizeof(ppp_frame_t *);
 
-        // 从队列获取帧(超时100ms)
-        int ret = osal_msg_queue_read_copy(g_ppp_frame_queue, &frame, &msg_size, OSAL_MSGQ_WAIT_FOREVER);
+        // 从队列获取数据块(超时100ms,避免无限阻塞)
+        int ret = osal_msg_queue_read_copy(g_ppp_frame_queue, &data_block, &msg_size, OSAL_WAIT_FOREVER);
         
-        if (ret == OSAL_SUCCESS && frame) {
-            // 处理完整PPP帧
-            PPP_DEBUG_DEBUG("Processing PPP frame: %u bytes", frame->length);
+        if (ret == OSAL_SUCCESS && data_block) {
+            // 处理数据块
+            PPP_DEBUG_DEBUG("Processing data block: %u bytes", data_block->length);
             
-            // 调用lwIP处理
-            ppp_lwip_input(frame->data, frame->length);
+            PPP_DEBUG_PRINT("PPP RX Data: ");
+            for (uint32_t i = 0; i < data_block->length ; i++) {
+                PPP_DEBUG_PRINT("%02X ", data_block->data[i]);
+            }
+            PPP_DEBUG_PRINT("\n");
+            // 调用lwIP流式处理
+            ppp_error_t process_ret = ppp_process_and_print_data(data_block->data, data_block->length);
             
-            // 更新统计
-            processed_frames++;
-            processed_bytes += frame->length;
             
-            // 更新处理统计(统计实际传递给lwIP的字节数,但排除我们添加的0x7E)
-            g_ppp_discard_stats.total_frames_processed++;
-            // 减去我们添加的额外0x7E标志(每帧最多添加1个)
-            uint32_t original_bytes = frame->length;
-            if (frame->length > 0 && frame->data[frame->length-1] == 0x7E) {
-                original_bytes--; // 减去结束时添加的0x7E
+            // 更新统计
+            processed_blocks++;
+            processed_bytes += data_block->length;
+            if (process_ret != PPP_ERR_OK) {
+                g_ppp_discard_stats.total_bytes_discarded += data_block->length;
+            } else {
+                g_ppp_discard_stats.total_bytes_processed += data_block->length;
             }
-            g_ppp_discard_stats.total_bytes_processed += original_bytes;
             
-            // 释放帧内存
-            free(frame->data);
-            free(frame);
+            // 释放数据块内存
+            free(data_block->data);
+            free(data_block);
             
             // 定期打印统计
-            if ((processed_frames % 50) == 0) {
-                PPP_DEBUG_DEBUG("PPP Process: %u frames, %u bytes processed", 
-                    processed_frames, processed_bytes);
+            if ((processed_blocks % 50) == 0) {
+                PPP_DEBUG_DEBUG("PPP Process: %u blocks, %u bytes processed", 
+                    processed_blocks, processed_bytes);
             }
         } else if (ret != OSAL_SUCCESS) {
             // 超时或其他错误
@@ -357,95 +315,118 @@ static void ppp_lwip_process_thread(void *arg)
                 PPP_DEBUG_DEBUG("PPP process thread stopping");
                 break;
             }
-            // 超时是正常的,其他错误才需要警告
-            if (ret != 0) {  // 假设超时返回非0值
-                PPP_DEBUG_WARN("Failed to read from frame queue: %d", ret);
-            }
+            // 超时是正常的,不需要警告。只有真正的错误才需要警告
+            // OSAL_FAILURE (-1) 通常表示超时,这是正常的
+            // 这里我们不再对超时进行警告,因为这是正常的队列空闲状态
+            PPP_DEBUG_DEBUG("Queue read timeout (normal when no data), ret: %d", ret);
         }
         // 超时是正常的,继续循环
     }
 
-    // 清理队列中剩余的帧
-    ppp_frame_t *frame = NULL;
+    // 清理队列中剩余的数据块
+    ppp_frame_t *data_block = NULL;
     uint32_t msg_size = sizeof(ppp_frame_t *);
-    while (osal_msg_queue_read_copy(g_ppp_frame_queue, &frame, &msg_size, 0) == OSAL_SUCCESS) {
-        if (frame) {
-            free(frame->data);
-            free(frame);
+    while (osal_msg_queue_read_copy(g_ppp_frame_queue, &data_block, &msg_size, 0) == OSAL_SUCCESS) {
+        if (data_block) {
+            free(data_block->data);
+            free(data_block);
         }
     }
 
-    PPP_DEBUG_INFO("PPP process thread completed, processed %u frames, %u bytes", 
-                   processed_frames, processed_bytes);
+    PPP_DEBUG_INFO("PPP process thread completed, processed %u blocks, %u bytes", 
+                   processed_blocks, processed_bytes);
     g_ppp_process_thread_completed = true;
 }
+#endif /* PPP_USE_DUAL_THREAD */
 
 /**
  * @brief 启动PPP接收和处理线程
  */
 ppp_error_t ppp_lwip_start_receive_thread(void)
 {
-    if (g_ppp_rx_thread != NULL || g_ppp_process_thread != NULL) {
+#if PPP_USE_DUAL_THREAD
+    if (g_ppp_rx_thread_handle != 0 || g_ppp_process_thread_handle != 0) {
         PPP_DEBUG_WARN("PPP threads already running");
         return PPP_ERR_INVALID_STATE;
     }
     
-    PPP_DEBUG_INFO("Starting PPP receive and process threads");
-    
-    // 初始化帧拼包器
-    ppp_error_t ret = ppp_frame_assembler_init();
-    if (ret != PPP_ERR_OK) {
-        PPP_DEBUG_ERROR("Failed to initialize frame assembler");
-        return ret;
+    PPP_DEBUG_INFO("Starting PPP receive and process threads (" PPP_THREAD_MODE_STR " mode)");
+#else
+    if (g_ppp_rx_thread_handle != 0) {
+        PPP_DEBUG_WARN("PPP thread already running");
+        return PPP_ERR_INVALID_STATE;
     }
     
-    // 创建帧队列
-    int queue_ret = osal_msg_queue_create("ppp_frames", PPP_FRAME_QUEUE_SIZE, 
-                                          &g_ppp_frame_queue, 0, sizeof(ppp_frame_t *));
-    if (queue_ret != OSAL_SUCCESS) {
-        PPP_DEBUG_ERROR("Failed to create PPP frame queue: %d", queue_ret);
-        ppp_frame_assembler_cleanup();
-        return PPP_ERR_MEMORY;
-    }
+    PPP_DEBUG_INFO("Starting PPP receive thread (" PPP_THREAD_MODE_STR " mode)");
+#endif
     
     // 重置完成标志
     g_ppp_rx_thread_completed = false;
+
+#if PPP_USE_DUAL_THREAD
     g_ppp_process_thread_completed = false;
     
+    // 创建数据队列(仅双线程模式)
+    int queue_ret = osal_msg_queue_create("ppp_data", PPP_FRAME_QUEUE_SIZE, 
+                                          &g_ppp_frame_queue, 0, sizeof(ppp_frame_t *));
+    if (queue_ret != OSAL_SUCCESS) {
+        PPP_DEBUG_ERROR("Failed to create PPP data queue: %d", queue_ret);
+        return PPP_ERR_MEMORY;
+    }
+    
     // 启动处理线程
     g_ppp_process_thread_running = true;
-    g_ppp_process_thread = osal_kthread_create((osal_kthread_handler)ppp_lwip_process_thread, 
-                                               NULL, "ppp_process", 4096);
-    if (!g_ppp_process_thread) {
-        PPP_DEBUG_ERROR("Failed to create PPP process thread");
+    
+    app_task_definition_t process_task_cfg = {0};
+    process_task_cfg.create_queue_handle = NULL;
+    process_task_cfg.attr.name = "ppp_process";
+    process_task_cfg.attr.priority = osPriorityNormal1;
+    process_task_cfg.attr.stack_size = 4096;
+    process_task_cfg.func = ppp_lwip_process_thread;
+    process_task_cfg.task_handle = &g_ppp_process_thread_handle;
+    process_task_cfg.use_mem = USE_EXTEND_MEM;
+    
+    errcode_t process_ret = uapi_create_osThread_custom(&process_task_cfg);
+    if (process_ret != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to create PPP process thread: %d", process_ret);
         g_ppp_process_thread_running = false;
         osal_msg_queue_delete(g_ppp_frame_queue);
         g_ppp_frame_queue = 0;
-        ppp_frame_assembler_cleanup();
         return PPP_ERR_MEMORY;
     }
+#endif /* PPP_USE_DUAL_THREAD */
     
     // 启动接收线程
     g_ppp_rx_thread_running = true;
-    g_ppp_rx_thread = osal_kthread_create((osal_kthread_handler)ppp_lwip_receive_thread, 
-                                          NULL, "ppp_receive", 4096);
-    if (!g_ppp_rx_thread) {
-        PPP_DEBUG_ERROR("Failed to create PPP receive thread");
+    
+    app_task_definition_t rx_task_cfg = {0};
+    rx_task_cfg.create_queue_handle = NULL;
+    rx_task_cfg.attr.name = "ppp_receive";
+    rx_task_cfg.attr.priority = osPriorityNormal1;
+    rx_task_cfg.attr.stack_size = 6144;  // 单线程模式需要更大栈空间
+    rx_task_cfg.func = ppp_lwip_receive_thread;
+    rx_task_cfg.task_handle = &g_ppp_rx_thread_handle;
+    rx_task_cfg.use_mem = USE_EXTEND_MEM;
+    
+    errcode_t rx_ret = uapi_create_osThread_custom(&rx_task_cfg);
+    if (rx_ret != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to create PPP receive thread: %d", rx_ret);
         g_ppp_rx_thread_running = false;
         
+#if PPP_USE_DUAL_THREAD
         // 清理处理线程
         g_ppp_process_thread_running = false;
-        osal_kthread_destroy(g_ppp_process_thread, 0);
-        g_ppp_process_thread = NULL;
+        osThreadTerminate((osThreadId_t)g_ppp_process_thread_handle);
+        g_ppp_process_thread_handle = 0;
         
         // 清理资源
         osal_msg_queue_delete(g_ppp_frame_queue);
         g_ppp_frame_queue = 0;
-        ppp_frame_assembler_cleanup();
+#endif
         return PPP_ERR_MEMORY;
     }
     
-    PPP_DEBUG_INFO("PPP receive and process threads started successfully");
+    PPP_DEBUG_INFO("PPP threads started successfully (" PPP_THREAD_MODE_STR " mode)");
     return PPP_ERR_OK;
 }
 
@@ -454,14 +435,20 @@ ppp_error_t ppp_lwip_start_receive_thread(void)
  */
 ppp_error_t ppp_lwip_stop_receive_thread(void)
 {
-    if (!g_ppp_rx_thread && !g_ppp_process_thread) {
+#if PPP_USE_DUAL_THREAD
+    if (g_ppp_rx_thread_handle == 0 && g_ppp_process_thread_handle == 0) {
+        return PPP_ERR_OK;
+    }
+#else
+    if (g_ppp_rx_thread_handle == 0) {
         return PPP_ERR_OK;
     }
+#endif
     
-    PPP_DEBUG_INFO("Stopping PPP receive and process threads");
+    PPP_DEBUG_INFO("Stopping PPP threads (" PPP_THREAD_MODE_STR " mode)");
     
     // 停止接收线程
-    if (g_ppp_rx_thread) {
+    if (g_ppp_rx_thread_handle != 0) {
         g_ppp_rx_thread_running = false;
         
         // 等待接收线程完成
@@ -479,12 +466,13 @@ ppp_error_t ppp_lwip_stop_receive_thread(void)
             PPP_DEBUG_WARN("PPP receive thread did not complete within timeout");
         }
         
-        osal_kthread_destroy(g_ppp_rx_thread, 0);
-        g_ppp_rx_thread = NULL;
+        osThreadTerminate((osThreadId_t)g_ppp_rx_thread_handle);
+        g_ppp_rx_thread_handle = 0;
     }
     
+#if PPP_USE_DUAL_THREAD
     // 停止处理线程
-    if (g_ppp_process_thread) {
+    if (g_ppp_process_thread_handle != 0) {
         g_ppp_process_thread_running = false;
         
         // 等待处理线程完成
@@ -502,8 +490,8 @@ ppp_error_t ppp_lwip_stop_receive_thread(void)
             PPP_DEBUG_WARN("PPP process thread did not complete within timeout");
         }
         
-        osal_kthread_destroy(g_ppp_process_thread, 0);
-        g_ppp_process_thread = NULL;
+        osThreadTerminate((osThreadId_t)g_ppp_process_thread_handle);
+        g_ppp_process_thread_handle = 0;
     }
     
     // 清理队列
@@ -511,15 +499,15 @@ ppp_error_t ppp_lwip_stop_receive_thread(void)
         osal_msg_queue_delete(g_ppp_frame_queue);
         g_ppp_frame_queue = 0;
     }
-    
-    // 清理帧拼包器
-    ppp_frame_assembler_cleanup();
+#endif
     
     // 重置状态标志
     g_ppp_rx_thread_running = false;
-    g_ppp_process_thread_running = false;
     g_ppp_rx_thread_completed = false;
+#if PPP_USE_DUAL_THREAD
+    g_ppp_process_thread_running = false;
     g_ppp_process_thread_completed = false;
+#endif
     
     PPP_DEBUG_INFO("PPP receive and process threads stopped");
     return PPP_ERR_OK;
@@ -530,8 +518,12 @@ ppp_error_t ppp_lwip_stop_receive_thread(void)
  */
 bool ppp_lwip_is_receive_thread_running(void)
 {
-    return g_ppp_rx_thread_running && (g_ppp_rx_thread != NULL) &&
-           g_ppp_process_thread_running && (g_ppp_process_thread != NULL);
+#if PPP_USE_DUAL_THREAD
+    return g_ppp_rx_thread_running && (g_ppp_rx_thread_handle != 0) &&
+           g_ppp_process_thread_running && (g_ppp_process_thread_handle != 0);
+#else
+    return g_ppp_rx_thread_running && (g_ppp_rx_thread_handle != 0);
+#endif
 }
 
 /**
index 822706a..a444b64 100644 (file)
@@ -2,6 +2,7 @@
 #include "ppp_config.h"
 #include "ppp_types.h"
 #include "ppp_debug.h"
+#include "ppp_interrupt.h"  // 添加此头文件以访问 ppp_interrupt_get_buffer_config
 #include "uart.h"  // 简化路径
 #include "schedule/osal_task.h"
 #include "semaphore/osal_semaphore.h"
@@ -171,14 +172,26 @@ ppp_error_t ppp_serial_init(const ppp_serial_config_t *config)
     // }
     // PPP_DEBUG_INFO("UART deinitialized successfully");
 
-    /* 初始化UART */
-    PPP_DEBUG_DEBUG("Calling uapi_uart_init...");
-    // 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);
-    errcode_t ret = uapi_uart_set_attr(g_serial_ctx.uart_bus, &g_serial_ctx.uart_attr);
+    /* 初始化UART - 使用PPP中断模块提供的硬件缓冲区配置 */
+    PPP_DEBUG_DEBUG("Calling uapi_uart_init with buffer config...");
+    
+    // 从ppp_interrupt模块获取硬件缓冲区配置
+    void *hw_buffer = NULL;
+    uint32_t hw_buffer_size = 0;
+    ppp_interrupt_get_buffer_config(&hw_buffer, &hw_buffer_size);
+    
+    uart_buffer_config_t hw_buffer_config = {
+        .rx_buffer = hw_buffer,
+        .rx_buffer_size = hw_buffer_size
+    };
+    
+    PPP_DEBUG_INFO("Using hardware buffer: %u bytes at 0x%p", hw_buffer_size, hw_buffer);
+    
+    errcode_t ret = uapi_uart_init(g_serial_ctx.uart_bus, 
+                                   &g_serial_ctx.pin_config,
+                                   &g_serial_ctx.uart_attr, 
+                                   NULL, 
+                                   &hw_buffer_config);  // 使用硬件缓冲区配置
     if (ret != ERRCODE_SUCC) {
         PPP_DEBUG_ERROR("Failed to initialize UART: error code = %d (0x%x)", ret, ret);
         PPP_DEBUG_ERROR("UART init failed with bus=%u, tx_pin=%u, rx_pin=%u, baudrate=%u", 
@@ -191,7 +204,7 @@ ppp_error_t ppp_serial_init(const ppp_serial_config_t *config)
         return PPP_ERR_UART;
     }
 
-    PPP_DEBUG_INFO("UART initialized successfully (error code = %d)", ret);
+    PPP_DEBUG_INFO("UART initialized successfully with %u-byte hardware buffer", hw_buffer_size);
 
     /* 创建同步对象 */
     PPP_DEBUG_DEBUG("Creating synchronization objects...");
@@ -484,33 +497,55 @@ ppp_error_t ppp_serial_read(uint8_t *buffer, uint32_t buffer_size, uint32_t *byt
         case PPP_SERIAL_MODE_PPP_DATA:
         /* PPP数据模式:使用优化的直接UART读取,平衡响应性和完整性 */
             {
-                /* 使用适中的超时时间来平衡响应性和帧完整性 */
-                // PPP_DEBUG_DEBUG("PPP mode: Attempting UART read (timeout: 200ms)");
-                /* 优化PPP数据模式读取超时:使用配置的优化值以提高协商响应速度 */
-                int32_t read_result = uapi_uart_read(g_serial_ctx.uart_bus, buffer, buffer_size, PPP_OPTIMIZED_UART_READ_TIMEOUT);
-                if (read_result > 0) {
-                    *bytes_read = (uint32_t)read_result;
-                    g_serial_ctx.rx_bytes += *bytes_read;
+                /* 使用类似SLIP的高效读取策略:
+                 * 1. 首次尝试非阻塞读取(1ms超时)
+                 * 2. 如果有数据,继续快速读取直到无数据
+                 * 3. 这样可以批量读取连续到达的数据,提高效率
+                 */
+                uint32_t total_read = 0;
+                const uint32_t MAX_BATCH_READ = 8; // 最多批量读取8次
+                uint32_t batch_count = 0;
+                
+                while (batch_count < MAX_BATCH_READ && total_read < buffer_size) {
+                    uint32_t remaining = buffer_size - total_read;
+                    uint8_t *current_buffer = buffer + total_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]);
-                    }
-                    PPP_DEBUG_PRINT("... (total %u bytes)\n", *bytes_read);
+                    // 使用短超时进行读取,类似sio_tryread的1ms超时
+                    int32_t read_result = uapi_uart_read(g_serial_ctx.uart_bus, current_buffer, 
+                                                        remaining, batch_count == 0 ? 10 : 1);
                     
-                    return PPP_ERR_OK;
-                } else if (read_result == 0) {
-                    /* 超时,无数据可读 */
-                    *bytes_read = 0;
-                    // PPP_DEBUG_DEBUG("PPP UART Read: No data available (timeout)");
+                    if (read_result > 0) {
+                        total_read += (uint32_t)read_result;
+                        g_serial_ctx.rx_bytes += (uint32_t)read_result;
+                        batch_count++;
+                        
+                        PPP_DEBUG_DEBUG("PPP batch read %u: got %d bytes (total: %u)", 
+                                       batch_count, read_result, total_read);
+                        
+                        // 如果读取的数据少于请求的数据,说明没有更多数据了
+                        if ((uint32_t)read_result < remaining) {
+                            break;
+                        }
+                    } else if (read_result == 0) {
+                        // 超时,无更多数据
+                        break;
+                    } else {
+                        // 读取错误
+                        if (total_read == 0) {
+                            PPP_DEBUG_ERROR("PPP UART Read: Error %d", read_result);
+                            return PPP_ERR_UART;
+                        }
+                        break;
+                    }
+                }
+                
+                *bytes_read = total_read;
+                
+                if (total_read > 0) {
+                    PPP_DEBUG_DEBUG("PPP optimized read: %u bytes in %u batches", total_read, batch_count);
                     return PPP_ERR_OK;
                 } else {
-                    /* UART读取错误 */
-                    *bytes_read = 0;
-                    g_serial_ctx.rx_errors++;
-                    PPP_DEBUG_ERROR("PPP UART Read: Error %d", read_result);
-                    return PPP_ERR_UART;
+                    return PPP_ERR_OK; // 无数据但无错误
                 }
             }
             break;
@@ -549,6 +584,42 @@ ppp_error_t ppp_serial_read(uint8_t *buffer, uint32_t buffer_size, uint32_t *byt
     return result;
 }
 
+/**
+ * @brief PPP快速尝试读取 - 类似SLIP的sio_tryread,使用1ms超时
+ * @param buffer 接收缓冲区
+ * @param buffer_size 缓冲区大小
+ * @param bytes_read 实际读取字节数
+ * @return 错误码
+ */
+ppp_error_t ppp_serial_tryread(uint8_t *buffer, uint32_t buffer_size, uint32_t *bytes_read)
+{
+    if (!g_serial_ctx.initialized || !buffer || !bytes_read || buffer_size == 0) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+
+    *bytes_read = 0;
+
+    if (g_serial_ctx.current_mode == PPP_SERIAL_MODE_PPP_DATA) {
+        /* PPP数据模式:使用1ms超时快速读取,类似SLIP的sio_tryread */
+        int32_t read_result = uapi_uart_read(g_serial_ctx.uart_bus, buffer, buffer_size, 1);
+        if (read_result > 0) {
+            *bytes_read = (uint32_t)read_result;
+            g_serial_ctx.rx_bytes += *bytes_read;
+            return PPP_ERR_OK;
+        } else if (read_result == 0) {
+            /* 超时,无数据可读 */
+            return PPP_ERR_OK;
+        } else {
+            /* UART读取错误 */
+            PPP_DEBUG_ERROR("PPP UART tryread error: %d", read_result);
+            return PPP_ERR_UART;
+        }
+    } else {
+        /* AT模式:使用标准读取 */
+        return ppp_serial_read(buffer, buffer_size, bytes_read);
+    }
+}
+
 /**
  * @brief 等待数据接收
  */
@@ -786,7 +857,7 @@ ppp_serial_mode_t ppp_serial_get_mode(void)
 /**
  * @brief 获取统计信息
  */
-uint32_t ppp_serial_get_stats(ppp_serial_stats_t *stats)
+ppp_error_t ppp_serial_get_stats(ppp_serial_stats_t *stats)
 {
     if (!g_serial_ctx.initialized || !stats) {
         return PPP_ERR_INVALID_PARAM;
@@ -808,6 +879,15 @@ uint32_t ppp_serial_get_stats(ppp_serial_stats_t *stats)
     osal_mutex_unlock(&g_serial_ctx.tx_mutex);
 
     return PPP_ERR_OK;
+}
+
+/**
+ * @brief 获取UART总线号
+ * @return UART总线号,如果未初始化返回UART_BUS_0
+ */
+uint8_t ppp_serial_get_uart_bus(void)
+{
+    return g_serial_ctx.uart_bus;
 } 
 
 /* 内部函数实现 */
index b3b7cfe..80ac372 100644 (file)
@@ -118,7 +118,7 @@ extern "C" {
 #define TCP_TEST_DEFAULT_RECV_TIMEOUT_MS 1000  // 默认接收超时1000ms
 
 /* 新的固定数据模式配置 */
-#define TCP_TEST_FIXED_DATA_SIZE    1024    // 固定数据长度,可通过宏配置
+#define TCP_TEST_FIXED_DATA_SIZE    2048    // 固定数据长度,可通过宏配置
 #define TCP_DATA_PATTERN_CYCLE      256     // 数据模式循环:0x00 ~ 0xFF
 
 /* TCP测试配置结构体 */
index a59c756..0f62ad9 100644 (file)
@@ -350,7 +350,7 @@ static errcode_t tcp_test_create_connection_threads(uint16_t conn_id)
     }
     *send_arg = conn_id;
     
-    TCP_TASK_CREATE(tcp_test_send_worker, send_arg, "tcp_send", 2048);
+    TCP_TASK_CREATE(tcp_test_send_worker, send_arg, "tcp_send", 4096);
     
     // 创建接收线程
     uint16_t *recv_arg = malloc(sizeof(uint16_t));
@@ -361,11 +361,10 @@ static errcode_t tcp_test_create_connection_threads(uint16_t conn_id)
     }
     *recv_arg = conn_id;
     
-    TCP_TASK_CREATE(tcp_test_recv_worker, recv_arg, "tcp_recv", 2048);
+    TCP_TASK_CREATE(tcp_test_recv_worker, recv_arg, "tcp_recv", 4096);
     
     return ERRCODE_SUCC;
 }
-
 /**
  * @brief 发送工作线程 - 只负责发送固定模式数据
  */
@@ -379,19 +378,23 @@ static void* tcp_test_send_worker(void *arg)
     
     conn->send_thread_running = true;
     
-    // å\88\86é\85\8då\8f\91é\80\81ç¼\93å\86²å\8cº - ä½¿ç\94¨å\8a¨æ\80\81å\88\86é\85\8dé\81¿å\85\8dæ \88溢å\87º
-    uint8_t *send_buffer = malloc(TCP_TEST_FIXED_DATA_SIZE);
-    if (!send_buffer) {
+    // å\8f\91é\80\81å\9bºå®\9a大å°\8fç\9a\84æ\95°æ\8d®å\8c\85
+    uint8_t *send_data = (uint8_t *)malloc(TCP_TEST_FIXED_DATA_SIZE);
+    if (send_data == NULL) {
         ZHIHUI_TCP_LOG_ERROR("[发送 %03d] 内存分配失败", conn_id);
-        conn->send_thread_running = false;
-        return NULL;
+        goto cleanup;
     }
     
-    uint32_t test_end_time = g_tcp_test_manager.global_stats.start_time + 
-                            (config->test_duration * 1000);
+    // 填充测试数据
+    for (int i = 0; i < TCP_TEST_FIXED_DATA_SIZE; i++) {
+        send_data[i] = (uint8_t)(i & 0xFF);
+    }
     
     ZHIHUI_TCP_LOG_INFO("[发送 %03d] 开始发送数据,固定长度: %d 字节", conn_id, TCP_TEST_FIXED_DATA_SIZE);
     
+    uint32_t test_end_time = g_tcp_test_manager.global_stats.start_time + 
+                            (config->test_duration * 1000);
+    
     uint32_t packet_counter = 0;
     uint32_t send_interval_ms = config->send_interval_ms;
     uint32_t last_send_time = 0;
@@ -408,7 +411,7 @@ static void* tcp_test_send_worker(void *arg)
         
         if (can_send) {
             // 生成固定模式数据
-            errcode_t ret = tcp_test_generate_fixed_pattern_data(current_pattern, send_buffer, TCP_TEST_FIXED_DATA_SIZE);
+            errcode_t ret = tcp_test_generate_fixed_pattern_data(current_pattern, send_data, TCP_TEST_FIXED_DATA_SIZE);
             if (ret != ERRCODE_SUCC) {
                 TCP_MUTEX_LOCK(g_tcp_stats_mutex);
                 conn->send_errors++;
@@ -419,7 +422,7 @@ static void* tcp_test_send_worker(void *arg)
             }
             
             // 发送数据
-            ssize_t bytes_sent = TCP_SEND(conn->socket_fd, send_buffer, TCP_TEST_FIXED_DATA_SIZE, 0);
+            ssize_t bytes_sent = TCP_SEND(conn->socket_fd, send_data, TCP_TEST_FIXED_DATA_SIZE, 0);
             
             if (bytes_sent > 0) {
                 TCP_MUTEX_LOCK(g_tcp_stats_mutex);
@@ -459,7 +462,8 @@ static void* tcp_test_send_worker(void *arg)
         TCP_SLEEP_MS(send_interval_ms );
     }
     
-    free(send_buffer);
+    free(send_data);
+cleanup:
     conn->send_thread_running = false;
     
     ZHIHUI_TCP_LOG_INFO("[发送 %03d] 发送线程结束,总发送: %d 包", conn_id, packet_counter);
@@ -480,7 +484,7 @@ static void* tcp_test_recv_worker(void *arg)
     conn->recv_thread_running = true;
     
     // 分配接收缓冲区
-    uint8_t *recv_buffer = malloc(TCP_TEST_FIXED_DATA_SIZE * 4); // 多缓冲一些数据
+            uint8_t *recv_buffer = malloc(TCP_TEST_FIXED_DATA_SIZE * 4); // 多缓冲一些数据
     if (!recv_buffer) {
         ZHIHUI_TCP_LOG_ERROR("[接收 %03d] 内存分配失败", conn_id);
         conn->recv_errors++;