N706A AT上网中间版
author孙春阳 <snickersun@163.com>
Sun, 2 Nov 2025 13:57:14 +0000 (21:57 +0800)
committer孙春阳 <snickersun@163.com>
Sun, 2 Nov 2025 13:57:14 +0000 (21:57 +0800)
49 files changed:
code/sdk/application/brandy/brandy_standard/service_init.c
code/sdk/bootloader/flashboot/brandy/main.c
code/sdk/build/config/target_config/brandy/config.py
code/sdk/zhihui/CMakeLists.txt
code/sdk/zhihui/leiniao/imsl_ln/ln_api.c
code/sdk/zhihui/n706a_net/CMakeLists.txt
code/sdk/zhihui/n706a_net/example/n706a_net_at_cmd.c [new file with mode: 0644]
code/sdk/zhihui/n706a_net/example/n706a_net_example.c [new file with mode: 0644]
code/sdk/zhihui/n706a_net/include/n706a_at_handler.h [new file with mode: 0644]
code/sdk/zhihui/n706a_net/include/n706a_http_client.h
code/sdk/zhihui/n706a_net/include/n706a_net_api.h [new file with mode: 0644]
code/sdk/zhihui/n706a_net/include/n706a_net_at_cmd.h [new file with mode: 0644]
code/sdk/zhihui/n706a_net/include/n706a_net_example.h [new file with mode: 0644]
code/sdk/zhihui/n706a_net/include/n706a_tcp_client.h
code/sdk/zhihui/n706a_net/include/ppp_cat1_api.h [new file with mode: 0644]
code/sdk/zhihui/n706a_net/include/ppp_config.h [new file with mode: 0644]
code/sdk/zhihui/n706a_net/include/ppp_debug.h [new file with mode: 0644]
code/sdk/zhihui/n706a_net/include/ppp_debug_manager.h [new file with mode: 0644]
code/sdk/zhihui/n706a_net/include/ppp_interrupt.h [new file with mode: 0644]
code/sdk/zhihui/n706a_net/include/ppp_power_ctl.h [new file with mode: 0644]
code/sdk/zhihui/n706a_net/include/ppp_serial.h [new file with mode: 0644]
code/sdk/zhihui/n706a_net/include/ppp_types.h [new file with mode: 0644]
code/sdk/zhihui/n706a_net/src/n706a_at_handler.c [new file with mode: 0644]
code/sdk/zhihui/n706a_net/src/n706a_http_client.c
code/sdk/zhihui/n706a_net/src/n706a_net_api.c [new file with mode: 0644]
code/sdk/zhihui/n706a_net/src/n706a_tcp_client.c
code/sdk/zhihui/n706a_net/src/n706a_websocket.c
code/sdk/zhihui/n706a_net/src/ppp_cat1_api.c [new file with mode: 0644]
code/sdk/zhihui/n706a_net/src/ppp_debug.c [new file with mode: 0644]
code/sdk/zhihui/n706a_net/src/ppp_debug_manager.c [new file with mode: 0644]
code/sdk/zhihui/n706a_net/src/ppp_interrupt.c [new file with mode: 0644]
code/sdk/zhihui/n706a_net/src/ppp_power_ctl.c [new file with mode: 0644]
code/sdk/zhihui/n706a_net/src/ppp_serial.c [new file with mode: 0644]
code/sdk/zhihui/ppp/example/n706a_http_tcp_example.c [deleted file]
code/sdk/zhihui/ppp/example/n706a_ssl_comparison_example.c [deleted file]
code/sdk/zhihui/ppp/example/n706a_websocket_example.c [deleted file]
code/sdk/zhihui/ppp/include/n706a_http_client.h [deleted file]
code/sdk/zhihui/ppp/include/n706a_tcp_client.h [deleted file]
code/sdk/zhihui/ppp/include/n706a_websocket.h [deleted file]
code/sdk/zhihui/ppp/src/n706a_http_client.c [deleted file]
code/sdk/zhihui/ppp/src/n706a_tcp_client.c [deleted file]
code/sdk/zhihui/ppp/src/n706a_websocket.c [deleted file]
code/sdk/zhihui/utils/custom_utils.c
code/sdk/zhihui/zhihui_net/adapter/zhihui_net_openharmony_adapter.c [deleted file]
code/sdk/zhihui/zhihui_net/adapter/zhihui_net_openharmony_adapter.h [deleted file]
code/sdk/zhihui/zhihui_net/adapter/zhihui_net_ppp_adapter.c [deleted file]
code/sdk/zhihui/zhihui_net/adapter/zhihui_net_ppp_adapter.h [deleted file]
code/sdk/zhihui/zhihui_net/include/zhihui_net.h
code/sdk/zhihui/zhihui_net/src/zhihui_net.c

index 0c7b0c8..4cc117a 100644 (file)
@@ -74,6 +74,9 @@
 #ifdef SUPPORT_AT_PPP\r
 #include "ppp_at_cmd.h"\r
 #endif\r
+#ifdef SUPPORT_AT_N706A_NET\r
+#include "n706a_net_at_cmd.h"\r
+#endif\r
 #include "log_file.h"\r
 #ifdef CONFIG_OTA_UPDATE_SUPPORT\r
 #include "upg.h"\r
@@ -191,6 +194,12 @@ static void register_at_service(void)
     at_cmd_add_moudle(ppp_table, ppp_cmd_count);\r
 #endif\r
 \r
+#ifdef SUPPORT_AT_N706A_NET\r
+    uint32_t n706a_net_cmd_count;\r
+    at_cmd_table_t *n706a_net_table = get_n706a_net_cmd_table(&n706a_net_cmd_count);\r
+    at_cmd_add_moudle(n706a_net_table, n706a_net_cmd_count);\r
+#endif\r
+\r
 #ifdef SUPPORT_ZHIHUI_AI_OLD\r
     uint32_t ai_old_cmd_count;\r
     at_cmd_table_t *ai_old_table = get_ai_old_cmd_table(&ai_old_cmd_count);\r
index 9d0b4a9..9a039a4 100644 (file)
@@ -794,20 +794,6 @@ static void fs_init(void)
     uapi_tcxo_delay_ms(50);    
 #endif
 
-#ifdef BOARD_LEINIAO
-    uapi_gpio_set_dir(S_AGPIO_L32, GPIO_DIRECTION_OUTPUT);
-    uapi_gpio_set_val(S_AGPIO_L32, GPIO_LEVEL_HIGH);
-
-    uapi_gpio_set_dir(S_AGPIO_R0, GPIO_DIRECTION_OUTPUT);
-    uapi_gpio_set_val(S_AGPIO_R0, GPIO_LEVEL_HIGH);
-
-    uapi_gpio_set_dir(S_HGPIO4, GPIO_DIRECTION_OUTPUT);
-    uapi_gpio_set_val(S_HGPIO4, GPIO_LEVEL_LOW);
-
-    uapi_gpio_set_dir(S_HGPIO0, GPIO_DIRECTION_OUTPUT);
-    uapi_gpio_set_val(S_HGPIO0, GPIO_LEVEL_LOW);
-#endif
-
 #ifdef CFG_DRIVERS_NANDFLASH
     nandflash_qspi_init();
 #endif
@@ -834,6 +820,31 @@ void main(void)
 #endif
 
     chip_init(rom_codeloadered);
+
+
+/************************雷鸟马达控制********************* */
+#ifdef BOARD_LEINIAO
+/*
+马达1
+双IO 正反转控制,默认低双电平或者双高电平 马达不转,AGPIOL32 高,AGPIOR0 低,马达正转,AGPIOL32 低,AGPIOR0 高,马达反转,
+*/
+    uapi_gpio_set_dir(S_AGPIO_L32, GPIO_DIRECTION_OUTPUT);    
+    uapi_gpio_set_val(S_AGPIO_L32, GPIO_LEVEL_HIGH);
+
+    uapi_gpio_set_dir(S_AGPIO_R0, GPIO_DIRECTION_OUTPUT);
+    uapi_gpio_set_val(S_AGPIO_R0, GPIO_LEVEL_HIGH);
+
+/*
+马达2
+双IO 正反转控制,默认低双电平或者双高电平 马达不转,HGPIO4 高,HGPIO0 低,马达正转,HGPIO4 低,HGPIO0 高,马达反转,
+*/
+    uapi_gpio_set_dir(S_HGPIO4, GPIO_DIRECTION_OUTPUT);
+    uapi_gpio_set_val(S_HGPIO4, GPIO_LEVEL_LOW);
+
+    uapi_gpio_set_dir(S_HGPIO0, GPIO_DIRECTION_OUTPUT);
+    uapi_gpio_set_val(S_HGPIO0, GPIO_LEVEL_LOW);
+#endif
+
     flash_init();
 
     while (uapi_uart_has_pending_transmissions(SW_DEBUG_UART_BUS)) { }
index 5b68f44..dad8a99 100644 (file)
@@ -1420,8 +1420,6 @@ target = {
             'ENABLE_CUSTOM_I2C',
             #'ENABLE_VIBRATOR',
             # 'ENCODER_SUPPORT',
-            # 'SUPPORT_SPO2_NOTIFICATION',
-            # 'SUPPORT_SPO2_NOTIFICATION_TEST',
             'SUPPORT_DEVICE_PAIRING_NOTIFICATION',
             # 'ENABLE_FONT_VECTOR_GLOBAL', 
             # 'ENABLE_SHAPING',
@@ -1429,7 +1427,6 @@ target = {
             # 'SUPPORT_AT_CUSTOMUTILS',
             # 'SUPPORT_BLE_SERVICE',
             # 'SUPPORT_MAG_SERVICE',
-            # 'SUPPORT_PPG_SERVICE',
             # 'SUPPORT_CYWEE_SERVICE',
             'SUPPORT_BATTERY_SERVICE',
             'LEINIAO',
@@ -1468,20 +1465,18 @@ target = {
         ],
         #添加自定义应用
        'ram_component': [
-                          'audio_at_service', 
-                          'media_at_service', 
-                          'bt_manager_at_service',
-                        #    "ppg_sensor_hx3695",
-                        #   "ppgBleService",
-                        #    "mag_sensor_mmc5603",
-                          "vibrator",
-                          "vibrator_service",
-                        #   "-:lwip",
-                          "thunderbird_toys",#雷鸟
-                          "leiniaoMediaService",
-                         #cat1 相关配置
-                         #有方需要开启  PPP
-                          "ppp",
+                        'audio_at_service', 
+                        'media_at_service', 
+                        'bt_manager_at_service',
+                        "vibrator",
+                        "vibrator_service",
+                        "thunderbird_toys",#雷鸟
+                        "leiniaoMediaService",
+                        #cat1 相关配置
+                        #有方需要开启  ppp和n706a_net 两个网络库之一
+                        # 注意:n706a_net 需要 ppp 组件提供 runtime 更新函数
+                        # "ppp",
+                        "n706a_net",
 
                         #EG810 需要开启 cat1Service 和 cat1Test
                         # "cat1Service",
@@ -1494,8 +1489,7 @@ target = {
 
                         #zhihui_net 相关配置
                         "zhihui_net",
-                        "n706a_net",
-                    
+
                         #ai 相关配置
                         "aiMediaService",       
                         "aiService",
@@ -1509,37 +1503,28 @@ target = {
                         "imsl",
                         "minimp3",
 
-                          "nativeabilityfwk",
-                          "custom_utils",
-                          "custom_utilscpp",
-                          "custom_config",
-                        #   "rotary_encoder",
-                           "nativelauncher",
-                            # "ppg_service",
-                            # "cywee_service",
-                           "batterry_service",
-                        #    "bleservice",
-                        #    "blemoder",
-                           "transspecard",
-                        #    "factorytest_service",
-                        #    "hid_service",
-                        #    "producttest",
-                            # "ppg_hal",
-                            # "mag_service",
-                            # "cywee_dml",
-                            #"cyweeBleService",
-                            'AT_factory_test',
-                            "-:alipay_soc", 
-                            "-:alipay_soc_adapt", 
-                            "-:alipay_service", 
-                            "-:alipay_hal", 
-                            "-:alipay_antchain",
-                            "-:alipay_msg",
-                           ],
+                        "nativeabilityfwk",
+                        "custom_utils",
+                        "custom_utilscpp",
+                        "custom_config",
+                        "nativelauncher",
+                        "batterry_service",
+                        #  "bleservice",
+                        #  "blemoder",
+                        "transspecard",
+                        #  "factorytest_service",
+                        #  "hid_service",
+                        'AT_factory_test',
+                        "-:alipay_soc", 
+                        "-:alipay_soc_adapt", 
+                        "-:alipay_service", 
+                        "-:alipay_hal", 
+                        "-:alipay_antchain",
+                        "-:alipay_msg",
+        ],
                'image_analysis': False,
                'fs_image_path':'leiniao',
         'ssb_version': 'brandy-native-js-ln-ssb',
-               # 'fs_image_path':'evb',
                'fs_image': True
     },
     'brandy-native-js-lnppp-r': {
@@ -1551,14 +1536,13 @@ target = {
                     # 'NANDFLASH_F35UQA',
                     'NANDFLASH_GD5F2G',
                     # 'NANDFLASH_XT26Q02D',
-                    # 'TPTYPE_FT6X46',
                     'CFG_FLASH_SIZE=16',
                     'CONFIG_NORFLASH_SIZE=16',
                      'CUSTOM_UTILS',
                     'LEINIAO',
                                        'SINGLE_USER_PARTITION',
-                      # 添加显示支持
-                     'LCD_JD9885',
+                    # 添加显示支持
+                    'LCD_JD9885',
                ],
                'ram_component': ["at_cmd"]
     },
index 8195aac..1d56c5a 100644 (file)
@@ -33,3 +33,87 @@ add_subdirectory_if_exist(minimp3)
 add_subdirectory_if_exist(shake)
 add_subdirectory_if_exist(n706a_net)
 add_subdirectory_if_exist(zhihui_net)
+
+
+# ========== PPP 和 N706A_NET 强制互斥检测 ==========
+# PPP 和 N706A_NET 使用同一个 UART 但工作模式不同,不能同时启用
+
+# 检测 SUPPORT_PPP_SERVICE_* 和 SUPPORT_N706A_NET 宏定义
+set(HAS_PPP_SERVICE FALSE)
+set(HAS_N706A_NET FALSE)
+
+# 检查 SUPPORT_PPP_SERVICE(从config.py的defines传递)
+if("SUPPORT_PPP_SERVICE" IN_LIST DEFINES OR "ppp" IN_LIST RAM_COMPONENT)
+    set(HAS_PPP_SERVICE TRUE)
+    if(NOT "SUPPORT_PPP_SERVICE" IN_LIST DEFINES)
+        list(APPEND DEFINES "SUPPORT_PPP_SERVICE")
+        message(STATUS "Auto-detected ppp component, added SUPPORT_PPP_SERVICE to DEFINES")
+    endif()
+endif()
+
+# 检查 SUPPORT_N706A_NET(支持两种方式检测)
+# 方式1:从config.py的defines传递(推荐)
+# 方式2:从ram_component检测组件是否被引入
+if("SUPPORT_N706A_NET" IN_LIST DEFINES OR "n706a_net" IN_LIST RAM_COMPONENT)
+    set(HAS_N706A_NET TRUE)
+    # 确保DEFINES中也有此宏(供其他地方使用,如互斥检测)
+    if(NOT "SUPPORT_N706A_NET" IN_LIST DEFINES)
+        list(APPEND DEFINES "SUPPORT_N706A_NET")
+        message(STATUS "Auto-detected n706a_net component, added SUPPORT_N706A_NET to DEFINES")
+    endif()
+endif()
+
+# 强制互斥检测:如果同时定义则终止编译
+if(HAS_PPP_SERVICE AND HAS_N706A_NET)
+    message(FATAL_ERROR "
+================================================================================
+【致命错误】网络组件冲突 - 编译终止!
+================================================================================
+
+SUPPORT_PPP_SERVICE 和 SUPPORT_N706A_NET 是互斥的网络实现方式,不能同时启用!
+
+当前配置错误:
+    ✗ SUPPORT_PPP_SERVICE = 已定义
+    ✗ SUPPORT_N706A_NET = 已定义
+    
+这两个宏不能同时存在!
+
+原因:
+    - 两者都使用同一个 UART (UART_BUS_0) 进行 4G 通信
+    - PPP 使用 PPP 协议拨号上网(需要 AT/PPP 模式切换)
+    - N706A_NET 使用纯 AT 命令实现网络通信(始终 AT 模式)
+    - 同时启用会导致 UART 访问冲突和通信失败
+
+解决方法:
+    请在 config.py 的 'defines' 中只保留其中一个:
+
+    方案A - 使用 PPP 拨号上网:
+        'defines': [
+            'SUPPORT_PPP_SERVICE_INTERRUPT',  # 或 SUPPORT_PPP_SERVICE_POLLING
+            # 'SUPPORT_N706A_NET',  # 注释掉此行
+            ...
+        ],
+        'ram_component': ['ppp', 'zhihui_net', ...]
+
+    方案B - 使用 N706A AT 网络:
+        'defines': [
+            # 'SUPPORT_PPP_SERVICE_INTERRUPT',  # 注释掉此行
+            'SUPPORT_N706A_NET',
+            ...
+        ],
+        'ram_component': ['n706a_net', 'zhihui_net', ...]
+
+请修改配置后重新编译!
+================================================================================
+")
+endif()
+
+# 提示当前使用的网络模式
+if(HAS_PPP_SERVICE)
+    message(STATUS "【网络模式】PPP Service (${PPP_MODE} mode)")
+elseif(HAS_N706A_NET)
+    message(STATUS "【网络模式】N706A AT Network (Pure AT mode)")
+else()
+    message(STATUS "【网络模式】No network mode selected")
+endif()
+
index f559259..6b864e1 100644 (file)
@@ -1739,20 +1739,13 @@ errcode_t uapi_ln_http_server_init(void)
 {
     printf("uapi_ln_http_server_init !\r\n");
 
-    /* 初始化 zhihui_net 
-     * 说明:
-     * - PPP拨号模式:使用 OpenHarmony (PPP + lwIP + haisi_websocket)
-     * - 非PPP模式:使用 N706A AT指令(纯AT,不拨号)
+    /* 初始化 zhihui_net
+     * 模式由 SUPPORT_N706A_NET 宏自动决定:
+     * - 定义了 SUPPORT_N706A_NET → N706A AT 模式(不拨号PPP)
+     * - 未定义 SUPPORT_N706A_NET → OpenHarmony 模式(PPP拨号 + lwIP)
+     * 
+     * 无需手动调用 ZhihuiNetSetImplementation(),已自动配置
      */
-    #if defined(SUPPORT_PPP_SERVICE_INTERRUPT) || defined(SUPPORT_PPP_SERVICE_POLLING)
-    /* PPP拨号模式:使用OpenHarmony实现(基于lwIP) */
-    ZhihuiNetSetImplementation(ZHIHUI_NET_IMPL_OPENHARMONY);
-    printf("[LeiNiao] Using OpenHarmony (PPP + lwIP) network implementation\r\n");
-    #else
-    /* 非PPP模式:使用N706A AT指令 */
-    ZhihuiNetSetImplementation(ZHIHUI_NET_IMPL_N706A_AT);
-    printf("[LeiNiao] Using N706A AT command network implementation\r\n");
-    #endif
     ZhihuiNetInit();
 
     ln_send_taskcfg.create_queue_handle = create_ln_http_send_queue;
index 9d74e56..7c08449 100644 (file)
@@ -1,5 +1,5 @@
 #===============================================================================
-# @brief    N706A PPP网络接口层
+# @brief    N706A AT网络接口层(独立于PPP)
 # Copyright (c) @CompanyNameMagicTag 2023-2025. All rights reserved.
 #===============================================================================
 set(COMPONENT_NAME "n706a_net")
@@ -8,6 +8,16 @@ set(SOURCES ${SOURCES}
     ${CMAKE_CURRENT_SOURCE_DIR}/src/n706a_tcp_client.c
     ${CMAKE_CURRENT_SOURCE_DIR}/src/n706a_http_client.c
     ${CMAKE_CURRENT_SOURCE_DIR}/src/n706a_websocket.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/n706a_at_handler.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/n706a_net_api.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ppp_interrupt.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ppp_serial.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_debug.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ppp_debug_manager.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/example/n706a_net_example.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/example/n706a_net_at_cmd.c
 )
 
 set(PUBLIC_HEADER
@@ -15,15 +25,19 @@ set(PUBLIC_HEADER
 )
 
 set(PUBLIC_DEFINES
-    SUPPORT_N706A_NET
+    SUPPORT_N706A_NET           # 定义此宏启用 N706A AT 模式(独立于PPP)
+    SUPPORT_AT_N706A_NET        # 开机自动注册 N706A AT 命令
+    # SSL实现方式(二选一,仅影响n706a_net内部):
+    N706A_SSL_USE_AT_COMMAND    # 使用AT指令实现SSL(推荐,利用N706A内置SSL)
+    # N706A_SSL_USE_MBEDTLS     # 使用mbedtls库实现SSL(不推荐:与AT模式不兼容)
 )
 
 set(PRIVATE_HEADER
+    ${CMAKE_CURRENT_SOURCE_DIR}/../ppp/include
 )
 
 set(PRIVATE_DEFINES
-# N706A_SSL_USE_MBEDTLS
-N706A_SSL_USE_AT_COMMAND
+    # SSL宏已移至 PUBLIC_DEFINES,以便其他模块能检测到
 )
 
 # use this when you want to add ccflags like -include xxx
@@ -44,6 +58,11 @@ set(MAIN_COMPONENT
     false
 )
 
+# 添加依赖:n706a_net 需要链接 ppp 组件的部分函数
+set(DEPENDENCIES
+    ppp
+)
+
 build_component()
 
 install_sdk(${CMAKE_CURRENT_SOURCE_DIR} "*")
diff --git a/code/sdk/zhihui/n706a_net/example/n706a_net_at_cmd.c b/code/sdk/zhihui/n706a_net/example/n706a_net_at_cmd.c
new file mode 100644 (file)
index 0000000..d3e2458
--- /dev/null
@@ -0,0 +1,475 @@
+/**
+ * @file n706a_net_at_cmd.c
+ * @brief N706A AT网络的AT命令接口(参考ppp_at_cmd.c实现)
+ */
+
+#include "n706a_net_at_cmd.h"
+#include "n706a_net_example.h"
+#include "n706a_net_api.h"
+#include "n706a_at_handler.h"
+#include "ppp_debug.h"
+#include "ppp_interrupt.h"
+#include "at_cmd_api.h"
+#include "osal_debug.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 工具宏定义 */
+#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
+#define CUSTOM_UTILS_MAX_ARGC            8
+#define CUSTOM_UTILS_MAX_ARGV_LEN        256
+#define CUSTOM_UTILS_SUCCESS             0
+#define CUSTOM_UTILS_FAILED              (-1)
+
+/**
+ * @brief 参数解析工具函数
+ */
+static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen,
+        uint8_t argv[CUSTOM_UTILS_MAX_ARGC][CUSTOM_UTILS_MAX_ARGV_LEN], uint32_t* argc)
+{
+    uint32_t pos = 0;
+    *argc = 0;
+
+    for (uint32_t i = 0; i < paraLen; i++) {
+        if ((para[i] == ' ' || para[i] == ',' || para[i] == '\n') && pos != 0) {
+            argv[*argc][pos] = '\0';
+            *argc += 1;
+            pos = 0;
+            if (*argc >= CUSTOM_UTILS_MAX_ARGC) {
+                return CUSTOM_UTILS_FAILED;
+            }
+        } else {
+            argv[*argc][pos] = para[i];
+            pos++;
+            if (pos >= CUSTOM_UTILS_MAX_ARGV_LEN) {
+                return CUSTOM_UTILS_FAILED;
+            }
+        }
+    }
+    if (pos != 0) {
+        *argc += 1;
+    }
+
+    return CUSTOM_UTILS_SUCCESS;
+}
+
+/**
+ * @brief AT^N706ANETINIT - 初始化N706A AT网络环境
+ * 
+ * 用法: AT^N706ANETINIT
+ * 
+ * 该命令会初始化:
+ * - 4G模块电源控制
+ * - UART串口(2M波特率)
+ * - AT命令处理器(异步接收)
+ * - 中断接收系统(Ping-Pong缓冲)
+ */
+static errcode_t at_n706a_net_env_init(uint8_t *para, uint32_t para_len, char *strCommonCmd)
+{
+    UNUSED(para);
+    UNUSED(para_len);
+    UNUSED(strCommonCmd);
+
+    PPP_DEBUG_INFO("=== N706A AT Network Initialization ===\n");
+    
+    int ret = n706a_net_env_init();
+    if (ret != 0) {
+        PPP_DEBUG_ERROR("N706A network initialization failed: %d\n", ret);
+        return ERRCODE_FAIL;
+    }
+    
+    PPP_DEBUG_INFO("SUCCESS: N706A AT network initialized\n");
+    PPP_DEBUG_INFO("  - You can now use HTTP/WebSocket functions\n");
+    PPP_DEBUG_INFO("  - Example: Use zhihui_net APIs for networking\n");
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief AT^N706ANETDEINIT - 反初始化N706A AT网络环境
+ * 
+ * 用法: AT^N706ANETDEINIT
+ */
+static errcode_t at_n706a_net_env_deinit(uint8_t *para, uint32_t para_len, char *strCommonCmd)
+{
+    UNUSED(para);
+    UNUSED(para_len);
+    UNUSED(strCommonCmd);
+
+    PPP_DEBUG_INFO("=== N706A AT Network Deinitialization ===\n");
+    
+    int ret = n706a_net_env_deinit();
+    if (ret != 0) {
+        PPP_DEBUG_ERROR("N706A network deinitialization failed: %d\n", ret);
+        return ERRCODE_FAIL;
+    }
+    
+    PPP_DEBUG_INFO("SUCCESS: N706A AT network deinitialized\n");
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief AT^N706ANETSTATUS - 查询N706A AT网络状态
+ * 
+ * 用法: AT^N706ANETSTATUS
+ */
+static errcode_t at_n706a_net_status(uint8_t *para, uint32_t para_len, char *strCommonCmd)
+{
+    UNUSED(para);
+    UNUSED(para_len);
+    UNUSED(strCommonCmd);
+
+    PPP_DEBUG_INFO("=== N706A AT Network Status ===\n");
+    
+    bool initialized = is_n706a_env_initialized();
+    uint32_t baudrate = get_n706a_baudrate();
+    
+    PPP_DEBUG_INFO("Initialized: %s\n", initialized ? "YES" : "NO");
+    PPP_DEBUG_INFO("Baudrate: %u\n", baudrate);
+    PPP_DEBUG_INFO("Mode: Pure AT commands (no PPP)\n");
+    PPP_DEBUG_INFO("Reception: Asynchronous interrupt\n");
+    
+    // 打印中断统计信息
+    ppp_interrupt_print_stats();
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief AT^N706ANETBAUD - 设置N706A波特率
+ * 
+ * 用法: AT^N706ANETBAUD=<baudrate>
+ * 参数: baudrate - 波特率(建议2000000或1000000)
+ * 
+ * 示例: AT^N706ANETBAUD=2000000
+ */
+static errcode_t at_n706a_net_set_baudrate(uint8_t *para, uint32_t para_len, char *strCommonCmd)
+{
+    UNUSED(strCommonCmd);
+    
+    if (para == NULL || para_len == 0) {
+        PPP_DEBUG_ERROR("Missing baudrate parameter\n");
+        PPP_DEBUG_INFO("Usage: AT^N706ANETBAUD=<baudrate>\n");
+        PPP_DEBUG_INFO("Example: AT^N706ANETBAUD=2000000\n");
+        return ERRCODE_FAIL;
+    }
+
+    uint8_t argv[CUSTOM_UTILS_MAX_ARGC][CUSTOM_UTILS_MAX_ARGV_LEN] = { 0 };
+    uint32_t argc = 0;
+    
+    int ret = ConvertCmdToParam(para, para_len, argv, &argc);
+    if (ret != CUSTOM_UTILS_SUCCESS || argc != 1) {
+        PPP_DEBUG_ERROR("Invalid parameter format\n");
+        return ERRCODE_FAIL;
+    }
+    
+    uint32_t baudrate = atoi((char*)argv[0]);
+    
+    if (baudrate != 115200 && baudrate != 1000000 && baudrate != 2000000) {
+        PPP_DEBUG_WARN("Unusual baudrate value: %u\n", baudrate);
+        PPP_DEBUG_INFO("Recommended: 2000000, 1000000, or 115200\n");
+    }
+
+    set_n706a_baudrate(baudrate);
+    PPP_DEBUG_INFO("Baudrate set to: %u\n", baudrate);
+    PPP_DEBUG_INFO("Note: This will take effect on next initialization\n");
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief AT^N706ANETTEST - 测试AT命令通信
+ * 
+ * 用法: AT^N706ANETTEST
+ */
+static errcode_t at_n706a_net_test_communication(uint8_t *para, uint32_t para_len, char *strCommonCmd)
+{
+    UNUSED(para);
+    UNUSED(para_len);
+    UNUSED(strCommonCmd);
+
+    PPP_DEBUG_INFO("=== N706A AT Communication Test ===\n");
+    
+    if (!is_n706a_env_initialized()) {
+        PPP_DEBUG_ERROR("N706A network not initialized\n");
+        PPP_DEBUG_INFO("Please run AT^N706ANETINIT first\n");
+        return ERRCODE_FAIL;
+    }
+    
+    n706a_at_error_t ret = n706a_at_test_communication();
+    if (ret == N706A_AT_OK) {
+        PPP_DEBUG_INFO("AT communication test PASSED\n");
+        return ERRCODE_SUCC;
+    } else {
+        PPP_DEBUG_ERROR("AT communication test FAILED: %d\n", ret);
+        return ERRCODE_FAIL;
+    }
+}
+
+/**
+ * @brief AT^N706ANETCMD - 发送原始AT命令
+ * 
+ * 用法: AT^N706ANETCMD=<AT命令>
+ * 示例: AT^N706ANETCMD=AT+CSQ
+ */
+static errcode_t at_n706a_net_send_at_command(uint8_t *para, uint32_t para_len, char *strCommonCmd)
+{
+    UNUSED(strCommonCmd);
+    
+    if (para == NULL || para_len == 0) {
+        PPP_DEBUG_ERROR("Missing AT command parameter\n");
+        PPP_DEBUG_INFO("Usage: AT^N706ANETCMD=<AT_COMMAND>\n");
+        PPP_DEBUG_INFO("Example: AT^N706ANETCMD=AT+CSQ\n");
+        return ERRCODE_FAIL;
+    }
+
+    if (!is_n706a_env_initialized()) {
+        PPP_DEBUG_ERROR("N706A network not initialized\n");
+        PPP_DEBUG_INFO("Please run AT^N706ANETINIT first\n");
+        return ERRCODE_FAIL;
+    }
+
+    // 构建AT命令字符串
+    char at_cmd[256];
+    if (para_len >= sizeof(at_cmd)) {
+        PPP_DEBUG_ERROR("AT command too long (max %d chars)\n", sizeof(at_cmd) - 1);
+        return ERRCODE_FAIL;
+    }
+    
+    memcpy(at_cmd, para, para_len);
+    at_cmd[para_len] = '\0';
+    
+    PPP_DEBUG_CRITICAL("Sending AT command: [%s]", at_cmd);
+    
+    // 发送AT命令
+    n706a_at_response_t response;
+    const uint32_t timeout_ms = 5000;
+    
+    n706a_at_error_t ret = n706a_at_send_command(at_cmd, NULL, timeout_ms, &response);
+    
+    if (ret == N706A_AT_OK && response.success) {
+        if (response.length > 0) {
+            // 强制打印响应(使用 CRITICAL 级别确保可见)
+            PPP_DEBUG_CRITICAL("=== AT Response (%u bytes) ===", response.length);
+            PPP_DEBUG_CRITICAL("%s", response.response);
+            PPP_DEBUG_CRITICAL("=== End AT Response ===");
+        } else {
+            PPP_DEBUG_WARN("Command executed successfully but no response data received");
+        }
+        return ERRCODE_SUCC;
+    } else {
+        PPP_DEBUG_ERROR("AT command failed: error=%d, success=%d", ret, response.success);
+        return ERRCODE_FAIL;
+    }
+}
+
+/**
+ * @brief AT^N706ANETSIGNAL - 获取信号强度
+ * 
+ * 用法: AT^N706ANETSIGNAL
+ */
+static errcode_t at_n706a_net_get_signal(uint8_t *para, uint32_t para_len, char *strCommonCmd)
+{
+    UNUSED(para);
+    UNUSED(para_len);
+    UNUSED(strCommonCmd);
+
+    PPP_DEBUG_INFO("=== N706A Signal Information ===\n");
+    
+    if (!is_n706a_env_initialized()) {
+        PPP_DEBUG_ERROR("N706A network not initialized\n");
+        return ERRCODE_FAIL;
+    }
+    
+    n706a_network_signal_info_t signal_info;
+    n706a_at_error_t ret = n706a_at_get_network_signal_info(&signal_info);
+    
+    if (ret == N706A_AT_OK && signal_info.valid) {
+        PPP_DEBUG_INFO("Signal Information:\n");
+        PPP_DEBUG_INFO("  RXLEV: %d (GSM signal level, 0-63, 99=invalid)\n", signal_info.rxlev);
+        PPP_DEBUG_INFO("  BER: %d (Bit error rate, 0-7, 99=invalid)\n", signal_info.ber);
+        PPP_DEBUG_INFO("  RSCP: %d (UMTS, 0-96, 255=invalid)\n", signal_info.rscp);
+        PPP_DEBUG_INFO("  ECNO: %d (UMTS, 0-49, 255=invalid)\n", signal_info.ecno);
+        PPP_DEBUG_INFO("  RSRQ: %d (LTE quality, 0-49, 255=invalid)\n", signal_info.rsrq);
+        PPP_DEBUG_INFO("  RSRP: %d (LTE power, 0-97, 255=invalid)\n", signal_info.rsrp);
+        return ERRCODE_SUCC;
+    } else {
+        PPP_DEBUG_ERROR("Failed to get signal information: %d\n", ret);
+        return ERRCODE_FAIL;
+    }
+}
+
+/**
+ * @brief AT^N706ANETDEBUG - 设置调试级别
+ * 
+ * 用法: AT^N706ANETDEBUG=<level>
+ * level: 0=NONE, 1=ERROR, 2=WARN, 3=INFO, 4=DEBUG
+ */
+static errcode_t at_n706a_net_set_debug_level(uint8_t *para, uint32_t para_len, char *strCommonCmd)
+{
+    UNUSED(strCommonCmd);
+    
+    if (!para || para_len == 0) {
+        PPP_DEBUG_ERROR("Missing debug level parameter\n");
+        PPP_DEBUG_INFO("Usage: AT^N706ANETDEBUG=<level>\n");
+        PPP_DEBUG_INFO("Levels: 0=NONE, 1=ERROR, 2=WARN, 3=INFO, 4=DEBUG\n");
+        return ERRCODE_FAIL;
+    }
+    
+    uint8_t argv[CUSTOM_UTILS_MAX_ARGC][CUSTOM_UTILS_MAX_ARGV_LEN] = { 0 };
+    uint32_t argc = 0;
+    
+    int ret = ConvertCmdToParam(para, para_len, argv, &argc);
+    if (ret != CUSTOM_UTILS_SUCCESS || argc != 1) {
+        PPP_DEBUG_ERROR("Invalid parameter format\n");
+        return ERRCODE_FAIL;
+    }
+    
+    int level = atoi((char*)argv[0]);
+    
+    if (level < 0 || level > 4) {
+        PPP_DEBUG_ERROR("Invalid debug level %d (must be 0-4)\n", level);
+        return ERRCODE_FAIL;
+    }
+    
+    ppp_error_t ppp_ret = ppp_debug_set_level(level);
+    if (ppp_ret == PPP_ERR_OK) {
+        PPP_DEBUG_INFO("Debug level set to %d (%s)\n", level, ppp_debug_get_level_name(level));
+        return ERRCODE_SUCC;
+    } else {
+        PPP_DEBUG_ERROR("Failed to set debug level\n");
+        return ERRCODE_FAIL;
+    }
+}
+
+/**
+ * @brief AT^N706ASETBAUD - 设置N706A波特率到配置模型(对应PPP的AT^PPPSETBAUD)
+ * @param para 参数: 波特率值
+ * @param para_len 参数长度
+ * 
+ * 用法: AT^N706ASETBAUD=<baudrate>
+ * 示例: AT^N706ASETBAUD=115200
+ * 
+ * 支持的波特率: 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600, 1000000, 2000000
+ */
+static errcode_t at_n706a_set_config_baudrate(uint8_t *para, uint32_t para_len, char *strCommonCmd)
+{
+    UNUSED(strCommonCmd);
+    
+    if (!para || para_len == 0) {
+        PPP_DEBUG_ERROR("N706A SET BAUDRATE: Missing baudrate parameter\n");
+        return ERRCODE_FAIL;
+    }
+    
+    uint8_t argv[CUSTOM_UTILS_MAX_ARGC][CUSTOM_UTILS_MAX_ARGV_LEN] = { 0 };
+    uint32_t argc = 0;
+    
+    int ret = ConvertCmdToParam(para, para_len, argv, &argc);
+    if (ret != CUSTOM_UTILS_SUCCESS || argc != 1) {
+        PPP_DEBUG_ERROR("N706A SET BAUDRATE: Invalid parameter format, usage: AT^N706ASETBAUD=baudrate\n");
+        return ERRCODE_FAIL;
+    }
+    
+    uint32_t baudrate = atoi((char*)argv[0]);
+    
+    // 检查波特率是否为支持的值
+    if (baudrate != 9600 && baudrate != 19200 && baudrate != 38400 && 
+        baudrate != 57600 && baudrate != 115200 && baudrate != 230400 && 
+        baudrate != 460800 && baudrate != 921600 && baudrate != 1000000 && baudrate != 2000000) {
+        PPP_DEBUG_ERROR("N706A SET BAUDRATE: Invalid baudrate %d\n", baudrate);
+        PPP_DEBUG_ERROR("N706A SET BAUDRATE: Supported values: 9600,19200,38400,57600,115200,230400,460800,921600,1000000,2000000\n");
+        return ERRCODE_FAIL;
+    }
+    
+    // 获取当前配置的波特率
+    uint32_t current_baudrate = get_n706a_baudrate();
+    
+    if (current_baudrate == baudrate) {
+        PPP_DEBUG_INFO("N706A SET BAUDRATE: Baudrate already set to %d, no change needed\n", baudrate);
+        // return ERRCODE_SUCC;
+    }
+    
+    // 设置新的波特率到配置模型
+    set_n706a_baudrate(baudrate);
+    
+    PPP_DEBUG_INFO("N706A SET BAUDRATE: Config model updated: %d -> %d\n", current_baudrate, baudrate);
+    
+    // 尝试动态更新 N706A模块 波特率(发送 AT+IPR 命令)
+    PPP_DEBUG_INFO("N706A SET BAUDRATE: Attempting to set N706A module baudrate to %d...\n", baudrate);
+    errcode_t rett = n706a_api_set_baudrate_in_all_mode(baudrate);
+    
+    if (rett == ERRCODE_SUCC) {
+        PPP_DEBUG_INFO("N706A SET BAUDRATE: Successfully set N706A module baudrate to %d\n", baudrate);
+        PPP_DEBUG_INFO("N706A SET BAUDRATE: Baudrate change completed successfully\n");
+    } else {
+        PPP_DEBUG_ERROR("N706A SET BAUDRATE: Failed to set N706A module baudrate (ret: %d)\n", ret);
+        PPP_DEBUG_ERROR("N706A SET BAUDRATE: Config model updated, but N706A module baudrate NOT changed\n");
+        PPP_DEBUG_ERROR("N706A SET BAUDRATE: Please restart N706A module to apply the new baudrate\n");
+        // 虽然模块设置失败,但配置已更新,下次重启会生效
+        // 根据需求可以选择返回 ERRCODE_SUCC 或 ERRCODE_FAIL
+        return ERRCODE_FAIL;  // 返回失败,让用户知道当前操作未完全成功
+    }
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief AT^N706AGETBAUD - 获取N706A波特率配置(对应PPP的AT^PPPGETBAUD)
+ * 
+ * 用法: AT^N706AGETBAUD
+ */
+static errcode_t at_n706a_get_config_baudrate(uint8_t *para, uint32_t para_len, char *strCommonCmd)
+{
+    UNUSED(para);
+    UNUSED(para_len);
+    UNUSED(strCommonCmd);
+    
+    uint32_t config_baudrate = get_n706a_baudrate();
+    
+    PPP_DEBUG_INFO("N706A GET BAUDRATE: Config model baudrate: %d\n", config_baudrate);
+    PPP_DEBUG_INFO("N706A GET BAUDRATE: This is the baudrate that will be used for N706A communication\n");
+    
+    if (is_n706a_env_initialized()) {
+        PPP_DEBUG_INFO("N706A GET BAUDRATE: N706A is currently initialized with this baudrate\n");
+    } else {
+        PPP_DEBUG_INFO("N706A GET BAUDRATE: N706A is not initialized yet\n");
+    }
+    
+    return ERRCODE_SUCC;
+}
+
+/* N706A AT网络命令表 */
+static const at_cmd_table_t g_n706a_net_at_cmd_table[] = {
+    { (char *)"AT^N706ANETINIT",    at_n706a_net_env_init,           (char *)" " },
+    { (char *)"AT^N706ANETDEINIT",  at_n706a_net_env_deinit,         (char *)" " },
+    { (char *)"AT^N706ANETSTATUS",  at_n706a_net_status,             (char *)" " },
+    { (char *)"AT^N706ANETBAUD",    at_n706a_net_set_baudrate,       (char *)"=<baudrate>" },
+    { (char *)"AT^N706ANETTEST",    at_n706a_net_test_communication, (char *)" " },
+    { (char *)"AT^N706ANETCMD",     at_n706a_net_send_at_command,    (char *)"=<AT_COMMAND>" },
+    { (char *)"AT^N706ANETSIGNAL",  at_n706a_net_get_signal,         (char *)" " },
+    { (char *)"AT^N706ANETDEBUG",   at_n706a_net_set_debug_level,    (char *)"=<level>" },
+    { (char *)"AT^N706ASETBAUD",    at_n706a_set_config_baudrate,    (char *)"=<baudrate>" },
+    { (char *)"AT^N706AGETBAUD",    at_n706a_get_config_baudrate,    (char *)" " },
+};
+
+/**
+ * @brief 获取N706A AT网络命令表
+ * 
+ * @param cmd_count 输出参数,返回命令数量
+ * @return 命令表指针
+ */
+at_cmd_table_t *get_n706a_net_cmd_table(uint32_t *cmd_count)
+{
+    *cmd_count = sizeof(g_n706a_net_at_cmd_table) / sizeof(at_cmd_table_t);
+    return (at_cmd_table_t *)g_n706a_net_at_cmd_table;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/code/sdk/zhihui/n706a_net/example/n706a_net_example.c b/code/sdk/zhihui/n706a_net/example/n706a_net_example.c
new file mode 100644 (file)
index 0000000..e48c131
--- /dev/null
@@ -0,0 +1,171 @@
+/**
+ * @file n706a_net_example.c
+ * @brief N706A AT网络使用示例
+ */
+
+#include "n706a_net_example.h"
+#include "n706a_net_api.h"
+#include "ppp_config.h"
+#include "ppp_debug.h"
+#include "osal_debug.h"
+#include "schedule/osal_task.h"
+#include "ConfigModelC.h"  // 用于ConfigModel波特率持久化
+#include <stdio.h>
+
+/* 使用 PPP_DEBUG_INFO 替代 PRINT */
+#ifndef PRINT
+#define PRINT(fmt, ...) PPP_DEBUG_INFO(fmt, ##__VA_ARGS__)
+#endif
+
+static bool g_n706a_env_initialized = false;
+static uint32_t g_n706a_baudrate = PPP_UART_BAUDRATE;
+
+/**
+ * @brief N706A网络环境初始化
+ * @return 0成功,-1失败
+ */
+int n706a_net_env_init(void)
+{
+    if (g_n706a_env_initialized) {
+        PRINT("N706A network environment already initialized\r\n");
+        return 0;
+    }
+
+    PRINT("N706A Network Environment Initialization Started\r\n");
+
+    /* 1. 配置N706A网络参数 */
+    n706a_net_config_t config = {
+        .baudrate = g_n706a_baudrate,      // 波特率(2M或1M)
+        .auto_baudrate = true,             // 启用自动波特率检测
+        .init_timeout = 30000              // 30秒初始化超时
+    };
+
+    /* 2. 初始化N706A AT网络系统 */
+    PRINT("Initializing N706A AT network system...\r\n");
+    errcode_t ret = n706a_net_init(&config);
+    if (ret != ERRCODE_SUCC) {
+        PRINT("N706A network init failed: error code %d\r\n", ret);
+        return -1;
+    }
+
+    g_n706a_env_initialized = true;
+    PRINT("N706A network environment initialized successfully (Pure AT mode)\r\n");
+    PRINT("  - Mode: AT commands only (no PPP dialing)\r\n");
+    PRINT("  - Reception: Asynchronous interrupt with ring buffer\r\n");
+    PRINT("  - Baudrate: %u\r\n", g_n706a_baudrate);
+    
+    if (n706a_net_is_power_initialized()) {
+        PRINT("4G power control is enabled\r\n");
+    } else {
+        PRINT("4G power control is disabled\r\n");
+    }
+    
+    /* 等待5秒让调制解调器完全稳定 */
+    PRINT("Waiting for modem stabilization...\r\n");
+    osal_msleep(5000);
+    
+    /* 更新所有运行时状态(IMEI、信号、运营商等) */
+    PRINT("Updating runtime status...\r\n");
+    ret = n706a_api_update_all_runtime_status();
+    if (ret != ERRCODE_SUCC) {
+        PRINT("Warning: Failed to update runtime status\r\n");
+    }
+    
+    /* 获取并显示网络信号信息 */
+    PRINT("Getting network signal info...\r\n");
+    ret = n706a_get_network_signal_info();
+    if (ret != ERRCODE_SUCC) {
+        PRINT("Warning: Failed to get network signal info\r\n");
+    }
+    
+    #if 0
+    /* 启用省电模式 */
+    PRINT("Enabling power save mode...\r\n");
+    ret = n706a_enable_power_save_mode();
+    if (ret != ERRCODE_SUCC) {
+        PRINT("Warning: Failed to enable power save mode\r\n");
+    }
+    #endif
+    
+    PRINT("N706A network ready for use\r\n");
+    
+    /* 启动 WebSocket 服务 */
+    extern errcode_t uapi_ln_ws_start(void);
+    PRINT("Starting WebSocket service...\r\n");
+    ret = uapi_ln_ws_start();
+    if (ret != ERRCODE_SUCC) {
+        PRINT("Warning: Failed to start WebSocket service: %d\r\n", ret);
+    } else {
+        PRINT("WebSocket service started successfully\r\n");
+    }
+    
+    return 0;
+}
+
+/**
+ * @brief 获取N706A波特率
+ * 
+ * @note N706A和PPP是互斥的,复用PPP的ConfigModel配置项
+ */
+uint32_t get_n706a_baudrate(void)
+{
+    // 从ConfigModel读取(与PPP共用配置项,因为它们互斥)
+    uint32_t baudrate = get_ppp_baudrate_from_config_model();
+    
+    // 如果ConfigModel中没有配置,返回默认值
+    if (baudrate == 0) {
+        baudrate = g_n706a_baudrate;  // 使用默认值
+    }
+    
+    return baudrate;
+}
+
+/**
+ * @brief 设置N706A波特率
+ * 
+ * @note N706A和PPP是互斥的,复用PPP的ConfigModel配置项实现持久化
+ */
+void set_n706a_baudrate(uint32_t value)
+{
+    // 同时更新全局变量和ConfigModel(持久化保存)
+    g_n706a_baudrate = value;
+    
+    // 保存到ConfigModel(与PPP共用配置项,因为它们互斥)
+    set_ppp_baudrate_from_config_model(value);
+    
+    PPP_DEBUG_INFO("N706A baudrate saved to ConfigModel: %u", value);
+}
+
+/**
+ * @brief 检查N706A网络环境是否已初始化
+ */
+bool is_n706a_env_initialized(void)
+{
+    return g_n706a_env_initialized;
+}
+
+/**
+ * @brief N706A网络环境反初始化
+ */
+int n706a_net_env_deinit(void)
+{
+    if (!g_n706a_env_initialized) {
+        PRINT("N706A network environment not initialized\r\n");
+        return 0;
+    }
+
+    PRINT("N706A Network Environment Deinitialization Started\r\n");
+
+    /* 反初始化N706A网络系统 */
+    errcode_t ret = n706a_net_deinit();
+    if (ret != ERRCODE_SUCC) {
+        PRINT("N706A network deinit failed: error code %d\r\n", ret);
+        return -1;
+    }
+
+    g_n706a_env_initialized = false;
+    PRINT("N706A network environment deinitialized successfully\r\n");
+    
+    return 0;
+}
+
diff --git a/code/sdk/zhihui/n706a_net/include/n706a_at_handler.h b/code/sdk/zhihui/n706a_net/include/n706a_at_handler.h
new file mode 100644 (file)
index 0000000..431023d
--- /dev/null
@@ -0,0 +1,139 @@
+/**
+ * @file n706a_at_handler.h
+ * @brief N706A AT命令处理器(纯AT模式)
+ * 
+ * 专用于n706a_net的AT指令处理,与PPP模式互斥
+ * 提供异步串口接收保证高速数据完整性
+ */
+
+#ifndef N706A_AT_HANDLER_H
+#define N706A_AT_HANDLER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+/* AT响应最大长度 */
+#define N706A_AT_RESPONSE_MAX_LEN    1024
+#define N706A_AT_CMD_MAX_LEN         256
+#define N706A_AT_CMD_TIMEOUT         5000   // 默认5秒超时
+
+/* 错误码定义 */
+typedef enum {
+    N706A_AT_OK = 0,
+    N706A_AT_ERR_INVALID_PARAM,
+    N706A_AT_ERR_MEMORY,
+    N706A_AT_ERR_UART,
+    N706A_AT_ERR_TIMEOUT,
+    N706A_AT_ERR_AT_FAILED,
+} n706a_at_error_t;
+
+/**
+ * @brief AT响应结构体
+ */
+typedef struct {
+    char response[N706A_AT_RESPONSE_MAX_LEN];  // 响应内容
+    uint32_t length;                            // 响应长度
+    bool success;                               // 是否成功
+    n706a_at_error_t error_code;               // 错误码
+} n706a_at_response_t;
+
+/**
+ * @brief 初始化AT命令处理模块
+ * @param uart_bus UART总线号
+ * @param baudrate 波特率
+ * @return 错误码
+ */
+n706a_at_error_t n706a_at_handler_init(uint8_t uart_bus, uint32_t baudrate);
+
+/**
+ * @brief 反初始化AT命令处理模块
+ */
+void n706a_at_handler_deinit(void);
+
+/**
+ * @brief 发送AT命令并等待响应
+ * @param command AT命令字符串(不含\r\n)
+ * @param expected_response 期望的响应字符串(如"OK"),NULL表示不检查
+ * @param timeout 超时时间(ms)
+ * @param response 响应结构体指针
+ * @return 错误码
+ */
+n706a_at_error_t n706a_at_send_command(const char *command, 
+                                       const char *expected_response, 
+                                       uint32_t timeout, 
+                                       n706a_at_response_t *response);
+
+/**
+ * @brief 发送原始数据(不带AT命令格式)
+ * @param data 要发送的数据
+ * @param len 数据长度
+ * @param timeout 超时时间(ms)
+ * @return 错误码
+ * @note 用于 TCP/SSL 数据发送,在 AT+TCPSEND/AT+SSLTCPSEND 命令后使用
+ */
+n706a_at_error_t n706a_at_send_raw_data(const void *data, size_t len, uint32_t timeout);
+
+/**
+ * @brief 设置波特率
+ * @param baudrate 波特率
+ * @return 错误码
+ */
+n706a_at_error_t n706a_at_set_baudrate(uint32_t baudrate);
+
+/**
+ * @brief 获取当前波特率
+ * @return 当前波特率
+ */
+uint32_t n706a_at_get_current_baudrate(void);
+
+/**
+ * @brief 测试AT通信是否正常
+ * @return 错误码
+ */
+n706a_at_error_t n706a_at_test_communication(void);
+
+/**
+ * @brief 网络信号信息结构体 (基于AT+CESQ命令)
+ */
+typedef struct {
+    int16_t rxlev;              // GSM信号接收功率 (0-63, 99=无效)
+    int16_t ber;                // 误码率 (0-7, 99=无效)
+    int16_t rscp;               // UMTS下行载波干扰比率 (0-96, 255=无效)
+    int16_t ecno;               // UMTS下行载波干扰比率 (0-49, 255=无效)
+    int16_t rsrq;               // LTE参考信号质量 (0-49, 255=无效)
+    int16_t rsrp;               // LTE参考信号接收功率 (0-97, 255=无效)
+    bool valid;                 // 数据是否有效
+} n706a_network_signal_info_t;
+
+/**
+ * @brief 获取网络信号信息
+ * @param info 信号信息结构体指针
+ * @return 错误码
+ */
+n706a_at_error_t n706a_at_get_network_signal_info(n706a_network_signal_info_t *info);
+
+/**
+ * @brief TCP URC数据接收回调函数类型
+ * @param socket_id Socket ID (0-5)
+ * @param data 接收到的TCP数据
+ * @param length 数据长度
+ */
+typedef void (*n706a_tcp_urc_callback_t)(int socket_id, const uint8_t *data, size_t length);
+
+/**
+ * @brief 注册TCP URC接收回调
+ * @param callback 回调函数指针,NULL表示取消注册
+ */
+void n706a_at_register_tcp_urc_callback(n706a_tcp_urc_callback_t callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* N706A_AT_HANDLER_H */
+
index fe6b150..5e6a918 100644 (file)
@@ -53,6 +53,7 @@ typedef enum {
     N706A_HTTP_EPROTO   = -10, /**< 协议错误         */
     N706A_HTTP_EUNKOWN  = -11, /**< 未知错误          */
     N706A_HTTP_ETIMEOUT = -12, /**< 超时                */
+    N706A_HTTP_ENOMEM   = -13, /**< 内存分配失败         */
 } n706a_httpc_result_t;
 
 /**
diff --git a/code/sdk/zhihui/n706a_net/include/n706a_net_api.h b/code/sdk/zhihui/n706a_net/include/n706a_net_api.h
new file mode 100644 (file)
index 0000000..3ea7d89
--- /dev/null
@@ -0,0 +1,130 @@
+/**
+ * @file n706a_net_api.h
+ * @brief N706A AT命令网络API接口(独立于PPP)
+ */
+
+#ifndef N706A_NET_API_H
+#define N706A_NET_API_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "errcode.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief N706A网络状态枚举
+ */
+typedef enum {
+    N706A_NET_STATE_IDLE = 0,       // 空闲状态
+    N706A_NET_STATE_READY,          // 就绪状态(已初始化)
+    N706A_NET_STATE_ERROR           // 错误状态
+} n706a_net_state_t;
+
+/**
+ * @brief N706A网络配置参数
+ */
+typedef struct {
+    uint32_t baudrate;              // 波特率(建议2000000或1000000)
+    bool auto_baudrate;             // 是否启用自动波特率检测
+    uint32_t init_timeout;          // 初始化超时时间(毫秒)
+} n706a_net_config_t;
+
+/**
+ * @brief 初始化N706A AT网络系统
+ * 
+ * 该函数会完成以下初始化:
+ * 1. 4G模块电源控制
+ * 2. UART串口初始化
+ * 3. AT命令处理器初始化
+ * 4. 异步中断接收系统初始化
+ * 
+ * @param config 网络配置参数
+ * @return ERRCODE_SUCC 成功,其他值失败
+ */
+errcode_t n706a_net_init(const n706a_net_config_t *config);
+
+/**
+ * @brief 反初始化N706A AT网络系统
+ * 
+ * @return ERRCODE_SUCC 成功,其他值失败
+ */
+errcode_t n706a_net_deinit(void);
+
+/**
+ * @brief 初始化4G电源控制
+ * 
+ * @return ERRCODE_SUCC 成功,其他值失败
+ */
+errcode_t n706a_net_power_init(void);
+
+/**
+ * @brief 控制4G电源开关
+ * 
+ * @param is_open true打开,false关闭
+ * @return ERRCODE_SUCC 成功,其他值失败
+ */
+errcode_t n706a_net_power_control(bool is_open);
+
+/**
+ * @brief 检查4G电源是否已初始化
+ * 
+ * @return true已初始化,false未初始化
+ */
+bool n706a_net_is_power_initialized(void);
+
+/**
+ * @brief 获取N706A网络状态
+ * 
+ * @return n706a_net_state_t 当前状态
+ */
+n706a_net_state_t n706a_net_get_state(void);
+
+/**
+ * @brief 获取并显示网络信号信息
+ * 
+ * @return ERRCODE_SUCC 成功,其他值失败
+ */
+errcode_t n706a_get_network_signal_info(void);
+
+/**
+ * @brief 启用4G模块电源省电模式
+ * 
+ * @return ERRCODE_SUCC 成功,其他值失败
+ * 
+ * 功能说明:
+ * - 执行 AT+NWENPWRSAVE=1 命令
+ * - 配置为:低电平唤醒,高电平进入休眠
+ */
+errcode_t n706a_enable_power_save_mode(void);
+
+/**
+ * @brief 更新所有runtime变量值
+ * 
+ * @return ERRCODE_SUCC 成功,其他值失败
+ * 
+ * 包括:IMEI、信号强度、运营商、ICCID、SIM卡状态、网络状态、版本、时间等
+ */
+errcode_t n706a_api_update_all_runtime_status(void);
+
+/**
+ * @brief 动态设置N706A模块波特率(在所有模式下)
+ * 
+ * @param baudrate 目标波特率
+ * @return ERRCODE_SUCC 成功,其他值失败
+ * 
+ * 功能说明:
+ * - 发送 AT+IPR 命令设置N706A模块波特率
+ * - 同步更新MCU UART配置
+ * - 如果设置失败会进行重试
+ */
+errcode_t n706a_api_set_baudrate_in_all_mode(uint32_t baudrate);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* N706A_NET_API_H */
+
diff --git a/code/sdk/zhihui/n706a_net/include/n706a_net_at_cmd.h b/code/sdk/zhihui/n706a_net/include/n706a_net_at_cmd.h
new file mode 100644 (file)
index 0000000..f21153e
--- /dev/null
@@ -0,0 +1,41 @@
+/**
+ * @file n706a_net_at_cmd.h
+ * @brief N706A AT网络的AT命令接口
+ */
+
+#ifndef N706A_NET_AT_CMD_H
+#define N706A_NET_AT_CMD_H
+
+#include <stdint.h>
+#include "errcode.h"
+#include "at_cmd_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief 获取N706A AT网络命令表
+ * 
+ * 该函数返回N706A_NET的AT命令表,包含以下命令:
+ * - AT^N706ANETINIT           : 初始化N706A AT网络
+ * - AT^N706ANETDEINIT         : 反初始化N706A AT网络
+ * - AT^N706ANETSTATUS         : 查询网络状态(含中断统计)
+ * - AT^N706ANETBAUD=<value>   : 设置波特率
+ * - AT^N706ANETTEST           : 测试AT通信
+ * - AT^N706ANETCMD=<cmd>      : 发送原始AT命令
+ * - AT^N706ANETSIGNAL         : 获取信号强度
+ * - AT^N706ANETDEBUG=<level>  : 设置调试级别
+ * 
+ * @param cmd_count 输出参数,返回命令数量
+ * @return 命令表指针
+ * 
+ * @note 该函数通常由系统启动代码调用,自动注册所有命令
+ */
+at_cmd_table_t *get_n706a_net_cmd_table(uint32_t *cmd_count);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* N706A_NET_AT_CMD_H */
diff --git a/code/sdk/zhihui/n706a_net/include/n706a_net_example.h b/code/sdk/zhihui/n706a_net/include/n706a_net_example.h
new file mode 100644 (file)
index 0000000..87ef49b
--- /dev/null
@@ -0,0 +1,62 @@
+/**
+ * @file n706a_net_example.h
+ * @brief N706A AT网络使用示例接口
+ */
+
+#ifndef N706A_NET_EXAMPLE_H
+#define N706A_NET_EXAMPLE_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief N706A网络环境初始化
+ * 
+ * 该函数会完成所有必要的初始化工作:
+ * - 4G模块电源控制
+ * - UART串口初始化
+ * - AT命令处理器初始化
+ * - 异步中断接收系统初始化
+ * 
+ * @return 0成功,-1失败
+ */
+int n706a_net_env_init(void);
+
+/**
+ * @brief N706A网络环境反初始化
+ * 
+ * @return 0成功,-1失败
+ */
+int n706a_net_env_deinit(void);
+
+/**
+ * @brief 获取N706A波特率
+ * 
+ * @return 当前波特率
+ */
+uint32_t get_n706a_baudrate(void);
+
+/**
+ * @brief 设置N706A波特率
+ * 
+ * @param value 波特率值(建议2000000或1000000)
+ */
+void set_n706a_baudrate(uint32_t value);
+
+/**
+ * @brief 检查N706A网络环境是否已初始化
+ * 
+ * @return true已初始化,false未初始化
+ */
+bool is_n706a_env_initialized(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* N706A_NET_EXAMPLE_H */
+
index 227cace..8687c14 100644 (file)
@@ -74,6 +74,12 @@ typedef struct {
     bool is_ssl;                    /**< 是否SSL连接 */
     uint32_t timeout_ms;            /**< 超时时间 */
     
+    /* URC接收缓存(用于存储 +TCPRECV URC 收到的数据) */
+    uint8_t *urc_recv_buffer;       /**< URC接收缓冲区 */
+    size_t urc_recv_capacity;       /**< 缓冲区容量 */
+    size_t urc_recv_length;         /**< 当前数据长度 */
+    void *urc_recv_mutex;           /**< 缓冲区互斥锁 */
+    
     /* SSL相关字段(根据编译宏不同而不同) */
 #ifdef N706A_SSL_USE_AT_COMMAND
     /* AT指令模式:SSL由模组处理 */
@@ -194,6 +200,31 @@ bool n706a_tcp_is_connected(const n706a_tcp_socket_t *sock);
  */
 n706a_tcp_state_t n706a_tcp_get_state(const n706a_tcp_socket_t *sock);
 
+/**
+ * @brief 初始化TCP socket的URC接收缓存
+ * @param sock TCP socket指针
+ * @param buffer_size 缓冲区大小(建议2048字节)
+ * @return N706A_TCP_SUCCESS成功,其他值表示失败
+ * @note 由 n706a_tcp_socket_create 自动调用,通常不需要手动调用
+ */
+n706a_tcp_result_t n706a_tcp_init_urc_buffer(n706a_tcp_socket_t *sock, size_t buffer_size);
+
+/**
+ * @brief 释放TCP socket的URC接收缓存
+ * @param sock TCP socket指针
+ * @note 由 n706a_tcp_close 自动调用,通常不需要手动调用
+ */
+void n706a_tcp_free_urc_buffer(n706a_tcp_socket_t *sock);
+
+/**
+ * @brief 全局TCP URC数据接收回调(由n706a_at_handler调用)
+ * @param socket_id Socket ID
+ * @param data TCP数据
+ * @param length 数据长度
+ * @note 此函数在中断/线程上下文中被调用,需要注意线程安全
+ */
+void n706a_tcp_on_urc_received(int socket_id, const uint8_t *data, size_t length);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/code/sdk/zhihui/n706a_net/include/ppp_cat1_api.h b/code/sdk/zhihui/n706a_net/include/ppp_cat1_api.h
new file mode 100644 (file)
index 0000000..43cdf4b
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * @brief PPP模块的cat1 API兼容接口声明
+ * @description 提供与cat1Service相同的接口声明,让UI和其他服务无需修改
+ * Copyright (c) CompanyNameMagicTag 2024-2024. All rights reserved.
+ */
+
+#ifndef __PPP_CAT1_API_H
+#define __PPP_CAT1_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "errcode.h"
+#include "platform_core.h"
+
+// 前向声明,避免重复定义
+typedef enum _4g_cmd CMD_4G_T;
+typedef struct ctl_pin_4g_s ctl_pin_4g_t;
+typedef struct time_ctl_funcs_s time_ctl_funcs_t;
+typedef errcode_t (*f_cat1_msg_callback)(int msg, void *msg_buf, uint16_t msglen);
+
+/********************** 主要接口 **********************/
+
+
+/**
+ * @brief cat1 开关机设置, 输入 true 开机, false 关机
+ */
+void cat1_api_enable_cat1(bool isopen);
+
+
+/**
+ * @brief 获取cat1是否使能(开机)状态
+ */
+bool cat1_api_is_cat1_enabled(void);
+
+
+
+/**
+ * @brief return cmd uart rx enable flag
+ */
+bool cat1_api_custom_is_cmd_rx_enabled(void);
+
+/********************** 运行时状态获取接口 **********************/
+
+/**
+ * @brief 获取cat1电源开启状态
+ * @return 1 开机,0 关机
+ */
+uint8_t cat1_api_runtime_get_cat1_powerstat(void);
+
+/**
+ * @brief 获取cat1网络状态
+ * @return 1 网络在线,0 断网
+ */
+uint8_t cat1_api_runtime_get_cat1_networkstat(void);
+
+/**
+ * @brief 获取cat1信号强度
+ * @return 1~31 或者 99,99代表无网络
+ */
+int cat1_api_runtime_get_cat1_signal(void);
+
+/**
+ * @brief 获取sim卡状态
+ * @return 1 有sim卡,0 无sim卡
+ */
+int cat1_api_runtime_get_cat1_simstat(void);
+
+/**
+ * @brief 获取网络类型
+ * @return 0 "无网络", 1 "GSM", 2 "3G", 4 "4G/LTE"
+ */
+uint8_t cat1_api_runtime_get_cat1_networktype(void);
+
+/**
+ * @brief 获取Cat1运营商信息
+ * @return 返回运营商字符串
+ */
+char* cat1_api_runtime_get_cat1_operator(void);
+
+/**
+ * @brief 获取Cat1 ICCID号
+ * @return 返回iccid字符串
+ */
+char* cat1_api_runtime_get_cat1_iccid(void);
+
+/**
+ * @brief 获取Cat1 IMEI号
+ * @return 返回imei字符串
+ */
+char* cat1_api_runtime_get_cat1_imei(void);
+
+/**
+ * @brief 获取Cat1主应用版本号
+ * @return 返回主应用版本号
+ */
+char* cat1_api_runtime_get_cat1_pyver(void);
+
+/**
+ * @brief 获取modem版本
+ * @return modem版本字符串
+ */
+char* cat1_api_runtime_get_cat1_modemver(void);
+
+/********************** 运行时状态设置接口 **********************/
+
+/**
+ * @brief 设置cat1电源状态
+ */
+void cat1_api_runtime_set_cat1_powerstat(uint8_t cat1_powerOn);
+
+/**
+ * @brief 设置cat1网络状态
+ */
+void cat1_api_runtime_set_cat1_networkstat(uint8_t network_on);
+
+/**
+ * @brief 设置cat1信号强度
+ */
+void cat1_api_runtime_set_cat1_signal(int signal);
+
+/**
+ * @brief 设置sim卡状态
+ */
+void cat1_api_runtime_set_cat1_simstat(int simstat);
+
+/**
+ * @brief 设置网络类型
+ */
+void cat1_api_runtime_set_cat1_networktype(uint8_t networktype);
+
+/**
+ * @brief 设置Cat1运营商信息
+ */
+void cat1_api_runtime_set_cat1_operator(char* cat1_operator);
+
+/**
+ * @brief 设置Cat1 IMEI号
+ */
+void cat1_api_runtime_set_cat1_imei(char* imei);
+
+/**
+ * @brief 设置Cat1 ICCID号
+ */
+void cat1_api_runtime_set_cat1_iccid(char* iccid);
+
+/**
+ * @brief 设置Cat1主应用版本号
+ */
+void cat1_api_runtime_set_cat1_pyver(char* pyver);
+
+/**
+ * @brief 设置modem版本
+ */
+void cat1_api_runtime_set_cat1_modemver(char* modemver);
+
+/********************** 控制接口 **********************/
+
+/**
+ * @brief cat1 唤醒设置, 输入 true 唤醒cat1 modem, false cat1 modem自动休眠
+ */
+void cat1_api_wakeup_cat1(uint8_t wakeup);
+
+/**
+ * @brief 保持唤醒Cat1
+ */
+void cat1_api_keep_wakeup(uint8_t keep_wakeup);
+
+/**
+ * @brief 注册控制4G的gpio值
+ */
+errcode_t cat1_register_ctl_pin(ctl_pin_4g_t ctl_pin);
+
+/**
+ * @brief cat1唤醒蓝牙中断处理函数
+ */
+void cat1_ring_isr_callback(pin_t pin, uintptr_t param);
+
+/********************** 其他接口 **********************/
+
+/**
+ * @brief 发送指令给Cat1
+ */
+errcode_t cat1_cmd_send(CMD_4G_T cmd, void *cmd_buf, uint16_t cmdlen);
+
+/**
+ * @brief 注册消息回调函数
+ */
+errcode_t cat1_register_msg_callback(f_cat1_msg_callback func);
+
+/**
+ * @brief 注册时间控制函数
+ */
+errcode_t cat1_register_time_ctl_functions(time_ctl_funcs_t *funcs);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __PPP_CAT1_API_H */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/n706a_net/include/ppp_config.h b/code/sdk/zhihui/n706a_net/include/ppp_config.h
new file mode 100644 (file)
index 0000000..2f98361
--- /dev/null
@@ -0,0 +1,138 @@
+#ifndef PPP_CONFIG_H
+#define PPP_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/* PPP配置参数 - UART配置统一使用SIO (在lwipopts_default.h中定义) */
+#define PPP_LOW_POWER_MODE          1
+
+/* SIO设备号配置 - 与SLIP区分开 */
+#define PPP_IFNUM                   0                   // PPP使用的SIO设备号,与SLIP_IFNUM(0)区分
+
+/* UART引脚配置 - 对应SIO配置 */
+#ifndef SIO_UART_TX_PIN
+#define SIO_UART_TX_PIN             S_MGPIO19         // UART TX引脚
+#endif
+#ifndef SIO_UART_RX_PIN  
+#define SIO_UART_RX_PIN             S_MGPIO20         // UART RX引脚
+#endif
+#ifndef SIO_UART_BUS
+#define SIO_UART_BUS                UART_BUS_0          // UART总线
+#endif
+#ifndef SIO_UART_IRQ_NUM
+#define SIO_UART_IRQ_NUM            UART_0_IRQN         // UART IRQ引脚
+#endif
+
+#define PPP_UART_BAUDRATE          1000000
+
+/* 支持的波特率列表(自适应模式) */
+#define PPP_BAUDRATE_AUTO_LIST      {115200,921600,1000000,2000000}
+#define PPP_BAUDRATE_AUTO_COUNT     4
+
+/* 支持的固定波特率列表 */
+#define PPP_BAUDRATE_FIXED_LIST     {4800, 9600, 57600, 115200, 230400, 460800, 750000, 921600, 1000000, 2000000, 4000000}
+#define PPP_BAUDRATE_FIXED_COUNT    11
+
+/* AT命令配置 */
+#define PPP_AT_CMD_TIMEOUT          3000                // AT命令超时时间(ms)
+#define PPP_AT_DEFAULT_TIMEOUT      5000                // AT默认超时时间(ms)
+#define PPP_AT_CMD_MAX_LEN          256                 // AT命令最大长度
+#define PPP_AT_RESPONSE_MAX_LEN     1024                // AT响应最大长度
+#define PPP_AT_RETRY_COUNT          3                   // AT命令重试次数
+
+/* PPP拨号配置 */
+#define PPP_DIAL_TIMEOUT            30000               // 拨号超时时间(ms)
+#define PPP_DIAL_RETRY_COUNT        3                   // 拨号重试次数
+#define PPP_KEEPALIVE_INTERVAL      30                  // 保活间隔(秒)
+
+/* PPP接收模式配置 */
+#ifdef SUPPORT_PPP_SERVICE_POLLING
+#define PPP_USE_INTERRUPT_MODE      0                  // 1=中断模式(UART中断接收), 0=轮询模式(线程轮询)
+#elif defined(SUPPORT_PPP_SERVICE_INTERRUPT)
+#define PPP_USE_INTERRUPT_MODE      1                  // 1=中断模式(UART中断接收), 0=轮询模式(线程轮询)
+#endif
+//测试串口读取能力,注意不要注释掉,只用1和0 开启关闭即可。否则可能影响编译
+
+#if defined(SKIP_LN_PROTOCOL_TEST)
+#define PPP_DO_SERIAL_TEST          1                   // 1=进行串口读取能力测试, 0=不进行串口读取能力测试
+#else
+#define PPP_DO_SERIAL_TEST          0                   // 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                // 发送缓冲区大小
+
+/* PPP数据接收线程配置 */
+#define PPP_RX_THREAD_STACK_SIZE        4096                // 接收线程栈大小
+#define PPP_RX_THREAD_PRIORITY          osPriorityHigh      // 接收线程优先级(提高以确保及时读取数据)
+#define PPP_PROCESS_THREAD_PRIORITY     osPriorityAboveNormal // 处理线程优先级
+
+/* 调试配置 */
+#define PPP_DEBUG_ENABLE            1                   // 启用调试输出
+// #define PPP_DEBUG_LEVEL             PPP_DEBUG_LEVEL_DEBUG // 默认只显示警告和错误 (1=ERROR, 2=WARN, 3=INFO, 4=DEBUG)
+// #define PPP_DEBUG_LEVEL             PPP_DEBUG_LEVEL_INFO // 默认只显示警告和错误 (1=ERROR, 2=WARN, 3=INFO, 4=DEBUG)
+#define PPP_DEBUG_LEVEL             PPP_DEBUG_LEVEL_WARN // 默认只显示警告和错误 (1=ERROR, 2=WARN, 3=INFO, 4=DEBUG)
+
+/*
+ * 调试级别说明:
+ * PPP_DEBUG_LEVEL_ERROR (1)  - 只显示错误信息
+ * PPP_DEBUG_LEVEL_WARN  (2)  - 显示警告和错误信息  
+ * PPP_DEBUG_LEVEL_INFO  (3)  - 显示信息、警告和错误
+ * PPP_DEBUG_LEVEL_DEBUG (4)  - 显示所有调试信息
+ * 
+ * 关键连接状态信息(PPP_DEBUG_CRITICAL)始终显示,不受此级别控制
+ * 
+ * 如需完整调试信息,可将上面的PPP_DEBUG_LEVEL改为PPP_DEBUG_LEVEL_DEBUG
+ */
+
+/* PPP状态定义 */
+typedef enum {
+    PPP_STATE_IDLE = 0,                                 // 空闲状态
+    PPP_STATE_INITIALIZED,                              // 已初始化状态
+    PPP_STATE_INIT,                                     // 初始化状态
+    PPP_STATE_AT_HANDSHAKE,                            // AT握手状态
+    PPP_STATE_SET_BAUDRATE,                            // 设置波特率状态
+    PPP_STATE_DIALING,                                // 拨号中
+    PPP_STATE_CONNECTING,                               // 连接中
+    PPP_STATE_CONNECTED,                               // 已连接状态
+    PPP_STATE_DISCONNECTING,                           // 断开连接状态
+    PPP_STATE_ERROR,                                    // 错误状态
+    PPP_STATE_MAX
+} ppp_state_t;
+
+/* PPP错误码定义 */
+typedef enum {
+    PPP_ERR_OK = 0,                                    // 成功
+    PPP_ERR_TIMEOUT,                                   // 超时
+    PPP_ERR_AT_FAILED,                                 // AT命令失败
+    PPP_ERR_DIAL_FAILED,                              // 拨号失败
+    PPP_ERR_NO_CARRIER,                               // 无载波
+    PPP_ERR_BUSY,                                      // 忙
+    PPP_ERR_NO_DIALTONE,                              // 无拨号音
+    PPP_ERR_INVALID_PARAM,                            // 无效参数
+    PPP_ERR_MEMORY,                                    // 内存错误
+    PPP_ERR_UART,                                      // 串口错误
+    PPP_ERR_INVALID_STATE,                            // 无效状态
+    PPP_ERR_UNKNOWN,                                    // 未知错误
+    PPP_ERR_MAX
+} ppp_error_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPP_CONFIG_H */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/n706a_net/include/ppp_debug.h b/code/sdk/zhihui/n706a_net/include/ppp_debug.h
new file mode 100644 (file)
index 0000000..ecf7b4a
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef PPP_DEBUG_H
+#define PPP_DEBUG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include "ppp_config.h"
+#include "debug_print.h"
+
+/* 调试级别定义 */
+#define PPP_DEBUG_LEVEL_NONE    0
+#define PPP_DEBUG_LEVEL_ERROR   1
+#define PPP_DEBUG_LEVEL_WARN    2
+#define PPP_DEBUG_LEVEL_INFO    3
+#define PPP_DEBUG_LEVEL_DEBUG   4
+
+#if PPP_DEBUG_ENABLE
+
+/* 前向声明动态调试级别函数 */
+extern int ppp_debug_get_level(void);
+
+#define PPP_DEBUG_ERROR(fmt, ...) \
+    do { \
+        if (ppp_debug_get_level() >= PPP_DEBUG_LEVEL_ERROR) { \
+            PRINT("[PPP ERROR] " fmt "\r\n", ##__VA_ARGS__); \
+        } \
+    } while(0)
+
+#define PPP_DEBUG_WARN(fmt, ...) \
+    do { \
+        if (ppp_debug_get_level() >= PPP_DEBUG_LEVEL_WARN) { \
+            PRINT("[PPP WARN] " fmt "\r\n", ##__VA_ARGS__); \
+        } \
+    } while(0)
+
+#define PPP_DEBUG_INFO(fmt, ...) \
+    do { \
+        if (ppp_debug_get_level() >= PPP_DEBUG_LEVEL_INFO) { \
+            PRINT("[PPP INFO] " fmt "\r\n", ##__VA_ARGS__); \
+        } \
+    } while(0)
+
+#define PPP_DEBUG_DEBUG(fmt, ...) \
+    do { \
+        if (ppp_debug_get_level() >= PPP_DEBUG_LEVEL_DEBUG) { \
+            PRINT("[PPP DEBUG] " fmt "\r\n", ##__VA_ARGS__); \
+        } \
+    } while(0)
+
+#define PPP_DEBUG_HEXDUMP(data, len) \
+    do { \
+        if (ppp_debug_get_level() >= PPP_DEBUG_LEVEL_DEBUG) { \
+            ppp_debug_hexdump(data, len); \
+        } \
+    } while(0)
+
+/* 兼容性宏 - 用于旧代码 */
+#define PPP_DEBUG_PRINT(fmt, ...) \
+    do { \
+    if (ppp_debug_get_level() >= PPP_DEBUG_LEVEL_INFO) { \
+        print_str(fmt, ##__VA_ARGS__); \
+    } \
+    } while(0)  
+
+/* 关键信息宏 - 始终打印重要的连接状态信息 */
+#define PPP_DEBUG_CRITICAL(fmt, ...) \
+    do { \
+        PRINT("[PPP] " fmt "\r\n", ##__VA_ARGS__); \
+    } while(0)
+
+#else
+
+#define PPP_DEBUG_ERROR(fmt, ...)
+#define PPP_DEBUG_WARN(fmt, ...)
+#define PPP_DEBUG_INFO(fmt, ...)
+#define PPP_DEBUG_DEBUG(fmt, ...)
+#define PPP_DEBUG_HEXDUMP(data, len)
+#define PPP_DEBUG_PRINT(fmt, ...)
+#define PPP_DEBUG_CRITICAL(fmt, ...) PRINT("[PPP] " fmt "\r\n", ##__VA_ARGS__)
+
+#endif /* PPP_DEBUG_ENABLE */
+
+/**
+ * @brief 十六进制数据转储
+ * @param data 数据指针
+ * @param len 数据长度
+ */
+void ppp_debug_hexdump(const uint8_t *data, uint32_t len);
+
+/**
+ * @brief 获取错误码字符串
+ * @param error_code 错误码
+ * @return 错误码字符串
+ */
+const char *ppp_debug_error_string(ppp_error_t error_code);
+
+/**
+ * @brief 获取状态字符串
+ * @param state PPP状态
+ * @return 状态字符串
+ */
+const char *ppp_debug_state_string(ppp_state_t state);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPP_DEBUG_H */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/n706a_net/include/ppp_debug_manager.h b/code/sdk/zhihui/n706a_net/include/ppp_debug_manager.h
new file mode 100644 (file)
index 0000000..a92f872
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * @file ppp_debug_manager.h
+ * @brief PPP调试级别动态管理模块头文件
+ */
+
+#ifndef PPP_DEBUG_MANAGER_H
+#define PPP_DEBUG_MANAGER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ppp_types.h"
+
+/**
+ * @brief 获取当前动态调试级别
+ * @return 当前调试级别
+ */
+int ppp_debug_get_level(void);
+
+/**
+ * @brief 设置动态调试级别
+ * @param level 调试级别 (0-4)
+ * @return PPP_ERR_OK-成功,其他-失败
+ */
+ppp_error_t ppp_debug_set_level(int level);
+
+/**
+ * @brief 获取调试级别名称
+ * @param level 调试级别
+ * @return 级别名称字符串
+ */
+const char* ppp_debug_get_level_name(int level);
+
+/**
+ * @brief 根据名称设置调试级别
+ * @param level_name 级别名称 ("NONE", "ERROR", "WARN", "INFO", "DEBUG")
+ * @return PPP_ERR_OK-成功,其他-失败
+ */
+ppp_error_t ppp_debug_set_level_by_name(const char* level_name);
+
+/**
+ * @brief 重置调试级别为默认值
+ * @return PPP_ERR_OK-成功
+ */
+ppp_error_t ppp_debug_reset_level(void);
+
+/**
+ * @brief 检查指定级别是否启用
+ * @param level 要检查的级别
+ * @return true-启用,false-未启用
+ */
+bool ppp_debug_is_level_enabled(int level);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPP_DEBUG_MANAGER_H */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/n706a_net/include/ppp_interrupt.h b/code/sdk/zhihui/n706a_net/include/ppp_interrupt.h
new file mode 100644 (file)
index 0000000..24452b1
--- /dev/null
@@ -0,0 +1,153 @@
+/**
+ * @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错误丢弃的字节数
+    uint32_t dropped_malloc_fail;        // 因内存分配失败丢弃的字节数
+    uint32_t dropped_queue_full;         // 因消息队列满丢弃的字节数
+} 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 启用PPP UART中断接收
+ * @return PPP_ERR_OK 成功,其他值失败
+ * 
+ * @note 调用此函数前:
+ *       1. ppp_serial必须已初始化(UART总线号从ppp_serial_get_uart_bus()获取)
+ *       2. UART必须已经初始化(硬件缓冲区在uart_porting.c中配置)
+ */
+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);
+
+/**
+ * @brief 检查是否可以安全执行+++命令切换到命令模式
+ * @return true 安全,false 不安全
+ * 
+ * 判断标准:
+ * 1. PPP已连接
+ * 2. 接收空闲时间 >= 5秒
+ * 3. 接收速率 < 100 bps
+ * 4. 所有buffer都是EMPTY状态
+ */
+bool ppp_interrupt_is_safe_for_command_switch(void);
+
+/**
+ * @brief 等待安全切换窗口
+ * @param timeout_ms 超时时间(毫秒)
+ * @return true 找到安全窗口,false 超时
+ */
+bool ppp_interrupt_wait_for_safe_switch(uint32_t timeout_ms);
+
+/**
+ * @brief 打印数据传输状态信息(调试用)
+ */
+void ppp_interrupt_print_data_state(void);
+
+/**
+ * @brief 暂停PPP中断处理(用于临时切换到AT模式)
+ * @return PPP_ERR_OK 成功,其他值失败
+ * 
+ * 极简实现(只需停止 UART 中断):
+ * 1. 注销UART中断回调 → 无新数据
+ * 2. Timer 继续运行 → 自动 flush 残留数据
+ * 3. 线程自然阻塞 → 使用 OSAL_MSGQ_WAIT_FOREVER
+ * 
+ * 优势:
+ * - 代码极简(只有一行操作)
+ * - 自动处理(Timer 自动 flush,线程自动阻塞)
+ * - 资源保留(所有资源保持,包括 Timer)
+ * 
+ * 注意:
+ * - 与 ppp_interrupt_disable() 不同,本函数保留所有资源
+ * - 必须与 ppp_interrupt_resume() 配对使用
+ * - Timer 持续运行保证数据按顺序 flush
+ */
+ppp_error_t ppp_interrupt_pause(void);
+
+/**
+ * @brief 恢复PPP中断处理(从AT模式返回)
+ * @return PPP_ERR_OK 成功,其他值失败
+ * 
+ * 极简实现(只需重新注册 UART 中断):
+ * 1. 注册UART中断回调 → 开始接收新数据
+ * 2. 线程自动唤醒 → 从阻塞队列读取中返回
+ * 3. Timer 一直在运行 → 无需重启
+ * 
+ * 优势:
+ * - 代码极简(只有一行操作)
+ * - 自动唤醒(线程自动响应新数据)
+ * - 无需清理(Timer 已经处理过了)
+ * 
+ * 注意:
+ * - 与 ppp_interrupt_pause() 配对使用
+ * - 不重新创建任何资源,只恢复运行状态
+ * - Buffer 已经被 Timer 自动 flush 干净
+ */
+ppp_error_t ppp_interrupt_resume(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPP_INTERRUPT_H */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/n706a_net/include/ppp_power_ctl.h b/code/sdk/zhihui/n706a_net/include/ppp_power_ctl.h
new file mode 100644 (file)
index 0000000..687e470
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * @brief PPP模块电源控制接口
+ * @description 提供PPP模块专用的4G电源控制功能,与SLIP模块互斥使用
+ * Copyright (c) CompanyNameMagicTag 2024-2024. All rights reserved.
+ */
+
+#ifndef __PPP_POWER_CTL_H
+#define __PPP_POWER_CTL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "platform_core.h"
+#include "errcode.h"
+
+/**
+ * @brief PPP模块4G电源控制引脚配置结构体
+ */
+typedef struct {
+    pin_t bat_pin;              // 控制Cat1 battery 的gpio,没有控制,设置为 PIN_NONE 即可
+    uint8_t bat_pin_en_value;   // battery引脚使能值
+    pin_t pwr_pin;              // 控制cat1开机键的gpio
+    uint8_t pwr_pin_en_value;   // 电源引脚使能值
+    pin_t reset_pin;            // 控制cat1重置键的gpio
+    uint8_t reset_pin_en_value; // 复位引脚使能值
+    pin_t ring_pin;             // cat1唤醒蓝牙用的gpio
+    uint8_t ring_pin_en_value;  // 唤醒引脚使能值
+    pin_t wakemodem_pin;        // 蓝牙唤醒cat1用的gpio
+    uint8_t wakemodem_pin_en_value; // 唤醒modem引脚使能值
+} ppp_ctl_pin_4g_t;
+
+/**
+ * @brief PPP模块GPIO初始化
+ */
+void ppp_api_gpio_init(void);
+
+/**
+ * @brief PPP模块UART初始化
+ */
+void ppp_api_uart_init(void);
+
+/**
+ * @brief PPP模块设置电源引脚状态
+ * @param pwron 1-开启电源,0-关闭电源
+ * @return 0-成功,其他-失败
+ */
+uint32_t ppp_api_cat1_power_pin(uint32_t pwron);
+
+/**
+ * @brief PPP模块设置复位引脚状态
+ * @param pwron 1-复位,0-释放复位
+ * @return 0-成功,其他-失败
+ */
+uint32_t ppp_api_cat1_reset_pin(uint32_t pwron);
+
+/**
+ * @brief PPP模块设置电池引脚状态
+ * @param pwron 1-开启电池,0-关闭电池
+ * @return 0-成功,其他-失败
+ */
+uint32_t ppp_api_cat1_bat_pin(uint32_t pwron);
+
+/**
+ * @brief PPP模块4G上电序列
+ */
+void ppp_power_on_cat1(void);
+
+/**
+ * @brief PPP模块4G下电序列
+ */
+void ppp_power_off_cat1(void);
+
+/**
+ * @brief PPP模块4G重置序列
+ */
+void ppp_power_reset_cat1(void);
+
+/**
+ * @brief PPP模块检查4G是否使能
+ * @return true-已使能,false-未使能
+ */
+bool ppp_api_is_cat1_enabled(void);
+
+/**
+ * @brief PPP模块唤醒Cat1
+ * @param wakeup 1-唤醒,0-不唤醒
+ */
+void ppp_api_wakeup_cat1(uint8_t wakeup);
+
+/**
+ * @brief PPP模块保持唤醒Cat1
+ * @param keep_wakeup 1-保持唤醒,0-允许休眠
+ */
+void ppp_api_keep_wakeup(uint8_t keep_wakeup);
+
+
+/**
+ * @brief PPP模块注册4G控制引脚配置
+ * @param ctl_pin 引脚配置结构体指针
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_register_ctl_pin(ppp_ctl_pin_4g_t *ctl_pin);
+
+/**
+ * @brief PPP模块Cat1唤醒中断回调函数
+ * @param pin 中断引脚
+ * @param param 参数
+ */
+void ppp_ring_isr_callback(pin_t pin, uintptr_t param);
+
+/**
+ * @brief PPP模块专用的4G使能控制接口
+ * @param isopen true-开启4G,false-关闭4G
+ * @note 此接口与SLIP模块互斥,只能有一个模块控制4G电源
+ */
+void ppp_api_enable_cat1(bool isopen);
+
+/**
+ * @brief PPP模块反初始化
+ */
+void ppp_api_deinit(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __PPP_POWER_CTL_H */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/n706a_net/include/ppp_serial.h b/code/sdk/zhihui/n706a_net/include/ppp_serial.h
new file mode 100644 (file)
index 0000000..316e506
--- /dev/null
@@ -0,0 +1,176 @@
+/**
+ * @brief PPP串口模块头文件 - 统一缓冲区管理 + PPP模式智能发送缓冲
+ */
+
+#ifndef PPP_SERIAL_H
+#define PPP_SERIAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ppp_types.h"
+
+/* 串口接收回调函数类型 */
+typedef void (*ppp_serial_rx_callback_t)(const uint8_t *data, uint16_t length, void *arg);
+
+/* 串口工作模式 */
+typedef enum {
+    PPP_SERIAL_MODE_NONE = 0,    // 未初始化
+    PPP_SERIAL_MODE_AT,          // AT命令模式(直接使用UART)
+    PPP_SERIAL_MODE_PPP_DATA     // PPP数据模式(使用UART + 软件缓冲区 + 智能发送缓冲)
+} ppp_serial_mode_t;
+
+/**
+ * @brief 串口配置结构
+ */
+typedef struct {
+    uint8_t uart_bus;                                   // UART总线号
+    uint8_t irq_num;                                    // UART IRQ引脚
+    uint32_t baudrate;                                  // 波特率
+    uint8_t tx_pin;                                     // 发送引脚
+    uint8_t rx_pin;                                     // 接收引脚
+    uint32_t rx_buffer_size;                            // 接收缓冲区大小
+    uint32_t tx_buffer_size;                            // 发送缓冲区大小(PPP模式使用)
+    ppp_serial_rx_callback_t rx_callback;              // 接收回调函数
+    void *rx_callback_arg;                              // 回调函数参数
+} ppp_serial_config_t;
+
+/**
+ * @brief 串口统计信息
+ */
+typedef struct {
+    uint32_t tx_bytes;                                  // 发送字节数
+    uint32_t rx_bytes;                                  // 接收字节数
+    uint32_t tx_errors;                                 // 发送错误数
+    uint32_t rx_errors;                                 // 接收错误数
+    uint32_t rx_buffer_usage;                           // 接收缓冲区使用量
+    uint32_t rx_buffer_size;                            // 接收缓冲区大小
+    uint32_t tx_buffer_usage;                           // 发送缓冲区使用量
+    uint32_t tx_buffer_size;                            // 发送缓冲区大小
+} ppp_serial_stats_t;
+
+/**
+ * @brief 初始化PPP串口(统一缓冲区管理)
+ * @param config 串口配置
+ * @return 错误码
+ */
+ppp_error_t ppp_serial_init(const ppp_serial_config_t *config);
+
+/**
+ * @brief 去初始化PPP串口
+ */
+void ppp_serial_deinit(void);
+
+/**
+ * @brief 切换到PPP数据模式(启用软件缓冲区管理)
+ * @return 错误码
+ */
+ppp_error_t ppp_serial_switch_to_ppp_mode(void);
+
+/* ppp_serial_switch_to_at_mode() 已删除 - N706A_NET始终处于AT模式 */
+/* 如需清空缓冲区,请使用 ppp_serial_flush_rx() */
+
+/**
+ * @brief 获取当前串口模式
+ * @return 当前模式
+ */
+ppp_serial_mode_t ppp_serial_get_mode(void);
+
+/**
+ * @brief 发送数据(AT模式直接发送,PPP模式使用智能缓冲发送)
+ * @param data 数据指针
+ * @param length 数据长度
+ * @return 错误码
+ */
+ppp_error_t ppp_serial_write(const uint8_t *data, uint32_t length);
+
+/**
+ * @brief 读取数据(AT模式直接从UART读取,PPP模式从软件缓冲区读取)
+ * @param buffer 接收缓冲区
+ * @param buffer_size 缓冲区大小
+ * @param bytes_read 实际读取字节数
+ * @return 错误码
+ */
+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 超时时间(毫秒)
+ * @return 错误码
+ */
+ppp_error_t ppp_serial_wait_data(uint32_t timeout_ms);
+
+/**
+ * @brief 获取可读数据长度
+ * @return 可读数据长度
+ */
+uint32_t ppp_serial_available(void);
+
+/**
+ * @brief 清空接收缓冲区
+ */
+void ppp_serial_flush_rx(void);
+
+/* TX buffer removed - 发送改为直接UART写入,无需buffer和flush */
+
+/**
+ * @brief 设置接收回调函数
+ * @param callback 回调函数
+ * @param arg 回调函数参数
+ * @return 错误码
+ */
+ppp_error_t ppp_serial_set_rx_callback(ppp_serial_rx_callback_t callback, void *arg);
+
+/**
+ * @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 丢弃的数据块数量
+ */
+void ppp_get_interrupt_rx_stats(uint32_t *queue_count, uint32_t *bytes_queued, uint32_t *chunks_dropped);
+
+/**
+ * @brief 重置串口状态
+ */
+ppp_error_t ppp_serial_reset(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPP_SERIAL_H */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/n706a_net/include/ppp_types.h b/code/sdk/zhihui/n706a_net/include/ppp_types.h
new file mode 100644 (file)
index 0000000..7d865e8
--- /dev/null
@@ -0,0 +1,165 @@
+#ifndef PPP_TYPES_H
+#define PPP_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ppp_config.h"
+
+/* 前向声明,避免直接包含lwIP头文件 */
+struct netif;
+struct ip4_addr;
+
+/* PPP配置结构(简化版,用于新API) */
+typedef struct {
+    char apn[64];                                       // APN接入点名称
+    char username[32];                                  // 用户名
+    char password[32];                                  // 密码
+    uint32_t baudrate;                                  // 串口波特率
+    bool auto_baudrate;                                 // 是否自动波特率检测
+    uint32_t dial_timeout;                              // 拨号超时时间(ms)
+    uint8_t retry_count;                                // 重试次数
+} ppp_config_t;
+
+/* PPP连接信息结构(简化版,用于新API) */
+typedef struct {
+    uint32_t local_ip;                                  // 本地IP地址
+    uint32_t remote_ip;                                 // 远程IP地址
+    uint32_t primary_dns;                               // 主DNS服务器
+    uint32_t secondary_dns;                             // 辅DNS服务器
+    uint16_t mtu;                                       // MTU大小
+    bool connected;                                     // 连接状态
+    uint32_t connect_time;                              // 连接时间(秒)
+} ppp_connection_info_t;
+
+/* PPP拨号参数结构(原有的,保持兼容性) */
+typedef struct {
+    char apn[64];                                       // APN接入点名称
+    char username[32];                                  // 用户名
+    char password[32];                                  // 密码
+    uint32_t baudrate;                                  // 串口波特率
+    bool auto_baudrate;                                 // 是否自动波特率检测
+    uint32_t dial_timeout;                              // 拨号超时时间(ms)
+    uint8_t retry_count;                                // 重试次数
+} ppp_dial_config_t;
+
+/* PPP网络信息结构 */
+typedef struct {
+    uint32_t local_ip;                                  // 本地IP地址
+    uint32_t remote_ip;                                 // 远程IP地址
+    uint32_t primary_dns;                               // 主DNS服务器
+    uint32_t secondary_dns;                             // 辅DNS服务器
+    uint32_t netmask;                                   // 子网掩码
+    uint32_t gateway;                                   // 网关地址
+    uint16_t mtu;                                       // MTU大小
+    bool connected;                                     // 连接状态
+} ppp_network_info_t;
+
+/* PPP统计信息结构 */
+typedef struct {
+    uint32_t tx_packets;                                // 发送包数
+    uint32_t rx_packets;                                // 接收包数
+    uint32_t tx_bytes;                                  // 发送字节数
+    uint32_t rx_bytes;                                  // 接收字节数
+    uint32_t tx_errors;                                 // 发送错误数
+    uint32_t rx_errors;                                 // 接收错误数
+    uint32_t connect_time;                              // 连接时间(秒)
+    uint32_t last_activity;                             // 最后活动时间戳
+} ppp_stats_t;
+
+/* PPP字节丢弃统计结构 */
+typedef struct {
+    uint32_t total_bytes_received;                      // 总接收字节数
+    uint32_t total_bytes_processed;                     // 总处理字节数
+    uint32_t total_bytes_discarded;                     // 总丢弃字节数
+    uint32_t invalid_frame_bytes;                       // 无效帧丢弃字节数
+    uint32_t queue_full_bytes;                          // 队列满丢弃字节数
+    uint32_t malloc_fail_bytes;                         // 内存分配失败丢弃字节数
+    uint32_t oversized_frame_bytes;                     // 超大帧丢弃字节数
+    uint32_t incomplete_frame_bytes;                    // 不完整帧丢弃字节数
+    uint32_t total_frames_received;                     // 总接收帧数
+    uint32_t total_frames_processed;                    // 总处理帧数
+    uint32_t total_frames_discarded;                    // 总丢弃帧数
+} ppp_discard_stats_t;
+
+/* PPP事件类型 */
+typedef enum {
+    PPP_EVENT_CONNECTED = 0,                            // 连接成功
+    PPP_EVENT_DISCONNECTED,                             // 连接断开
+    PPP_EVENT_ERROR,                                    // 发生错误
+    PPP_EVENT_IP_ACQUIRED,                              // 获取到IP地址
+    PPP_EVENT_DNS_ACQUIRED,                             // 获取到DNS地址
+    PPP_EVENT_AT_RESPONSE,                              // AT命令响应
+    PPP_EVENT_DATA_RECEIVED                             // 接收到数据
+} ppp_event_type_t;
+
+/* PPP事件数据结构 */
+typedef struct {
+    ppp_event_type_t type;                              // 事件类型
+    ppp_error_t error_code;                             // 错误码
+    void *data;                                         // 事件数据
+    uint32_t data_len;                                  // 数据长度
+} ppp_event_t;
+
+/* PPP事件回调函数类型 */
+typedef void (*ppp_event_callback_t)(const ppp_event_t *event);
+
+/* PPP状态枚举 - 定义在ppp_config.h中 */
+
+/* PPP控制块结构 */
+typedef struct {
+    ppp_state_t state;                                  // 当前状态
+    ppp_dial_config_t config;                           // 拨号配置
+    ppp_network_info_t network;                         // 网络信息
+    ppp_stats_t stats;                                  // 统计信息
+    
+    /* lwIP相关 */
+    struct netif *netif;                                // 网络接口指针
+    void *ppp_pcb;                                      // PPP控制块
+    
+    /* 串口相关 */
+    uint8_t uart_bus;                                   // 串口总线
+    uint8_t *rx_buffer;                                 // 接收缓冲区
+    uint8_t *tx_buffer;                                 // 发送缓冲区
+    uint32_t rx_buffer_size;                            // 接收缓冲区大小
+    uint32_t tx_buffer_size;                            // 发送缓冲区大小
+    
+    /* 同步相关 */
+    void *mutex;                                        // 互斥锁
+    void *semaphore;                                    // 信号量
+    void *task_handle;                                  // 任务句柄
+    
+    /* 回调函数 */
+    ppp_event_callback_t event_callback;               // 事件回调函数
+    
+    /* 内部状态 */
+    uint32_t last_at_time;                              // 最后AT命令时间
+    uint32_t connect_start_time;                        // 连接开始时间
+    bool initialized;                                   // 初始化标志
+    bool running;                                       // 运行标志
+} ppp_context_t;
+
+/* AT命令结构 */
+typedef struct {
+    char command[PPP_AT_CMD_MAX_LEN];                   // AT命令
+    char expected_response[64];                         // 期望响应
+    uint32_t timeout;                                   // 超时时间(ms)
+    uint8_t retry_count;                                // 重试次数
+} ppp_at_cmd_t;
+
+/* AT响应结构 */
+typedef struct {
+    char response[PPP_AT_RESPONSE_MAX_LEN];             // 响应内容
+    uint32_t length;                                    // 响应长度
+    bool success;                                       // 是否成功
+    ppp_error_t error_code;                             // 错误码
+} ppp_at_response_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPP_TYPES_H */ 
\ No newline at end of file
diff --git a/code/sdk/zhihui/n706a_net/src/n706a_at_handler.c b/code/sdk/zhihui/n706a_net/src/n706a_at_handler.c
new file mode 100644 (file)
index 0000000..089b754
--- /dev/null
@@ -0,0 +1,1278 @@
+#include "n706a_at_handler.h"
+#include "ppp_config.h"
+#include "ppp_types.h"
+#include "ppp_debug.h"
+#include "ppp_serial.h"
+#include "uart.h"
+#include "schedule/osal_task.h"
+#include "lock/osal_mutex.h"
+#include "semaphore/osal_semaphore.h"
+#include "soc_osal.h"
+#include "securec.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h> // For malloc and free
+
+/* ========== AT响应异步缓冲区(由ppp_interrupt.c写入) ========== */
+#define N706A_AT_RESPONSE_RING_BUFFER_SIZE  4096  // 4KB环形缓冲区
+
+static uint8_t g_at_response_ring_buffer[N706A_AT_RESPONSE_RING_BUFFER_SIZE];
+static volatile uint32_t g_at_response_head = 0;
+static volatile uint32_t g_at_response_tail = 0;
+static osal_mutex g_at_response_mutex;
+static osal_semaphore g_at_response_sem;
+
+/* AT命令处理上下文 */
+static struct {
+    bool initialized;
+    uint8_t uart_bus;
+    uint32_t current_baudrate;
+    uint32_t target_baudrate;   
+    bool auto_baudrate_mode;
+    ppp_at_response_t last_response;
+    osal_mutex at_mutex;  // 改为结构体,不是指针
+} g_at_ctx = {0};
+
+/* 支持的波特率列表 */
+static const uint32_t g_auto_baudrates[] = PPP_BAUDRATE_AUTO_LIST;
+static const uint32_t g_fixed_baudrates[] = PPP_BAUDRATE_FIXED_LIST;
+
+/* 全局AT响应缓存 - 1024字节动态分配 */
+static uint8_t *g_at_response_buffer = NULL;
+static uint32_t g_at_buffer_size = 1024;
+
+/* TCP URC回调 */
+static n706a_tcp_urc_callback_t g_tcp_urc_callback = NULL;
+
+/* AT命令响应解析 */
+static bool ppp_at_parse_response(const char *response, const char *expected);
+static ppp_error_t ppp_at_wait_response(ppp_at_response_t *response, uint32_t timeout);
+static ppp_error_t ppp_at_set_baudrate(uint32_t baudrate);
+static ppp_error_t ppp_at_send_command(const char *command, const char *expected_response, 
+                                       uint32_t timeout, ppp_at_response_t *response);
+
+/* URC解析函数 */
+static bool n706a_parse_tcprecv_urc(const char *urc_data, size_t urc_len, 
+                                    int *socket_id, size_t *data_len, const uint8_t **data);
+
+/**
+ * @brief 写入AT响应数据到环形缓冲区(由ppp_interrupt.c调用)
+ * @param data 数据指针
+ * @param length 数据长度
+ */
+void n706a_at_response_buffer_write(const uint8_t *data, uint32_t length)
+{
+    if (!data || length == 0) {
+        return;
+    }
+    
+    // 检测是否是 +TCPRECV URC(TCP数据接收通知)
+    // 格式:+TCPRECV: <socket_id>,<length>,<data>\r\n
+    if (length >= 10 && memcmp(data, "+TCPRECV: ", 10) == 0 && g_tcp_urc_callback) {
+        int socket_id;
+        size_t data_len;
+        const uint8_t *tcp_data;
+        
+        if (n706a_parse_tcprecv_urc((const char *)data, length, &socket_id, &data_len, &tcp_data)) {
+            PPP_DEBUG_INFO("TCP URC detected: socket=%d, len=%u", socket_id, (unsigned int)data_len);
+            
+            // 立即回调应用层(在中断上下文或处理线程中)
+            g_tcp_urc_callback(socket_id, tcp_data, data_len);
+            
+            // URC已处理,不需要写入AT响应缓冲区
+            return;
+        } else {
+            PPP_DEBUG_WARN("Failed to parse +TCPRECV URC");
+        }
+    }
+    
+    // 普通AT响应或无法识别的数据,写入环形缓冲区
+    osal_mutex_lock(&g_at_response_mutex);
+    
+    for (uint32_t i = 0; i < length; i++) {
+        g_at_response_ring_buffer[g_at_response_head] = data[i];
+        g_at_response_head = (g_at_response_head + 1) % N706A_AT_RESPONSE_RING_BUFFER_SIZE;
+        
+        // 检查溢出(缓冲区满时丢弃最老的数据)
+        if (g_at_response_head == g_at_response_tail) {
+            g_at_response_tail = (g_at_response_tail + 1) % N706A_AT_RESPONSE_RING_BUFFER_SIZE;
+            PPP_DEBUG_WARN("AT response buffer overflow, dropping oldest byte");
+        }
+    }
+    
+    osal_mutex_unlock(&g_at_response_mutex);
+    
+    // 通知有新数据到达
+    osal_sem_up(&g_at_response_sem);
+    
+    PPP_DEBUG_DEBUG("AT response buffer: wrote %u bytes", length);
+}
+
+/**
+ * @brief 初始化AT命令处理模块
+ */
+ppp_error_t ppp_at_handler_init(uint8_t uart_bus, uint32_t current_baudrate, bool auto_baudrate_mode)
+{
+    if (g_at_ctx.initialized) {
+        PPP_DEBUG_WARN("AT handler already initialized");
+        return PPP_ERR_OK;
+    }
+
+    g_at_ctx.uart_bus = uart_bus;
+    g_at_ctx.current_baudrate = current_baudrate;
+    g_at_ctx.auto_baudrate_mode = auto_baudrate_mode;
+
+    /* 创建AT命令互斥锁 */
+    if (osal_mutex_init(&g_at_ctx.at_mutex) != OSAL_SUCCESS) {
+        PPP_DEBUG_ERROR("Failed to create AT mutex");
+        return PPP_ERR_MEMORY;
+    }
+
+    /* 创建AT响应缓冲区互斥锁 */
+    if (osal_mutex_init(&g_at_response_mutex) != OSAL_SUCCESS) {
+        PPP_DEBUG_ERROR("Failed to create AT response mutex");
+        osal_mutex_destroy(&g_at_ctx.at_mutex);
+        return PPP_ERR_MEMORY;
+    }
+
+    /* 创建AT响应信号量 */
+    if (osal_sem_init(&g_at_response_sem, 0) != OSAL_SUCCESS) {
+        PPP_DEBUG_ERROR("Failed to create AT response semaphore");
+        osal_mutex_destroy(&g_at_ctx.at_mutex);
+        osal_mutex_destroy(&g_at_response_mutex);
+        return PPP_ERR_MEMORY;
+    }
+
+    /* 初始化环形缓冲区 */
+    g_at_response_head = 0;
+    g_at_response_tail = 0;
+    memset(g_at_response_ring_buffer, 0, sizeof(g_at_response_ring_buffer));
+
+    /* 分配全局AT响应缓存 */
+    g_at_response_buffer = (uint8_t *)malloc(g_at_buffer_size);
+    if (g_at_response_buffer == NULL) {
+        PPP_DEBUG_ERROR("Failed to allocate AT response buffer");
+        osal_mutex_destroy(&g_at_ctx.at_mutex);
+        osal_mutex_destroy(&g_at_response_mutex);
+        osal_sem_destroy(&g_at_response_sem);
+        return PPP_ERR_MEMORY;
+    }
+
+    g_at_ctx.initialized = true;
+    PPP_DEBUG_INFO("n706a_net AT handler initialized on UART%d with async ring buffer", uart_bus);
+    
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 反初始化AT命令处理模块
+ */
+void ppp_at_handler_deinit(void)
+{
+    if (!g_at_ctx.initialized) {
+        return;
+    }
+
+    /* 销毁互斥锁和信号量 */
+    osal_mutex_destroy(&g_at_ctx.at_mutex);
+    osal_mutex_destroy(&g_at_response_mutex);
+    osal_sem_destroy(&g_at_response_sem);
+
+    /* 释放全局AT响应缓存 */
+    if (g_at_response_buffer) {
+        free(g_at_response_buffer);
+        g_at_response_buffer = NULL;
+    }
+
+    /* 清空环形缓冲区 */
+    g_at_response_head = 0;
+    g_at_response_tail = 0;
+
+    memset_s(&g_at_ctx, sizeof(g_at_ctx), 0, sizeof(g_at_ctx));
+    PPP_DEBUG_INFO("n706a_net AT handler deinitialized");
+}
+
+/**
+ * @brief 执行波特率自适应握手
+ *
+ * 进入自适应波特率,证明1000000没有正常工作,需要先reset,等5秒,开始设置自动握手的第一个波特率,
+ * 读取所有缓存数据丢掉,下达at指令,等待结果,重试3次,如果不成功,就设置第二个波特率,读取所有缓存数据丢掉,
+ * 下达at指令,等结果,重试3次,直至第三个波特率检测。如果都没有成功,则返回失败。
+ * 如果任何一次at指令返回正确ok,直接在当前设置下,下达指 AT+IPR 配置 1000000 波特率,并返回成功。
+ * 设置当前波特率为1000000,再次reset 模组,让其自动工作在 1000000波特率下。
+ */
+ppp_error_t ppp_at_baudrate_handshake(void)
+{
+    if (!g_at_ctx.initialized) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+
+    PPP_DEBUG_INFO("Starting baudrate handshake (prove %d not working, then try auto handshake)",g_at_ctx.current_baudrate);
+
+    // uint8_t dummy_buffer[256]={0};
+
+    // 2. 依次尝试自动波特率列表
+    for (int i = 0; i < PPP_BAUDRATE_AUTO_COUNT; i++) {
+        uint32_t baudrate = g_auto_baudrates[i];
+        PPP_DEBUG_DEBUG("=== Trying Baudrate %u (index %d/%d) ===", baudrate, i + 1, PPP_BAUDRATE_AUTO_COUNT);
+
+        // 配置串口波特率
+        uart_attr_t uart_attr = {
+            .baud_rate = baudrate,
+            .data_bits = UART_DATA_BIT_8,
+            .parity = UART_PARITY_NONE,
+            .stop_bits = UART_STOP_BIT_1,
+        };
+        if (uapi_uart_set_attr(g_at_ctx.uart_bus, &uart_attr) != ERRCODE_SUCC) {
+            PPP_DEBUG_WARN("Failed to set baudrate %u", baudrate);
+            continue;
+        }
+        PPP_DEBUG_DEBUG("UART configured for baudrate %u", baudrate);
+
+        // 清空接收缓冲区
+        // PPP_DEBUG_DEBUG("Clearing UART RX buffer before AT test...");
+        // int clear_cnt = 0;
+        // memset(dummy_buffer,0,sizeof(dummy_buffer));
+        // while (uapi_uart_read(g_at_ctx.uart_bus, dummy_buffer, sizeof(dummy_buffer), 100) > 0) {
+        //     clear_cnt++;
+        // }
+        // if (clear_cnt > 0) {
+        //     PPP_DEBUG_DEBUG("Cleared %d RX buffer rounds", clear_cnt);
+        // }
+
+        // 3次重试AT
+        ppp_error_t ret = PPP_ERR_AT_FAILED;
+        for (int retry = 0; retry < 2; retry++) {
+            PPP_DEBUG_DEBUG("--- AT Test at %u baud, retry %d/3 ---", baudrate, retry + 1);
+
+            // 再次清空缓冲区,防止上次残留
+        // memset(dummy_buffer,0,sizeof(dummy_buffer));
+        // while (uapi_uart_read(g_at_ctx.uart_bus, dummy_buffer, sizeof(dummy_buffer), 100) > 0) {}
+
+            ppp_at_response_t response;
+            ret = ppp_at_send_command("AT", "OK", 1000, &response);
+
+            if (ret == PPP_ERR_OK) {
+                PPP_DEBUG_INFO("AT command successful at baudrate %u", baudrate);
+
+                // 在当前波特率下,设置AT+IPR=1000000
+               ret = ppp_at_set_baudrate(g_at_ctx.current_baudrate);
+               if (ret != PPP_ERR_OK) {
+                    ret = ppp_at_set_baudrate(g_at_ctx.current_baudrate);
+                    if (ret != PPP_ERR_OK) {
+                        PPP_DEBUG_ERROR("Failed to set baudrate %u", g_at_ctx.current_baudrate);
+                        return ret;
+                    }
+                }
+                // 再次reset模组,让其自动工作在1000000波特率下
+                PPP_DEBUG_DEBUG("Resetting module again to switch to baudrate %d...",g_at_ctx.current_baudrate);
+                // ppp_power_reset_cat1();               
+                // osal_msleep(5000);
+                ret = ppp_at_send_command("AT", "OK", 1000, &response);
+                if(ret != PPP_ERR_OK) {
+                    PPP_DEBUG_INFO("Baudrate handshake failed, now at %d baud",g_at_ctx.current_baudrate);
+                }else{
+                    PPP_DEBUG_INFO("Baudrate handshake successful, now at %d baud",g_at_ctx.current_baudrate);
+                }
+                return PPP_ERR_OK;
+            } else {
+                PPP_DEBUG_WARN("AT command failed at baudrate %u, retry %d/3 (error: %d)", baudrate, retry + 1, ret);
+                osal_msleep(500);
+            }
+        }
+
+        PPP_DEBUG_WARN("Baudrate %u failed after 3 retries, trying next...", baudrate);
+        osal_msleep(100);
+    }
+
+    PPP_DEBUG_ERROR("Baudrate handshake failed: all baudrates tried, no success");
+    return PPP_ERR_AT_FAILED;
+}
+
+/**
+ * @brief 解析AT+IPR?响应,提取当前波特率
+ * @param response AT+IPR?的响应字符串
+ * @return 解析出的波特率,失败返回0
+ */
+static uint32_t ppp_parse_ipr_response(const char *response)
+{
+    if (!response) {
+        return 0;
+    }
+    
+    PPP_DEBUG_DEBUG("Parsing IPR response: [%s]", response);
+    
+    /* 查找 "+IPR: " 字符串 */
+    const char *ipr_pos = strstr(response, "+IPR: ");
+    if (!ipr_pos) {
+        PPP_DEBUG_WARN("IPR response format error: no '+IPR: ' found in response");
+        return 0;
+    }
+    
+    /* 跳过 "+IPR: " 部分 */
+    ipr_pos += 6;
+    
+    /* 跳过可能的空格 */
+    while (*ipr_pos == ' ' || *ipr_pos == '\t') {
+        ipr_pos++;
+    }
+    
+    /* 解析波特率数字,只读取数字部分 */
+    uint32_t baudrate = 0;
+    const char *num_start = ipr_pos;
+    
+    /* 找到数字的结束位置(遇到非数字字符停止) */
+    while (*ipr_pos >= '0' && *ipr_pos <= '9') {
+        baudrate = baudrate * 10 + (*ipr_pos - '0');
+        ipr_pos++;
+    }
+    
+    /* 检查是否成功解析到数字 */
+    if (ipr_pos == num_start) {
+        PPP_DEBUG_WARN("IPR response format error: no valid number found after '+IPR: '");
+        return 0;
+    }
+    
+    /* 验证波特率是否合理 */
+    if (baudrate < 1200 || baudrate > 4000000) {
+        PPP_DEBUG_WARN("IPR response contains unreasonable baudrate: %u", baudrate);
+        return 0;
+    }
+    
+    PPP_DEBUG_DEBUG("Successfully parsed current baudrate from IPR response: %u", baudrate);
+    return baudrate;
+}
+
+/**
+ * @brief 查询当前modem波特率
+ * @return 当前modem波特率,失败返回0
+ */
+static uint32_t ppp_query_current_modem_baudrate(void)
+{
+    ppp_at_response_t response;
+    ppp_error_t ret = ppp_at_send_command("AT+IPR?", "OK", PPP_AT_CMD_TIMEOUT, &response);
+    
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_WARN("Failed to query current baudrate with AT+IPR?, error: %d", ret);
+        return 0;
+    }
+    
+    return ppp_parse_ipr_response(response.response);
+}
+
+/**
+ * @brief 设置固定波特率(内部函数)
+ */
+static ppp_error_t ppp_at_set_baudrate(uint32_t baudrate)
+{
+    if (!g_at_ctx.initialized) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+
+    /* 检查波特率是否支持 */
+    bool supported = false;
+    for (int i = 0; i < PPP_BAUDRATE_FIXED_COUNT; i++) {
+        if (g_fixed_baudrates[i] == baudrate) {
+            supported = true;
+            break;
+        }
+    }
+
+    if (!supported) {
+        PPP_DEBUG_ERROR("Unsupported baudrate: %u", baudrate);
+        return PPP_ERR_INVALID_PARAM;
+    }
+#if defined(PPP_DO_SERIAL_TEST) && (PPP_DO_SERIAL_TEST == 1)
+    uint32_t current_modem_baudrate = baudrate; // 测试模式下,直接使用输入的波特率
+#else
+    /* 先查询当前modem波特率 */
+    uint32_t current_modem_baudrate = ppp_query_current_modem_baudrate();
+    if (current_modem_baudrate == baudrate) {
+        PPP_DEBUG_INFO("Modem already at target baudrate %u, skipping AT+IPR command", baudrate);
+        
+        /* 仍需要更新本地UART配置以确保一致性 */
+        uart_attr_t uart_attr = {
+            .baud_rate = baudrate,
+            .data_bits = UART_DATA_BIT_8,
+            .parity = UART_PARITY_NONE,
+            .stop_bits = UART_STOP_BIT_1,
+        };
+        
+        if (uapi_uart_set_attr(g_at_ctx.uart_bus, &uart_attr) != ERRCODE_SUCC) {
+            PPP_DEBUG_ERROR("Failed to update UART baudrate");
+            return PPP_ERR_UART;
+        }
+
+        g_at_ctx.current_baudrate = baudrate;
+        g_at_ctx.auto_baudrate_mode = false;
+        
+        PPP_DEBUG_DEBUG("Baudrate confirmed at %u (no change needed)", baudrate);
+        return PPP_ERR_OK;
+    }
+
+    /* 需要设置新波特率 */
+    PPP_DEBUG_INFO("Changing modem baudrate from %u to %u", current_modem_baudrate, baudrate);
+    
+    /* 发送AT+IPR命令设置波特率 */
+    char cmd[64];
+    snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "AT+IPR=%u", baudrate);
+    
+    ppp_at_response_t response;
+    ppp_error_t ret = ppp_at_send_command(cmd, "OK", PPP_AT_CMD_TIMEOUT, &response);
+    
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("Failed to set baudrate to %u", baudrate);
+        return ret;
+    }
+#endif
+    /* 更新串口配置 */
+    uart_attr_t uart_attr = {
+        .baud_rate = baudrate,
+        .data_bits = UART_DATA_BIT_8,
+        .parity = UART_PARITY_NONE,
+        .stop_bits = UART_STOP_BIT_1,
+    };
+    
+    if (uapi_uart_set_attr(g_at_ctx.uart_bus, &uart_attr) != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to update UART baudrate");
+        return PPP_ERR_UART;
+    }
+
+    g_at_ctx.current_baudrate = baudrate;
+    g_at_ctx.auto_baudrate_mode = false;
+    
+    PPP_DEBUG_DEBUG("Baudrate set bus(%d) to %u (changed from %u)", g_at_ctx.uart_bus, baudrate, current_modem_baudrate);
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 发送AT命令(内部函数)
+ * @note 检查内存泄露:所有malloc分配的内存都应在所有分支free
+ */
+static ppp_error_t ppp_at_send_command(const char *command, const char *expected_response, 
+                                uint32_t timeout, ppp_at_response_t *response)
+{
+    uint32_t start_timestamp = (uint32_t)osal_get_jiffies();
+
+    PPP_DEBUG_CRITICAL("=== AT COMMAND START ===");
+    PPP_DEBUG_CRITICAL("Timestamp: %u", start_timestamp);
+    PPP_DEBUG_CRITICAL("Command: [%s]", command ? command : "NULL");
+    PPP_DEBUG_CRITICAL("Expected: [%s]", expected_response ? expected_response : "NULL");
+    PPP_DEBUG_CRITICAL("Timeout: %u ms", timeout);
+
+    if (!g_at_ctx.initialized || !command || !response) {
+        PPP_DEBUG_ERROR("Invalid parameters: initialized=%d, command=%p, response=%p", 
+                       g_at_ctx.initialized, command, response);
+        return PPP_ERR_INVALID_PARAM;
+    }
+
+    /* 防止系统卡死的安全措施 */
+    const uint32_t MAX_COMMAND_TIMEOUT = 60000;  // 绝对最大超时时间60秒
+    if (timeout > MAX_COMMAND_TIMEOUT) {
+        PPP_DEBUG_WARN("Command timeout %u ms exceeds maximum %u ms, capping it", 
+                       timeout, MAX_COMMAND_TIMEOUT);
+        timeout = MAX_COMMAND_TIMEOUT;
+    }
+
+    PPP_DEBUG_CRITICAL("Step 1: Attempting to acquire AT mutex...");
+    uint32_t mutex_start = (uint32_t)osal_get_jiffies();
+
+    /* 使用带超时的互斥锁获取,防止永久阻塞 */
+    int mutex_result = osal_mutex_lock_timeout(&g_at_ctx.at_mutex, timeout + 5000);
+    if (mutex_result != OSAL_SUCCESS) {
+        PPP_DEBUG_ERROR("Failed to acquire AT mutex within timeout, this indicates a serious problem");
+        PPP_DEBUG_ERROR("Possible causes: 1) Previous AT command hung 2) Mutex corruption 3) Deadlock");
+        return PPP_ERR_TIMEOUT;
+    }
+
+    uint32_t mutex_end = (uint32_t)osal_get_jiffies();
+    PPP_DEBUG_CRITICAL("Step 1: AT mutex acquired in %u ms", osal_jiffies_to_msecs(mutex_end - mutex_start));
+
+    PPP_DEBUG_DEBUG("=== AT Command Send ===");
+    PPP_DEBUG_DEBUG("Command: %s", command);
+    PPP_DEBUG_DEBUG("Expected: %s", expected_response ? expected_response : "None");
+    PPP_DEBUG_DEBUG("Timeout: %u ms", timeout);
+
+    /* 清空响应缓冲区 */
+    memset_s(response, sizeof(ppp_at_response_t), 0, sizeof(ppp_at_response_t));
+
+    /* 发送命令 */
+    size_t command_len = strlen(command);
+    char *cmd_with_crlf = (char *)malloc(command_len + 4);
+    if (!cmd_with_crlf) {
+        PPP_DEBUG_ERROR("Failed to allocate memory for cmd_with_crlf");
+        osal_mutex_unlock(&g_at_ctx.at_mutex);
+        return PPP_ERR_MEMORY;
+    }
+    snprintf_s(cmd_with_crlf, command_len + 4, command_len + 3, "%s\r\n", command);
+
+    uint32_t cmd_len = strlen(cmd_with_crlf);
+
+    /* 打印发送的字符串(可见字符) */
+    char *printable_cmd = (char *)malloc(PPP_AT_CMD_MAX_LEN + 20);
+    if (printable_cmd == NULL) {
+        PPP_DEBUG_ERROR("Failed to allocate memory for printable command");
+        free(cmd_with_crlf); // 防止内存泄露
+        osal_mutex_unlock(&g_at_ctx.at_mutex);
+        return PPP_ERR_MEMORY;
+    }
+
+    uint32_t j = 0;
+    for (uint32_t i = 0; i < cmd_len && j < (PPP_AT_CMD_MAX_LEN + 20) - 10; i++) {
+        if (cmd_with_crlf[i] == '\r') {
+            printable_cmd[j++] = '\\';
+            printable_cmd[j++] = 'r';
+        } else if (cmd_with_crlf[i] == '\n') {
+            printable_cmd[j++] = '\\';
+            printable_cmd[j++] = 'n';
+        } else if (cmd_with_crlf[i] >= 32 && cmd_with_crlf[i] <= 126) {
+            printable_cmd[j++] = cmd_with_crlf[i];
+        } else {
+            j += snprintf_s(printable_cmd + j, (PPP_AT_CMD_MAX_LEN + 20) - j, (PPP_AT_CMD_MAX_LEN + 20) - j - 1, "\\x%02X", (uint8_t)cmd_with_crlf[i]);
+        }
+    }
+    printable_cmd[j] = '\0';
+    PPP_DEBUG_DEBUG("Send String: %s", printable_cmd);
+    free(printable_cmd);
+
+    PPP_DEBUG_CRITICAL("Step 2: Sending AT command via UART...");
+    uint32_t uart_write_start = (uint32_t)osal_get_jiffies();
+
+    int32_t write_result = uapi_uart_write(g_at_ctx.uart_bus, (const uint8_t *)cmd_with_crlf, cmd_len, 0);
+    uint32_t uart_write_end = (uint32_t)osal_get_jiffies();
+
+    free(cmd_with_crlf);
+
+    PPP_DEBUG_CRITICAL("Step 2: UART write completed in %u ms, result: %d (expected: %u)", 
+                      osal_jiffies_to_msecs(uart_write_end - uart_write_start), write_result, cmd_len);
+
+    if (write_result != cmd_len) {
+        PPP_DEBUG_ERROR("Failed to send AT command: wrote %d bytes, expected %u", write_result, cmd_len);
+        osal_mutex_unlock(&g_at_ctx.at_mutex);
+        return PPP_ERR_UART;
+    }
+
+    PPP_DEBUG_CRITICAL("Step 2: AT command sent successfully on bus %d", g_at_ctx.uart_bus);
+
+    /* 等待响应 */
+    PPP_DEBUG_CRITICAL("Step 3: Starting to wait for AT response...");
+    uint32_t response_wait_start = (uint32_t)osal_get_jiffies();
+    ppp_error_t ret = ppp_at_wait_response(response, timeout);
+    uint32_t response_wait_end = (uint32_t)osal_get_jiffies();
+    PPP_DEBUG_CRITICAL("Step 3: AT response wait completed in %u ms, result: %d", 
+                      osal_jiffies_to_msecs(response_wait_end - response_wait_start), ret);
+
+    /* 打印响应结果 */
+    PPP_DEBUG_DEBUG("=== AT Command Response ===");
+    if (ret == PPP_ERR_OK) {
+        PPP_DEBUG_DEBUG("Response received (%u bytes):", response->length);
+
+        /* 打印接收的字符串(可见字符) */
+        char *printable_resp = (char *)malloc(PPP_AT_RESPONSE_MAX_LEN + 100);
+        if (printable_resp != NULL) {
+            uint32_t j = 0;
+            for (uint32_t i = 0; i < response->length && j < (PPP_AT_RESPONSE_MAX_LEN + 100) - 10; i++) {
+                if (response->response[i] == '\r') {
+                    printable_resp[j++] = '\\';
+                    printable_resp[j++] = 'r';
+                } else if (response->response[i] == '\n') {
+                    printable_resp[j++] = '\\';
+                    printable_resp[j++] = 'n';
+                } else if (response->response[i] >= 32 && response->response[i] <= 126) {
+                    printable_resp[j++] = response->response[i];
+                } else {
+                    j += snprintf_s(printable_resp + j, (PPP_AT_RESPONSE_MAX_LEN + 100) - j, (PPP_AT_RESPONSE_MAX_LEN + 100) - j - 1, "\\x%02X", (uint8_t)response->response[i]);
+                }
+            }
+            printable_resp[j] = '\0';
+            PPP_DEBUG_DEBUG("Response String: %s", printable_resp);
+            free(printable_resp);
+        }
+        PPP_DEBUG_DEBUG("Raw Response: %s", response->response);
+    } else {
+        PPP_DEBUG_ERROR("No response received (error: %d)", ret);
+    }
+
+    if (ret == PPP_ERR_OK) {
+        if (expected_response) {
+            if (!ppp_at_parse_response(response->response, expected_response)) {
+                PPP_DEBUG_WARN("Response validation failed - Expected: %s", expected_response);
+                PPP_DEBUG_WARN("Response validation failed - Received: %s", response->response);
+                response->success = false;
+                response->error_code = PPP_ERR_AT_FAILED;
+                ret = PPP_ERR_AT_FAILED;
+            } else {
+                PPP_DEBUG_DEBUG("Response validation successful - Expected: %s", expected_response);
+                response->success = true;
+                response->error_code = PPP_ERR_OK;
+            }
+        } else {
+            // 没有期望响应时,只要收到响应就认为成功
+            response->success = true;
+            response->error_code = PPP_ERR_OK;
+        }
+    } else {
+        response->success = false;
+        response->error_code = ret;
+    }
+
+    PPP_DEBUG_DEBUG("=== AT Command Complete (Result: %s) ===", ret == PPP_ERR_OK ? "SUCCESS" : "FAILED");
+
+    PPP_DEBUG_CRITICAL("Step 4: Releasing AT mutex...");
+    uint32_t mutex_unlock_start = (uint32_t)osal_get_jiffies();
+    osal_mutex_unlock(&g_at_ctx.at_mutex);
+    uint32_t mutex_unlock_end = (uint32_t)osal_get_jiffies();
+
+    uint32_t total_time = osal_jiffies_to_msecs(mutex_unlock_end - start_timestamp);
+    PPP_DEBUG_CRITICAL("Step 4: AT mutex released in %u ms", osal_jiffies_to_msecs(mutex_unlock_end - mutex_unlock_start));
+    PPP_DEBUG_CRITICAL("=== AT COMMAND END (Total: %u ms, Result: %d) ===", total_time, ret);
+
+    return ret;
+}
+
+/**
+ * @brief 发送原始数据(不带AT命令格式)
+ * @note 用于 TCP/SSL 数据发送,在 AT+TCPSEND/AT+SSLTCPSEND 命令后使用
+ */
+ppp_error_t ppp_at_send_raw_data(const void *data, size_t len, uint32_t timeout)
+{
+    if (!g_at_ctx.initialized || !data || len == 0) {
+        PPP_DEBUG_ERROR("Invalid parameters: initialized=%d, data=%p, len=%zu", 
+                       g_at_ctx.initialized, data, len);
+        return PPP_ERR_INVALID_PARAM;
+    }
+
+    PPP_DEBUG_DEBUG("=== Sending Raw Data ===");
+    PPP_DEBUG_DEBUG("Length: %zu bytes", len);
+    PPP_DEBUG_DEBUG("Timeout: %u ms", timeout);
+
+    /* 直接通过 UART 发送原始数据,不添加 \r\n */
+    int32_t write_result = uapi_uart_write(g_at_ctx.uart_bus, (const uint8_t *)data, len, 0);
+
+    if (write_result != (int32_t)len) {
+        PPP_DEBUG_ERROR("Failed to send raw data: wrote %d bytes, expected %zu", write_result, len);
+        return PPP_ERR_UART;
+    }
+
+    PPP_DEBUG_DEBUG("Raw data sent successfully (%zu bytes) on bus %d", len, g_at_ctx.uart_bus);
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 跳过开机日志 (对应chat文件中的 '' \rAT)
+ */
+static ppp_error_t ppp_at_skip_startup_logs(void)
+{
+    PPP_DEBUG_DEBUG("Skipping startup logs...");
+    
+    // 清空接收缓冲区,跳过开机时的各种日志输出
+    uint8_t dummy_buffer[256];
+    uint32_t bytes_read;
+    
+    // 连续读取并丢弃开机日志,直到没有更多数据
+    int retry_count = 0;
+    const int max_retries = 10;
+    
+    do {
+        ppp_error_t ret = ppp_serial_read(dummy_buffer, sizeof(dummy_buffer), &bytes_read);
+        if (ret != PPP_ERR_OK) {
+            break;
+        }
+        
+        if (bytes_read > 0) {
+            PPP_DEBUG_DEBUG("Skipped %u bytes of startup logs", bytes_read);
+            retry_count = 0; // 重置重试计数
+        } else {
+            retry_count++;
+        }
+        
+        osal_msleep(100);
+    } while (retry_count < max_retries);
+    
+    PPP_DEBUG_DEBUG("Startup logs skipped");
+    return PPP_ERR_OK;
+}
+
+/* ========== PPP拨号函数已删除 ========== */
+/* N706A_NET 使用纯AT命令模式,不需要PPP拨号功能 */
+/* 如需PPP功能,请使用 ppp 组件 */
+/**
+ * @brief 发送AT关机指令,支持快速关机和正常关机
+ * @param shutdown_type 关机类型: 0-快速关机, 1-正常流程关机
+ * @return ppp_error_t
+ */
+ppp_error_t ppp_at_poweroff_modem(uint8_t shutdown_type)
+{
+    if (!g_at_ctx.initialized) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+
+    PPP_DEBUG_INFO("Sending AT+NWPWROFF=%d to power off modem", shutdown_type);
+
+    char cmd[32];
+    snprintf(cmd, sizeof(cmd), "AT+NWPWROFF=%d", shutdown_type);
+
+    ppp_at_response_t response;
+    ppp_error_t ret = ppp_at_send_command(cmd, "OK", 10000, &response);
+
+    if (ret == PPP_ERR_OK) {
+        PPP_DEBUG_INFO("Modem power off command sent successfully");
+    } else {
+        PPP_DEBUG_ERROR("Failed to send modem power off command");
+    }
+    ppp_power_off_cat1();
+    return ret;
+}
+
+/* ========== PPP挂断函数已删除 ========== */
+/* N706A_NET 使用纯AT命令模式,不需要PPP挂断功能 */
+
+/**
+ * @brief 获取当前波特率
+ */
+uint32_t ppp_at_get_current_baudrate(void)
+{
+    return g_at_ctx.current_baudrate;
+}
+
+/**
+ * @brief 检查是否为自动波特率模式
+ */
+bool ppp_at_is_auto_baudrate_mode(void)
+{
+    return g_at_ctx.auto_baudrate_mode;
+}
+
+/**
+ * @brief 测试AT通信是否正常
+ */
+ppp_error_t ppp_at_test_communication(void)
+{
+    PPP_DEBUG_INFO("Testing AT communication...");
+    
+    ppp_at_response_t response;
+    
+    // 发送简单的AT命令测试通信
+    ppp_error_t ret = ppp_at_send_command("AT", "OK", 1000, &response);
+    if (ret == PPP_ERR_OK) {
+        PPP_DEBUG_INFO("AT communication test passed");
+    } else {
+        PPP_DEBUG_ERROR("AT communication test failed: %d", ret);
+    }
+    
+    return ret;
+}
+
+/* 内部函数实现 */
+
+/**
+ * @brief 检查AT响应是否完整
+ * @param buffer 响应缓冲区
+ * @param length 缓冲区长度
+ * @return true 如果响应完整,false 否则
+ */
+static bool ppp_at_check_response_complete(const char *buffer, uint32_t length)
+{
+    if (!buffer || length == 0) {
+        return false;
+    }
+    
+    /* 搜索OK终止符 - 修复无符号整数下溢问题 */
+    if (length >= 2) {
+        for (uint32_t i = 0; i <= length - 2; i++) {
+            if (buffer[i] == 'O' && buffer[i+1] == 'K') {
+                /* 检查OK前面是否有换行符(避免误匹配) */
+                if (i == 0 || buffer[i-1] == '\n' || buffer[i-1] == '\r') {
+                    PPP_DEBUG_DEBUG("Found OK terminator at position %u", i);
+                    return true;
+                }
+            }
+        }
+    }
+    
+    /* 搜索ERROR终止符 - 已经有长度检查,但确保安全 */
+    if (length >= 5) {
+        for (uint32_t i = 0; i <= length - 5; i++) {
+            if (strncmp(&buffer[i], "ERROR", 5) == 0) {
+                /* 检查ERROR前面是否有换行符 */
+                if (i == 0 || buffer[i-1] == '\n' || buffer[i-1] == '\r') {
+                    PPP_DEBUG_DEBUG("Found ERROR terminator at position %u", i);
+                    return true;
+                }
+            }
+        }
+    }
+    
+    /* 检查其他终止符 */
+    if (strstr(buffer, "CONNECT") ||
+        strstr(buffer, "NO CARRIER") ||
+        strstr(buffer, "BUSY") ||
+        strstr(buffer, "NO DIALTONE") ||
+        strstr(buffer, "+CME ERROR") ||
+        strstr(buffer, "+CMS ERROR")) {
+        PPP_DEBUG_DEBUG("Found other terminator in response");
+        return true;
+    }
+    
+    return false;
+}
+
+/**
+ * @brief 解析AT命令响应
+ */
+static bool ppp_at_parse_response(const char *response, const char *expected)
+{
+    if (!response) {
+        return false;
+    }
+
+
+     // 检查期望响应 ,优先检测期望响应
+    if (expected && strstr(response, expected)) {
+        return true;
+    }
+
+    // 检查ABORT条件 (对应chat文件中的ABORT指令)
+    if (strstr(response, "BUSY") || 
+        strstr(response, "ERROR") || 
+        strstr(response, "NO CARRIER")) {
+        PPP_DEBUG_ERROR("AT command aborted: %s", response);
+        return false;
+    }
+
+   
+
+    return false;
+}
+
+/**
+ * @brief 等待AT命令响应 - 异步版本(从环形缓冲区读取)
+ * 
+ * 该函数从ppp_interrupt.c填充的环形缓冲区中异步读取AT响应数据
+ * 提供同步的函数接口,但底层是异步的高速串口接收
+ */
+static ppp_error_t ppp_at_wait_response(ppp_at_response_t *response, uint32_t timeout)
+{
+    PPP_DEBUG_DEBUG(">>> N706A AT WAIT_RESPONSE START (async mode, timeout: %u ms) <<<", timeout);
+    
+    if (!response || !g_at_response_buffer) {
+        PPP_DEBUG_ERROR("Invalid parameters: response=%p, buffer=%p", response, g_at_response_buffer);
+        return PPP_ERR_INVALID_PARAM;
+    }
+
+    uint32_t start_time = (uint32_t)osal_get_jiffies();
+    uint32_t bytes_received = 0;
+    bool response_complete = false;
+    
+    /* 清空全局缓存 */
+    memset(g_at_response_buffer, 0, g_at_buffer_size);
+    
+    PPP_DEBUG_DEBUG("N706A AT: Waiting for response from async ring buffer (timeout: %u ms)", timeout);
+    
+    /* 循环从环形缓冲区读取数据直到完整响应或超时 */
+    while (!response_complete) {
+        uint32_t current_time = (uint32_t)osal_get_jiffies();
+        uint32_t elapsed = osal_jiffies_to_msecs(current_time - start_time);
+        
+        /* 检查超时 */
+        if (elapsed >= timeout) {
+            PPP_DEBUG_WARN("N706A AT: Response timeout after %u ms", elapsed);
+            break;
+        }
+        
+        /* 等待信号量(有新数据到达),使用剩余超时时间 */
+        uint32_t remaining_timeout = timeout - elapsed;
+        if (remaining_timeout > 100) {
+            remaining_timeout = 100;  // 最多等100ms,然后检查一次
+        }
+        
+        int sem_result = osal_sem_down_timeout(&g_at_response_sem, remaining_timeout);
+        if (sem_result == OSAL_SUCCESS || sem_result == OSAL_FAILURE) {
+            /* 有新数据到达或信号量操作失败,尝试读取环形缓冲区 */
+            osal_mutex_lock(&g_at_response_mutex);
+            
+            /* 从环形缓冲区读取数据到响应缓冲区 */
+            while (g_at_response_tail != g_at_response_head && 
+                   bytes_received < (g_at_buffer_size - 1)) {
+                g_at_response_buffer[bytes_received] = g_at_response_ring_buffer[g_at_response_tail];
+                g_at_response_tail = (g_at_response_tail + 1) % N706A_AT_RESPONSE_RING_BUFFER_SIZE;
+                bytes_received++;
+            }
+            
+            osal_mutex_unlock(&g_at_response_mutex);
+            
+            /* 设置字符串结束符 */
+            if (bytes_received > 0) {
+                g_at_response_buffer[bytes_received] = '\0';
+                
+                PPP_DEBUG_DEBUG("N706A AT: Read %u bytes from ring buffer", bytes_received);
+                
+                /* 检查是否收到完整响应 */
+                if (ppp_at_check_response_complete((char*)g_at_response_buffer, bytes_received)) {
+                    PPP_DEBUG_DEBUG("N706A AT: Complete response detected");
+                    response_complete = true;
+                    break;
+                }
+            }
+        }
+        
+        /* 短暂延迟避免CPU占用过高 */
+        if (!response_complete) {
+            osal_msleep(10);
+        }
+    }
+    
+    /* 处理结果 */
+    if (bytes_received > 0) {
+        uint32_t copy_len = (bytes_received < PPP_AT_RESPONSE_MAX_LEN - 1) ? 
+                           bytes_received : PPP_AT_RESPONSE_MAX_LEN - 1;
+        
+        memcpy_s(response->response, PPP_AT_RESPONSE_MAX_LEN, 
+                g_at_response_buffer, copy_len);
+        response->response[copy_len] = '\0';
+        response->length = copy_len;
+        
+        uint32_t final_time = (uint32_t)osal_get_jiffies();
+        uint32_t total_elapsed = osal_jiffies_to_msecs(final_time - start_time);
+        
+        PPP_DEBUG_DEBUG("N706A AT: SUCCESS - %u bytes in %u ms", bytes_received, total_elapsed);
+        PPP_DEBUG_DEBUG(">>> N706A AT WAIT_RESPONSE END (SUCCESS) <<<");
+        return PPP_ERR_OK;
+    } else {
+        uint32_t final_time = (uint32_t)osal_get_jiffies();
+        uint32_t total_elapsed = osal_jiffies_to_msecs(final_time - start_time);
+        
+        PPP_DEBUG_WARN("N706A AT: FAILED - No response after %u ms", total_elapsed);
+        PPP_DEBUG_DEBUG(">>> N706A AT WAIT_RESPONSE END (FAILED) <<<");
+        response->length = 0;
+        response->response[0] = '\0';
+        return PPP_ERR_TIMEOUT;
+    }
+}
+
+/**
+ * @brief 解析AT+CESQ响应
+ * 参考N706A AT命令手册: +CESQ: <rxlev>,<ber>,<rscp>,<ecno>,<rsrq>,<rsrp>
+ */
+static ppp_error_t ppp_parse_cesq_response(const char *response, n706a_network_signal_info_t *info)
+{
+    if (!response || !info) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+
+    memset_s(info, sizeof(n706a_network_signal_info_t), 0, sizeof(n706a_network_signal_info_t));
+
+    // 查找+CESQ:开头的行
+    const char *cesq_line = strstr(response, "+CESQ:");
+    if (!cesq_line) {
+        PPP_DEBUG_WARN("No +CESQ: found in response");
+        return PPP_ERR_AT_FAILED;
+    }
+
+    // 跳过"+CESQ:"
+    cesq_line += 6;
+    while (*cesq_line == ' ' || *cesq_line == '\t') cesq_line++;
+
+    // +CESQ: <rxlev>,<ber>,<rscp>,<ecno>,<rsrq>,<rsrp>
+    int rxlev = 99, ber = 99, rscp = 255, ecno = 255, rsrq = 255, rsrp = 255;
+    int parsed = sscanf(cesq_line, "%d,%d,%d,%d,%d,%d", &rxlev, &ber, &rscp, &ecno, &rsrq, &rsrp);
+
+    if (parsed == 6) {
+        info->valid = true;
+        info->rxlev = rxlev;
+        info->ber = ber;
+        info->rscp = rscp;
+        info->ecno = ecno;
+        info->rsrq = rsrq;
+        info->rsrp = rsrp;
+        PPP_DEBUG_INFO("CESQ parsed successfully: rxlev=%d, ber=%d, rscp=%d, ecno=%d, rsrq=%d, rsrp=%d",
+            rxlev, ber, rscp, ecno, rsrq, rsrp);
+        return PPP_ERR_OK;
+    } else {
+        PPP_DEBUG_WARN("Failed to parse CESQ response, parsed: %d", parsed);
+        return PPP_ERR_AT_FAILED;
+    }
+}
+
+/**
+ * @brief 获取网络信号信息 (AT+CESQ)
+ */
+ppp_error_t ppp_at_get_network_signal_info(n706a_network_signal_info_t *info)
+{
+    if (!g_at_ctx.initialized || !info) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+    // N706A_NET模式下始终处于AT模式,无需检查
+    // (PPP模式需要检查是否成功切换到AT模式)
+    
+    PPP_DEBUG_INFO("Getting network signal information (AT+CESQ)...");
+
+    ppp_at_response_t response;
+    ppp_error_t ret = ppp_at_send_command("AT+CESQ", "OK", 5000, &response);
+
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("AT+CESQ command failed: %d", ret);
+        return ret;
+    }
+
+    // 解析响应
+    ret = ppp_parse_cesq_response(response.response, info);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("Failed to parse CESQ response");
+        return ret;
+    }
+
+    // 打印详细信息
+    PPP_DEBUG_INFO("=== Network Signal Information (AT+CESQ) ===");
+    PPP_DEBUG_INFO("rxlev: %d", info->rxlev);
+    PPP_DEBUG_INFO("ber: %d", info->ber);
+    PPP_DEBUG_INFO("rscp: %d", info->rscp);
+    PPP_DEBUG_INFO("ecno: %d", info->ecno);
+    PPP_DEBUG_INFO("rsrq: %d", info->rsrq);
+    PPP_DEBUG_INFO("rsrp: %d", info->rsrp);
+
+    // LTE信号质量评估 - 仅关注RSRQ和RSRP
+    PPP_DEBUG_INFO("=== LTE Signal Quality Analysis ===");
+    
+    // RSRQ评估 (0-49有效,255无效)
+    if (info->rsrq == 255) {
+        PPP_DEBUG_INFO("RSRQ: 无法获取LTE信号质量");
+    } else if (info->rsrq >= 0 && info->rsrq <= 49) {
+        // RSRQ转换公式: 实际值(dB) = (rsrq - 94)/10
+        float rsrq_db = (info->rsrq - 94) / 10.0f;
+        PPP_DEBUG_INFO("RSRQ: %d (%.1f dB)", info->rsrq, rsrq_db);
+        
+        // RSRQ评估标准 (范围: -19.5dB ~ -3dB,数值越大质量越好)
+        if (rsrq_db >= -6.0) {
+            PPP_DEBUG_INFO("RSRQ评级: 极佳 (信号质量优秀)");
+        } else if (rsrq_db >= -9.0) {
+            PPP_DEBUG_INFO("RSRQ评级: 良好 (信号质量稳定)");
+        } else if (rsrq_db >= -12.0) {
+            PPP_DEBUG_INFO("RSRQ评级: 一般 (信号质量可用)");
+        } else {
+            PPP_DEBUG_INFO("RSRQ评级: 较差 (信号质量不佳)");
+        }
+    } else {
+        PPP_DEBUG_INFO("RSRQ: %d (超出有效范围0-49)", info->rsrq);
+    }
+    
+    // RSRP评估 (0-97有效,255无效)
+    if (info->rsrp == 255) {
+        PPP_DEBUG_INFO("RSRP: 无法获取LTE信号强度");
+    } else if (info->rsrp >= 0 && info->rsrp <= 97) {
+        // RSRP转换公式: 实际值(dBm) = rsrp - 140
+        float rsrp_dbm = info->rsrp - 140.0f;
+        PPP_DEBUG_INFO("RSRP: %d (%.0f dBm)", info->rsrp, rsrp_dbm);
+        
+        // RSRP评估标准 (范围: -140dBm ~ -43dBm,数值越大信号越强)
+        if (rsrp_dbm >= -80) {
+            PPP_DEBUG_INFO("RSRP评级: 极佳 (信号强度优秀)");
+        } else if (rsrp_dbm >= -90) {
+            PPP_DEBUG_INFO("RSRP评级: 良好 (信号强度稳定)");
+        } else if (rsrp_dbm >= -100) {
+            PPP_DEBUG_INFO("RSRP评级: 一般 (信号强度可用)");
+        } else {
+            PPP_DEBUG_INFO("RSRP评级: 较差 (信号强度不足)");
+        }
+    } else {
+        PPP_DEBUG_INFO("RSRP: %d (超出有效范围0-97)", info->rsrp);
+    }
+    
+    // 综合LTE信号质量评估
+    if (info->rsrq != 255 && info->rsrp != 255 && 
+        info->rsrq >= 0 && info->rsrq <= 49 && 
+        info->rsrp >= 0 && info->rsrp <= 97) {
+        
+        float rsrq_db = (info->rsrq - 94) / 10.0f;
+        float rsrp_dbm = info->rsrp - 140.0f;
+        
+        const char *overall_quality = "未知";
+        if (rsrq_db >= -6.0 && rsrp_dbm >= -80) {
+            overall_quality = "LTE信号极佳 (质量和强度都优秀)";
+        } else if (rsrq_db >= -9.0 && rsrp_dbm >= -90) {
+            overall_quality = "LTE信号良好 (质量和强度都稳定)";
+        } else if (rsrq_db >= -12.0 && rsrp_dbm >= -100) {
+            overall_quality = "LTE信号一般 (质量和强度可用)";
+        } else {
+            overall_quality = "LTE信号较差 (需要改善网络环境)";
+        }
+        
+        PPP_DEBUG_INFO("=== 综合评估: %s ===", overall_quality);
+    } else {
+        PPP_DEBUG_INFO("=== 综合评估: LTE参数无效,无法评估 ===");
+    }
+
+    PPP_DEBUG_INFO("=== End Network Signal Information ===");
+
+    return PPP_ERR_OK;
+}
+
+/* ========== 导出的N706A API包装函数(用于n706a_tcp_client和n706a_net_at_cmd) ========== */
+
+/**
+ * @brief N706A对外导出:发送AT命令并等待响应
+ */
+n706a_at_error_t n706a_at_send_command(const char *command, 
+                                       const char *expected_response, 
+                                       uint32_t timeout, 
+                                       n706a_at_response_t *response)
+{
+    ppp_at_response_t ppp_resp;
+    ppp_error_t ret = ppp_at_send_command(command, expected_response, timeout, &ppp_resp);
+    
+    if (response) {
+        /* 转换ppp_at_response_t到n706a_at_response_t */
+        memcpy_s(response->response, sizeof(response->response), ppp_resp.response, sizeof(ppp_resp.response));
+        response->length = ppp_resp.length;
+        response->success = ppp_resp.success;
+        response->error_code = (ret == PPP_ERR_OK) ? N706A_AT_OK : N706A_AT_ERR_AT_FAILED;
+    }
+    
+    return (ret == PPP_ERR_OK) ? N706A_AT_OK : N706A_AT_ERR_AT_FAILED;
+}
+
+/**
+ * @brief N706A对外导出:测试AT通信是否正常
+ */
+n706a_at_error_t n706a_at_test_communication(void)
+{
+    if (!g_at_ctx.initialized) {
+        return N706A_AT_ERR_INVALID_PARAM;
+    }
+    
+    n706a_at_response_t response;
+    n706a_at_error_t ret = n706a_at_send_command("AT", "OK", 3000, &response);
+    
+    if (ret == N706A_AT_OK && response.success) {
+        PPP_DEBUG_INFO("AT communication test passed\n");
+        return N706A_AT_OK;
+    } else {
+        PPP_DEBUG_ERROR("AT communication test failed\n");
+        return N706A_AT_ERR_AT_FAILED;
+    }
+}
+
+/**
+ * @brief N706A对外导出:获取网络信号信息
+ */
+n706a_at_error_t n706a_at_get_network_signal_info(n706a_network_signal_info_t *signal_info)
+{
+    if (!signal_info) {
+        return N706A_AT_ERR_INVALID_PARAM;
+    }
+    
+    /* 调用内部的ppp_at_get_network_signal_info */
+    n706a_network_signal_info_t ppp_signal;
+    ppp_error_t ret = ppp_at_get_network_signal_info(&ppp_signal);
+    
+    if (ret == PPP_ERR_OK) {
+        /* 转换数据结构 */
+        signal_info->rxlev = ppp_signal.rxlev;
+        signal_info->ber = ppp_signal.ber;
+        signal_info->rscp = ppp_signal.rscp;
+        signal_info->ecno = ppp_signal.ecno;
+        signal_info->rsrq = ppp_signal.rsrq;
+        signal_info->rsrp = ppp_signal.rsrp;
+        signal_info->valid = ppp_signal.valid;
+        return N706A_AT_OK;
+    } else {
+        signal_info->valid = false;
+        return N706A_AT_ERR_AT_FAILED;
+    }
+}
+
+/**
+ * @brief N706A对外导出:设置波特率
+ */
+n706a_at_error_t n706a_at_set_baudrate(uint32_t baudrate)
+{
+    ppp_error_t ret = ppp_at_set_baudrate(baudrate);
+    return (ret == PPP_ERR_OK) ? N706A_AT_OK : N706A_AT_ERR_UART;
+}
+
+/**
+ * @brief N706A对外导出:获取当前波特率
+ */
+uint32_t n706a_at_get_current_baudrate(void)
+{
+    return g_at_ctx.current_baudrate;
+}
+
+/**
+ * @brief 解析 +TCPRECV URC
+ * @param urc_data URC数据(以 "+TCPRECV: " 开头)
+ * @param urc_len URC数据长度
+ * @param socket_id 输出:socket ID
+ * @param data_len 输出:数据长度
+ * @param data 输出:数据指针(指向 urc_data 内部)
+ * @return true=解析成功,false=失败
+ * 
+ * URC格式:+TCPRECV: <socket_id>,<length>,<data>\r\n
+ * 例如:+TCPRECV: 0,10,1234567890\r\n
+ */
+static bool n706a_parse_tcprecv_urc(const char *urc_data, size_t urc_len, 
+                                    int *socket_id, size_t *data_len, const uint8_t **data)
+{
+    if (!urc_data || !socket_id || !data_len || !data || urc_len < 15) {
+        return false;
+    }
+    
+    // 跳过 "+TCPRECV: "
+    const char *p = urc_data + 10;
+    const char *end = urc_data + urc_len;
+    
+    // 解析 socket_id
+    *socket_id = 0;
+    while (p < end && *p >= '0' && *p <= '9') {
+        *socket_id = *socket_id * 10 + (*p - '0');
+        p++;
+    }
+    
+    if (p >= end || *p != ',') {
+        PPP_DEBUG_ERROR("URC parse error: no comma after socket_id");
+        return false;
+    }
+    p++;  // 跳过逗号
+    
+    // 解析 length
+    *data_len = 0;
+    while (p < end && *p >= '0' && *p <= '9') {
+        *data_len = *data_len * 10 + (*p - '0');
+        p++;
+    }
+    
+    if (p >= end || *p != ',') {
+        PPP_DEBUG_ERROR("URC parse error: no comma after length");
+        return false;
+    }
+    p++;  // 跳过逗号
+    
+    // 数据起始位置
+    *data = (const uint8_t *)p;
+    
+    // 验证数据长度是否合理
+    size_t remaining = end - p;
+    if (*data_len > remaining) {
+        PPP_DEBUG_WARN("URC data_len=%u exceeds remaining=%u, truncating", 
+                      (unsigned int)*data_len, (unsigned int)remaining);
+        *data_len = remaining;
+        
+        // 移除尾部的 \r\n(如果存在)
+        if (*data_len >= 2 && (*data)[*data_len - 2] == '\r' && (*data)[*data_len - 1] == '\n') {
+            *data_len -= 2;
+        }
+    }
+    
+    PPP_DEBUG_DEBUG("Parsed URC: socket=%d, len=%u", *socket_id, (unsigned int)*data_len);
+    return true;
+}
+
+/**
+ * @brief 注册TCP URC接收回调
+ * @param callback 回调函数指针,NULL表示取消注册
+ */
+void n706a_at_register_tcp_urc_callback(n706a_tcp_urc_callback_t callback)
+{
+    g_tcp_urc_callback = callback;
+    PPP_DEBUG_INFO("TCP URC callback %s", callback ? "registered" : "unregistered");
+}
\ No newline at end of file
index 649e370..d289d59 100644 (file)
@@ -118,13 +118,18 @@ n706a_httpc_result_t n706a_http_client_get(n706a_http_client_t *client,
         return N706A_HTTP_ECONN;
     }
     
-    /* 构造GET请求 */
-    char request_buf[2048];
+    /* 动态分配请求缓冲区 */
+    char *request_buf = (char *)malloc(2048);
+    if (!request_buf) {
+        return N706A_HTTP_ENOMEM;
+    }
+    
     int request_len = http_build_request(client, "GET", path,
                                         NULL, 0, NULL,
-                                        request_buf, sizeof(request_buf));
+                                        request_buf, 2048);
     
     if (request_len < 0) {
+        free(request_buf);
         return N706A_HTTP_ENOBUFS;
     }
     
@@ -135,28 +140,37 @@ n706a_httpc_result_t n706a_http_client_get(n706a_http_client_t *client,
                                             request_len,
                                             &sent);
     
+    free(request_buf);
+    
     if (ret != N706A_TCP_SUCCESS || sent != (size_t)request_len) {
         return N706A_HTTP_ESEND;
     }
     
-    /* 接收响应 */
-    uint8_t response_buf[8192];
-    size_t received;
+    /* 动态分配响应缓冲区 */
+    uint8_t *response_buf = (uint8_t *)malloc(8192);
+    if (!response_buf) {
+        return N706A_HTTP_ENOMEM;
+    }
     
+    size_t received;
     ret = n706a_tcp_recv(&client->tcp_sock,
                         response_buf,
-                        sizeof(response_buf) - 1,
+                        8192 - 1,
                         &received,
                         client->timeout_ms);
     
     if (ret != N706A_TCP_SUCCESS) {
+        free(response_buf);
         return N706A_HTTP_ERECV;
     }
     
     response_buf[received] = '\0';
     
     /* 解析响应 */
-    return http_parse_response((char*)response_buf, received, client, client_data);
+    n706a_httpc_result_t result = http_parse_response((char*)response_buf, received, client, client_data);
+    free(response_buf);
+    
+    return result;
 }
 
 /**
@@ -177,13 +191,18 @@ n706a_httpc_result_t n706a_http_client_post(n706a_http_client_t *client,
         return N706A_HTTP_ECONN;
     }
     
-    /* 构造POST请求 */
-    char request_buf[4096];
+    /* 动态分配请求缓冲区 */
+    char *request_buf = (char *)malloc(4096);
+    if (!request_buf) {
+        return N706A_HTTP_ENOMEM;
+    }
+    
     int request_len = http_build_request(client, "POST", path,
                                         body, body_len, content_type,
-                                        request_buf, sizeof(request_buf));
+                                        request_buf, 4096);
     
     if (request_len < 0) {
+        free(request_buf);
         return N706A_HTTP_ENOBUFS;
     }
     
@@ -194,27 +213,36 @@ n706a_httpc_result_t n706a_http_client_post(n706a_http_client_t *client,
                                             request_len,
                                             &sent);
     
+    free(request_buf);
+    
     if (ret != N706A_TCP_SUCCESS) {
         return N706A_HTTP_ESEND;
     }
     
-    /* 接收响应 */
-    uint8_t response_buf[8192];
-    size_t received;
+    /* 动态分配响应缓冲区 */
+    uint8_t *response_buf = (uint8_t *)malloc(8192);
+    if (!response_buf) {
+        return N706A_HTTP_ENOMEM;
+    }
     
+    size_t received;
     ret = n706a_tcp_recv(&client->tcp_sock,
                         response_buf,
-                        sizeof(response_buf) - 1,
+                        8192 - 1,
                         &received,
                         client->timeout_ms);
     
     if (ret != N706A_TCP_SUCCESS) {
+        free(response_buf);
         return N706A_HTTP_ERECV;
     }
     
     response_buf[received] = '\0';
     
-    return http_parse_response((char*)response_buf, received, client, client_data);
+    n706a_httpc_result_t result = http_parse_response((char*)response_buf, received, client, client_data);
+    free(response_buf);
+    
+    return result;
 }
 
 /**
@@ -235,26 +263,41 @@ n706a_httpc_result_t n706a_http_client_put(n706a_http_client_t *client,
         return N706A_HTTP_ECONN;
     }
     
-    char request_buf[4096];
+    /* 动态分配请求缓冲区 */
+    char *request_buf = (char *)malloc(4096);
+    if (!request_buf) {
+        return N706A_HTTP_ENOMEM;
+    }
+    
     int request_len = http_build_request(client, "PUT", path,
                                         body, body_len, content_type,
-                                        request_buf, sizeof(request_buf));
+                                        request_buf, 4096);
     
     if (request_len < 0) {
+        free(request_buf);
         return N706A_HTTP_ENOBUFS;
     }
     
     size_t sent;
     n706a_tcp_send(&client->tcp_sock, (uint8_t*)request_buf, request_len, &sent);
+    free(request_buf);
+    
+    /* 动态分配响应缓冲区 */
+    uint8_t *response_buf = (uint8_t *)malloc(8192);
+    if (!response_buf) {
+        return N706A_HTTP_ENOMEM;
+    }
     
-    uint8_t response_buf[8192];
     size_t received;
-    n706a_tcp_recv(&client->tcp_sock, response_buf, sizeof(response_buf) - 1,
+    n706a_tcp_recv(&client->tcp_sock, response_buf, 8192 - 1,
                    &received, client->timeout_ms);
     
     response_buf[received] = '\0';
     
-    return http_parse_response((char*)response_buf, received, client, client_data);
+    n706a_httpc_result_t result = http_parse_response((char*)response_buf, received, client, client_data);
+    free(response_buf);
+    
+    return result;
 }
 
 /**
@@ -272,26 +315,41 @@ n706a_httpc_result_t n706a_http_client_delete(n706a_http_client_t *client,
         return N706A_HTTP_ECONN;
     }
     
-    char request_buf[2048];
+    /* 动态分配请求缓冲区 */
+    char *request_buf = (char *)malloc(2048);
+    if (!request_buf) {
+        return N706A_HTTP_ENOMEM;
+    }
+    
     int request_len = http_build_request(client, "DELETE", path,
                                         NULL, 0, NULL,
-                                        request_buf, sizeof(request_buf));
+                                        request_buf, 2048);
     
     if (request_len < 0) {
+        free(request_buf);
         return N706A_HTTP_ENOBUFS;
     }
     
     size_t sent;
     n706a_tcp_send(&client->tcp_sock, (uint8_t*)request_buf, request_len, &sent);
+    free(request_buf);
+    
+    /* 动态分配响应缓冲区 */
+    uint8_t *response_buf = (uint8_t *)malloc(8192);
+    if (!response_buf) {
+        return N706A_HTTP_ENOMEM;
+    }
     
-    uint8_t response_buf[8192];
     size_t received;
-    n706a_tcp_recv(&client->tcp_sock, response_buf, sizeof(response_buf) - 1,
+    n706a_tcp_recv(&client->tcp_sock, response_buf, 8192 - 1,
                    &received, client->timeout_ms);
     
     response_buf[received] = '\0';
     
-    return http_parse_response((char*)response_buf, received, client, client_data);
+    n706a_httpc_result_t result = http_parse_response((char*)response_buf, received, client, client_data);
+    free(response_buf);
+    
+    return result;
 }
 
 /**
@@ -309,26 +367,41 @@ n706a_httpc_result_t n706a_http_client_head(n706a_http_client_t *client,
         return N706A_HTTP_ECONN;
     }
     
-    char request_buf[2048];
+    /* 动态分配请求缓冲区 */
+    char *request_buf = (char *)malloc(2048);
+    if (!request_buf) {
+        return N706A_HTTP_ENOMEM;
+    }
+    
     int request_len = http_build_request(client, "HEAD", path,
                                         NULL, 0, NULL,
-                                        request_buf, sizeof(request_buf));
+                                        request_buf, 2048);
     
     if (request_len < 0) {
+        free(request_buf);
         return N706A_HTTP_ENOBUFS;
     }
     
     size_t sent;
     n706a_tcp_send(&client->tcp_sock, (uint8_t*)request_buf, request_len, &sent);
+    free(request_buf);
+    
+    /* 动态分配响应缓冲区 */
+    uint8_t *response_buf = (uint8_t *)malloc(8192);
+    if (!response_buf) {
+        return N706A_HTTP_ENOMEM;
+    }
     
-    uint8_t response_buf[8192];
     size_t received;
-    n706a_tcp_recv(&client->tcp_sock, response_buf, sizeof(response_buf) - 1,
+    n706a_tcp_recv(&client->tcp_sock, response_buf, 8192 - 1,
                    &received, client->timeout_ms);
     
     response_buf[received] = '\0';
     
-    return http_parse_response((char*)response_buf, received, client, client_data);
+    n706a_httpc_result_t result = http_parse_response((char*)response_buf, received, client, client_data);
+    free(response_buf);
+    
+    return result;
 }
 
 /**
diff --git a/code/sdk/zhihui/n706a_net/src/n706a_net_api.c b/code/sdk/zhihui/n706a_net/src/n706a_net_api.c
new file mode 100644 (file)
index 0000000..e72adf4
--- /dev/null
@@ -0,0 +1,908 @@
+/**
+ * @file n706a_net_api.c
+ * @brief N706A AT命令网络API实现(独立于PPP)
+ */
+
+#include "n706a_net_api.h"
+#include "n706a_at_handler.h"
+#include "n706a_tcp_client.h"
+#include "ppp_config.h"
+#include "ppp_debug.h"
+#include "ppp_power_ctl.h"
+#include "ppp_serial.h"
+#include "ppp_cat1_api.h"
+#include "ppp_interrupt.h"
+#include "ppp_api.h"
+#include "soc_osal.h"
+#include "osal_debug.h"
+#include "schedule/osal_task.h"
+#include "securec.h"
+#include <string.h>
+#include <stdlib.h>
+
+// N706A网络状态
+static n706a_net_state_t g_n706a_state = N706A_NET_STATE_IDLE;
+
+// N706A配置参数
+static n706a_net_config_t g_n706a_config = {0};
+
+// 4G电源初始化状态
+static bool g_4g_power_initialized = false;
+
+// 外部声明cat1_api_enable_cat1函数
+extern void cat1_api_enable_cat1(bool isopen);
+
+/**
+ * @brief 初始化4G电源控制
+ */
+errcode_t n706a_net_power_init(void)
+{
+    if (g_4g_power_initialized) {
+        PPP_DEBUG_PRINT("4G power already initialized\n");
+        return ERRCODE_SUCC;
+    }
+
+    // 1. 配置4G电源控制引脚
+    PPP_DEBUG_PRINT("Configuring N706A power pins\n");
+    
+    ppp_ctl_pin_4g_t pin_config = {
+        .bat_pin = S_AGPIO_L18,
+        .bat_pin_en_value = 1,
+        .pwr_pin = S_AGPIO_L23,
+        .pwr_pin_en_value = 1,
+        .reset_pin = S_AGPIO_L24,
+        .reset_pin_en_value = 1,
+        .ring_pin = S_MGPIO21,  // CTS cat1 wakeup mcu
+        .ring_pin_en_value = 1,
+        .wakemodem_pin = S_MGPIO22,  // RTS mcu wakeup cat1
+        .wakemodem_pin_en_value = 0
+    };
+ 
+    // 注册4G电源控制引脚配置
+    ppp_register_ctl_pin(&pin_config);
+
+    PPP_DEBUG_PRINT("Initializing GPIO system\n");
+    ppp_api_gpio_init();
+
+    PPP_DEBUG_PRINT("4G power control pins registered successfully\n");
+    g_4g_power_initialized = true;  
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 控制4G电源开关
+ */
+errcode_t n706a_net_power_control(bool is_open)
+{
+    if (is_open) {
+        // 启用4G电源
+        PPP_DEBUG_PRINT("Enabling N706A module power...\n");
+        cat1_api_enable_cat1(true);
+        osal_msleep(500);
+
+        // 唤醒4G模块
+        PPP_DEBUG_PRINT("Waking up N706A module...\n");
+        cat1_api_wakeup_cat1(true);  // true = 唤醒
+        PPP_DEBUG_PRINT("N706A module power enabled\n");
+    } else {
+        // 关闭4G电源
+        PPP_DEBUG_PRINT("Disabling N706A module power...\n");
+        cat1_api_enable_cat1(false);
+        PPP_DEBUG_PRINT("N706A module power disabled\n");
+    }
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 检查4G电源是否已初始化
+ */
+bool n706a_net_is_power_initialized(void)
+{
+    return g_4g_power_initialized;
+}
+
+/**
+ * @brief 初始化N706A AT网络系统
+ */
+errcode_t n706a_net_init(const n706a_net_config_t *config)
+{
+    if (!config) {
+        PPP_DEBUG_ERROR("Invalid config parameter\n");
+        return ERRCODE_FAIL;
+    }
+
+    if (g_n706a_state != N706A_NET_STATE_IDLE) {
+        PPP_DEBUG_WARN("N706A network already initialized\n");
+        return ERRCODE_SUCC;
+    }
+
+    // 保存配置
+    memcpy_s(&g_n706a_config, sizeof(n706a_net_config_t), 
+             config, sizeof(n706a_net_config_t));
+
+    PPP_DEBUG_PRINT("=== N706A AT Network Initialization Start ===\n");
+
+    // 1. 初始化4G电源控制(如果还没初始化)
+    if (!g_4g_power_initialized) {
+        PPP_DEBUG_PRINT("Step 1: Initializing 4G power control\n");
+        errcode_t ret = n706a_net_power_init();
+        if (ret != ERRCODE_SUCC) {
+            PPP_DEBUG_ERROR("Failed to initialize 4G power control\n");
+            return ret;
+        }
+    }
+
+    // 2. 打开4G电源
+    PPP_DEBUG_PRINT("Step 2: Powering on N706A module\n");
+    errcode_t ret = n706a_net_power_control(true);
+    if (ret != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to power on N706A module\n");
+        return ret;
+    }
+
+    // 3. 初始化串口
+    PPP_DEBUG_PRINT("Step 3: Initializing UART (baudrate: %u)\n", config->baudrate);
+    ppp_serial_config_t serial_config = {
+        .uart_bus = SIO_UART_BUS,
+        .baudrate = config->baudrate,
+        .rx_buffer_size = 4096,  // 4KB接收缓冲区(用于高速数据接收)
+        .tx_buffer_size = 2048,  // 2KB发送缓冲区
+        .rx_callback = NULL,     // N706A使用中断方式,不需要回调
+        .rx_callback_arg = NULL
+    };
+    ret = ppp_serial_init(&serial_config);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("Failed to initialize UART\n");
+        n706a_net_power_control(false);
+        return ERRCODE_FAIL;
+    }
+
+    // 4. 初始化AT命令处理器
+    PPP_DEBUG_PRINT("Step 4: Initializing AT command handler\n");
+    ret = ppp_at_handler_init(SIO_UART_BUS, config->baudrate, config->auto_baudrate);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("Failed to initialize AT handler\n");
+        ppp_serial_deinit();
+        n706a_net_power_control(false);
+        return ERRCODE_FAIL;
+    }
+
+    // 5. 清空串口缓冲区(N706A_NET始终处于AT模式,无需切换)
+    PPP_DEBUG_PRINT("Step 5: Clearing UART buffer (always in AT mode)\n");
+    ppp_serial_flush_rx();  // 清理启动时可能残留的数据
+
+    // 6. 启动中断接收系统
+    PPP_DEBUG_PRINT("Step 6: Enabling interrupt reception\n");
+    ret = ppp_interrupt_enable();
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("Failed to enable interrupt reception\n");
+        ppp_at_handler_deinit();
+        ppp_serial_deinit();
+        n706a_net_power_control(false);
+        return ERRCODE_FAIL;
+    }
+
+    // 7. 配置TCP接收模式为直接输出(URC模式)
+    PPP_DEBUG_PRINT("Step 7: Configuring TCP URC mode\n");
+    n706a_at_response_t at_resp;
+    n706a_at_error_t at_ret = n706a_at_send_command("AT+RECVMODE=1", "OK", 3000, &at_resp);
+    if (at_ret != N706A_AT_OK) {
+        PPP_DEBUG_WARN("Failed to set RECVMODE=1, using default\n");
+    }
+    PPP_DEBUG_INFO("response: %d , %s\n",at_resp.length,at_resp.response);
+    // 8. 注册TCP URC接收回调
+    PPP_DEBUG_PRINT("Step 8: Registering TCP URC callback\n");
+    n706a_at_register_tcp_urc_callback(n706a_tcp_on_urc_received);
+
+    // 9. 检查GPRS附着状态(AT+CGATT?)
+    PPP_DEBUG_PRINT("Step 9: Checking GPRS attachment status (AT+CGATT?)\n");
+    at_ret = n706a_at_send_command("AT+CGATT?", "OK", 5000, &at_resp);
+    if (at_ret != N706A_AT_OK) {
+        PPP_DEBUG_ERROR("Failed to query GPRS attachment status\n");
+        goto cleanup;
+    }
+    
+    // 解析+CGATT响应 (期望: "+CGATT: 1")
+    bool gprs_attached = false;
+    if (at_resp.length > 0 && strstr(at_resp.response, "+CGATT: 1")) {
+        gprs_attached = true;
+        PPP_DEBUG_PRINT("GPRS already attached\n");
+    } else {
+        PPP_DEBUG_WARN("GPRS not attached, attempting manual attach (AT+CGATT=1)\n");
+        
+        // 10. 手动附着GPRS(AT+CGATT=1)
+        at_ret = n706a_at_send_command("AT+CGATT=1", "OK", 30000, &at_resp);  // 30s超时
+        if (at_ret != N706A_AT_OK) {
+            PPP_DEBUG_ERROR("Failed to attach GPRS, cannot proceed\n");
+            PPP_DEBUG_ERROR("Response: %s\n", at_resp.length > 0 ? at_resp.response : "NULL");
+            goto cleanup;
+        }
+        
+        PPP_DEBUG_PRINT("GPRS attached successfully\n");
+        gprs_attached = true;
+        
+        // 等待附着稳定
+        osal_msleep(1000);
+    }
+
+    // 11. 激活网络连接(AT+XIIC=1)
+    PPP_DEBUG_PRINT("Step 11: Activating PDP context (AT+XIIC=1)\n");
+    at_ret = n706a_at_send_command("AT+XIIC=1", "OK", 15000, &at_resp);  // 增加超时至15s
+    if (at_ret != N706A_AT_OK) {
+        PPP_DEBUG_ERROR("Failed to activate PDP context (AT+XIIC=1)\n");
+        PPP_DEBUG_ERROR("Response: %s\n", at_resp.length > 0 ? at_resp.response : "NULL");
+        PPP_DEBUG_ERROR("Possible causes:");
+        PPP_DEBUG_ERROR("  1. SIM card not detected or locked");
+        PPP_DEBUG_ERROR("  2. Network registration failed (check AT+CREG?)");
+        PPP_DEBUG_ERROR("  3. APN configuration error");
+        PPP_DEBUG_ERROR("  4. Operator network issue");
+        goto cleanup;
+    }
+    
+    PPP_DEBUG_PRINT("PDP context activated successfully\n");
+    PPP_DEBUG_INFO("response: %d , %s\n",at_resp.length,at_resp.response);
+
+    g_n706a_state = N706A_NET_STATE_READY;
+    PPP_DEBUG_PRINT("=== N706A AT Network Initialized Successfully ===\n");
+    PPP_DEBUG_PRINT("Mode: Pure AT commands (no PPP dialing)\n");
+    PPP_DEBUG_PRINT("Reception: Asynchronous interrupt + URC push\n");
+    PPP_DEBUG_PRINT("Network: PDP context activated\n");
+    PPP_DEBUG_PRINT("GPRS: Attached and ready\n");
+    
+    return ERRCODE_SUCC;
+
+cleanup:
+    PPP_DEBUG_ERROR("=== N706A AT Network Initialization Failed ===\n");
+    n706a_net_deinit();
+    return ERRCODE_FAIL;
+}
+
+/**
+ * @brief 反初始化N706A AT网络系统
+ */
+errcode_t n706a_net_deinit(void)
+{
+    if (g_n706a_state == N706A_NET_STATE_IDLE) {
+        PPP_DEBUG_WARN("N706A network not initialized\n");
+        return ERRCODE_SUCC;
+    }
+
+    PPP_DEBUG_PRINT("=== N706A AT Network Deinitialization Start ===\n");
+
+    // 1. 停止中断接收
+    PPP_DEBUG_PRINT("Step 1: Disabling interrupt reception\n");
+    ppp_interrupt_disable();
+
+    // 2. 反初始化AT处理器
+    PPP_DEBUG_PRINT("Step 2: Deinitializing AT handler\n");
+    ppp_at_handler_deinit();
+
+    // 3. 反初始化串口
+    PPP_DEBUG_PRINT("Step 3: Deinitializing UART\n");
+    ppp_serial_deinit();
+
+    // 4. 关闭4G电源
+    PPP_DEBUG_PRINT("Step 4: Powering off N706A module\n");
+    n706a_net_power_control(false);
+
+    g_n706a_state = N706A_NET_STATE_IDLE;
+    PPP_DEBUG_PRINT("=== N706A AT Network Deinitialized ===\n");
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 获取N706A网络状态
+ */
+n706a_net_state_t n706a_net_get_state(void)
+{
+    return g_n706a_state;
+}
+
+/**
+ * @brief 获取并显示网络信号信息
+ * @return 错误码
+ */
+errcode_t n706a_get_network_signal_info(void)
+{
+    if (g_n706a_state == N706A_NET_STATE_IDLE) {
+        PPP_DEBUG_ERROR("N706A not initialized");
+        return ERRCODE_FAIL;
+    }
+    
+    PPP_DEBUG_INFO("Getting network signal information...");
+    
+    n706a_network_signal_info_t signal_info;
+    n706a_at_error_t ret = n706a_at_get_network_signal_info(&signal_info);
+    
+    if (ret != N706A_AT_OK) {
+        PPP_DEBUG_ERROR("Failed to get network signal information: %d", ret);
+        return ERRCODE_FAIL;
+    }
+    
+    if (!signal_info.valid) {
+        PPP_DEBUG_WARN("Network signal information is not valid");
+        return ERRCODE_FAIL;
+    }
+    
+    // 输出格式化的信号信息摘要
+    PPP_DEBUG_CRITICAL("=== Network Signal Summary (AT+CESQ) ===");
+    
+    // 仅关注LTE关键参数: RSRQ和RSRP
+    if (signal_info.rsrq != 255 && signal_info.rsrp != 255 && 
+        signal_info.rsrq >= 0 && signal_info.rsrq <= 49 && 
+        signal_info.rsrp >= 0 && signal_info.rsrp <= 97) {
+        
+        // CESQ格式的RSRQ和RSRP转换 (使用正确公式)
+        float rsrq_db = (signal_info.rsrq - 94) / 10.0f;   // (rsrq - 94)/10
+        float rsrp_dbm = signal_info.rsrp - 140.0f;        // rsrp - 140
+        
+        PPP_DEBUG_CRITICAL("LTE Signal Quality:");
+        PPP_DEBUG_CRITICAL("  RSRQ: %d (%.1f dB)", signal_info.rsrq, rsrq_db);
+        PPP_DEBUG_CRITICAL("  RSRP: %d (%.0f dBm)", signal_info.rsrp, rsrp_dbm);
+        
+        // 综合质量评估 (基于RSRQ和RSRP)
+        const char *overall_quality = "未知";
+        if (rsrq_db >= -6.0 && rsrp_dbm >= -80) {
+            overall_quality = "LTE信号极佳 (质量和强度都优秀)";
+        } else if (rsrq_db >= -9.0 && rsrp_dbm >= -90) {
+            overall_quality = "LTE信号良好 (质量和强度都稳定)";
+        } else if (rsrq_db >= -12.0 && rsrp_dbm >= -100) {
+            overall_quality = "LTE信号一般 (质量和强度可用)";
+        } else {
+            overall_quality = "LTE信号较差 (需要改善网络环境)";
+        }
+        
+        PPP_DEBUG_CRITICAL("Overall LTE Quality: %s", overall_quality);
+    } else {
+        PPP_DEBUG_CRITICAL("LTE参数无效,无法评估信号质量");
+        PPP_DEBUG_CRITICAL("RSRQ: %d, RSRP: %d", signal_info.rsrq, signal_info.rsrp);
+    }
+    
+    PPP_DEBUG_CRITICAL("=== End Signal Summary ===");
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 启用4G模块电源省电模式
+ * @return ERRCODE_SUCC-成功,其他-失败
+ * 
+ * 功能说明:
+ * - 执行 AT+NWENPWRSAVE=1 命令
+ * - 配置为:低电平唤醒,高电平进入休眠
+ * - N706A_NET始终在AT模式
+ */
+errcode_t n706a_enable_power_save_mode(void)
+{
+    if (g_n706a_state == N706A_NET_STATE_IDLE) {
+        PPP_DEBUG_ERROR("N706A not initialized");
+        return ERRCODE_FAIL;
+    }
+    
+    PPP_DEBUG_INFO("Enabling power save mode (AT+NWENPWRSAVE=1)...");
+    
+    n706a_at_response_t response;
+    n706a_at_error_t ret = n706a_at_send_command("AT+NWENPWRSAVE=1", "OK", 5000, &response);
+    
+    if (ret != N706A_AT_OK) {
+        PPP_DEBUG_ERROR("Failed to send AT+NWENPWRSAVE command");
+        return ERRCODE_FAIL;
+    }
+    
+    if (!response.success) {
+        PPP_DEBUG_ERROR("AT+NWENPWRSAVE command failed, response: %s", response.response);
+        return ERRCODE_FAIL;
+    }
+    
+    PPP_DEBUG_CRITICAL("Power save mode enabled successfully");
+    PPP_DEBUG_INFO("  Mode: High level wakes up, Low level enters sleep");
+    
+    return ERRCODE_SUCC;
+}
+
+/* ========== Runtime Status Update Helper Functions ========== */
+
+/**
+ * @brief 解析AT+CGSN响应获取IMEI号
+ */
+static errcode_t n706a_parse_imei_response(const char *response, char *imei, size_t imei_size)
+{
+    if (!response || !imei || imei_size == 0) {
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    const char *start = strstr(response, "+CGSN: ");
+    if (start == NULL) {
+        return ERRCODE_FAIL;
+    }
+    
+    start += 7; // 跳过"+CGSN: "
+    const char *end = strstr(start, "\r");
+    if (end == NULL) {
+        end = strstr(start, "\n");
+    }
+    if (end == NULL) {
+        return ERRCODE_FAIL;
+    }
+    
+    size_t len = end - start;
+    if (len >= imei_size) {
+        len = imei_size - 1;
+    }
+    
+    strncpy_s(imei, imei_size, start, len);
+    imei[len] = '\0';
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 解析AT+CSQ响应获取信号强度
+ */
+static errcode_t n706a_parse_signal_response(const char *response, int *signal)
+{
+    if (!response || !signal) {
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    const char *start = strstr(response, "+CSQ: ");
+    if (start == NULL) {
+        return ERRCODE_FAIL;
+    }
+    
+    start += 6; // 跳过"+CSQ: "
+    int sig, ber;
+    if (sscanf_s(start, "%d,%d", &sig, &ber) == 2) {
+        *signal = sig;
+        return ERRCODE_SUCC;
+    }
+    
+    return ERRCODE_FAIL;
+}
+
+/**
+ * @brief 解析AT+COPS响应获取运营商信息
+ */
+static errcode_t n706a_parse_operator_response(const char *response, char *operator, size_t operator_size)
+{
+    if (!response || !operator || operator_size == 0) {
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    const char *start = strstr(response, "+COPS: ");
+    if (start == NULL) {
+        return ERRCODE_FAIL;
+    }
+    
+    // 查找第一个引号
+    const char *quote_start = strchr(start, '"');
+    if (quote_start == NULL) {
+        return ERRCODE_FAIL;
+    }
+    quote_start++; // 跳过引号
+    
+    // 查找第二个引号
+    const char *quote_end = strchr(quote_start, '"');
+    if (quote_end == NULL) {
+        return ERRCODE_FAIL;
+    }
+    
+    size_t len = quote_end - quote_start;
+    if (len >= operator_size) {
+        len = operator_size - 1;
+    }
+    
+    strncpy_s(operator, operator_size, quote_start, len);
+    operator[len] = '\0';
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 解析AT+CCID响应获取ICCID
+ */
+static errcode_t n706a_parse_iccid_response(const char *response, char *iccid, size_t iccid_size)
+{
+    if (!response || !iccid || iccid_size == 0) {
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    const char *start = strstr(response, "+CCID: ");
+    if (start == NULL) {
+        return ERRCODE_FAIL;
+    }
+    
+    start += 7; // 跳过"+CCID: "
+    const char *end = strstr(start, "\r");
+    if (end == NULL) {
+        end = strstr(start, "\n");
+    }
+    if (end == NULL) {
+        return ERRCODE_FAIL;
+    }
+    
+    size_t len = end - start;
+    if (len >= iccid_size) {
+        len = iccid_size - 1;
+    }
+    
+    strncpy_s(iccid, iccid_size, start, len);
+    iccid[len] = '\0';
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 解析AT+GMR响应获取版本信息
+ */
+static errcode_t n706a_parse_version_response(const char *response, char *version, size_t version_size)
+{
+    if (!response || !version || version_size == 0) {
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    const char *start = strstr(response, "+GMR: ");
+    if (start == NULL) {
+        return ERRCODE_FAIL;
+    }
+    
+    start += 6; // 跳过"+GMR: "
+    const char *end = strstr(start, "\r");
+    if (end == NULL) {
+        end = strstr(start, "\n");
+    }
+    if (end == NULL) {
+        return ERRCODE_FAIL;
+    }
+    
+    size_t len = end - start;
+    if (len >= version_size) {
+        len = version_size - 1;
+    }
+    
+    strncpy_s(version, version_size, start, len);
+    version[len] = '\0';
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 解析AT+CREG或AT+CEREG响应获取网络注册状态
+ */
+static errcode_t n706a_parse_network_status_response(const char *response, uint8_t *network_status)
+{
+    if (!response || !network_status) {
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    const char *start = strstr(response, "+CREG: ");
+    if (start == NULL) {
+        start = strstr(response, "+CEREG: ");
+        if (start == NULL) {
+            return ERRCODE_FAIL;
+        }
+        start += 8; // 跳过"+CEREG: "
+    } else {
+        start += 7; // 跳过"+CREG: "
+    }
+    
+    int n, stat;
+    if (sscanf_s(start, "%d,%d", &n, &stat) == 2) {
+        *network_status = (uint8_t)stat;
+        return ERRCODE_SUCC;
+    }
+    
+    return ERRCODE_FAIL;
+}
+
+/* ========== Runtime Status Update Functions ========== */
+
+/**
+ * @brief 通过AT命令获取IMEI号并更新runtime状态
+ */
+static errcode_t n706a_api_update_imei(void)
+{
+    char imei_temp[32] = {0};
+    n706a_at_response_t response;
+    
+    // 发送AT+CGSN命令
+    n706a_at_error_t ret = n706a_at_send_command("AT+CGSN", "OK", 1000, &response);
+    if (ret != N706A_AT_OK) {
+        PPP_DEBUG_ERROR("Failed to send AT+CGSN command");
+        return ERRCODE_FAIL;
+    }
+    
+    if (n706a_parse_imei_response(response.response, imei_temp, sizeof(imei_temp)) != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to parse IMEI response");
+        return ERRCODE_FAIL;
+    }
+    
+    // 更新runtime状态
+    cat1_api_runtime_set_cat1_imei(imei_temp);
+    PPP_DEBUG_CRITICAL("Updated IMEI: %s", imei_temp);
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 通过AT命令获取信号强度并更新runtime状态
+ */
+static errcode_t n706a_api_update_signal(void)
+{
+    int signal = 99; // 默认无信号
+    n706a_at_response_t response;
+    
+    // 发送AT+CSQ命令
+    n706a_at_error_t ret = n706a_at_send_command("AT+CSQ", "OK", 1000, &response);
+    if (ret != N706A_AT_OK) {
+        PPP_DEBUG_ERROR("Failed to send AT+CSQ command");
+        return ERRCODE_FAIL;
+    }
+    
+    if (n706a_parse_signal_response(response.response, &signal) != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to parse signal response");
+        return ERRCODE_FAIL;
+    }
+    
+    // 更新runtime状态
+    cat1_api_runtime_set_cat1_signal(signal);
+    PPP_DEBUG_CRITICAL("Updated signal strength: %d", signal);
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 通过AT命令获取运营商信息并更新runtime状态
+ */
+static errcode_t n706a_api_update_operator(void)
+{
+    char operator_temp[64] = {0};
+    n706a_at_response_t response;
+    
+    // 发送AT+COPS?命令
+    n706a_at_error_t ret = n706a_at_send_command("AT+COPS?", "OK", 10000, &response);
+    if (ret != N706A_AT_OK) {
+        PPP_DEBUG_ERROR("Failed to send AT+COPS command");
+        return ERRCODE_FAIL;
+    }
+    
+    if (n706a_parse_operator_response(response.response, operator_temp, sizeof(operator_temp)) != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to parse operator response");
+        return ERRCODE_FAIL;
+    }
+    
+    // 更新runtime状态
+    cat1_api_runtime_set_cat1_operator(operator_temp);
+    PPP_DEBUG_CRITICAL("Updated operator: %s", operator_temp);
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 通过AT命令获取ICCID并更新runtime状态
+ */
+static errcode_t n706a_api_update_iccid(void)
+{
+    char iccid_temp[32] = {0};
+    n706a_at_response_t response;
+    
+    // 发送AT+CCID命令
+    n706a_at_error_t ret = n706a_at_send_command("AT+CCID", "OK", 5000, &response);
+    if (ret != N706A_AT_OK) {
+        PPP_DEBUG_ERROR("Failed to send AT+CCID command");
+        return ERRCODE_FAIL;
+    }
+    
+    if (n706a_parse_iccid_response(response.response, iccid_temp, sizeof(iccid_temp)) != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to parse ICCID response");
+        return ERRCODE_FAIL;
+    }
+    
+    // 更新runtime状态
+    cat1_api_runtime_set_cat1_iccid(iccid_temp);
+    PPP_DEBUG_CRITICAL("Updated ICCID: %s", iccid_temp);
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 通过AT命令获取版本信息并更新runtime状态
+ */
+static errcode_t n706a_api_update_version(void)
+{
+    char version_temp[64] = {0};
+    n706a_at_response_t response;
+    
+    // 发送AT+GMR命令
+    n706a_at_error_t ret = n706a_at_send_command("AT+GMR", "OK", 5000, &response);
+    if (ret != N706A_AT_OK) {
+        PPP_DEBUG_ERROR("Failed to send AT+GMR command");
+        return ERRCODE_FAIL;
+    }
+    
+    if (n706a_parse_version_response(response.response, version_temp, sizeof(version_temp)) != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to parse version response");
+        return ERRCODE_FAIL;
+    }
+    
+    // 更新runtime状态
+    cat1_api_runtime_set_cat1_modemver(version_temp);
+    PPP_DEBUG_CRITICAL("Updated modem version: %s", version_temp);
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 通过AT命令获取网络注册状态并更新runtime状态
+ */
+static errcode_t n706a_api_update_network_status(void)
+{
+    uint8_t network_status = 0;
+    n706a_at_response_t response;
+    errcode_t ret;
+    
+    // 先尝试AT+CREG
+    n706a_at_error_t at_ret = n706a_at_send_command("AT+CREG?", "OK", 5000, &response);
+    if (at_ret == N706A_AT_OK) {
+        ret = n706a_parse_network_status_response(response.response, &network_status);
+        if (ret == ERRCODE_SUCC) {
+            // 根据网络注册状态设置网络类型
+            cat1_api_runtime_set_cat1_networktype(network_status);
+            PPP_DEBUG_CRITICAL("Updated network status (CREG): %d", network_status);
+            return ERRCODE_SUCC;
+        }
+    }
+    
+    // 如果CREG失败,尝试AT+CEREG
+    at_ret = n706a_at_send_command("AT+CEREG?", "OK", 5000, &response);
+    if (at_ret != N706A_AT_OK) {
+        PPP_DEBUG_ERROR("Failed to send AT+CEREG command");
+        return ERRCODE_FAIL;
+    }
+    
+    ret = n706a_parse_network_status_response(response.response, &network_status);
+    if (ret != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to parse network status response");
+        return ret;
+    }
+    
+    // 根据网络注册状态设置网络类型
+    cat1_api_runtime_set_cat1_networktype(network_status);
+    PPP_DEBUG_CRITICAL("Updated network status (CEREG): %d", network_status);
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 获取SIM卡状态并更新runtime状态
+ */
+static errcode_t n706a_api_update_sim_status(void)
+{
+    n706a_at_response_t response;
+    
+    // 通过AT+CCID命令检查SIM卡状态
+    n706a_at_error_t ret = n706a_at_send_command("AT+CCID", "OK", 1000, &response);
+    if (ret != N706A_AT_OK || !response.success) {
+        // 如果CCID命令失败,说明SIM卡可能未插入或有问题
+        cat1_api_runtime_set_cat1_simstat(0); // 0表示SIM卡异常
+        PPP_DEBUG_ERROR("SIM card not detected or error");
+        return ERRCODE_FAIL;
+    }
+    
+    // 检查响应中是否包含ERROR
+    if (strstr(response.response, "ERROR") != NULL) {
+        cat1_api_runtime_set_cat1_simstat(0); // 0表示SIM卡异常
+        PPP_DEBUG_ERROR("SIM card error");
+        return ERRCODE_FAIL;
+    }
+    
+    // 如果CCID命令成功,说明SIM卡正常
+    cat1_api_runtime_set_cat1_simstat(1); // 1表示SIM卡正常
+    PPP_DEBUG_CRITICAL("SIM card detected and normal");
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 更新所有runtime变量值
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t n706a_api_update_all_runtime_status(void)
+{
+    errcode_t ret = ERRCODE_SUCC;
+    
+    PPP_DEBUG_INFO("Updating all N706A runtime status...");
+    
+    // 检查模块是否已开机
+    if (!cat1_api_runtime_get_cat1_powerstat()) {
+        PPP_DEBUG_ERROR("Cat1 not powered on, cannot update runtime status");
+        return ERRCODE_FAIL;
+    }
+    
+    // 更新IMEI
+    PPP_DEBUG_CRITICAL("Step 1: Starting IMEI update...");
+    if (n706a_api_update_imei() != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to update IMEI");
+        ret = ERRCODE_FAIL;
+    } else {
+        PPP_DEBUG_CRITICAL("Step 1: IMEI update completed successfully");
+    }
+    
+    // 更新信号强度
+    PPP_DEBUG_CRITICAL("Step 2: Starting signal strength update...");
+    if (n706a_api_update_signal() != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to update signal");
+        ret = ERRCODE_FAIL;
+    } else {
+        PPP_DEBUG_CRITICAL("Step 2: Signal strength update completed successfully");
+    }
+    
+    // 更新运营商信息
+    PPP_DEBUG_CRITICAL("Step 3: Starting operator update...");
+    if (n706a_api_update_operator() != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to update operator");
+        ret = ERRCODE_FAIL;
+    }
+    
+    // 更新ICCID
+    if (n706a_api_update_iccid() != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to update ICCID");
+        ret = ERRCODE_FAIL;
+    }
+    
+    // 更新SIM卡状态
+    if (n706a_api_update_sim_status() != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to update SIM status");
+        ret = ERRCODE_FAIL;
+    }
+    
+    // 更新网络状态
+    if (n706a_api_update_network_status() != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to update network status");
+        ret = ERRCODE_FAIL;
+    }
+    
+    // 更新版本信息
+    if (n706a_api_update_version() != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to update version");
+        ret = ERRCODE_FAIL;
+    }
+    
+    PPP_DEBUG_INFO("N706A runtime status update completed");
+    return ret;
+}
+
+/**
+ * @brief 动态设置N706A模块波特率(在所有模式下)
+ * 
+ * @param baudrate 目标波特率
+ * @return ERRCODE_SUCC 成功,其他值失败
+ */
+errcode_t n706a_api_set_baudrate_in_all_mode(uint32_t baudrate)
+{
+    PPP_DEBUG_INFO("=== Starting baudrate change to %u ===", baudrate);
+    
+    // 使用N706A的AT命令接口设置波特率
+    n706a_at_error_t ret = n706a_at_set_baudrate(baudrate);
+    
+    if (ret != N706A_AT_OK) {
+        PPP_DEBUG_WARN("First attempt to set baudrate failed, retrying...");
+        
+        // 重试一次
+        ret = n706a_at_set_baudrate(baudrate);
+        if (ret != N706A_AT_OK) {
+            PPP_DEBUG_ERROR("Failed to set baudrate %u after retry (error: %d)", baudrate, ret);
+            return ERRCODE_FAIL;
+        } else {
+            PPP_DEBUG_INFO("Baudrate set successfully on retry");
+        }
+    } else {
+        PPP_DEBUG_INFO("Baudrate set successfully: %u", baudrate);
+    }
+    
+    PPP_DEBUG_INFO("=== Baudrate change completed successfully ===");
+    return ERRCODE_SUCC;
+}
+
index 2d9639d..219bf67 100644 (file)
@@ -8,12 +8,22 @@
  */
 
 #include "n706a_tcp_client.h"
-#include "ppp_at_handler.h"
+#include "n706a_at_handler.h"
 #include "ppp_types.h"
+#include "ppp_serial.h"
+#include "ppp_debug.h"
+#include "lock/osal_mutex.h"
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 
+/* ========== 全局socket管理 ========== */
+#define N706A_MAX_SOCKETS 6  // N706A支持0-5共6个socket
+
+static n706a_tcp_socket_t *g_tcp_sockets[N706A_MAX_SOCKETS] = {NULL};
+static osal_mutex g_socket_table_mutex;
+static bool g_socket_table_initialized = false;
+
 /* ========== 私有函数声明 ========== */
 
 #ifdef N706A_SSL_USE_MBEDTLS
@@ -41,6 +51,25 @@ n706a_tcp_result_t n706a_tcp_socket_create(n706a_tcp_socket_t *sock, int socket_
     sock->is_ssl = false;
     sock->timeout_ms = 15000;  // 默认15秒超时
     
+    // 初始化URC接收缓存(2KB)
+    n706a_tcp_result_t ret = n706a_tcp_init_urc_buffer(sock, 2048);
+    if (ret != N706A_TCP_SUCCESS) {
+        PPP_DEBUG_ERROR("Failed to init URC buffer for socket %d", socket_id);
+        return ret;
+    }
+    
+    // 注册到全局socket表
+    if (!g_socket_table_initialized) {
+        osal_mutex_init(&g_socket_table_mutex);
+        g_socket_table_initialized = true;
+    }
+    
+    osal_mutex_lock(&g_socket_table_mutex);
+    g_tcp_sockets[socket_id] = sock;
+    osal_mutex_unlock(&g_socket_table_mutex);
+    
+    PPP_DEBUG_INFO("Socket %d created with URC buffer", socket_id);
+    
 #ifdef N706A_SSL_USE_AT_COMMAND
     sock->ssl_version = 3;  // 默认TLS 1.2
     sock->auth_mode = 1;    // 默认服务器认证
@@ -81,17 +110,17 @@ n706a_tcp_result_t n706a_tcp_config_ssl(n706a_tcp_socket_t *sock,
         
         /* 设置SSL版本 */
         snprintf(at_cmd, sizeof(at_cmd), "AT+SSLTCPCFG=\"sslversion\",%d", ssl_version);
-        ppp_at_response_t response;
-        ppp_at_send_command(at_cmd, NULL, 5000, &response);
+        n706a_at_response_t response;
+        n706a_at_send_command(at_cmd, NULL, 5000, &response);
         
         /* 设置认证模式 */
         snprintf(at_cmd, sizeof(at_cmd), "AT+SSLTCPCFG=\"authmode\",%d", auth_mode);
-        ppp_at_send_command(at_cmd, NULL, 5000, &response);
+        n706a_at_send_command(at_cmd, NULL, 5000, &response);
         
         /* 设置CA证书 */
         if (ca_cert && strlen(ca_cert) > 0) {
             snprintf(at_cmd, sizeof(at_cmd), "AT+SSLTCPCFG=\"cacert\",\"%s\"", ca_cert);
-            ppp_at_send_command(at_cmd, NULL, 5000, &response);
+            n706a_at_send_command(at_cmd, NULL, 5000, &response);
         }
     }
 #endif
@@ -179,8 +208,8 @@ n706a_tcp_result_t n706a_tcp_connect(n706a_tcp_socket_t *sock,
     sock->timeout_ms = timeout_ms;
     
     char at_cmd[256];
-    ppp_at_response_t response;
-    ppp_error_t ret;
+    n706a_at_response_t response;
+    n706a_at_error_t ret;
     
     sock->state = N706A_TCP_STATE_CONNECTING;
     
@@ -194,13 +223,25 @@ n706a_tcp_result_t n706a_tcp_connect(n706a_tcp_socket_t *sock,
                 port,
                 sock->auth_mode);
         
-        ret = ppp_at_send_command(at_cmd, NULL, timeout_ms, &response);
+        ret = n706a_at_send_command(at_cmd, NULL, timeout_ms, &response);
+        
+        PPP_DEBUG_CRITICAL("[N706A_TCP] AT+SSLTCPSETUP response: ret=%d, len=%u", ret, response.length);
+        if (response.length > 0) {
+            PPP_DEBUG_CRITICAL("[N706A_TCP] Response: %s", response.response);
+        }
         
-        if (ret == PPP_ERR_OK && response.length > 0 &&
-            strstr(response.response, "+SSLTCPSETUP:") &&
-            strstr(response.response, ",OK")) {
+        /* 检查响应是否包含OK且不包含ERROR */
+        if (ret == N706A_AT_OK && response.length > 0 &&
+            strstr(response.response, "OK") &&
+            !strstr(response.response, "ERROR")) {
+            PPP_DEBUG_CRITICAL("[N706A_TCP] SSL TCP connection established successfully!");
             sock->state = N706A_TCP_STATE_CONNECTED;
             return N706A_TCP_SUCCESS;
+        } else {
+            PPP_DEBUG_ERROR("[N706A_TCP] SSL TCP connection failed! Response: %s", 
+                           response.length > 0 ? response.response : "(empty)");
+            sock->state = N706A_TCP_STATE_ERROR;
+            return N706A_TCP_ECONNREF;
         }
     } else {
         /* 普通TCP */
@@ -210,13 +251,25 @@ n706a_tcp_result_t n706a_tcp_connect(n706a_tcp_socket_t *sock,
                 host,
                 port);
         
-        ret = ppp_at_send_command(at_cmd, NULL, timeout_ms, &response);
+        ret = n706a_at_send_command(at_cmd, NULL, timeout_ms, &response);
         
-        if (ret == PPP_ERR_OK && response.length > 0 &&
-            strstr(response.response, "+TCPSETUP:") &&
-            strstr(response.response, ",OK")) {
+        PPP_DEBUG_CRITICAL("[N706A_TCP] AT+TCPSETUP response: ret=%d, len=%u", ret, response.length);
+        if (response.length > 0) {
+            PPP_DEBUG_CRITICAL("[N706A_TCP] Response: %s", response.response);
+        }
+        
+        /* 检查响应是否包含OK且不包含ERROR */
+        if (ret == N706A_AT_OK && response.length > 0 &&
+            strstr(response.response, "OK") &&
+            !strstr(response.response, "ERROR")) {
+            PPP_DEBUG_CRITICAL("[N706A_TCP] TCP connection established successfully!");
             sock->state = N706A_TCP_STATE_CONNECTED;
             return N706A_TCP_SUCCESS;
+        } else {
+            PPP_DEBUG_ERROR("[N706A_TCP] TCP connection failed! Response: %s", 
+                           response.length > 0 ? response.response : "(empty)");
+            sock->state = N706A_TCP_STATE_ERROR;
+            return N706A_TCP_ECONNREF;
         }
     }
 #endif
@@ -231,48 +284,88 @@ n706a_tcp_result_t n706a_tcp_connect(n706a_tcp_socket_t *sock,
             host,
             port);
     
-    ret = ppp_at_send_command(at_cmd, NULL, timeout_ms, &response);
+    ret = n706a_at_send_command(at_cmd, NULL, timeout_ms, &response);
     
-    if (ret != PPP_ERR_OK || response.length == 0 ||
-        !strstr(response.response, "+TCPSETUP:") ||
-        !strstr(response.response, ",OK")) {
+    PPP_DEBUG_CRITICAL("[N706A_TCP] AT+TCPSETUP (mbedtls mode) response: ret=%d, len=%u", ret, response.length);
+    if (response.length > 0) {
+        PPP_DEBUG_CRITICAL("[N706A_TCP] Response: %s", response.response);
+    }
+    
+    /* N706A的AT+TCPSETUP成功响应格式:
+     * AT+TCPSETUP=0,host,port
+     * OK
+     * 
+     * 只需检查是否包含"OK"且不包含"ERROR"
+     */
+    if (ret != N706A_AT_OK || response.length == 0 ||
+        !strstr(response.response, "OK") ||
+        strstr(response.response, "ERROR")) {
+        PPP_DEBUG_ERROR("[N706A_TCP] TCP connection failed! Response: %s", 
+                       response.length > 0 ? response.response : "(empty)");
         sock->state = N706A_TCP_STATE_ERROR;
         return N706A_TCP_ECONNREF;
     }
     
+    PPP_DEBUG_CRITICAL("[N706A_TCP] TCP connection established successfully!");
+    
+    /* TCP连接已建立,标记为已连接(如果不使用SSL) */
+    if (!use_ssl) {
+        sock->state = N706A_TCP_STATE_CONNECTED;
+        return N706A_TCP_SUCCESS;
+    }
+    
     /* 2. 如果使用SSL,进行SSL握手 */
     if (use_ssl) {
+        PPP_DEBUG_CRITICAL("[N706A_TCP] Starting SSL handshake (mbedtls)...");
+        
         n706a_tcp_result_t ssl_ret = tcp_mbedtls_init_ssl(sock);
         if (ssl_ret != N706A_TCP_SUCCESS) {
+            PPP_DEBUG_ERROR("[N706A_TCP] Failed to initialize SSL context!");
             n706a_tcp_close(sock);
             return ssl_ret;
         }
         
+        PPP_DEBUG_CRITICAL("[N706A_TCP] SSL context initialized, setting hostname: %s", host);
+        
         /* 设置主机名(用于SNI) */
         mbedtls_ssl_set_hostname(&sock->ssl, host);
         
         /* 执行SSL握手 */
+        PPP_DEBUG_CRITICAL("[N706A_TCP] Performing SSL handshake...");
         int handshake_ret;
+        int handshake_attempts = 0;
         while ((handshake_ret = mbedtls_ssl_handshake(&sock->ssl)) != 0) {
+            handshake_attempts++;
             if (handshake_ret != MBEDTLS_ERR_SSL_WANT_READ &&
                 handshake_ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
                 /* 握手失败 */
+                PPP_DEBUG_ERROR("[N706A_TCP] SSL handshake failed after %d attempts! Error: -0x%04x", 
+                               handshake_attempts, -handshake_ret);
                 tcp_mbedtls_cleanup_ssl(sock);
                 n706a_tcp_close(sock);
                 sock->state = N706A_TCP_STATE_ERROR;
                 return N706A_TCP_ERROR;
             }
+            
+            if (handshake_attempts % 10 == 0) {
+                PPP_DEBUG_DEBUG("[N706A_TCP] SSL handshake in progress... (attempt %d)", handshake_attempts);
+            }
         }
         
+        PPP_DEBUG_CRITICAL("[N706A_TCP] SSL handshake completed successfully after %d attempts", handshake_attempts);
+        
         /* 验证证书 */
         uint32_t flags = mbedtls_ssl_get_verify_result(&sock->ssl);
         if (flags != 0 && sock->auth_mode != MBEDTLS_SSL_VERIFY_NONE) {
             /* 证书验证失败 */
+            PPP_DEBUG_ERROR("[N706A_TCP] Certificate verification failed! Flags: 0x%08x", flags);
             tcp_mbedtls_cleanup_ssl(sock);
             n706a_tcp_close(sock);
             sock->state = N706A_TCP_STATE_ERROR;
             return N706A_TCP_ERROR;
         }
+        
+        PPP_DEBUG_CRITICAL("[N706A_TCP] Certificate verified successfully");
     }
 #endif
     
@@ -311,7 +404,7 @@ n706a_tcp_result_t n706a_tcp_send(n706a_tcp_socket_t *sock,
     
     /* AT指令模式或普通TCP */
     char at_cmd[64];
-    ppp_at_response_t response;
+    n706a_at_response_t response;
     
 #ifdef N706A_SSL_USE_AT_COMMAND
     if (sock->is_ssl) {
@@ -325,14 +418,14 @@ n706a_tcp_result_t n706a_tcp_send(n706a_tcp_socket_t *sock,
     }
     
     /* 发送命令,等待'>'提示符 */
-    ppp_error_t ret = ppp_at_send_command(at_cmd, NULL, 5000, &response);
-    if (ret != PPP_ERR_OK) {
+    n706a_at_error_t ret = n706a_at_send_command(at_cmd, NULL, 5000, &response);
+    if (ret != N706A_AT_OK) {
         return N706A_TCP_ERROR;
     }
     
     /* 发送实际数据 */
     ret = ppp_at_send_raw_data(data, len, sock->timeout_ms);
-    if (ret != PPP_ERR_OK) {
+    if (ret != N706A_AT_OK) {
         return N706A_TCP_ERROR;
     }
     
@@ -357,6 +450,29 @@ n706a_tcp_result_t n706a_tcp_recv(n706a_tcp_socket_t *sock,
         return N706A_TCP_ENOTCONN;
     }
     
+    /* 优先从URC缓存读取数据(如果有) */
+    if (sock->urc_recv_buffer && sock->urc_recv_mutex && sock->urc_recv_length > 0) {
+        osal_mutex *mutex = (osal_mutex *)sock->urc_recv_mutex;
+        osal_mutex_lock(mutex);
+        
+        size_t copy_len = (sock->urc_recv_length < len) ? sock->urc_recv_length : len;
+        memcpy(buffer, sock->urc_recv_buffer, copy_len);
+        
+        // 移动剩余数据到缓冲区开头
+        if (copy_len < sock->urc_recv_length) {
+            memmove(sock->urc_recv_buffer, sock->urc_recv_buffer + copy_len, 
+                   sock->urc_recv_length - copy_len);
+        }
+        sock->urc_recv_length -= copy_len;
+        
+        osal_mutex_unlock(mutex);
+        
+        *received = copy_len;
+        PPP_DEBUG_DEBUG("Read from URC buffer: socket=%d, len=%u, remaining=%u", 
+                       sock->socket_id, (unsigned int)copy_len, (unsigned int)sock->urc_recv_length);
+        return N706A_TCP_SUCCESS;
+    }
+    
 #ifdef N706A_SSL_USE_MBEDTLS
     /* mbedtls模式:通过SSL接收 */
     if (sock->is_ssl && sock->ssl_initialized) {
@@ -377,7 +493,7 @@ n706a_tcp_result_t n706a_tcp_recv(n706a_tcp_socket_t *sock,
     
     /* AT指令模式或普通TCP */
     char at_cmd[64];
-    ppp_at_response_t response;
+    n706a_at_response_t response;
     
 #ifdef N706A_SSL_USE_AT_COMMAND
     if (sock->is_ssl) {
@@ -390,8 +506,8 @@ n706a_tcp_result_t n706a_tcp_recv(n706a_tcp_socket_t *sock,
                 sock->socket_id, len);
     }
     
-    ppp_error_t ret = ppp_at_send_command(at_cmd, NULL, timeout_ms, &response);
-    if (ret != PPP_ERR_OK) {
+    n706a_at_error_t ret = n706a_at_send_command(at_cmd, NULL, timeout_ms, &response);
+    if (ret != N706A_AT_OK) {
         return N706A_TCP_ETIMEDOUT;
     }
     
@@ -440,7 +556,7 @@ n706a_tcp_result_t n706a_tcp_close(n706a_tcp_socket_t *sock)
     
     /* 发送关闭命令 */
     char at_cmd[32];
-    ppp_at_response_t response;
+    n706a_at_response_t response;
     
 #ifdef N706A_SSL_USE_AT_COMMAND
     if (sock->is_ssl) {
@@ -451,11 +567,23 @@ n706a_tcp_result_t n706a_tcp_close(n706a_tcp_socket_t *sock)
         snprintf(at_cmd, sizeof(at_cmd), "AT+TCPCLOSE=%d", sock->socket_id);
     }
     
-    ppp_at_send_command(at_cmd, NULL, 5000, &response);
+    n706a_at_send_command(at_cmd, NULL, 5000, &response);
     
     sock->state = N706A_TCP_STATE_CLOSED;
     sock->is_ssl = false;
     
+    // 从全局socket表中移除
+    if (g_socket_table_initialized) {
+        osal_mutex_lock(&g_socket_table_mutex);
+        g_tcp_sockets[sock->socket_id] = NULL;
+        osal_mutex_unlock(&g_socket_table_mutex);
+    }
+    
+    // 释放URC接收缓存
+    n706a_tcp_free_urc_buffer(sock);
+    
+    PPP_DEBUG_INFO("Socket %d closed and URC buffer freed", sock->socket_id);
+    
     return N706A_TCP_SUCCESS;
 }
 
@@ -600,15 +728,15 @@ static int tcp_mbedtls_send_callback(void *ctx, const unsigned char *buf, size_t
     snprintf(at_cmd, sizeof(at_cmd), "AT+TCPSEND=%d,%zu",
             sock->socket_id, len);
     
-    ppp_at_response_t response;
-    ppp_error_t ret = ppp_at_send_command(at_cmd, NULL, 5000, &response);
-    if (ret != PPP_ERR_OK) {
+    n706a_at_response_t response;
+    n706a_at_error_t ret = n706a_at_send_command(at_cmd, NULL, 5000, &response);
+    if (ret != N706A_AT_OK) {
         return MBEDTLS_ERR_NET_SEND_FAILED;
     }
     
     /* 发送数据 */
     ret = ppp_at_send_raw_data(buf, len, sock->timeout_ms);
-    if (ret != PPP_ERR_OK) {
+    if (ret != N706A_AT_OK) {
         return MBEDTLS_ERR_NET_SEND_FAILED;
     }
     
@@ -631,9 +759,9 @@ static int tcp_mbedtls_recv_callback(void *ctx, unsigned char *buf, size_t len)
     snprintf(at_cmd, sizeof(at_cmd), "AT+TCPREAD=%d,%zu",
             sock->socket_id, len);
     
-    ppp_at_response_t response;
-    ppp_error_t ret = ppp_at_send_command(at_cmd, NULL, sock->timeout_ms, &response);
-    if (ret != PPP_ERR_OK) {
+    n706a_at_response_t response;
+    n706a_at_error_t ret = n706a_at_send_command(at_cmd, NULL, sock->timeout_ms, &response);
+    if (ret != N706A_AT_OK) {
         return MBEDTLS_ERR_NET_RECV_FAILED;
     }
     
@@ -658,3 +786,118 @@ static int tcp_mbedtls_recv_callback(void *ctx, unsigned char *buf, size_t len)
 
 #endif /* N706A_SSL_USE_MBEDTLS */
 
+/* ========== URC接收支持 ========== */
+
+/**
+ * @brief 初始化TCP socket的URC接收缓存
+ */
+n706a_tcp_result_t n706a_tcp_init_urc_buffer(n706a_tcp_socket_t *sock, size_t buffer_size)
+{
+    if (!sock || buffer_size == 0) {
+        return N706A_TCP_EINVAL;
+    }
+    
+    // 分配缓冲区
+    sock->urc_recv_buffer = (uint8_t *)malloc(buffer_size);
+    if (!sock->urc_recv_buffer) {
+        PPP_DEBUG_ERROR("Failed to allocate URC buffer (%u bytes)", (unsigned int)buffer_size);
+        return N706A_TCP_ENOBUFS;
+    }
+    
+    sock->urc_recv_capacity = buffer_size;
+    sock->urc_recv_length = 0;
+    
+    // 初始化互斥锁
+    osal_mutex *mutex = (osal_mutex *)malloc(sizeof(osal_mutex));
+    if (!mutex) {
+        free(sock->urc_recv_buffer);
+        sock->urc_recv_buffer = NULL;
+        return N706A_TCP_ENOBUFS;
+    }
+    
+    osal_mutex_init(mutex);
+    sock->urc_recv_mutex = mutex;
+    
+    PPP_DEBUG_DEBUG("URC buffer initialized: socket=%d, size=%u", 
+                   sock->socket_id, (unsigned int)buffer_size);
+    
+    return N706A_TCP_SUCCESS;
+}
+
+/**
+ * @brief 释放TCP socket的URC接收缓存
+ */
+void n706a_tcp_free_urc_buffer(n706a_tcp_socket_t *sock)
+{
+    if (!sock) {
+        return;
+    }
+    
+    if (sock->urc_recv_mutex) {
+        osal_mutex *mutex = (osal_mutex *)sock->urc_recv_mutex;
+        osal_mutex_destroy(mutex);
+        free(mutex);
+        sock->urc_recv_mutex = NULL;
+    }
+    
+    if (sock->urc_recv_buffer) {
+        free(sock->urc_recv_buffer);
+        sock->urc_recv_buffer = NULL;
+    }
+    
+    sock->urc_recv_capacity = 0;
+    sock->urc_recv_length = 0;
+    
+    PPP_DEBUG_DEBUG("URC buffer freed: socket=%d", sock->socket_id);
+}
+
+/**
+ * @brief 全局TCP URC数据接收回调(由n706a_at_handler调用)
+ */
+void n706a_tcp_on_urc_received(int socket_id, const uint8_t *data, size_t length)
+{
+    if (socket_id < 0 || socket_id >= N706A_MAX_SOCKETS || !data || length == 0) {
+        PPP_DEBUG_ERROR("Invalid URC parameters: socket=%d, len=%u", socket_id, (unsigned int)length);
+        return;
+    }
+    
+    // 获取socket
+    osal_mutex_lock(&g_socket_table_mutex);
+    n706a_tcp_socket_t *sock = g_tcp_sockets[socket_id];
+    osal_mutex_unlock(&g_socket_table_mutex);
+    
+    if (!sock) {
+        PPP_DEBUG_WARN("URC for unregistered socket %d, dropping %u bytes", socket_id, (unsigned int)length);
+        return;
+    }
+    
+    if (!sock->urc_recv_buffer || !sock->urc_recv_mutex) {
+        PPP_DEBUG_ERROR("URC buffer not initialized for socket %d", socket_id);
+        return;
+    }
+    
+    // 写入缓冲区(线程安全)
+    osal_mutex *mutex = (osal_mutex *)sock->urc_recv_mutex;
+    osal_mutex_lock(mutex);
+    
+    size_t available_space = sock->urc_recv_capacity - sock->urc_recv_length;
+    size_t copy_len = (length <= available_space) ? length : available_space;
+    
+    if (copy_len < length) {
+        PPP_DEBUG_WARN("URC buffer overflow: socket=%d, need=%u, available=%u", 
+                      socket_id, (unsigned int)length, (unsigned int)available_space);
+    }
+    
+    if (copy_len > 0) {
+        memcpy(sock->urc_recv_buffer + sock->urc_recv_length, data, copy_len);
+        sock->urc_recv_length += copy_len;
+        
+        PPP_DEBUG_INFO("URC data buffered: socket=%d, received=%u, total=%u/%u", 
+                      socket_id, (unsigned int)copy_len, 
+                      (unsigned int)sock->urc_recv_length, 
+                      (unsigned int)sock->urc_recv_capacity);
+    }
+    
+    osal_mutex_unlock(mutex);
+}
+
index 70b86a2..02e9eb9 100644 (file)
@@ -429,7 +429,12 @@ int n706a_websocket_destructor(int client_id)
  */
 static int ws_perform_handshake(n706a_websocket_client_t *client)
 {
-    char handshake_req[1024];
+    /* 动态分配握手请求缓冲区 */
+    char *handshake_req = (char *)malloc(1024);
+    if (!handshake_req) {
+        return -1;
+    }
+    
     char sec_key[25];
     
     /* 生成Sec-WebSocket-Key */
@@ -437,7 +442,7 @@ static int ws_perform_handshake(n706a_websocket_client_t *client)
     strncpy(client->sec_key, sec_key, sizeof(client->sec_key) - 1);
     
     /* 构造握手请求 */
-    int len = snprintf(handshake_req, sizeof(handshake_req),
+    int len = snprintf(handshake_req, 1024,
         "GET %s HTTP/1.1\r\n"
         "Host: %s\r\n"
         "Upgrade: websocket\r\n"
@@ -457,21 +462,27 @@ static int ws_perform_handshake(n706a_websocket_client_t *client)
                                             len,
                                             &sent);
     
+    free(handshake_req);
+    
     if (ret != N706A_TCP_SUCCESS) {
         return -1;
     }
     
-    /* 接收握手响应 */
-    uint8_t response[2048];
-    size_t received;
+    /* 动态分配响应缓冲区 */
+    uint8_t *response = (uint8_t *)malloc(2048);
+    if (!response) {
+        return -1;
+    }
     
+    size_t received;
     ret = n706a_tcp_recv(&client->tcp_sock,
                         response,
-                        sizeof(response) - 1,
+                        2048 - 1,
                         &received,
                         10000);
     
     if (ret != N706A_TCP_SUCCESS || received == 0) {
+        free(response);
         return -1;
     }
     
@@ -481,6 +492,7 @@ static int ws_perform_handshake(n706a_websocket_client_t *client)
     if (!strstr((char *)response, "HTTP/1.1 101") ||
         !strstr((char *)response, "Upgrade: websocket") ||
         !strstr((char *)response, "Connection: Upgrade")) {
+        free(response);
         return -1;
     }
     
@@ -494,10 +506,12 @@ static int ws_perform_handshake(n706a_websocket_client_t *client)
         n706a_websocket_calculate_accept(sec_key, expected_accept);
         
         if (strncmp(accept_start, expected_accept, strlen(expected_accept)) != 0) {
+            free(response);
             return -1;  // Accept值不匹配
         }
     }
     
+    free(response);
     return 0;
 }
 
diff --git a/code/sdk/zhihui/n706a_net/src/ppp_cat1_api.c b/code/sdk/zhihui/n706a_net/src/ppp_cat1_api.c
new file mode 100644 (file)
index 0000000..28b4d8f
--- /dev/null
@@ -0,0 +1,512 @@
+/*
+ * @brief PPP模块的cat1 API兼容实现
+ * @description 实现与cat1Service相同的接口,让UI和其他服务无需修改
+ * Copyright (c) CompanyNameMagicTag 2024-2024. All rights reserved.
+ */
+
+#include "ppp_power_ctl.h"
+#include "ppp_debug.h"
+#include "ppp_types.h"
+#include "errcode.h"
+#include "securec.h"
+#include "platform_core.h"
+#include <string.h>
+#include "pm_definition.h"
+#include "pm.h"
+
+// 兼容cat1Service的类型定义
+typedef enum _4g_message {
+    MESSAGE_4G_POWERON,//无参数 (BOOTUP)
+    MESSAGE_4G_POWEROFF,//无参数
+    MESSAGE_4G_NETWORK_CONNECTED,//无参数
+    MESSAGE_4G_NETWORK_DISCONNECTED,//无参数
+    MESSAGE_4G_NETWORK_STAT_CHANGED,//含signal,sim,运营商,
+    MESSAGE_4G_CALL_COMMING,//带电话号
+    MESSAGE_4G_CALL_CONNECTED,//带电话号
+    MESSAGE_4G_CALL_DISCONNECTED,//带电话号
+    MESSAGE_4G_SMS_RECEIVED, //返回值为字符串
+    MESSAGE_4G_AT_RECEIVED, //返回值为字符串
+    MESSAGE_4G_TIME_SYNCED,//时间同步完成
+    MESSAGE_4G_VERSION_SYNCED,//版本同步完成
+    MESSAGE_4G_MAX,
+} MESSAGE_4G_T;
+
+typedef enum _4g_cmd {
+    CMD_4G_POWERON,//无参数
+    CMD_4G_POWEROFF,//无参数
+    CMD_4G_GET_SIGNAL,//无参数
+    CMD_4G_GET_VERSION,//无参数
+    CMD_4G_GET_TIME,//无参数
+    CMD_4G_MAKE_CALL,//需要输入参数 电话号
+    CMD_4G_ANSWER_CALL,//无参数
+    CMD_4G_HUNGUP_CALL,//无参数
+    CMD_4G_SEND_DTMF, //需要输入参数 DTMF NUM(单个数字) , 包括 0 ~ 9, * , #
+    CMD_4G_AT, //需要AT指令,要求结尾带\r\n
+    CMD_4G_MAX,
+} CMD_4G_T;
+
+typedef struct {
+    uint8_t bat_pin; //控制Cat1 battery 的gpio,没有控制,设置为 PIN_NONE 即可
+    uint8_t bat_pin_en_value;
+    uint8_t pwr_pin; //控制cat1开机键的gpio
+    uint8_t pwr_pin_en_value;
+    uint8_t reset_pin; //控制cat1重置键的gpio
+    uint8_t reset_pin_en_value;
+    uint8_t ring_pin; //cat1唤醒蓝牙用的gpio
+    uint8_t ring_pin_en_value;
+    uint8_t wakemodem_pin; //蓝牙唤醒cat1用的gpio
+    uint8_t wakemodem_pin_en_value;
+} ctl_pin_4g_t;
+
+// 消息回调函数类型
+typedef errcode_t (*f_cat1_msg_callback)(MESSAGE_4G_T msg, void *msg_buf, uint16_t msglen);
+
+// 时间控制函数类型
+typedef uint16_t (*f_get_timezone)(void);
+typedef void (*f_set_timezone)(uint16_t timezone_quarters);
+typedef uint32_t (*f_sync_time_utc)(uint32_t timestamp, uint32_t timezone_quarters);
+
+typedef struct {
+    f_get_timezone get_timezone;
+    f_set_timezone set_timezone;
+    f_sync_time_utc sync_time_utc;
+} time_ctl_funcs_t;
+
+// PPP模块的运行时状态结构(与cat1Service保持一致)
+typedef struct {
+    uint8_t cat1_powerOn;
+    uint8_t volte;
+    uint8_t network_on;
+    uint8_t cat1_network_type;
+    int sim;
+    int signal;
+    int rsrp;
+    int rsrq;
+    char opera[64];
+    char imei[32];
+    char pyVer[32];
+    char iccid[32];
+    char modemVer[64];
+} ppp_cat1_runtime_status_t;
+
+typedef struct {
+    int rsrp;
+    int rsrq;
+} ppp_cat1_signal_info_t;
+
+// PPP模块的运行时状态
+static ppp_cat1_runtime_status_t g_ppp_runtime = {0};
+
+// PPP模块的控制引脚配置
+static ppp_ctl_pin_4g_t g_ppp_ctl_pins = {0};
+
+// PPP模块的初始化状态
+static bool g_ppp_cat1_initialized = false;
+
+/********************** 电源控制接口 **********************/
+
+/**
+ * @brief cat1 开关机设置, 输入 true 开机, false 关机
+ */
+void cat1_api_enable_cat1(bool isopen)
+{
+    PPP_DEBUG_PRINT("PPP: cat1_api_enable_cat1(%s)\n", isopen ? "true" : "false");
+    
+    if (isopen) {
+        if (g_ppp_runtime.cat1_powerOn) {
+            PPP_DEBUG_PRINT("PPP: Cat1 already powered on\n");
+            return;
+        }
+        
+        // PPP模块开启4G
+        ppp_power_on_cat1();
+        g_ppp_runtime.cat1_powerOn = 1;
+        
+        // 可以在这里添加PPP特定的初始化逻辑
+        // 例如:启动PPP协议栈等
+        
+    } else {
+        if (!g_ppp_runtime.cat1_powerOn) {
+            PPP_DEBUG_PRINT("PPP: Cat1 already powered off\n");
+            return;
+        }
+        
+        // PPP模块关闭4G
+        ppp_power_off_cat1();
+        g_ppp_runtime.cat1_powerOn = 0;
+        
+        // 清理网络状态
+        g_ppp_runtime.network_on = 0;
+        g_ppp_runtime.signal = 99; // 无信号
+        g_ppp_runtime.sim = 0;
+        g_ppp_runtime.cat1_network_type = 0;
+    }
+}
+
+/**
+ * @brief cat1 唤醒设置, 输入 true 唤醒cat1 modem, false cat1 modem自动休眠
+ */
+void cat1_api_wakeup_cat1(uint8_t wakeup)
+{
+    ppp_api_wakeup_cat1(wakeup);
+}
+
+/**
+ * @brief 获取cat1是否使能(开机)状态
+ */
+bool cat1_api_is_cat1_enabled(void)
+{
+    return ppp_api_is_cat1_enabled();
+}
+
+/**
+ * @brief 获取Cat1 ICCID号
+ */
+char* cat1_api_runtime_get_cat1_iccid(void)
+{
+    return g_ppp_runtime.iccid;
+}   
+
+/**
+ * @brief 设置Cat1 ICCID号
+ */
+void cat1_api_runtime_set_cat1_iccid(char* iccid)
+{
+    if (iccid != NULL) {
+        (void)strncpy_s(g_ppp_runtime.iccid, sizeof(g_ppp_runtime.iccid), 
+                        iccid, sizeof(g_ppp_runtime.iccid) - 1);
+        g_ppp_runtime.iccid[sizeof(g_ppp_runtime.iccid) - 1] = '\0';
+    }
+}   
+
+/**
+ * @brief return cmd uart rx enable flag
+ */
+bool cat1_api_custom_is_cmd_rx_enabled(void)
+{
+    // PPP模块默认启用接收
+    return true;
+}
+
+void cat1_api_remove_cat1_vote(void)
+{
+    uint8_t cnt = pm_veto_get_id_cnt(PM_ID_CAT1);
+    if (cnt == 1) {
+        uapi_pm_remove_sleep_veto(PM_ID_CAT1);
+    } else {
+        // PPP_DEBUG_PRINT("CAT1 SERVICE MCU has delete pm_id_cat1 vote\r\n");
+    }
+    PPP_DEBUG_PRINT("\r\nCAT1 SERVICE MCU SLEEP SUCCESS\r\n");
+}
+
+void cat1_api_add_cat1_vote(void)
+{
+    uint8_t cnt = pm_veto_get_id_cnt(PM_ID_CAT1);
+    if (cnt == 0) {
+        uapi_pm_add_sleep_veto(PM_ID_CAT1);
+    } else {
+        // PPP_DEBUG_PRINT("CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
+    }
+    PPP_DEBUG_PRINT("\r\nCAT1 SERVICE MCU WAKEUP SUCCESS\r\n");
+}
+
+errcode_t cat1_api_disable_cat1_cmd(uint8_t disable_cmd)
+{
+    return ERRCODE_SUCC;
+}
+
+/********************** 运行时状态获取接口 **********************/
+
+/**
+ * @brief 获取cat1电源开启状态
+ */
+uint8_t cat1_api_runtime_get_cat1_powerstat(void)
+{
+    return g_ppp_runtime.cat1_powerOn;
+}
+
+/**
+ * @brief 获取cat1网络状态
+ */
+uint8_t cat1_api_runtime_get_cat1_networkstat(void)
+{
+    return g_ppp_runtime.network_on;
+}
+
+/**
+ * @brief 获取cat1信号强度
+ */
+int cat1_api_runtime_get_cat1_signal(void)
+{
+    return g_ppp_runtime.signal;
+}
+
+/**
+ * @brief 获取sim卡状态
+ */
+int cat1_api_runtime_get_cat1_simstat(void)
+{
+    return g_ppp_runtime.sim;
+}
+
+/**
+ * @brief 获取网络类型
+ */
+uint8_t cat1_api_runtime_get_cat1_networktype(void)
+{
+    return g_ppp_runtime.cat1_network_type;
+}
+
+/**
+ * @brief 获取Cat1运营商信息
+ */
+char* cat1_api_runtime_get_cat1_operator(void)
+{
+    return g_ppp_runtime.opera;
+}
+
+/**
+ * @brief 获取Cat1 IMEI号
+ */
+char* cat1_api_runtime_get_cat1_imei(void)
+{
+    return g_ppp_runtime.imei;
+}
+
+/**
+ * @brief 获取Cat1主应用版本号
+ */
+char* cat1_api_runtime_get_cat1_pyver(void)
+{
+    return g_ppp_runtime.pyVer;
+}
+
+/**
+ * @brief 获取modem版本
+ */
+char* cat1_api_runtime_get_cat1_modemver(void)
+{
+    return g_ppp_runtime.modemVer;
+}
+
+/********************** 运行时状态设置接口 **********************/
+
+/**
+ * @brief 设置cat1电源状态
+ */
+void cat1_api_runtime_set_cat1_powerstat(uint8_t cat1_powerOn)
+{
+    g_ppp_runtime.cat1_powerOn = cat1_powerOn;
+}
+
+/**
+ * @brief 设置cat1网络状态
+ */
+void cat1_api_runtime_set_cat1_networkstat(uint8_t network_on)
+{
+    g_ppp_runtime.network_on = network_on;
+}
+
+/**
+ * @brief 设置cat1信号强度
+ */
+void cat1_api_runtime_set_cat1_signal(int signal)
+{
+    g_ppp_runtime.signal = signal;
+}
+
+/**
+ * @brief 设置sim卡状态
+ */
+void cat1_api_runtime_set_cat1_simstat(int simstat)
+{
+    g_ppp_runtime.sim = simstat;
+}
+
+/**
+ * @brief 设置网络类型
+ */
+void cat1_api_runtime_set_cat1_networktype(uint8_t networktype)
+{
+    g_ppp_runtime.cat1_network_type = networktype;
+}
+
+/**
+ * @brief 设置Cat1运营商信息
+ */
+void cat1_api_runtime_set_cat1_operator(char* cat1_operator)
+{
+    if (cat1_operator != NULL) {
+        (void)strncpy_s(g_ppp_runtime.opera, sizeof(g_ppp_runtime.opera), 
+                        cat1_operator, sizeof(g_ppp_runtime.opera) - 1);
+        g_ppp_runtime.opera[sizeof(g_ppp_runtime.opera) - 1] = '\0';
+    }
+}
+
+/**
+ * @brief 设置Cat1 IMEI号
+ */
+void cat1_api_runtime_set_cat1_imei(char* imei)
+{
+    if (imei != NULL) {
+        (void)strncpy_s(g_ppp_runtime.imei, sizeof(g_ppp_runtime.imei), 
+                        imei, sizeof(g_ppp_runtime.imei) - 1);
+        g_ppp_runtime.imei[sizeof(g_ppp_runtime.imei) - 1] = '\0';
+    }
+}
+
+/**
+ * @brief 设置Cat1主应用版本号
+ */
+void cat1_api_runtime_set_cat1_pyver(char* pyver)
+{
+    if (pyver != NULL) {
+        (void)strncpy_s(g_ppp_runtime.pyVer, sizeof(g_ppp_runtime.pyVer), 
+                        pyver, sizeof(g_ppp_runtime.pyVer) - 1);
+        g_ppp_runtime.pyVer[sizeof(g_ppp_runtime.pyVer) - 1] = '\0';
+    }
+}
+
+/**
+ * @brief 设置modem版本
+ */
+void cat1_api_runtime_set_cat1_modemver(char* modemver)
+{
+    if (modemver != NULL) {
+        (void)strncpy_s(g_ppp_runtime.modemVer, sizeof(g_ppp_runtime.modemVer), 
+                        modemver, sizeof(g_ppp_runtime.modemVer) - 1);
+        g_ppp_runtime.modemVer[sizeof(g_ppp_runtime.modemVer) - 1] = '\0';
+    }
+}
+
+/********************** 控制接口 **********************/
+
+
+/**
+ * @brief 保持唤醒Cat1
+ */
+void cat1_api_keep_wakeup(uint8_t keep_wakeup)
+{
+    ppp_api_keep_wakeup(keep_wakeup);
+}
+
+/**
+ * @brief 注册控制4G的gpio值
+ */
+errcode_t cat1_register_ctl_pin(ctl_pin_4g_t ctl_pin)
+{
+    // 转换为PPP模块的引脚配置结构
+    ppp_ctl_pin_4g_t ppp_pin_config = {
+        .bat_pin = ctl_pin.bat_pin,
+        .bat_pin_en_value = ctl_pin.bat_pin_en_value,
+        .pwr_pin = ctl_pin.pwr_pin,
+        .pwr_pin_en_value = ctl_pin.pwr_pin_en_value,
+        .reset_pin = ctl_pin.reset_pin,
+        .reset_pin_en_value = ctl_pin.reset_pin_en_value,
+        .ring_pin = ctl_pin.ring_pin,
+        .ring_pin_en_value = ctl_pin.ring_pin_en_value,
+        .wakemodem_pin = ctl_pin.wakemodem_pin,
+        .wakemodem_pin_en_value = ctl_pin.wakemodem_pin_en_value
+    };
+    
+    return ppp_register_ctl_pin(&ppp_pin_config);
+}
+
+/**
+ * @brief cat1唤醒蓝牙中断处理函数
+ */
+void cat1_ring_isr_callback(pin_t pin, uintptr_t param)
+{
+    ppp_ring_isr_callback(pin, param);
+}
+
+/********************** 协议栈休眠/唤醒接口 (PPP专用) **********************/
+
+/**
+ * @brief 挂起PPP协议栈 (PPP模式专用实现)
+ * 
+ * 功能:
+ * 1. 挂起lwIP tcpip线程
+ * 2. 挂起PPP接收/处理线程
+ * 3. 停止PPP定时器
+ */
+void cat1_api_suspend_protocol(void)
+{
+    PPP_DEBUG_INFO("=== PPP: cat1_api_suspend_protocol (PPP mode) ===\n");
+    
+    // 1. 挂起lwIP tcpip线程
+    #ifdef SUPPORT_LWIP
+        tcpip_thread_suspend();
+        PPP_DEBUG_INFO("PPP: lwIP tcpip thread suspended\n");
+    #endif
+    
+    // 2. 挂起PPP协议栈 (PPP专用)
+    extern void ppp_suspend(void);
+    ppp_suspend();
+    PPP_DEBUG_INFO("PPP: PPP protocol stack suspended\n");
+    
+    PPP_DEBUG_INFO("=== PPP: Protocol stack suspended successfully ===\n");
+}
+
+/**
+ * @brief 恢复PPP协议栈 (PPP模式专用实现)
+ * 
+ * 功能:
+ * 1. 恢复lwIP tcpip线程
+ * 2. 恢复PPP接收/处理线程
+ * 3. 重启PPP定时器
+ */
+void cat1_api_resume_protocol(void)
+{
+    PPP_DEBUG_INFO("=== PPP: cat1_api_resume_protocol (PPP mode) ===\n");
+    
+    // 1. 恢复lwIP tcpip线程
+    #ifdef SUPPORT_LWIP
+        tcpip_thread_resume();
+        PPP_DEBUG_INFO("PPP: lwIP tcpip thread resumed\n");
+    #endif
+    
+    // 2. 恢复PPP协议栈 (PPP专用)
+    extern void ppp_resume(void);
+    ppp_resume();
+    PPP_DEBUG_INFO("PPP: PPP protocol stack resumed\n");
+    
+    PPP_DEBUG_INFO("=== PPP: Protocol stack resumed successfully ===\n");
+}
+
+/********************** 其他接口(暂时返回默认值或空实现) **********************/
+
+/**
+ * @brief 发送指令给Cat1
+ */
+errcode_t cat1_cmd_send(CMD_4G_T cmd, void *cmd_buf, uint16_t cmdlen)
+{
+    PPP_DEBUG_PRINT("PPP: cat1_cmd_send cmd=%d, len=%d\n", cmd, cmdlen);
+    // TODO: 实现PPP模块的AT命令发送
+    (void)cmd;
+    (void)cmd_buf;
+    (void)cmdlen;
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 注册消息回调函数
+ */
+errcode_t cat1_register_msg_callback(f_cat1_msg_callback func)
+{
+    PPP_DEBUG_PRINT("PPP: cat1_register_msg_callback\n");
+    // TODO: 实现PPP模块的消息回调注册
+    (void)func;
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 注册时间控制函数
+ */
+errcode_t cat1_register_time_ctl_functions(time_ctl_funcs_t *funcs)
+{
+    PPP_DEBUG_PRINT("PPP: cat1_register_time_ctl_functions\n");
+    // TODO: 实现PPP模块的时间控制函数注册
+    (void)funcs;
+    return ERRCODE_SUCC;
+} 
\ No newline at end of file
diff --git a/code/sdk/zhihui/n706a_net/src/ppp_debug.c b/code/sdk/zhihui/n706a_net/src/ppp_debug.c
new file mode 100644 (file)
index 0000000..44e098a
--- /dev/null
@@ -0,0 +1,119 @@
+#include "ppp_debug.h"
+#include "ppp_config.h"
+#include "ppp_types.h"
+#include <stdio.h>
+
+#if PPP_DEBUG_ENABLE
+
+/**
+ * @brief 十六进制数据转储
+ */
+void ppp_debug_hexdump(const uint8_t *data, uint32_t len)
+{
+    if (!data || len == 0) {
+        return;
+    }
+
+    PRINT("[PPP HEXDUMP] Length: %u bytes\r\n", len);
+    
+    for (uint32_t i = 0; i < len; i += 16) {
+        /* 打印地址 */
+        PRINT("%08X: ", i);
+        
+        /* 打印十六进制数据 */
+        for (uint32_t j = 0; j < 16; j++) {
+            if (i + j < len) {
+                PRINT("%02X ", data[i + j]);
+            } else {
+                PRINT("   ");
+            }
+            
+            if (j == 7) {
+                PRINT(" ");
+            }
+        }
+        
+        PRINT(" |");
+        
+        /* 打印ASCII字符 */
+        for (uint32_t j = 0; j < 16 && i + j < len; j++) {
+            uint8_t c = data[i + j];
+            if (c >= 32 && c <= 126) {
+                PRINT("%c", c);
+            } else {
+                PRINT(".");
+            }
+        }
+        
+        PRINT("|\r\n");
+    }
+}
+
+#else
+
+void ppp_debug_hexdump(const uint8_t *data, uint32_t len)
+{
+    (void)data;
+    (void)len;
+}
+
+#endif /* PPP_DEBUG_ENABLE */
+
+/**
+ * @brief 获取错误码字符串
+ */
+const char *ppp_debug_error_string(ppp_error_t error_code)
+{
+    switch (error_code) {
+        case PPP_ERR_OK:
+            return "OK";
+        case PPP_ERR_TIMEOUT:
+            return "TIMEOUT";
+        case PPP_ERR_AT_FAILED:
+            return "AT_FAILED";
+        case PPP_ERR_DIAL_FAILED:
+            return "DIAL_FAILED";
+        case PPP_ERR_NO_CARRIER:
+            return "NO_CARRIER";
+        case PPP_ERR_BUSY:
+            return "BUSY";
+        case PPP_ERR_NO_DIALTONE:
+            return "NO_DIALTONE";
+        case PPP_ERR_INVALID_PARAM:
+            return "INVALID_PARAM";
+        case PPP_ERR_MEMORY:
+            return "MEMORY";
+        case PPP_ERR_UART:
+            return "UART";
+        case PPP_ERR_UNKNOWN:
+        default:
+            return "UNKNOWN";
+    }
+}
+
+/**
+ * @brief 获取状态字符串
+ */
+const char *ppp_debug_state_string(ppp_state_t state)
+{
+    switch (state) {
+        case PPP_STATE_IDLE:
+            return "IDLE";
+        case PPP_STATE_INIT:
+            return "INIT";
+        case PPP_STATE_AT_HANDSHAKE:
+            return "AT_HANDSHAKE";
+        case PPP_STATE_SET_BAUDRATE:
+            return "SET_BAUDRATE";
+        case PPP_STATE_DIALING:
+            return "DIALING";
+        case PPP_STATE_CONNECTED:
+            return "CONNECTED";
+        case PPP_STATE_DISCONNECTING:
+            return "DISCONNECTING";
+        case PPP_STATE_ERROR:
+            return "ERROR";
+        default:
+            return "UNKNOWN";
+    }
+} 
\ No newline at end of file
diff --git a/code/sdk/zhihui/n706a_net/src/ppp_debug_manager.c b/code/sdk/zhihui/n706a_net/src/ppp_debug_manager.c
new file mode 100644 (file)
index 0000000..afbc2f1
--- /dev/null
@@ -0,0 +1,101 @@
+/**
+ * @file ppp_debug_manager.c
+ * @brief PPP调试级别动态管理模块
+ * 
+ * 提供运行时动态调整PPP调试输出级别的功能
+ */
+
+#include "ppp_debug_manager.h"
+#include "ppp_debug.h"
+#include "ppp_config.h"
+#include <string.h>
+
+/* 全局调试级别变量 */
+static volatile int g_ppp_dynamic_debug_level = PPP_DEBUG_LEVEL;
+
+/**
+ * @brief 获取当前动态调试级别
+ * @return 当前调试级别
+ */
+int ppp_debug_get_level(void)
+{
+    return g_ppp_dynamic_debug_level;
+}
+
+/**
+ * @brief 设置动态调试级别
+ * @param level 调试级别 (0-4)
+ * @return PPP_ERR_OK-成功,其他-失败
+ */
+ppp_error_t ppp_debug_set_level(int level)
+{
+    if (level < PPP_DEBUG_LEVEL_NONE || level > PPP_DEBUG_LEVEL_DEBUG) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+    
+    g_ppp_dynamic_debug_level = level;
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 获取调试级别名称
+ * @param level 调试级别
+ * @return 级别名称字符串
+ */
+const char* ppp_debug_get_level_name(int level)
+{
+    switch (level) {
+        case PPP_DEBUG_LEVEL_NONE:  return "NONE";
+        case PPP_DEBUG_LEVEL_ERROR: return "ERROR";
+        case PPP_DEBUG_LEVEL_WARN:  return "WARN";
+        case PPP_DEBUG_LEVEL_INFO:  return "INFO";
+        case PPP_DEBUG_LEVEL_DEBUG: return "DEBUG";
+        default: return "UNKNOWN";
+    }
+}
+
+/**
+ * @brief 根据名称设置调试级别
+ * @param level_name 级别名称 ("NONE", "ERROR", "WARN", "INFO", "DEBUG")
+ * @return PPP_ERR_OK-成功,其他-失败
+ */
+ppp_error_t ppp_debug_set_level_by_name(const char* level_name)
+{
+    if (!level_name) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+    
+    if (strcasecmp(level_name, "NONE") == 0) {
+        return ppp_debug_set_level(PPP_DEBUG_LEVEL_NONE);
+    } else if (strcasecmp(level_name, "ERROR") == 0) {
+        return ppp_debug_set_level(PPP_DEBUG_LEVEL_ERROR);
+    } else if (strcasecmp(level_name, "WARN") == 0) {
+        return ppp_debug_set_level(PPP_DEBUG_LEVEL_WARN);
+    } else if (strcasecmp(level_name, "INFO") == 0) {
+        return ppp_debug_set_level(PPP_DEBUG_LEVEL_INFO);
+    } else if (strcasecmp(level_name, "DEBUG") == 0) {
+        return ppp_debug_set_level(PPP_DEBUG_LEVEL_DEBUG);
+    } else {
+        return PPP_ERR_INVALID_PARAM;
+    }
+}
+
+/**
+ * @brief 重置调试级别为默认值
+ * @return PPP_ERR_OK-成功
+ */
+ppp_error_t ppp_debug_reset_level(void)
+{
+    g_ppp_dynamic_debug_level = PPP_DEBUG_LEVEL;
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 检查指定级别是否启用
+ * @param level 要检查的级别
+ * @return true-启用,false-未启用
+ */
+bool ppp_debug_is_level_enabled(int level)
+{
+    return g_ppp_dynamic_debug_level >= level;
+} 
\ No newline at end of file
diff --git a/code/sdk/zhihui/n706a_net/src/ppp_interrupt.c b/code/sdk/zhihui/n706a_net/src/ppp_interrupt.c
new file mode 100644 (file)
index 0000000..b7150ef
--- /dev/null
@@ -0,0 +1,1597 @@
+/**
+ * @file ppp_interrupt.c
+ * @brief UART中断接收处理 - 使用乒乓缓冲区优化
+ * 
+ * 核心设计:
+ * - 使用乒乓缓冲区(多个buffer,每个2KB)避免频繁malloc/free
+ * - ISR中写入当前buffer,满了自动切换到另一个buffer
+ * - 通过消息队列传递buffer索引(而非拷贝数据)
+ * - 定时器监控buffer状态,超时自动flush(30ms)
+ * - 处理线程负责数据转发:
+ *   * PPP模式:调用pppos_input_tcpip()送入lwIP协议栈
+ *   * N706A_NET模式:写入AT响应缓冲区供应用层读取
+ */
+#include "ppp_interrupt.h"
+#include "ppp_config.h"
+#include "ppp_debug.h"
+#ifndef SUPPORT_N706A_NET
+#include "ppp_lwip.h"      // 仅PPP模式需要
+#endif
+#include "ppp_serial.h"
+#include "uart.h"
+#include "hal_uart.h"
+#include "errcode.h"
+#include "osal_task.h"
+#include "osal_msgqueue.h"
+#include "time/osal_timer.h"
+#include "soc_osal.h"
+#include "custom_utils.h"  // 添加:用于uapi_create_osThread_custom
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+/* lwIP相关头文件(仅PPP模式) */
+#ifndef SUPPORT_N706A_NET
+#include "lwip/err.h"
+#include "lwip/stats.h"
+#include "netif/ppp/ppp.h"
+#include "netif/ppp/pppos.h"
+#endif
+
+/* 乒乓缓冲区配置 */
+#ifndef PPP_PING_PONG_BUFFER_SIZE
+#define PPP_PING_PONG_BUFFER_SIZE  2048  // 每个buffer大小(2KB)
+#endif
+
+#define PPP_PING_PONG_BUFFER_COUNT 4     // 三缓冲模式(改为3个)
+#define PPP_PING_PONG_TIMEOUT_MS   50    // buffer超时时间(30ms)
+
+/* PPP中断消息队列配置 */
+#define PPP_IRQ_MSG_QUEUE_SIZE     16    // 队列深度(乒乓模式下无需太大)
+#define PPP_IRQ_PROCESS_TASK_PRIO  24    // 处理线程优先级
+#define PPP_IRQ_PROCESS_STACK_SIZE 4096  // 处理线程栈大小
+
+/* 乒乓缓冲区状态 */
+typedef enum {
+    PPP_BUFFER_STATE_EMPTY = 0,      // 空闲,可以写入
+    PPP_BUFFER_STATE_FILLING,        // 正在填充中
+    PPP_BUFFER_STATE_FULL,           // 已满或超时,等待处理
+    PPP_BUFFER_STATE_PROCESSING      // 正在处理中
+} ppp_buffer_state_t;
+
+/* 乒乓缓冲区结构 */
+typedef struct {
+    uint8_t data[PPP_PING_PONG_BUFFER_SIZE];  // 数据缓冲区
+    volatile uint32_t write_pos;              // 当前写入位置
+    volatile ppp_buffer_state_t state;        // 缓冲区状态
+    volatile uint32_t last_write_time;        // 最后写入时间戳(ms)
+    volatile uint32_t first_write_time;       // 首次写入时间戳(用于统计填充时间)
+} ppp_ping_pong_buffer_t;
+
+/* PPP中断消息结构 - 通过消息队列传递buffer索引 */
+typedef struct {
+    uint8_t buffer_index;   // 缓冲区索引(0~PPP_PING_PONG_BUFFER_COUNT-1)
+    uint16_t length;        // 数据长度
+} ppp_irq_msg_t;
+
+/* 中断使能标志 */
+static volatile bool g_ppp_interrupt_enabled = false;
+
+/* 处理线程相关 */
+// 中断模式全局变量(供 ppp_suspend/resume 访问)
+uint32_t g_ppp_irq_process_task = 0;  // 改为uint32_t以配合uapi_create_osThread_custom
+static unsigned long g_ppp_irq_msg_queue = 0;  // 消息队列ID (OSAL使用unsigned long)
+volatile bool g_ppp_irq_task_running = false;  // 移除 static,供外部访问
+
+/* 乒乓缓冲区(动态分配,避免占用DTCM) */
+static ppp_ping_pong_buffer_t *g_ping_pong_buffers = NULL;  // 改为指针,通过malloc动态分配
+static volatile uint8_t g_current_buffer_index = 0;  // ⚠️ volatile不保证原子性,但单字节写入在ARM上通常是原子的
+
+/* 全局时间戳(由定时器更新,ISR只读) */
+static volatile uint32_t g_timer_timestamp_ms = 0;
+
+/* 定时器相关 */
+// Timer 全局变量(供 ppp_suspend/resume 访问)
+osal_timer g_ppp_timeout_timer;  // 移除 static
+volatile bool g_ppp_timer_running = false;  // 移除 static
+
+/* 统计信息 */
+static ppp_interrupt_stats_t g_ppp_interrupt_stats = {0};
+
+/* 扩展统计信息:乒乓缓冲区相关 */
+typedef struct {
+    uint32_t buffer_full_count;       // buffer满次数
+    uint32_t buffer_timeout_count;    // buffer超时flush次数(未满但超时)
+    uint32_t buffer_switch_count;     // buffer切换次数
+    uint32_t dropped_both_full;       // 两个buffer都满导致丢弃的字节数
+    uint32_t switch_failed_count;     // buffer切换失败次数(安全性指标)
+    uint32_t race_condition_detected; // 检测到的竞态条件次数(诊断)
+    uint32_t cross_buffer_count;      // 跨buffer写入次数(数据跨两个buffer)
+    uint32_t timeout_unfilled_count;  // 超时时未满的flush次数
+    uint32_t fill_time_min_ms;        // buffer填充最短时间(ms)
+    uint32_t fill_time_max_ms;        // buffer填充最长时间(ms)
+    uint32_t fill_time_total_ms;      // buffer填充总时间(用于计算平均值)
+    uint32_t fill_time_count;         // buffer填充次数统计
+} ppp_pingpong_stats_t;
+
+static ppp_pingpong_stats_t g_pingpong_stats = {0};
+
+/* UART错误统计信息 */
+typedef struct {
+    uint32_t parity_error_count;        // 奇偶校验错误次数
+    uint32_t frame_error_count;         // 帧错误次数
+    uint32_t last_parity_error_info[4]; // 最近一次奇偶校验错误信息
+    uint32_t last_frame_error_info[4];  // 最近一次帧错误信息
+} ppp_uart_error_stats_t;
+
+static ppp_uart_error_stats_t g_uart_error_stats = {0};
+
+/* PPP数据传输状态检测(用于安全执行+++/ATO命令) */
+typedef struct {
+    uint32_t last_rx_time_ms;       // 最后接收数据时间
+    uint32_t rx_bytes_this_second;  // 本秒接收的字节数
+    uint32_t rx_rate_bps;           // 接收速率(bytes/sec)
+} ppp_data_state_t;
+
+static ppp_data_state_t g_ppp_data_state = {0};
+
+/* 配置参数 */
+#define PPP_SAFE_SWITCH_IDLE_MS     5000    // 5秒空闲才安全切换
+#define PPP_LIGHT_THRESHOLD_BPS     100     // 100 bps以下为轻量传输
+
+#ifdef SUPPORT_PPP_SERVICE_INTERRUPT
+#define PPP_CAT1_VOTE_IDLE_MS       3000    // 3秒空闲后移除CAT1 vote
+/* CAT1 vote 状态管理 */
+static volatile bool g_ppp_cat1_vote_added = false;  // CAT1 vote 状态标志
+
+#endif
+
+#ifdef SUPPORT_PPP_SERVICE_INTERRUPT
+/* 外部函数声明(CAT1 API) */
+extern void cat1_api_add_cat1_vote(void);
+extern void cat1_api_remove_cat1_vote(void);
+#endif
+
+/* 内部函数声明 */
+static uint32_t ppp_get_current_time_ms(void);
+static ppp_error_t ppp_flush_buffer(uint8_t buffer_index);
+static void ppp_timeout_timer_callback(unsigned long arg);
+static void ppp_uart_parity_error_callback(uint32_t *err_info, uint32_t len);
+static void ppp_uart_frame_error_callback(uint32_t *err_info, uint32_t len);
+
+/**
+ * @brief 获取当前时间戳(毫秒)
+ */
+static uint32_t ppp_get_current_time_ms(void)
+{
+    unsigned long long jiffies = osal_get_jiffies();
+    return (uint32_t)osal_jiffies_to_msecs((unsigned int)jiffies);
+}
+
+/**
+ * @brief UART中断数据处理线程(乒乓缓冲区模式)
+ * @note 从消息队列接收buffer索引,直接访问乒乓缓冲区
+ *       PPP模式:调用pppos_input_tcpip()送入lwIP
+ *       N706A_NET模式:写入AT响应缓冲区
+ */
+static void ppp_irq_process_thread(void *arg)
+{
+    (void)arg;
+    ppp_irq_msg_t msg;
+    unsigned int msg_size = sizeof(ppp_irq_msg_t);
+    
+    // ⚠️ 使用 WARN 级别确保能看到此日志,用于诊断线程是否正常启动
+#ifdef SUPPORT_N706A_NET
+    PPP_DEBUG_WARN(">>> N706A_NET IRQ process thread STARTED (ping-pong mode) <<<");
+    PPP_DEBUG_INFO("Thread running, waiting for AT data from ISR...");
+#else
+    PPP_DEBUG_WARN(">>> PPP IRQ process thread STARTED (ping-pong mode) <<<");
+    PPP_DEBUG_INFO("Thread running, waiting for PPP data from ISR...");
+#endif
+    #if defined(PPP_DO_SERIAL_TEST) && (PPP_DO_SERIAL_TEST == 1)
+    const uint8_t print_data[] = "PPP IRQ process thread started (ping-pong mode)\n";
+    uapi_uart_write(SIO_UART_BUS, print_data, sizeof(print_data), 100);
+    #endif
+    while (g_ppp_irq_task_running) {
+        // 从消息队列读取buffer索引消息(阻塞等待)
+        int ret = osal_msg_queue_read_copy(
+            g_ppp_irq_msg_queue,
+            &msg,
+            &msg_size,
+            OSAL_MSGQ_WAIT_FOREVER
+        );
+        
+        if (ret != OSAL_SUCCESS || !g_ppp_irq_task_running) {
+            continue;
+        }
+        
+        // 验证buffer索引
+        if (msg.buffer_index >= PPP_PING_PONG_BUFFER_COUNT) {
+            PPP_DEBUG_ERROR("Invalid buffer index: %u", msg.buffer_index);
+            continue;
+        }
+        
+        // ⚠️ 检查内存是否已分配
+        if (g_ping_pong_buffers == NULL) {
+            PPP_DEBUG_ERROR("Buffer memory not allocated");
+            continue;
+        }
+        
+        ppp_ping_pong_buffer_t *buffer = &g_ping_pong_buffers[msg.buffer_index];
+        
+        // 验证数据长度
+        if (msg.length == 0 || msg.length > PPP_PING_PONG_BUFFER_SIZE) {
+            PPP_DEBUG_ERROR("Invalid data length: %u", msg.length);
+            buffer->state = PPP_BUFFER_STATE_EMPTY;
+            buffer->write_pos = 0;
+            continue;
+        }
+        
+        // 标记为处理中
+        buffer->state = PPP_BUFFER_STATE_PROCESSING;
+        
+        // 打印摘要
+        PPP_DEBUG_DEBUG("PPP Process: buffer[%u], %u bytes", msg.buffer_index, msg.length);
+        
+        // 只打印前16字节
+        PPP_DEBUG_PRINT("  Data: ");
+        for (uint32_t i = 0; i < msg.length && i < 16; i++) {
+            PPP_DEBUG_PRINT("%02X ", buffer->data[i]);
+        }
+        if (msg.length > 16) {
+            PPP_DEBUG_PRINT("... (%u more bytes)", msg.length - 16);
+        }
+        PPP_DEBUG_PRINT("\n");
+        
+#if defined(PPP_DO_SERIAL_TEST) && (PPP_DO_SERIAL_TEST == 1)
+        err_t result = ERR_OK;
+        uint32_t write_result = uapi_uart_write(SIO_UART_BUS, buffer->data, msg.length, 100);
+        if (write_result != msg.length) {
+            PPP_DEBUG_WARN("uapi_uart_write failed: %d, dropped %u bytes", write_result, msg.length);
+            g_ppp_interrupt_stats.dropped_lwip_error += msg.length;
+            g_ppp_interrupt_stats.lwip_error_count++;
+        } else {
+            PPP_DEBUG_WARN("uapi_uart_write : %u bytes", msg.length);
+            g_ppp_interrupt_stats.total_bytes_sent_to_lwip += msg.length;
+            g_ppp_interrupt_stats.success_count++;
+        }
+#else //if defined(SUPPORT_N706A_NET)
+        // n706a_net模式:写入AT响应缓冲区(而非lwIP)
+        extern void n706a_at_response_buffer_write(const uint8_t *data, uint32_t length);
+        n706a_at_response_buffer_write(buffer->data, msg.length);
+        g_ppp_interrupt_stats.total_bytes_sent_to_lwip += msg.length;
+        g_ppp_interrupt_stats.success_count++;
+        PPP_DEBUG_DEBUG("n706a_net: Sent %u bytes to AT response buffer", msg.length);
+#endif
+        // 释放buffer(标记为空闲)
+        buffer->state = PPP_BUFFER_STATE_EMPTY;
+        buffer->write_pos = 0;
+        buffer->first_write_time = 0;  // 重置首次写入时间
+    }
+    
+    PPP_DEBUG_INFO("PPP IRQ process thread exited");
+}
+
+/**
+ * @brief 刷新指定buffer到消息队列
+ * @param buffer_index 缓冲区索引
+ * @param is_timeout 是否因超时触发(用于统计)
+ * @return PPP_ERR_OK 成功,其他值失败
+ */
+static ppp_error_t ppp_flush_buffer_internal(uint8_t buffer_index, bool is_timeout)
+{
+    if (buffer_index >= PPP_PING_PONG_BUFFER_COUNT) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+    
+    // ⚠️ 检查内存是否已分配
+    if (g_ping_pong_buffers == NULL) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+    
+    ppp_ping_pong_buffer_t *buffer = &g_ping_pong_buffers[buffer_index];
+    
+    // 只flush FILLING状态的buffer
+    if (buffer->state != PPP_BUFFER_STATE_FILLING || buffer->write_pos == 0) {
+        return PPP_ERR_OK;  // 没有数据需要flush
+    }
+    
+    // 统计填充时间(从首次写入到flush)
+    if (buffer->first_write_time > 0) {
+        uint32_t current_time = ppp_get_current_time_ms();
+        uint32_t fill_time = current_time - buffer->first_write_time;
+        
+        // 更新最小/最大填充时间
+        if (g_pingpong_stats.fill_time_count == 0) {
+            g_pingpong_stats.fill_time_min_ms = fill_time;
+            g_pingpong_stats.fill_time_max_ms = fill_time;
+        } else {
+            if (fill_time < g_pingpong_stats.fill_time_min_ms) {
+                g_pingpong_stats.fill_time_min_ms = fill_time;
+            }
+            if (fill_time > g_pingpong_stats.fill_time_max_ms) {
+                g_pingpong_stats.fill_time_max_ms = fill_time;
+            }
+        }
+        g_pingpong_stats.fill_time_total_ms += fill_time;
+        g_pingpong_stats.fill_time_count++;
+    }
+    
+    // 统计超时且未满的flush
+    if (is_timeout && buffer->write_pos < PPP_PING_PONG_BUFFER_SIZE) {
+        g_pingpong_stats.timeout_unfilled_count++;
+    }
+    
+    // 标记为FULL状态
+    buffer->state = PPP_BUFFER_STATE_FULL;
+    
+    // 准备消息
+    ppp_irq_msg_t msg = {
+        .buffer_index = buffer_index,
+        .length = (uint16_t)buffer->write_pos
+    };
+    
+    // 发送到消息队列(非阻塞)
+    int ret = osal_msg_queue_write_copy(
+        g_ppp_irq_msg_queue,
+        &msg,
+        sizeof(ppp_irq_msg_t),
+        OSAL_MSGQ_NO_WAIT
+    );
+    
+    if (ret != OSAL_SUCCESS) {
+        // 队列满,无法发送,保持FULL状态等待下次重试
+        g_ppp_interrupt_stats.dropped_queue_full += buffer->write_pos;
+        return PPP_ERR_UNKNOWN;
+    }
+    
+    return PPP_ERR_OK;
+}
+
+// 便利函数:非超时flush
+static ppp_error_t ppp_flush_buffer(uint8_t buffer_index)
+{
+    return ppp_flush_buffer_internal(buffer_index, false);
+}
+
+/**
+ * @brief 定时器回调:检查buffer超时并flush
+ * @note 定时器上下文,应快速返回
+ * @param arg 定时器参数(未使用)
+ * @warning osal_timer默认是one-shot,必须在回调中手动重启实现周期性执行
+ * 
+ * 数据安全设计(避免竞态):
+ * - 定时器职责:只检查和flush **非当前** buffer(避免与ISR竞争)
+ * - ISR 职责:
+ *   1. 在写入前检查当前buffer是否超时(last_write_time == 0),超时则flush+切换
+ *   2. 检查当前buffer状态,如果不可写则切换
+ *   3. 独占 g_current_buffer_index 的修改权
+ * - 分工明确:定时器不操作当前buffer,ISR负责当前buffer的超时处理
+ * - 数据保证:disable时强制flush所有buffer,确保数据不丢失
+ */
+static void ppp_timeout_timer_callback(unsigned long arg)
+{
+    (void)arg;
+    
+    // 增加定时器调用计数(用于诊断)
+    static volatile uint32_t timer_call_count = 0;
+    timer_call_count++;
+    
+    // 每100次(约3秒)打印一次诊断信息
+    if ((timer_call_count % 100) == 1) {
+        PPP_DEBUG_INFO("[TIMER] Callback executed %u times, enabled=%d, running=%d", 
+                      timer_call_count, g_ppp_interrupt_enabled, g_ppp_timer_running);
+    }
+    
+    // 每333次(约10秒)打印一次PPP丢失统计
+    // 30ms * 333 ≈ 10秒
+    if ((timer_call_count % 333) == 0) {
+        ppp_interrupt_print_stats();
+    }
+    
+    if (!g_ppp_interrupt_enabled || !g_ppp_timer_running) {
+        return;
+    }
+    
+    uint32_t current_time = ppp_get_current_time_ms();
+    
+    // ⚠️ 更新全局时间戳(供ISR使用,ISR中不能调用时间函数)
+    g_timer_timestamp_ms = current_time;
+    
+    // ✅ 每秒更新一次接收速率(用于安全执行+++/ATO命令)
+    static uint32_t last_rate_update_time = 0;
+    if (last_rate_update_time == 0) {
+        last_rate_update_time = current_time;
+    }
+    
+    uint32_t elapsed = current_time - last_rate_update_time;
+    if (elapsed >= 1000) {  // 每秒更新
+        g_ppp_data_state.rx_rate_bps = 
+            (g_ppp_data_state.rx_bytes_this_second * 1000) / elapsed;
+        g_ppp_data_state.rx_bytes_this_second = 0;
+        last_rate_update_time = current_time;
+    }
+    
+#ifdef SUPPORT_PPP_SERVICE_INTERRUPT
+    // ✅ CAT1 vote 管理:检测 idle 状态,超过阈值时移除 vote
+    if (g_ppp_cat1_vote_added) {
+        if (g_ppp_data_state.last_rx_time_ms > 0) {
+            uint32_t idle_time = current_time - g_ppp_data_state.last_rx_time_ms;
+            if (idle_time >= PPP_CAT1_VOTE_IDLE_MS) {
+                // 空闲时间超过阈值,移除 vote 允许 CAT1 休眠
+                cat1_api_remove_cat1_vote();
+                g_ppp_cat1_vote_added = false;
+                PPP_DEBUG_INFO("[CAT1_VOTE] Removed vote after %ums idle", idle_time);
+            }
+        }
+    }
+#endif
+    
+    uint8_t current_idx = g_current_buffer_index;  // 读取一次,避免重复读取
+    
+    // ⚠️ 检查内存是否已分配
+    if (g_ping_pong_buffers == NULL) {
+        return;
+    }
+    
+    // ⚠️ 检查所有buffer的超时状态并按写入顺序 flush
+    // ⚠️ 关键修复:必须按 first_write_time 排序,避免数据乱序
+    
+    // 第1步:更新时间戳并收集超时的 buffer
+    typedef struct {
+        uint8_t index;
+        uint32_t write_time;
+        bool is_current;
+    } buffer_order_t;
+    
+    buffer_order_t buffers_to_flush[PPP_PING_PONG_BUFFER_COUNT];
+    uint8_t flush_count = 0;
+    
+    for (uint8_t i = 0; i < PPP_PING_PONG_BUFFER_COUNT; i++) {
+        // ⚠️ 竞态检测:在处理过程中再次检查current_idx是否变化
+        uint8_t current_check = g_current_buffer_index;
+        bool is_current = (i == current_check);
+        
+        // 检测到current_idx在循环中变化(竞态)
+        if (!is_current && i == current_idx) {
+            g_pingpong_stats.race_condition_detected++;
+            continue;  // 跳过,避免竞态
+        }
+        
+        ppp_ping_pong_buffer_t *buffer = &g_ping_pong_buffers[i];
+        
+        // 只处理FILLING状态且有数据的buffer
+        if (buffer->state == PPP_BUFFER_STATE_FILLING && buffer->write_pos > 0) {
+            // last_write_time == 0 表示ISR刚写入数据,需要更新时间戳
+            if (buffer->last_write_time == 0) {
+                buffer->last_write_time = current_time;
+                PPP_DEBUG_DEBUG("[TIMER] Update timestamp for buffer[%u]", i);
+            } else {
+                // 检查是否超时
+                uint32_t elapsed = current_time - buffer->last_write_time;
+                
+                if (elapsed >= PPP_PING_PONG_TIMEOUT_MS) {
+                    // 记录需要 flush 的 buffer
+                    buffers_to_flush[flush_count].index = i;
+                    buffers_to_flush[flush_count].write_time = buffer->first_write_time;
+                    buffers_to_flush[flush_count].is_current = is_current;
+                    flush_count++;
+                    
+                    PPP_DEBUG_DEBUG("[TIMER] Buffer[%u] timeout (%u ms), %s, %u bytes", 
+                                   i, elapsed, 
+                                   is_current ? "CURRENT" : "non-current",
+                                   buffer->write_pos);
+                }
+            }
+        }
+    }
+    
+    // 第2步:按 first_write_time 排序
+    for (uint8_t i = 0; i < flush_count; i++) {
+        for (uint8_t j = i + 1; j < flush_count; j++) {
+            if (buffers_to_flush[j].write_time < buffers_to_flush[i].write_time) {
+                buffer_order_t temp = buffers_to_flush[i];
+                buffers_to_flush[i] = buffers_to_flush[j];
+                buffers_to_flush[j] = temp;
+            }
+        }
+    }
+    
+    // 第3步:按排序后的顺序 flush
+    for (uint8_t i = 0; i < flush_count; i++) {
+        uint8_t idx = buffers_to_flush[i].index;
+        
+        PPP_DEBUG_DEBUG("[TIMER] Flushing buffer[%u] (write_order=%u) due to timeout", idx, i);
+        
+        // 使用internal函数,标记为超时flush
+        if (ppp_flush_buffer_internal(idx, true) == PPP_ERR_OK) {
+            g_pingpong_stats.buffer_timeout_count++;
+            
+            // 如果是当前buffer超时被flush,需要切换到下一个
+            if (buffers_to_flush[i].is_current) {
+                uint8_t next_idx = (idx + 1) % PPP_PING_PONG_BUFFER_COUNT;
+                ppp_ping_pong_buffer_t *next_buffer = &g_ping_pong_buffers[next_idx];
+                
+                if (next_buffer->state == PPP_BUFFER_STATE_EMPTY) {
+                    g_current_buffer_index = next_idx;
+                    g_pingpong_stats.buffer_switch_count++;
+                    PPP_DEBUG_INFO("[TIMER] Switched from buffer[%u] to buffer[%u] after timeout", idx, next_idx);
+                }
+            }
+        }
+    }
+    
+    // ⚠️ 关键修复:osal_timer是one-shot类型,必须手动重启以实现周期性执行
+    // 不重启的话,定时器只会执行一次!
+    if (g_ppp_timer_running) {
+        osal_timer_start(&g_ppp_timeout_timer);
+    }
+}
+
+/**
+ * @brief UART奇偶校验错误回调函数
+ * @param err_info 错误信息数组
+ * @param len 错误信息数组长度
+ * @note 在中断上下文中执行,必须快速返回
+ */
+static void ppp_uart_parity_error_callback(uint32_t *err_info, uint32_t len)
+{
+    g_uart_error_stats.parity_error_count++;
+    
+    // 保存错误信息用于诊断(只保存前4个)
+    if (err_info && len > 0) {
+        uint32_t copy_len = (len > 4) ? 4 : len;
+        for (uint32_t i = 0; i < copy_len; i++) {
+            g_uart_error_stats.last_parity_error_info[i] = err_info[i];
+        }
+    }
+    
+    // ⚠️ 中断中禁止打印日志,只统计
+}
+
+/**
+ * @brief UART帧错误回调函数
+ * @param err_info 错误信息数组
+ * @param len 错误信息数组长度
+ * @note 在中断上下文中执行,必须快速返回
+ */
+static void ppp_uart_frame_error_callback(uint32_t *err_info, uint32_t len)
+{
+    g_uart_error_stats.frame_error_count++;
+    
+    // 保存错误信息用于诊断(只保存前4个)
+    if (err_info && len > 0) {
+        uint32_t copy_len = (len > 4) ? 4 : len;
+        for (uint32_t i = 0; i < copy_len; i++) {
+            g_uart_error_stats.last_frame_error_info[i] = err_info[i];
+        }
+    }
+    
+    // ⚠️ 中断中禁止打印日志,只统计
+}
+
+/**
+ * @brief UART接收中断回调函数(乒乓缓冲区模式)
+ * @note 中断上下文,必须极快返回
+ * 
+ * 优化策略:
+ * 1. 写入当前buffer(memcpy,~60字节 < 1μs)
+ * 2. buffer满了直接flush并切换(~2μs)
+ * 3. 无malloc/free,减少内存碎片和延迟
+ * 4. ⚠️ 新增:跨buffer写入支持(需求1)
+ * 5. 总耗时目标:< 5μs
+ */
+void _ppp_uart_rx_interrupt_handler(const void *buffer, uint16_t length, bool error)
+{
+    // ⚠️ 中断中禁止打印!必须极快返回
+    
+    // 快速路径:参数校验(异常情况也不打印,只统计)
+    if (!buffer || length == 0 || length > 200 || g_ping_pong_buffers == NULL) {
+        // 不打印!在中断中打印会阻塞系统,只记录统计
+        g_ppp_interrupt_stats.error_count++;
+        return;
+    }
+    if (error) {
+        g_ppp_interrupt_stats.error_count++;
+    }
+    
+    // 更新统计
+    g_ppp_interrupt_stats.total_interrupts++;
+    g_ppp_interrupt_stats.total_bytes_received += length;
+    
+    // ✅ 更新状态检测(用于安全执行+++/ATO命令)
+    g_ppp_data_state.last_rx_time_ms = g_timer_timestamp_ms;
+    g_ppp_data_state.rx_bytes_this_second += length;
+    
+#ifdef SUPPORT_PPP_SERVICE_INTERRUPT
+    // ✅ CAT1 vote 管理:接收数据时添加 vote(保持 CAT1 唤醒)
+    if (!g_ppp_cat1_vote_added) {
+        cat1_api_add_cat1_vote();
+        g_ppp_cat1_vote_added = true;
+    }
+#endif
+    
+    // 获取当前buffer
+    uint8_t current_idx = g_current_buffer_index;
+    ppp_ping_pong_buffer_t *current_buffer = &g_ping_pong_buffers[current_idx];
+    
+    // ⚠️ 检查当前buffer的超时
+    if (current_buffer->state == PPP_BUFFER_STATE_FILLING && 
+        current_buffer->write_pos > 0 && 
+        current_buffer->last_write_time != 0) {
+        uint32_t current_time = g_timer_timestamp_ms;
+        uint32_t elapsed = current_time - current_buffer->last_write_time;
+        
+        if (elapsed >= PPP_PING_PONG_TIMEOUT_MS) {
+            // 超时,flush并切换
+            ppp_flush_buffer(current_idx);
+            g_pingpong_stats.buffer_timeout_count++;
+            
+            uint8_t next_idx = (current_idx + 1) % PPP_PING_PONG_BUFFER_COUNT;
+            if (g_ping_pong_buffers[next_idx].state == PPP_BUFFER_STATE_EMPTY) {
+                g_current_buffer_index = next_idx;
+                g_pingpong_stats.buffer_switch_count++;
+                current_idx = next_idx;
+                current_buffer = &g_ping_pong_buffers[current_idx];
+            }
+        }
+    }
+    
+    // 如果当前buffer不可写,尝试切换
+    if (current_buffer->state != PPP_BUFFER_STATE_EMPTY && 
+        current_buffer->state != PPP_BUFFER_STATE_FILLING) {
+        uint8_t next_idx = (current_idx + 1) % PPP_PING_PONG_BUFFER_COUNT;
+        if (g_ping_pong_buffers[next_idx].state == PPP_BUFFER_STATE_EMPTY) {
+            g_current_buffer_index = next_idx;
+            g_pingpong_stats.buffer_switch_count++;
+            current_idx = next_idx;
+            current_buffer = &g_ping_pong_buffers[current_idx];
+        }
+    }
+    
+    // 初始化空buffer
+    if (current_buffer->state == PPP_BUFFER_STATE_EMPTY) {
+        current_buffer->state = PPP_BUFFER_STATE_FILLING;
+        current_buffer->write_pos = 0;
+        current_buffer->first_write_time = g_timer_timestamp_ms;  // ⚠️ 需求3:记录首次写入时间
+    }
+    
+    // 计算当前buffer剩余空间
+    uint32_t available = PPP_PING_PONG_BUFFER_SIZE - current_buffer->write_pos;
+    uint16_t remaining_data = length;
+    const uint8_t *data_ptr = (const uint8_t *)buffer;
+    
+    // ⚠️ 需求1:跨buffer写入处理
+    if (current_buffer->state == PPP_BUFFER_STATE_FILLING) {
+        if (remaining_data <= available) {
+            // 情况1:数据完全放得下,直接写入
+            memcpy(current_buffer->data + current_buffer->write_pos, data_ptr, remaining_data);
+            current_buffer->write_pos += remaining_data;
+            current_buffer->last_write_time = 0;  // 由定时器更新
+            
+            // 检查是否正好填满
+            if (current_buffer->write_pos >= PPP_PING_PONG_BUFFER_SIZE) {
+                ppp_flush_buffer(current_idx);
+                g_pingpong_stats.buffer_full_count++;
+                
+                // 切换buffer
+                uint8_t next_idx = (current_idx + 1) % PPP_PING_PONG_BUFFER_COUNT;
+                if (g_ping_pong_buffers[next_idx].state == PPP_BUFFER_STATE_EMPTY) {
+                    g_current_buffer_index = next_idx;
+                    g_pingpong_stats.buffer_switch_count++;
+                } else {
+                    g_pingpong_stats.switch_failed_count++;
+                }
+            }
+        } else {
+            // 情况2:数据超过当前buffer剩余空间,需要跨buffer写入
+            g_pingpong_stats.cross_buffer_count++;  // ⚠️ 统计跨buffer次数
+            
+            // 第1步:先填满当前buffer
+            if (available > 0) {
+                memcpy(current_buffer->data + current_buffer->write_pos, data_ptr, available);
+                current_buffer->write_pos += available;
+                data_ptr += available;
+                remaining_data -= available;
+            }
+            
+            // 第2步:flush当前buffer
+            ppp_flush_buffer(current_idx);
+            g_pingpong_stats.buffer_full_count++;
+            
+            // 第3步:切换到下一个buffer
+            uint8_t next_idx = (current_idx + 1) % PPP_PING_PONG_BUFFER_COUNT;
+            ppp_ping_pong_buffer_t *next_buffer = &g_ping_pong_buffers[next_idx];
+            
+            if (next_buffer->state == PPP_BUFFER_STATE_EMPTY && 
+                remaining_data <= PPP_PING_PONG_BUFFER_SIZE) {
+                // 第4步:把剩余数据写入新buffer
+                g_current_buffer_index = next_idx;
+                g_pingpong_stats.buffer_switch_count++;
+                
+                next_buffer->state = PPP_BUFFER_STATE_FILLING;
+                next_buffer->write_pos = 0;
+                next_buffer->first_write_time = g_timer_timestamp_ms;  // 新buffer的首次写入时间
+                
+                memcpy(next_buffer->data, data_ptr, remaining_data);
+                next_buffer->write_pos = remaining_data;
+                next_buffer->last_write_time = 0;  // 由定时器更新
+            } else {
+                // 下一个buffer不可用,剩余数据丢弃
+                g_pingpong_stats.dropped_both_full += remaining_data;
+                g_pingpong_stats.switch_failed_count++;
+            }
+        }
+    } else {
+        // 当前buffer不可用,数据丢弃
+        g_pingpong_stats.dropped_both_full += length;
+    }
+}
+
+void ppp_uart_rx_interrupt_handler(const void *buffer, uint16_t length, bool error)
+{
+    _ppp_uart_rx_interrupt_handler(buffer, length, error);
+    hal_uart_clear_pending(UART_BUS_0);
+}
+
+/**
+ * @brief 启用PPP UART中断接收(乒乓缓冲区模式)
+ * @return PPP_ERR_OK 成功,其他值失败
+ */
+ppp_error_t ppp_interrupt_enable(void)
+{
+    if (g_ppp_interrupt_enabled) {
+        PPP_DEBUG_WARN("PPP interrupt already enabled");
+        return PPP_ERR_OK;
+    }
+    
+    PPP_DEBUG_INFO("Enabling PPP UART interrupt mode (ping-pong buffer)");
+    
+    // 1. 动态分配乒乓缓冲区内存
+    if (g_ping_pong_buffers != NULL) {
+        PPP_DEBUG_ERROR("Memory leak detected: g_ping_pong_buffers is not NULL!");
+        free(g_ping_pong_buffers);
+        g_ping_pong_buffers = NULL;
+    }
+    
+    size_t buffer_size = sizeof(ppp_ping_pong_buffer_t) * PPP_PING_PONG_BUFFER_COUNT;
+    g_ping_pong_buffers = (ppp_ping_pong_buffer_t *)malloc(buffer_size);
+    
+    if (g_ping_pong_buffers == NULL) {
+        PPP_DEBUG_ERROR("Failed to allocate %zu bytes for ping-pong buffers", buffer_size);
+        return PPP_ERR_MEMORY;
+    }
+    
+    PPP_DEBUG_INFO("Allocated %zu bytes (%.2f KB) for ping-pong buffers via malloc", 
+                  buffer_size, buffer_size / 1024.0);
+    
+    // 2. 初始化乒乓缓冲区
+    for (uint8_t i = 0; i < PPP_PING_PONG_BUFFER_COUNT; i++) {
+        g_ping_pong_buffers[i].write_pos = 0;
+        g_ping_pong_buffers[i].state = PPP_BUFFER_STATE_EMPTY;
+        g_ping_pong_buffers[i].last_write_time = 0;
+        g_ping_pong_buffers[i].first_write_time = 0;
+        memset(g_ping_pong_buffers[i].data, 0, PPP_PING_PONG_BUFFER_SIZE);
+    }
+    g_current_buffer_index = 0;
+    
+#ifdef SUPPORT_PPP_SERVICE_INTERRUPT
+    // 2.1 初始化 CAT1 vote 状态
+    g_ppp_cat1_vote_added = false;
+#endif
+    
+    PPP_DEBUG_INFO("Ping-pong buffers initialized: %d x %d bytes = %d KB total", 
+                  PPP_PING_PONG_BUFFER_COUNT, PPP_PING_PONG_BUFFER_SIZE,
+                  (PPP_PING_PONG_BUFFER_COUNT * PPP_PING_PONG_BUFFER_SIZE) / 1024);
+    
+    // 3. 创建消息队列(只传递buffer索引,所以队列可以更小)
+    int ret = osal_msg_queue_create(
+        "ppp_irq_queue",
+        PPP_IRQ_MSG_QUEUE_SIZE,
+        &g_ppp_irq_msg_queue,
+        0,
+        sizeof(ppp_irq_msg_t)
+    );
+    
+    if (ret != OSAL_SUCCESS) {
+        PPP_DEBUG_ERROR("Failed to create message queue: 0x%x", ret);
+        free(g_ping_pong_buffers);
+        g_ping_pong_buffers = NULL;
+        return PPP_ERR_MEMORY;
+    }
+    
+    PPP_DEBUG_INFO("Message queue created (depth=%d, item_size=%d bytes)", 
+                  PPP_IRQ_MSG_QUEUE_SIZE, sizeof(ppp_irq_msg_t));
+    
+    // 4. 启动处理线程(使用 uapi_create_osThread_custom 在 PSRAM 中分配栈)
+    // ✅ 优化:通过 USE_EXTEND_MEM 将线程栈分配到 PSRAM,节省珍贵的 DTCM
+    g_ppp_irq_task_running = true;
+    
+    app_task_definition_t irq_task_cfg = {0};
+    irq_task_cfg.attr.name = "ppp_irq_proc";
+    irq_task_cfg.attr.priority = PPP_IRQ_PROCESS_TASK_PRIO;  // 优先级24(对应原MIDDLE)
+    irq_task_cfg.attr.stack_size = PPP_IRQ_PROCESS_STACK_SIZE;
+    irq_task_cfg.func = (osThreadFunc_t)ppp_irq_process_thread;
+    irq_task_cfg.task_handle = &g_ppp_irq_process_task;
+    irq_task_cfg.use_mem = USE_EXTEND_MEM;  // ⭐ 关键:使用 PSRAM 分配栈
+    irq_task_cfg.create_queue_handle = NULL;
+    
+    ret = uapi_create_osThread_custom(&irq_task_cfg);
+    if (ret != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to create IRQ process thread: 0x%x", ret);
+        osal_msg_queue_delete(g_ppp_irq_msg_queue);
+        g_ppp_irq_msg_queue = 0;
+        g_ppp_irq_task_running = false;
+        free(g_ping_pong_buffers);
+        g_ping_pong_buffers = NULL;
+        return PPP_ERR_MEMORY;
+    }
+    
+    PPP_DEBUG_WARN("IRQ process thread created with PSRAM stack (handle=0x%X)", 
+                  g_ppp_irq_process_task);
+    PPP_DEBUG_INFO("Process thread: stack=%d bytes in PSRAM, priority=Normal(24)", 
+                  PPP_IRQ_PROCESS_STACK_SIZE);
+    
+    // 5. 启动定时器(30ms周期检查buffer超时)
+    // 先设置timer的handler、data和interval
+    g_ppp_timeout_timer.handler = ppp_timeout_timer_callback;
+    g_ppp_timeout_timer.data = 0;
+    g_ppp_timeout_timer.interval = PPP_PING_PONG_TIMEOUT_MS;
+    
+    ret = osal_timer_init(&g_ppp_timeout_timer);
+    if (ret != OSAL_SUCCESS) {
+        PPP_DEBUG_ERROR("Failed to init timeout timer: 0x%x", ret);
+        g_ppp_irq_task_running = false;
+        osal_msleep(100);
+        osal_msg_queue_delete(g_ppp_irq_msg_queue);
+        g_ppp_irq_msg_queue = 0;
+        free(g_ping_pong_buffers);
+        g_ping_pong_buffers = NULL;
+        return PPP_ERR_MEMORY;
+    }
+    
+    g_ppp_timer_running = true;
+    ret = osal_timer_start(&g_ppp_timeout_timer);
+    if (ret != OSAL_SUCCESS) {
+        PPP_DEBUG_ERROR("Failed to start timeout timer: 0x%x", ret);
+        g_ppp_timer_running = false;
+        g_ppp_irq_task_running = false;
+        osal_timer_destroy(&g_ppp_timeout_timer);
+        osal_msleep(100);
+        osal_msg_queue_delete(g_ppp_irq_msg_queue);
+        g_ppp_irq_msg_queue = 0;
+        free(g_ping_pong_buffers);
+        g_ping_pong_buffers = NULL;
+        return PPP_ERR_MEMORY;
+    }
+    
+    PPP_DEBUG_INFO("Timeout timer started (period=%d ms)", PPP_PING_PONG_TIMEOUT_MS);
+    
+    // 6. 注册UART中断回调
+    uint8_t uart_bus = ppp_serial_get_uart_bus();
+    
+    PPP_DEBUG_INFO("Registering UART RX callback:");
+    PPP_DEBUG_INFO("  UART Bus: %d", uart_bus);
+    PPP_DEBUG_INFO("  Condition: 0x07 (FULL_OR_SUFFICIENT_DATA_OR_IDLE)");
+    PPP_DEBUG_INFO("  Threshold: 8 bytes");
+    PPP_DEBUG_INFO("  Callback: ppp_uart_rx_interrupt_handler @ %p", ppp_uart_rx_interrupt_handler);
+    
+    // ⚠️ 阈值说明:
+    //   - 参数是直接的字节数(不是编码)
+    //   - 8字节阈值确保小数据包能触发(PPP协商包通常30-50字节)
+    //   - 配合IDLE条件,即使不满8字节也会在数据停止时触发
+    ret = uapi_uart_register_rx_callback(
+        uart_bus,
+        0x07,  // UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE
+        8,     // 阈值:8字节
+        ppp_uart_rx_interrupt_handler
+    );
+    
+    PPP_DEBUG_WARN("uapi_uart_register_rx_callback returned: 0x%x (ERRCODE_SUCC=0x%x)", 
+                  ret, ERRCODE_SUCC);
+    
+    if (ret != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to register UART RX callback: 0x%x", ret);
+        
+        // 清理资源
+        g_ppp_timer_running = false;
+        osal_timer_stop(&g_ppp_timeout_timer);
+        osal_timer_destroy(&g_ppp_timeout_timer);
+        g_ppp_irq_task_running = false;
+        osal_msleep(100);
+        osal_msg_queue_delete(g_ppp_irq_msg_queue);
+        g_ppp_irq_msg_queue = 0;
+        free(g_ping_pong_buffers);
+        g_ping_pong_buffers = NULL;
+        
+        return PPP_ERR_UART;
+    }
+    
+    PPP_DEBUG_INFO("UART RX callback registered successfully!");
+    
+    // 7. 注册UART错误回调(用于详细错误诊断)
+    // 7.1 注册奇偶校验错误回调
+    ret = uapi_uart_register_parity_error_callback(uart_bus, ppp_uart_parity_error_callback);
+    if (ret != ERRCODE_SUCC) {
+        PPP_DEBUG_WARN("Failed to register parity error callback: 0x%x (non-critical)", ret);
+        // 不是关键错误,继续运行
+    } else {
+        PPP_DEBUG_INFO("Parity error callback registered");
+    }
+    
+    // 7.2 注册帧错误回调
+    ret = uapi_uart_register_frame_error_callback(uart_bus, ppp_uart_frame_error_callback);
+    if (ret != ERRCODE_SUCC) {
+        PPP_DEBUG_WARN("Failed to register frame error callback: 0x%x (non-critical)", ret);
+        // 不是关键错误,继续运行
+    } else {
+        PPP_DEBUG_INFO("Frame error callback registered");
+    }
+    
+    g_ppp_interrupt_enabled = true;
+    
+    PPP_DEBUG_WARN("PPP UART interrupt enabled successfully (ping-pong mode)");
+    PPP_DEBUG_WARN("  Ping-pong buffers: %d x %d KB", 
+                  PPP_PING_PONG_BUFFER_COUNT, PPP_PING_PONG_BUFFER_SIZE / 1024);
+    PPP_DEBUG_WARN("  Timeout: %d ms", PPP_PING_PONG_TIMEOUT_MS);
+    PPP_DEBUG_WARN("  Message queue: %d slots (only %d bytes per message)", 
+                  PPP_IRQ_MSG_QUEUE_SIZE, sizeof(ppp_irq_msg_t));
+    PPP_DEBUG_INFO("  ISR latency: <5μs (memcpy + queue_write, no malloc!)");
+#ifdef SUPPORT_N706A_NET
+    PPP_DEBUG_INFO("  Data flow: UART IRQ -> ping-pong buffer -> timer/full flush -> msg_queue -> process_thread -> AT response buffer");
+#else
+    PPP_DEBUG_INFO("  Data flow: UART IRQ -> ping-pong buffer -> timer/full flush -> msg_queue -> process_thread -> pppos_input_tcpip");
+#endif
+    PPP_DEBUG_INFO("  DIAGNOSTIC: Watch for [TIMER] and interrupt stats in ppp_interrupt_print_stats()");
+    
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 禁用PPP UART中断接收
+ */
+ppp_error_t ppp_interrupt_disable(void)
+{
+    if (!g_ppp_interrupt_enabled) {
+        return PPP_ERR_OK;
+    }
+    
+    PPP_DEBUG_INFO("Disabling PPP UART interrupt (ping-pong mode)");
+    
+    // 1. 注销UART中断回调
+    uint8_t uart_bus = ppp_serial_get_uart_bus();
+    uapi_uart_unregister_rx_callback(uart_bus);
+    
+    // 2. 停止定时器
+    if (g_ppp_timer_running) {
+        g_ppp_timer_running = false;
+        osal_timer_stop(&g_ppp_timeout_timer);
+        osal_timer_destroy(&g_ppp_timeout_timer);
+        
+        // ⚠️ 关键修复:清零 timer 指针,否则下次 osal_timer_init 会因为 timer != NULL 而失败
+        // osal_timer_destroy 不会清零 timer->timer,但 osal_timer_init 要求它必须为 NULL
+        g_ppp_timeout_timer.timer = NULL;
+        
+        PPP_DEBUG_INFO("Timeout timer stopped and cleared");
+    }
+    
+    // 3. 停止处理线程
+    g_ppp_irq_task_running = false;
+    
+    // 发送一个空消息以唤醒线程(如果阻塞在队列读取)
+    ppp_irq_msg_t empty_msg = {0};
+    osal_msg_queue_write_copy(g_ppp_irq_msg_queue, &empty_msg, 
+                             sizeof(ppp_irq_msg_t), OSAL_MSGQ_NO_WAIT);
+    
+    // 等待线程退出
+    osal_msleep(200);
+    
+    // 4. 删除消息队列
+    osal_msg_queue_delete(g_ppp_irq_msg_queue);
+    
+    // ⚠️ 关键修复:清零队列句柄,否则下次 osal_msg_queue_create 会因为队列句柄非0而失败或创建新队列
+    // osal_msg_queue_delete 不会清零队列句柄,但下次 create 需要它为 0
+    g_ppp_irq_msg_queue = 0;
+    
+    // 5. ⚠️ 数据安全:在清空前,先按写入顺序flush所有有数据的buffer,确保数据不丢失
+    if (g_ping_pong_buffers != NULL) {
+        PPP_DEBUG_INFO("Flushing all buffers in write order before disable...");
+        
+        // 收集并排序(与 pause 相同的逻辑,确保顺序正确)
+        typedef struct {
+            uint8_t index;
+            uint32_t write_time;
+        } buffer_order_t;
+        
+        buffer_order_t buffers_to_flush[PPP_PING_PONG_BUFFER_COUNT];
+        uint8_t flush_count = 0;
+        
+        for (uint8_t i = 0; i < PPP_PING_PONG_BUFFER_COUNT; i++) {
+            if (g_ping_pong_buffers[i].state == PPP_BUFFER_STATE_FILLING && 
+                g_ping_pong_buffers[i].write_pos > 0) {
+                buffers_to_flush[flush_count].index = i;
+                buffers_to_flush[flush_count].write_time = g_ping_pong_buffers[i].first_write_time;
+                flush_count++;
+            }
+        }
+        
+        // 按 first_write_time 排序
+        for (uint8_t i = 0; i < flush_count; i++) {
+            for (uint8_t j = i + 1; j < flush_count; j++) {
+                if (buffers_to_flush[j].write_time < buffers_to_flush[i].write_time) {
+                    buffer_order_t temp = buffers_to_flush[i];
+                    buffers_to_flush[i] = buffers_to_flush[j];
+                    buffers_to_flush[j] = temp;
+                }
+            }
+        }
+        
+        // 按正确顺序 flush
+        for (uint8_t i = 0; i < flush_count; i++) {
+            uint8_t idx = buffers_to_flush[i].index;
+            PPP_DEBUG_INFO("  Flushing buffer[%u] (write_order=%u): %u bytes", 
+                          idx, i, g_ping_pong_buffers[idx].write_pos);
+            ppp_flush_buffer(idx);
+            // 给处理线程一点时间处理最后的数据
+            osal_msleep(50);
+        }
+    }
+    
+    // 6. 清空乒乓缓冲区
+    if (g_ping_pong_buffers != NULL) {
+        for (uint8_t i = 0; i < PPP_PING_PONG_BUFFER_COUNT; i++) {
+            g_ping_pong_buffers[i].write_pos = 0;
+            g_ping_pong_buffers[i].state = PPP_BUFFER_STATE_EMPTY;
+            g_ping_pong_buffers[i].last_write_time = 0;
+        }
+    }
+    g_current_buffer_index = 0;
+    
+    // 7. 释放动态分配的内存
+    if (g_ping_pong_buffers != NULL) {
+        size_t buffer_size = sizeof(ppp_ping_pong_buffer_t) * PPP_PING_PONG_BUFFER_COUNT;
+        PPP_DEBUG_INFO("Freeing %zu bytes (%.2f KB) of ping-pong buffer memory", 
+                      buffer_size, buffer_size / 1024.0);
+        free(g_ping_pong_buffers);
+        g_ping_pong_buffers = NULL;
+    }
+    
+    // 8. 清零统计信息(为下次启用准备)
+    memset(&g_ppp_interrupt_stats, 0, sizeof(ppp_interrupt_stats_t));
+    memset(&g_pingpong_stats, 0, sizeof(ppp_pingpong_stats_t));
+    memset(&g_uart_error_stats, 0, sizeof(ppp_uart_error_stats_t));
+    memset(&g_ppp_data_state, 0, sizeof(ppp_data_state_t));
+    
+#ifdef SUPPORT_PPP_SERVICE_INTERRUPT
+    // 9. 清理 CAT1 vote(如果之前添加过)
+    if (g_ppp_cat1_vote_added) {
+        cat1_api_remove_cat1_vote();
+        g_ppp_cat1_vote_added = false;
+        PPP_DEBUG_INFO("CAT1 vote removed during PPP interrupt disable");
+    }
+#endif
+    
+    g_ppp_interrupt_enabled = false;
+    g_ppp_irq_process_task = 0;
+    
+    PPP_DEBUG_INFO("PPP UART interrupt disabled (memory freed)");
+    
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 检查中断是否已启用
+ */
+bool ppp_interrupt_is_enabled(void)
+{
+    return g_ppp_interrupt_enabled;
+}
+
+/**
+ * @brief 获取中断统计信息
+ */
+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));
+    memset(&g_pingpong_stats, 0, sizeof(ppp_pingpong_stats_t));
+    memset(&g_uart_error_stats, 0, sizeof(ppp_uart_error_stats_t));
+    PPP_DEBUG_INFO("PPP interrupt statistics reset (including ping-pong and UART error stats)");
+}
+
+/**
+ * @brief 打印中断统计信息(乒乓缓冲区模式)
+ */
+void ppp_interrupt_print_stats(void)
+{
+    PPP_DEBUG_WARN("=== PPP Interrupt Statistics (Ping-Pong Mode) ===");
+    PPP_DEBUG_WARN("Interrupt Status: %s", g_ppp_interrupt_enabled ? "ENABLED" : "DISABLED");
+    PPP_DEBUG_WARN("Ping-Pong Buffers: %d x %d bytes = %d KB total", 
+                   PPP_PING_PONG_BUFFER_COUNT, PPP_PING_PONG_BUFFER_SIZE,
+                   (PPP_PING_PONG_BUFFER_COUNT * PPP_PING_PONG_BUFFER_SIZE) / 1024);
+                   PPP_DEBUG_WARN("Timeout: %d ms", PPP_PING_PONG_TIMEOUT_MS);
+    PPP_DEBUG_WARN("Message Queue: %d slots (%d bytes per message)", 
+                   PPP_IRQ_MSG_QUEUE_SIZE, sizeof(ppp_irq_msg_t));
+    PPP_DEBUG_WARN("");
+    
+    // 乒乓缓冲区状态
+    PPP_DEBUG_WARN("Buffer Status:");
+    if (g_ping_pong_buffers != NULL) {
+        for (uint8_t i = 0; i < PPP_PING_PONG_BUFFER_COUNT; i++) {
+            const char *state_str = "UNKNOWN";
+            switch (g_ping_pong_buffers[i].state) {
+                case PPP_BUFFER_STATE_EMPTY:      state_str = "EMPTY"; break;
+                case PPP_BUFFER_STATE_FILLING:    state_str = "FILLING"; break;
+                case PPP_BUFFER_STATE_FULL:       state_str = "FULL"; break;
+                case PPP_BUFFER_STATE_PROCESSING: state_str = "PROCESSING"; break;
+            }
+            PPP_DEBUG_WARN("  Buffer[%u]: %s, %u/%u bytes%s", 
+                          i, state_str, g_ping_pong_buffers[i].write_pos, PPP_PING_PONG_BUFFER_SIZE,
+                          (i == g_current_buffer_index) ? " (current)" : "");
+        }
+    } else {
+        PPP_DEBUG_WARN("  Buffers not allocated");
+    }
+    PPP_DEBUG_WARN("");
+    
+    // 乒乓缓冲区统计
+    PPP_DEBUG_WARN("Ping-Pong Buffer Statistics:");
+    PPP_DEBUG_WARN("  Buffer Full Count: %u", g_pingpong_stats.buffer_full_count);
+    PPP_DEBUG_WARN("  Buffer Timeout Count: %u (total)", g_pingpong_stats.buffer_timeout_count);
+    PPP_DEBUG_WARN("    - Timeout Unfilled: %u ⚠️ (未满即超时)", g_pingpong_stats.timeout_unfilled_count);
+    PPP_DEBUG_WARN("  Buffer Switch Count: %u (success)", g_pingpong_stats.buffer_switch_count);
+    PPP_DEBUG_WARN("  Buffer Switch Failed: %u ⚠️", g_pingpong_stats.switch_failed_count);
+    PPP_DEBUG_WARN("  Cross-Buffer Writes: %u 📌 (跨buffer写入)", g_pingpong_stats.cross_buffer_count);
+    PPP_DEBUG_WARN("  Dropped (Both Full): %u bytes ⚠️", g_pingpong_stats.dropped_both_full);
+    
+    // 填充时间统计
+    if (g_pingpong_stats.fill_time_count > 0) {
+        uint32_t avg_fill_time = g_pingpong_stats.fill_time_total_ms / g_pingpong_stats.fill_time_count;
+        PPP_DEBUG_WARN("  Buffer Fill Time (从首字节到flush):");
+        PPP_DEBUG_WARN("    - Min: %u ms ⏱️", g_pingpong_stats.fill_time_min_ms);
+        PPP_DEBUG_WARN("    - Max: %u ms ⏱️", g_pingpong_stats.fill_time_max_ms);
+        PPP_DEBUG_WARN("    - Avg: %u ms ⏱️", avg_fill_time);
+        PPP_DEBUG_WARN("    - Sample Count: %u", g_pingpong_stats.fill_time_count);
+    } else {
+        PPP_DEBUG_WARN("  Buffer Fill Time: No data yet");
+    }
+    
+    if (g_pingpong_stats.race_condition_detected > 0) {
+        PPP_DEBUG_ERROR("  Race Conditions Detected: %u 🔴", g_pingpong_stats.race_condition_detected);
+    }
+    PPP_DEBUG_WARN("");
+    
+    // 中断层统计
+    PPP_DEBUG_WARN("=== Interrupt Layer Statistics ===");
+    PPP_DEBUG_WARN("Total UART Interrupts: %u", g_ppp_interrupt_stats.total_interrupts);
+    PPP_DEBUG_WARN("  - With RX Error: %u", g_ppp_interrupt_stats.error_count);
+    PPP_DEBUG_WARN("    · Parity Error: %u", g_uart_error_stats.parity_error_count);
+    PPP_DEBUG_WARN("    · Frame Error: %u", g_uart_error_stats.frame_error_count);
+    
+    // 如果有错误,显示错误率和详情
+    if (g_ppp_interrupt_stats.total_interrupts > 0) {
+        uint32_t avg_bytes_per_irq = g_ppp_interrupt_stats.total_bytes_received / 
+                                     g_ppp_interrupt_stats.total_interrupts;
+        PPP_DEBUG_WARN("  Average bytes per interrupt: %u", avg_bytes_per_irq);
+        
+        // 错误率
+        if (g_ppp_interrupt_stats.error_count > 0) {
+            uint32_t error_rate = (g_ppp_interrupt_stats.error_count * 10000) / 
+                                  g_ppp_interrupt_stats.total_interrupts;
+            PPP_DEBUG_WARN("  Error Rate: %u.%02u%%", error_rate / 100, error_rate % 100);
+            
+            // 如果错误率 > 1%,发出警告
+            if (error_rate > 100) {
+                PPP_DEBUG_ERROR("  ⚠️  High error rate! Check UART config and cable.");
+            }
+        }
+    }
+    
+    // 如果有奇偶校验错误,打印最近一次的错误信息
+    if (g_uart_error_stats.parity_error_count > 0) {
+        PPP_DEBUG_INFO("  Last Parity Error Info:");
+        for (uint32_t i = 0; i < 4; i++) {
+            if (g_uart_error_stats.last_parity_error_info[i] != 0) {
+                PPP_DEBUG_INFO("    [%u]: 0x%08X", i, 
+                              g_uart_error_stats.last_parity_error_info[i]);
+            }
+        }
+    }
+    
+    // 如果有帧错误,打印最近一次的错误信息
+    if (g_uart_error_stats.frame_error_count > 0) {
+        PPP_DEBUG_INFO("  Last Frame Error Info:");
+        for (uint32_t i = 0; i < 4; i++) {
+            if (g_uart_error_stats.last_frame_error_info[i] != 0) {
+                PPP_DEBUG_INFO("    [%u]: 0x%08X", i, 
+                              g_uart_error_stats.last_frame_error_info[i]);
+            }
+        }
+    }
+    PPP_DEBUG_WARN("");
+    
+    // 消息层统计
+    PPP_DEBUG_WARN("=== Message Layer Statistics ===");
+    PPP_DEBUG_WARN("Total Messages Sent to lwIP: %u", g_ppp_interrupt_stats.success_count);
+    PPP_DEBUG_WARN("  - lwIP Accept Error: %u", g_ppp_interrupt_stats.lwip_error_count);
+    if (g_ppp_interrupt_stats.success_count > 0) {
+        uint32_t avg_bytes = g_ppp_interrupt_stats.total_bytes_sent_to_lwip / 
+                            g_ppp_interrupt_stats.success_count;
+        PPP_DEBUG_WARN("  Average bytes per message: %u", avg_bytes);
+        
+        // 计算中断聚合比例
+        if (g_ppp_interrupt_stats.total_interrupts > 0) {
+            uint32_t irq_per_msg = g_ppp_interrupt_stats.total_interrupts / 
+                                   g_ppp_interrupt_stats.success_count;
+            PPP_DEBUG_WARN("  Interrupts per message: ~%u (aggregation ratio)", irq_per_msg);
+        }
+    }
+    PPP_DEBUG_WARN("");
+    
+    // lwIP PPP帧解析层统计
+    PPP_DEBUG_WARN("=== lwIP PPP Frame Parsing Statistics ===");
+#if LINK_STATS
+    PPP_DEBUG_WARN("Valid Frames Received: %u ✓", (uint32_t)lwip_stats.link.recv);
+    PPP_DEBUG_WARN("Frames Transmitted: %u", (uint32_t)lwip_stats.link.xmit);
+    
+    // 解析错误统计
+    uint32_t total_parse_errors = (uint32_t)(lwip_stats.link.drop + 
+                                             lwip_stats.link.chkerr + 
+                                             lwip_stats.link.lenerr + 
+                                             lwip_stats.link.memerr);
+    if (total_parse_errors > 0) {
+        PPP_DEBUG_WARN("Parse Errors: %u ⚠️", total_parse_errors);
+        PPP_DEBUG_WARN("  - FCS Checksum Error: %u", (uint32_t)lwip_stats.link.chkerr);
+        PPP_DEBUG_WARN("  - Length Error (incomplete): %u", (uint32_t)lwip_stats.link.lenerr);
+        PPP_DEBUG_WARN("  - Memory Error: %u", (uint32_t)lwip_stats.link.memerr);
+        PPP_DEBUG_WARN("  - Other Drop: %u", (uint32_t)lwip_stats.link.drop);
+        
+        // 计算错误率
+        uint32_t total_frames = (uint32_t)(lwip_stats.link.recv + total_parse_errors);
+        if (total_frames > 0) {
+            uint32_t error_rate = (total_parse_errors * 10000) / total_frames;
+            PPP_DEBUG_WARN("  Frame Error Rate: %u.%02u%%", error_rate / 100, error_rate % 100);
+            
+            // FCS错误率(如果有)
+            if (lwip_stats.link.chkerr > 0) {
+                uint32_t fcs_rate = ((uint32_t)lwip_stats.link.chkerr * 10000) / total_frames;
+                PPP_DEBUG_WARN("  FCS Error Rate: %u.%02u%% (check UART/cable)", 
+                              fcs_rate / 100, fcs_rate % 100);
+            }
+        }
+    } else {
+        PPP_DEBUG_WARN("Parse Errors: 0 ✓ (no errors)");
+    }
+#else
+    PPP_DEBUG_WARN("LINK_STATS not enabled in lwIP");
+#endif
+    PPP_DEBUG_WARN("");
+    
+    // 字节统计(与轮询模式格式一致)
+    uint32_t total_discarded = g_ppp_interrupt_stats.dropped_not_initialized + 
+                                g_ppp_interrupt_stats.dropped_lwip_error +
+                                g_ppp_interrupt_stats.dropped_queue_full +
+                                g_pingpong_stats.dropped_both_full;
+    
+    PPP_DEBUG_WARN("=== Byte-Level Statistics ===");
+    PPP_DEBUG_WARN("Total Bytes Received (UART): %u", g_ppp_interrupt_stats.total_bytes_received);
+    PPP_DEBUG_WARN("Total Bytes Sent to lwIP: %u", g_ppp_interrupt_stats.total_bytes_sent_to_lwip);
+    
+    // 丢弃统计
+    if (total_discarded > 0) {
+        PPP_DEBUG_WARN("Total Bytes Discarded: %u ⚠️", total_discarded);
+        PPP_DEBUG_WARN("  - Both Buffers Full: %u", g_pingpong_stats.dropped_both_full);
+        PPP_DEBUG_WARN("  - Queue Full: %u", g_ppp_interrupt_stats.dropped_queue_full);
+        PPP_DEBUG_WARN("  - Not Initialized: %u", g_ppp_interrupt_stats.dropped_not_initialized);
+        PPP_DEBUG_WARN("  - lwIP Input Error: %u", g_ppp_interrupt_stats.dropped_lwip_error);
+    } else {
+        PPP_DEBUG_WARN("Total Bytes Discarded: 0 ✓");
+    }
+    PPP_DEBUG_WARN("");
+    
+    // 计算字节级丢包率
+    if (g_ppp_interrupt_stats.total_bytes_received > 0 && total_discarded > 0) {
+        uint32_t drop_rate = (total_discarded * 10000) / g_ppp_interrupt_stats.total_bytes_received;
+        PPP_DEBUG_WARN("Byte-Level Drop Rate: %u.%02u%%", drop_rate / 100, drop_rate % 100);
+        
+        // 如果丢包率超过1%,提示可能的原因
+        if (drop_rate > 100) {
+            PPP_DEBUG_ERROR("⚠️  High byte drop rate detected!");
+            if (g_pingpong_stats.dropped_both_full > 0) {
+                PPP_DEBUG_ERROR("  -> Buffers too small or processing too slow");
+            }
+            if (g_ppp_interrupt_stats.dropped_queue_full > 0) {
+                PPP_DEBUG_ERROR("  -> Message queue too small or thread blocked");
+            }
+        }
+    }
+    
+    PPP_DEBUG_WARN("=================================================");
+}
+
+/**
+ * @brief 检查是否可以安全执行+++命令切换到命令模式
+ * @return true 安全,false 不安全
+ * 
+ * 判断标准:
+ * 1. PPP已连接(仅PPP模式)
+ * 2. 接收空闲时间 >= 5秒
+ * 3. 接收速率 < 100 bps
+ * 4. 所有buffer都是EMPTY状态
+ * 
+ * @note N706A_NET模式下始终返回true(纯AT模式无需切换)
+ */
+bool ppp_interrupt_is_safe_for_command_switch(void)
+{
+#ifdef SUPPORT_N706A_NET
+    // N706A_NET模式:始终处于AT模式,无需切换,始终安全
+    return true;
+#else
+    // PPP模式:需要检查是否可以安全切换到AT命令模式
+    // 1. 检查PPP是否已连接
+    if (!ppp_lwip_is_connected()) {
+        PPP_DEBUG_DEBUG("[SAFE_CHECK] Not safe: PPP not connected");
+        return false;
+    }
+    
+    uint32_t current_time = g_timer_timestamp_ms;
+    
+    // 2. 检查接收空闲时间
+    if (g_ppp_data_state.last_rx_time_ms == 0) {
+        // 从未接收过数据,认为是空闲
+        PPP_DEBUG_DEBUG("[SAFE_CHECK] No RX data yet, considered idle");
+    } else {
+        uint32_t idle_ms = current_time - g_ppp_data_state.last_rx_time_ms;
+        if (idle_ms < PPP_SAFE_SWITCH_IDLE_MS) {
+            PPP_DEBUG_DEBUG("[SAFE_CHECK] Not safe: RX idle=%ums < threshold=%ums", 
+                           idle_ms, PPP_SAFE_SWITCH_IDLE_MS);
+            return false;
+        }
+    }
+    
+    // 3. 检查接收速率
+    if (g_ppp_data_state.rx_rate_bps > PPP_LIGHT_THRESHOLD_BPS) {
+        PPP_DEBUG_DEBUG("[SAFE_CHECK] Not safe: RX rate=%u bps > threshold=%u bps", 
+                       g_ppp_data_state.rx_rate_bps, PPP_LIGHT_THRESHOLD_BPS);
+        return false;
+    }
+    
+    // 4. 检查所有buffer是否空闲
+    if (g_ping_pong_buffers != NULL) {
+        uint32_t non_empty_count = 0;
+        for (uint8_t i = 0; i < PPP_PING_PONG_BUFFER_COUNT; i++) {
+            if (g_ping_pong_buffers[i].state != PPP_BUFFER_STATE_EMPTY) {
+                non_empty_count++;
+                PPP_DEBUG_DEBUG("[SAFE_CHECK] Buffer[%u] not empty (state=%d)", 
+                               i, g_ping_pong_buffers[i].state);
+            }
+        }
+        if (non_empty_count > 0) {
+            PPP_DEBUG_DEBUG("[SAFE_CHECK] Not safe: %u buffers not empty", non_empty_count);
+            return false;
+        }
+    }
+    
+    // 全部检查通过
+    uint32_t idle_ms = (g_ppp_data_state.last_rx_time_ms > 0) ?
+                       (current_time - g_ppp_data_state.last_rx_time_ms) : 0xFFFFFFFF;
+    PPP_DEBUG_INFO("[SAFE_CHECK] ✓ Safe for command switch (idle=%ums, rate=%u bps)", 
+                  idle_ms, g_ppp_data_state.rx_rate_bps);
+    return true;
+#endif  // SUPPORT_N706A_NET
+}
+
+/**
+ * @brief 等待安全切换窗口
+ * @param timeout_ms 超时时间(毫秒)
+ * @return true 找到安全窗口,false 超时
+ */
+bool ppp_interrupt_wait_for_safe_switch(uint32_t timeout_ms)
+{
+    uint32_t start_time = ppp_get_current_time_ms();
+    uint32_t elapsed = 0;
+    
+    PPP_DEBUG_INFO("[SAFE_WAIT] Waiting for safe switch window (timeout=%ums)...", timeout_ms);
+    
+    while (elapsed < timeout_ms) {
+        if (ppp_interrupt_is_safe_for_command_switch()) {
+            PPP_DEBUG_INFO("[SAFE_WAIT] ✓ Safe window found (waited %ums)", elapsed);
+            return true;
+        }
+        
+        // 短暂休眠,避免占用过多CPU
+        osal_msleep(100);
+        
+        elapsed = ppp_get_current_time_ms() - start_time;
+    }
+    
+    PPP_DEBUG_WARN("[SAFE_WAIT] Timeout after %ums, no safe window found", elapsed);
+    return false;
+}
+
+/**
+ * @brief 打印数据传输状态信息(调试用)
+ */
+void ppp_interrupt_print_data_state(void)
+{
+    uint32_t current_time = g_timer_timestamp_ms;
+    uint32_t idle_ms = (g_ppp_data_state.last_rx_time_ms > 0) ?
+                       (current_time - g_ppp_data_state.last_rx_time_ms) : 0xFFFFFFFF;
+    
+    PPP_DEBUG_WARN("╔═══════════════════════════════════════╗");
+#ifdef SUPPORT_N706A_NET
+    PPP_DEBUG_WARN("║  N706A_NET Data Transfer State        ║");
+#else
+    PPP_DEBUG_WARN("║  PPP Data Transfer State              ║");
+#endif
+    PPP_DEBUG_WARN("╠═══════════════════════════════════════╣");
+#ifndef SUPPORT_N706A_NET
+    PPP_DEBUG_WARN("║ PPP Connected:  %s                    ║", 
+                   ppp_lwip_is_connected() ? "YES" : "NO ");
+#endif
+    PPP_DEBUG_WARN("║ RX Idle Time:   %u ms                 ║", idle_ms);
+    PPP_DEBUG_WARN("║ RX Rate:        %u bytes/sec          ║", g_ppp_data_state.rx_rate_bps);
+#ifdef SUPPORT_PPP_SERVICE_INTERRUPT
+    PPP_DEBUG_WARN("║ CAT1 Vote:      %s                    ║", 
+                   g_ppp_cat1_vote_added ? "ADDED (awake)" : "REMOVED (sleep)");
+#endif
+    PPP_DEBUG_WARN("║ Safe for +++:   %s                    ║", 
+                   ppp_interrupt_is_safe_for_command_switch() ? "YES ✓" : "NO  ✗");
+    PPP_DEBUG_WARN("╠═══════════════════════════════════════╣");
+    
+    // Buffer状态
+    if (g_ping_pong_buffers != NULL) {
+        PPP_DEBUG_WARN("║ Buffer Status:                        ║");
+        for (uint8_t i = 0; i < PPP_PING_PONG_BUFFER_COUNT; i++) {
+            const char *state_str = "?";
+            switch (g_ping_pong_buffers[i].state) {
+                case PPP_BUFFER_STATE_EMPTY:      state_str = "EMPTY     "; break;
+                case PPP_BUFFER_STATE_FILLING:    state_str = "FILLING   "; break;
+                case PPP_BUFFER_STATE_FULL:       state_str = "FULL      "; break;
+                case PPP_BUFFER_STATE_PROCESSING: state_str = "PROCESSING"; break;
+            }
+            PPP_DEBUG_WARN("║   Buffer[%u]: %s              ║", i, state_str);
+        }
+    } else {
+        PPP_DEBUG_WARN("║ Buffers: Not allocated                ║");
+    }
+    
+    PPP_DEBUG_WARN("╚═══════════════════════════════════════╝");
+}
+
+/**
+ * @brief 暂停PPP中断处理(用于临时切换到AT模式)
+ * @return PPP_ERR_OK 成功,其他值失败
+ * 
+ * 极简设计(只需停止 UART 中断):
+ * 
+ * 关键机制:
+ * 1. UART 中断停止 → 无新数据写入 buffer
+ * 2. Timer 继续运行 → 自动 flush buffer 中的残留数据
+ * 3. 线程继续运行 → 自动处理完队列后阻塞(使用 OSAL_MSGQ_WAIT_FOREVER)
+ * 
+ * 不需要:
+ * - ✗ 不停止 timer(让它自动 flush)
+ * - ✗ 不手动 flush buffer(timer 会处理)
+ * - ✗ 不等待队列排空(线程会自动阻塞)
+ * - ✗ 不暂停线程(阻塞队列读取是天然的暂停)
+ * 
+ * 资源保留:
+ * - ✓ 消息队列
+ * - ✓ 乒乓缓冲区
+ * - ✓ 统计信息
+ * - ✓ 定时器(继续运行)
+ * - ✓ 线程(自动阻塞)
+ */
+ppp_error_t ppp_interrupt_pause(void)
+{
+    if (!g_ppp_interrupt_enabled) {
+        PPP_DEBUG_WARN("PPP interrupt not enabled, nothing to pause");
+        return PPP_ERR_OK;
+    }
+    
+    PPP_DEBUG_CRITICAL("=== PPP Interrupt Pause (Minimal) ===");
+    
+    // ========== 唯一操作: 注销UART中断回调 ==========
+    uint8_t uart_bus = ppp_serial_get_uart_bus();
+    uapi_uart_unregister_rx_callback(uart_bus);
+    PPP_DEBUG_INFO("UART RX callback unregistered");
+    
+    // ========== 自动处理机制(无需手动操作)==========
+    // ✓ Timer 继续运行(g_ppp_timer_running 保持 true)
+    //   → 定期检查 buffer(30ms 周期)
+    //   → 发现有数据就自动 flush 到队列
+    //   → 最终所有 buffer 都会被 flush 干净
+    //   → buffer 按 first_write_time 排序 flush,保证顺序正确
+    //
+    // ✓ 线程继续运行(使用 OSAL_MSGQ_WAIT_FOREVER)
+    //   → 从队列读取并处理所有消息
+    //   → 队列为空时自然阻塞在 osal_msg_queue_read_copy()
+    //   → 无需 suspend 线程,阻塞读取就是天然的暂停
+    //
+    // ✓ 资源完全保留
+    //   → 消息队列保持
+    //   → 乒乓缓冲区保持
+    //   → 统计信息保持
+    //   → 定时器保持运行
+    //   → 线程保持(阻塞状态)
+    
+    PPP_DEBUG_INFO("Timer auto-flushes residual data, thread auto-blocks on empty queue");
+    PPP_DEBUG_CRITICAL("=== PPP Interrupt Paused ===");
+    PPP_DEBUG_INFO("All resources preserved, ready for quick resume");
+    
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 恢复PPP中断处理(从AT模式返回)
+ * @return PPP_ERR_OK 成功,其他值失败
+ * 
+ * 极简设计(只需重新注册 UART 中断):
+ * 
+ * 关键机制:
+ * 1. Timer 一直在运行 → 已自动 flush 所有 buffer
+ * 2. 线程自动唤醒 → 当新数据到达队列时自动从阻塞中返回
+ * 3. Buffer 已经干净 → Timer 已经 flush 过了
+ * 
+ * 不需要:
+ * - ✗ 不验证资源(pause 时保留了所有资源)
+ * - ✗ 不清理 buffer(timer 已经 flush 过了)
+ * - ✗ 不重启 timer(一直在运行)
+ * - ✗ 不恢复线程(会自动唤醒)
+ */
+ppp_error_t ppp_interrupt_resume(void)
+{
+    if (!g_ppp_interrupt_enabled) {
+        PPP_DEBUG_ERROR("PPP interrupt not enabled, cannot resume");
+        return PPP_ERR_INVALID_STATE;
+    }
+    
+    PPP_DEBUG_CRITICAL("=== PPP Interrupt Resume (Minimal) ===");
+    
+    // ========== 唯一操作: 重新注册UART中断回调 ==========
+    uint8_t uart_bus = ppp_serial_get_uart_bus();
+    
+    errcode_t ret = uapi_uart_register_rx_callback(
+        uart_bus,
+        UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE,
+        8,  // 阈值:8 字节
+        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;
+    }
+    
+    PPP_DEBUG_INFO("UART RX callback registered");
+    
+    // ========== 自动唤醒机制(无需手动操作)==========
+    // ✓ Timer 一直在运行
+    //   → 已经自动 flush 了所有残留数据
+    //   → Buffer 已经是干净的
+    //
+    // ✓ 线程自动唤醒
+    //   → 当新数据到达时,UART 中断写入队列
+    //   → 线程自动从 osal_msg_queue_read_copy() 返回
+    //   → 继续处理新数据
+    //
+    // ✓ 状态自然恢复
+    //   → 无需手动清理或验证
+    //   → 系统自动进入正常工作状态
+    
+    PPP_DEBUG_INFO("Timer kept running, thread auto-wakes on new data");
+    PPP_DEBUG_CRITICAL("=== PPP Interrupt Resumed ===");
+    PPP_DEBUG_INFO("Ready to receive PPP data");
+    
+    return PPP_ERR_OK;
+} 
\ No newline at end of file
diff --git a/code/sdk/zhihui/n706a_net/src/ppp_power_ctl.c b/code/sdk/zhihui/n706a_net/src/ppp_power_ctl.c
new file mode 100644 (file)
index 0000000..67169b6
--- /dev/null
@@ -0,0 +1,495 @@
+/*
+ * @brief PPP模块电源控制实现
+ * @description 提供PPP模块专用的4G电源控制功能,与SLIP模块互斥使用
+ * Copyright (c) CompanyNameMagicTag 2024-2024. All rights reserved.
+ */
+
+#include "ppp_power_ctl.h"
+#include "ppp_debug.h"
+#include "gpio.h"
+#include "gpio_porting.h"
+#include "platform_core.h"
+#include "pinctrl_porting.h"
+#include "osal_debug.h"
+#include "securec.h"
+#include "tcxo.h"  // 用于获取系统时间(去抖用)
+
+// PPP模块的4G控制引脚配置
+static ppp_ctl_pin_4g_t g_ppp_cat1_ctl_pins = {
+    #if defined(BOARD_FD230)
+    PIN_NONE, //bat_pin
+    1,
+    S_AGPIO_L23, // pwr_pin
+    1,
+    S_AGPIO_L28,//reset_pin
+    0,
+    S_AGPIO_L31,//ring_pin
+    1,
+    S_AGPIO_L30,//wakemodem_pin
+    1,
+    #elif defined(BOARD_L22)
+    S_AGPIO_L14, //bat_pin
+    1,
+    S_AGPIO_L23, // pwr_pin
+    1,
+    PIN_NONE,//reset_pin
+    0,
+    S_AGPIO_L31,//ring_pin
+    1,
+    S_AGPIO_L30,//wakemodem_pin
+    1,
+    #elif defined(BOARD_W9) || defined(BOARD_N9)
+    S_AGPIO_L17, //bat_pin
+    1,
+    S_AGPIO_L23, // pwr_pin
+    1,
+    S_AGPIO_L28,//reset_pin
+    0,
+    S_AGPIO_L31,//ring_pin
+    1,
+    S_AGPIO_L30,//wakemodem_pin
+    1,
+    #elif defined(BOARD_LEINIAO)
+    S_AGPIO_L18, //bat_pin
+    1,
+    S_AGPIO_L23, // pwr_pin
+    1,
+    S_AGPIO_L24,//reset_pin
+    1, //电路中 控制gpio拉高,reset才拉低
+    S_MGPIO21,//ring_pin GPIO_16
+    2,
+    S_MGPIO22,//wakemodem_pin GPIO_17 Main_DTR
+    1,
+    #else
+    PIN_NONE, //bat_pin
+    1,
+    S_AGPIO_L23, // pwr_pin
+    1,
+    S_AGPIO_L28,//reset_pin
+    0,
+    S_AGPIO_L31,//ring_pin
+    1,
+    S_AGPIO_L30,//wakemodem_pin
+    1,
+    #endif
+};
+
+// PPP模块的4G电源状态
+static bool g_ppp_cat1_power_status = false;
+
+/**
+ * @brief PPP模块GPIO初始化
+ */
+void ppp_api_gpio_init(void)
+{
+    PPP_DEBUG_PRINT("PPP GPIO init\n");
+    
+    pin_t gpiopin=g_ppp_cat1_ctl_pins.bat_pin;
+    if (gpiopin!=PIN_NONE)
+    {
+        uapi_pin_set_mode(gpiopin, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+        uapi_gpio_set_dir(gpiopin,GPIO_DIRECTION_OUTPUT);
+    }
+    gpiopin=g_ppp_cat1_ctl_pins.pwr_pin;
+    if (gpiopin!=PIN_NONE)
+    {
+        uapi_pin_set_mode(gpiopin, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+        uapi_gpio_set_dir(gpiopin,GPIO_DIRECTION_OUTPUT);
+    }
+    gpiopin=g_ppp_cat1_ctl_pins.reset_pin;
+    if (gpiopin!=PIN_NONE)
+    {
+        uapi_pin_set_mode(gpiopin, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+        uapi_gpio_set_dir(gpiopin,GPIO_DIRECTION_OUTPUT);
+    }
+    gpiopin=g_ppp_cat1_ctl_pins.wakemodem_pin;
+    if (gpiopin!=PIN_NONE)
+    {
+        uapi_pin_set_mode(gpiopin, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+        uapi_gpio_set_dir(gpiopin,GPIO_DIRECTION_OUTPUT);
+    }
+
+    gpiopin=g_ppp_cat1_ctl_pins.ring_pin;
+    if (gpiopin != PIN_NONE)
+    {
+        uapi_pin_set_mode(gpiopin, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+        uapi_gpio_set_dir(gpiopin, GPIO_DIRECTION_INPUT);
+        switch (g_ppp_cat1_ctl_pins.ring_pin_en_value)
+        {
+        case 0:
+            uapi_pin_set_pull(gpiopin, (pin_pull_t)HAL_PIO_PULL_UP);
+            uapi_gpio_register_isr_func(gpiopin, GPIO_INTERRUPT_FALLING_EDGE, ppp_ring_isr_callback);
+            PPP_DEBUG_PRINT("PPP: Register ring pin %d falling edge interrupt\n", gpiopin);
+            break;
+        case 1:
+            uapi_pin_set_pull(gpiopin, (pin_pull_t)HAL_PIO_PULL_DOWN);
+            uapi_gpio_register_isr_func(gpiopin, GPIO_INTERRUPT_RISING_EDGE, ppp_ring_isr_callback);
+            PPP_DEBUG_PRINT("PPP: Register ring pin %d rising edge interrupt\n", gpiopin);
+            break;
+        case 2:
+        default:
+            uapi_pin_set_pull(gpiopin, (pin_pull_t)HAL_PIO_PULL_MAX);
+            uapi_gpio_register_isr_func(gpiopin, GPIO_INTERRUPT_DEDGE, ppp_ring_isr_callback);
+            PPP_DEBUG_PRINT("PPP: Register ring pin %d both edge interrupt\n", gpiopin);
+            break;
+        }
+    }
+}
+
+void ppp_api_leiniao_serial_pin_to_gpio_input(void)
+{
+    uapi_pin_set_mode(SIO_UART_TX_PIN, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+    uapi_gpio_set_dir(SIO_UART_TX_PIN, GPIO_DIRECTION_INPUT);
+    uapi_pin_set_mode(SIO_UART_RX_PIN, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+    uapi_gpio_set_dir(SIO_UART_RX_PIN, GPIO_DIRECTION_INPUT);
+    PPP_DEBUG_PRINT("PPP: Leiniao serial pin to gpio input\n");
+}
+
+/**
+ * @brief PPP模块设置电源引脚状态
+ */
+uint32_t ppp_api_cat1_power_pin(uint32_t pwron)
+{
+    pin_t en_pin = g_ppp_cat1_ctl_pins.pwr_pin;
+    uint8_t en_value = g_ppp_cat1_ctl_pins.pwr_pin_en_value;
+    
+    if (en_pin == PIN_NONE) {
+        PPP_DEBUG_PRINT("PPP: cat1_power_on en_pin is none\n");
+        return 0xff;
+    }
+    
+    if (pwron == 0) {
+        uapi_gpio_set_dir(en_pin, GPIO_DIRECTION_OUTPUT);
+        if (en_value) {
+            uapi_gpio_set_val(en_pin, GPIO_LEVEL_LOW);
+            PPP_DEBUG_PRINT("PPP: Power Cat1 Off! pin %d value low\n", en_pin);
+        } else {
+            uapi_gpio_set_val(en_pin, GPIO_LEVEL_HIGH);
+            PPP_DEBUG_PRINT("PPP: Power Cat1 Off! pin %d value high\n", en_pin);
+        }
+    } else {
+        uapi_gpio_set_dir(en_pin, GPIO_DIRECTION_OUTPUT);
+        if (en_value) {
+            uapi_gpio_set_val(en_pin, GPIO_LEVEL_HIGH);
+            PPP_DEBUG_PRINT("PPP: Power Cat1 On! pin %d value high\n", en_pin);
+        } else {
+            uapi_gpio_set_val(en_pin, GPIO_LEVEL_LOW);
+            PPP_DEBUG_PRINT("PPP: Power Cat1 On! pin %d value low\n", en_pin);
+        }
+    }
+    return 0;
+}
+
+/**
+ * @brief PPP模块设置复位引脚状态
+ */
+uint32_t ppp_api_cat1_reset_pin(uint32_t pwron)
+{
+    pin_t en_pin = g_ppp_cat1_ctl_pins.reset_pin;
+    uint8_t en_value = g_ppp_cat1_ctl_pins.reset_pin_en_value;
+
+    if (en_pin == PIN_NONE) {
+        PPP_DEBUG_PRINT("PPP: cat1_reset en_pin is none\n");
+        return 0xff;
+    }
+
+    if (pwron == 0) { //取消复位
+        uapi_gpio_set_dir(en_pin, GPIO_DIRECTION_OUTPUT);
+        if (en_value) { //拉高复位,取消复位,应拉低
+            uapi_gpio_set_val(en_pin, GPIO_LEVEL_LOW);
+            PPP_DEBUG_PRINT("PPP: Cat1 reset Off! pin %d value low\n", en_pin);
+        } else { //拉低复位,取消复位,应拉高
+            uapi_gpio_set_val(en_pin, GPIO_LEVEL_HIGH);
+            PPP_DEBUG_PRINT("PPP: Cat1 reset Off! pin %d value high\n", en_pin);
+        }
+    } else { //复位
+        uapi_gpio_set_dir(en_pin, GPIO_DIRECTION_OUTPUT);
+        if (en_value) { //拉高复位
+            uapi_gpio_set_val(en_pin, GPIO_LEVEL_HIGH);
+            PPP_DEBUG_PRINT("PPP: Cat1 reset On! pin %d value high\n", en_pin);
+        } else { //拉低复位
+            uapi_gpio_set_val(en_pin, GPIO_LEVEL_LOW);
+            PPP_DEBUG_PRINT("PPP: Cat1 reset On! pin %d value low\n", en_pin);
+        }
+    }
+    uint8_t value = uapi_gpio_get_output_val(en_pin);
+    PPP_DEBUG_PRINT("PPP: Cat1 reset value %d\n", value);
+    return 0;
+}
+
+/**
+ * @brief PPP模块设置电池引脚状态
+ */
+uint32_t ppp_api_cat1_bat_pin(uint32_t pwron)
+{
+    pin_t en_pin = g_ppp_cat1_ctl_pins.bat_pin;
+    uint8_t en_value = g_ppp_cat1_ctl_pins.bat_pin_en_value;
+
+    if (en_pin == PIN_NONE) {
+        PPP_DEBUG_PRINT("PPP: cat1_bat_on en_pin is none\n");
+        return 0xff;
+    }
+
+    if (pwron == 0) {
+        uapi_gpio_set_dir(en_pin, GPIO_DIRECTION_OUTPUT);
+        if (en_value) {
+            uapi_gpio_set_val(en_pin, GPIO_LEVEL_LOW);
+            PPP_DEBUG_PRINT("PPP: Cat1 bat Off! pin %d value low\n", en_pin);
+        } else {
+            uapi_gpio_set_val(en_pin, GPIO_LEVEL_HIGH);
+            PPP_DEBUG_PRINT("PPP: Cat1 bat Off! pin %d value high\n", en_pin);
+        }
+    } else {
+        uapi_gpio_set_dir(en_pin, GPIO_DIRECTION_OUTPUT);
+        if (en_value) {
+            uapi_gpio_set_val(en_pin, GPIO_LEVEL_HIGH);
+            PPP_DEBUG_PRINT("PPP: Cat1 bat On! pin %d value high\n", en_pin);
+        } else {
+            uapi_gpio_set_val(en_pin, GPIO_LEVEL_LOW);
+            PPP_DEBUG_PRINT("PPP: Cat1 bat On! pin %d value low\n", en_pin);
+        }
+    }
+    return 0;
+}
+
+/**
+ * @brief PPP模块检查4G是否使能
+ */
+bool ppp_api_is_cat1_enabled(void)
+{
+#if defined(BOARD_W9) || defined(BOARD_N9) || defined(BOARD_LEINIAO)
+    pin_t en_pin = g_ppp_cat1_ctl_pins.bat_pin;
+    uint8_t en_value = g_ppp_cat1_ctl_pins.bat_pin_en_value;
+#else
+    pin_t en_pin = g_ppp_cat1_ctl_pins.pwr_pin;
+    uint8_t en_value = g_ppp_cat1_ctl_pins.pwr_pin_en_value;
+#endif
+    
+    if (en_pin == PIN_NONE) {
+        PPP_DEBUG_PRINT("PPP: is_cat1_enabled en_pin is none\n");
+        return false;
+    }
+    
+    if (en_value == uapi_gpio_get_output_val(en_pin)) {
+        PPP_DEBUG_PRINT("PPP: is_cat1_enabled en_value is %d\n", en_value);
+        return true;
+    } else {
+        PPP_DEBUG_PRINT("PPP: is_cat1_enabled en_value is %d\n", en_value);
+        return false;
+    }
+}
+
+/**
+ * @brief PPP模块4G上电序列
+ */
+void ppp_power_on_cat1(void)
+{
+#if defined(BOARD_FD230)
+    ppp_api_cat1_power_pin(1);    
+    ppp_api_cat1_reset_pin(0);
+#elif (defined(BOARD_W9) || defined(BOARD_N9) )
+    ppp_api_cat1_power_pin(1);  
+    ppp_api_cat1_bat_pin(1);
+    osal_msleep(900);  // 使用OSAL延时函数
+    ppp_api_cat1_power_pin(0);  
+#elif defined(BOARD_LEINIAO)
+    ppp_api_cat1_reset_pin(0);
+    ppp_api_cat1_power_pin(1);  
+    ppp_api_cat1_bat_pin(1);
+    osal_msleep(900);  // 使用OSAL延时函数
+    ppp_api_cat1_power_pin(0);  
+#if defined(PPP_DO_SERIAL_TEST) && (PPP_DO_SERIAL_TEST == 1)
+    ppp_api_cat1_reset_pin(1);
+#endif
+
+#endif
+    
+    g_ppp_cat1_power_status = true;
+    PPP_DEBUG_PRINT("PPP: Cat1 power on sequence completed\n");
+}
+
+/**
+ * @brief PPP模块4G下电序列
+ */
+void ppp_power_off_cat1(void)
+{
+#if defined(BOARD_FD230)
+    ppp_api_cat1_reset_pin(1);
+    ppp_api_cat1_power_pin(0);
+#elif (defined(BOARD_W9) || defined(BOARD_N9) )
+    ppp_api_cat1_power_pin(0);
+    ppp_api_cat1_bat_pin(0);
+#elif defined(BOARD_LEINIAO)
+    ppp_api_cat1_reset_pin(0);
+    ppp_api_cat1_power_pin(0);
+    ppp_api_cat1_bat_pin(0);
+#endif
+    
+    g_ppp_cat1_power_status = false;
+    PPP_DEBUG_PRINT("PPP: Cat1 power off sequence completed\n");
+}
+
+
+void ppp_power_reset_cat1(void)
+{
+    ppp_api_cat1_reset_pin(1);
+    osal_msleep(50);
+    ppp_api_cat1_reset_pin(0);
+}
+
+/**
+ * @brief PPP模块唤醒Cat1
+ */
+void ppp_api_wakeup_cat1(uint8_t wakeup)
+{
+    pin_t wake_pin = g_ppp_cat1_ctl_pins.wakemodem_pin;
+    uint8_t wake_value = g_ppp_cat1_ctl_pins.wakemodem_pin_en_value;
+    
+    if (wake_pin == PIN_NONE) {
+        PPP_DEBUG_PRINT("PPP: wakeup_cat1 wake_pin is none\n");
+        return;
+    }
+    
+    uapi_gpio_set_dir(wake_pin, GPIO_DIRECTION_OUTPUT);
+    if (wakeup) {
+        if (wake_value) {
+            uapi_gpio_set_val(wake_pin, GPIO_LEVEL_HIGH);
+        } else {
+            uapi_gpio_set_val(wake_pin, GPIO_LEVEL_LOW);
+        }
+        PPP_DEBUG_PRINT("PPP: Wakeup Cat1 pin %d\n", wake_pin);
+    } else {
+        if (wake_value) {
+            uapi_gpio_set_val(wake_pin, GPIO_LEVEL_LOW);
+        } else {
+            uapi_gpio_set_val(wake_pin, GPIO_LEVEL_HIGH);
+        }
+        PPP_DEBUG_PRINT("PPP: Release Wakeup Cat1 pin %d\n", wake_pin);
+    }
+}
+
+/**
+ * @brief PPP模块保持唤醒Cat1
+ */
+void ppp_api_keep_wakeup(uint8_t keep_wakeup)
+{
+    // 保持唤醒逻辑实现
+    PPP_DEBUG_PRINT("PPP: Keep wakeup Cat1: %d\n", keep_wakeup);
+}
+
+/**
+ * @brief PPP模块注册4G控制引脚配置
+ */
+errcode_t ppp_register_ctl_pin(ppp_ctl_pin_4g_t *ctl_pin)
+{
+    if (ctl_pin == NULL) {
+        PPP_DEBUG_PRINT("PPP: register_ctl_pin invalid parameter\n");
+        return ERRCODE_INVALID_PARAM;
+    }
+    
+    (void)memcpy_s(&g_ppp_cat1_ctl_pins, sizeof(ppp_ctl_pin_4g_t), 
+                   ctl_pin, sizeof(ppp_ctl_pin_4g_t));
+    
+    PPP_DEBUG_PRINT("PPP: Control pins registered successfully\n");
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief PPP模块Cat1唤醒中断回调函数(带去抖处理)
+ */
+void ppp_ring_isr_callback(pin_t pin, uintptr_t param)
+{
+    (void)param;
+    
+    // ⚠️ 去抖处理:防止信号抖动导致频繁中断
+    static uint64_t last_interrupt_time = 0;
+    static gpio_level_t last_level = GPIO_LEVEL_LOW;
+    static uint32_t same_level_count = 0;
+    
+    uint64_t current_time = uapi_tcxo_get_ms();  // 获取当前时间(毫秒)
+    gpio_level_t val = uapi_gpio_get_val(pin);
+    
+    // 去抖时间窗口:50ms(可根据实际情况调整)
+    #define RING_DEBOUNCE_TIME_MS 50
+    
+    // 检查是否在去抖时间内
+    if ((current_time - last_interrupt_time) < RING_DEBOUNCE_TIME_MS) {
+        // 在去抖时间内,检查电平是否一致
+        if (val == last_level) {
+            same_level_count++;
+            // 如果同一电平连续触发超过5次,打印警告
+            if (same_level_count == 5) {
+                PPP_DEBUG_WARN("PPP: ⚠️ Ring pin %d signal bouncing (level=%d, count=%u)\n", 
+                              pin, val, same_level_count);
+            }
+        } else {
+            same_level_count = 1;
+            last_level = val;
+        }
+        
+        // 清除中断标志,但不处理
+        // uapi_gpio_clear_interrupt(pin);
+        // return;
+    }
+    
+    // 去抖时间已过,处理中断
+    last_interrupt_time = current_time;
+    last_level = val;
+    same_level_count = 1;
+    
+    if (val == GPIO_LEVEL_HIGH) {
+        PPP_DEBUG_WARN("PPP: Cat1 ring interrupt on pin %d → HIGH \n", pin);
+        cat1_api_add_cat1_vote();
+} else {
+        PPP_DEBUG_WARN("PPP: Cat1 ring interrupt on pin %d → LOW\n", pin);
+        //idle后 remove
+    }
+    uapi_gpio_clear_interrupt(pin);
+    
+}
+
+/**
+ * @brief PPP模块专用的4G使能控制接口
+ */
+void ppp_api_enable_cat1(bool isopen)
+{
+    PPP_DEBUG_PRINT("PPP: Enable Cat1: %s\n", isopen ? "true" : "false");
+    
+    if (isopen) {
+        if (g_ppp_cat1_power_status) {
+            PPP_DEBUG_PRINT("PPP: Cat1 already powered on\n");
+            return;
+        }
+        
+        // PPP模块开启4G
+        ppp_power_on_cat1();
+        
+        // 可以在这里添加PPP特定的初始化逻辑
+        // 例如:启动PPP协议栈等
+        
+    } else {
+        if (!g_ppp_cat1_power_status) {
+            PPP_DEBUG_PRINT("PPP: Cat1 already powered off\n");
+            return;
+        }
+        
+        // PPP模块关闭4G
+        ppp_power_off_cat1();
+        
+        // 可以在这里添加PPP特定的清理逻辑
+        // 例如:停止PPP协议栈等
+    }
+}
+
+/**
+ * @brief PPP模块反初始化
+ */
+void ppp_api_deinit(void)
+{
+    PPP_DEBUG_PRINT("PPP: deinit\n");
+    
+    // 关闭电源
+    ppp_api_cat1_power_pin(0);
+    
+    g_ppp_cat1_power_status = false;
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/n706a_net/src/ppp_serial.c b/code/sdk/zhihui/n706a_net/src/ppp_serial.c
new file mode 100644 (file)
index 0000000..4d30498
--- /dev/null
@@ -0,0 +1,971 @@
+#include "ppp_serial.h"
+#include "ppp_config.h"
+#include "ppp_types.h"
+#include "ppp_debug.h"
+#include "uart.h"  // 简化路径
+#include "schedule/osal_task.h"
+#include "semaphore/osal_semaphore.h"
+#include "lock/osal_mutex.h"
+#include "memory/osal_addr.h"
+#include "soc_osal.h"
+#include "securec.h"
+#include <string.h>
+#include "arch_port.h"
+#include "pmu_interrupt.h"  // PMU中断管理:UART唤醒配置
+#include "pm_definition.h"
+
+/* PPP性能优化配置 */
+#define PPP_OPTIMIZED_UART_WRITE_TIMEOUT    200    /* UART写超时优化: 1000ms -> 200ms */
+#define PPP_OPTIMIZED_UART_READ_TIMEOUT     100    /* UART读超时优化: 200ms -> 100ms */
+#if defined(CONFIG_UART_SUPPORT_DMA)
+/*
+
+uint8_t src_width;          源端传输数据宽度   - 0: 1字节
+                                 *           - 1: 2字节
+                                 *           - 2: 4字节
+uint8_t dest_width;         目的端传输数据宽度 - 0: 1字节
+                                *           - 1: 2字节
+                                *           - 2: 4字节
+uint8_t burst_length;                       - 0: burst长度是1
+                                *           - 1: burst长度是4
+                                *           - 2: burst长度是8
+                                *           - 3: burst长度是16
+uint8_t priority;           传输通道优先级(最小为0以及最大为3) 
+*/
+#define UART_DMA_WIDTH                         2
+#define UART_DMA_BURST_LENGTH                  3
+#define UART_DMA_PRIORITY                      2
+#define UART_DMA_TX_ENABLE                     0
+#define UART_DMA_RX_ENABLE                     1
+#endif
+/* 串口上下文结构 - 优化缓存机制 */
+typedef struct {
+    bool initialized;
+    ppp_serial_mode_t current_mode;
+    uint8_t uart_bus;
+    uint8_t irq_num;
+    
+    /* UART配置参数 */
+    uart_pin_config_t pin_config;
+    uart_attr_t uart_attr;
+    uart_buffer_config_t buffer_config;
+    uart_extra_attr_t extra_attr;
+    
+    /* 统一的接收缓冲区(AT和PPP模式共用) */
+    uint8_t *rx_buffer;
+    uint32_t rx_buffer_size;
+    uint32_t rx_head;
+    uint32_t rx_tail;
+    uint32_t rx_count;
+    
+    /* 同步对象 */
+    osal_mutex rx_mutex;        // 改为结构体而不是指针
+    osal_semaphore rx_semaphore; // 改为结构体而不是指针
+    
+    /* 回调函数 */
+    ppp_serial_rx_callback_t rx_callback;
+    void *rx_callback_arg;
+    
+    /* 统计信息 */
+    uint32_t tx_bytes;
+    uint32_t rx_bytes;
+    uint32_t tx_errors;
+    uint32_t rx_errors;
+    
+    /* 智能flush策略相关 */
+    uint32_t last_tx_time;              // 最后发送时间(ms)
+    uint32_t consecutive_small_packets; // 连续小包计数
+    uint32_t idle_flush_threshold;      // 空闲flush阈值(ms)
+} ppp_serial_context_t;
+
+static ppp_serial_context_t g_serial_ctx = {0};
+
+/* 内部函数声明 */
+static void ppp_serial_rx_callback(const void *buffer, uint16_t length, bool remaining);
+static uint32_t ppp_serial_buffer_available_space(void);
+static uint32_t ppp_serial_buffer_data_count(void);
+/* ppp_serial_is_ppp_control_packet() 已删除 - N706A_NET不需要PPP协议检测 */
+static uint32_t ppp_serial_get_current_time_ms(void);
+static ppp_error_t ppp_serial_register_irq(void);
+static ppp_error_t ppp_serial_unregister_irq(void);
+
+/* IRQ相关代码已移除 - 使用简化的直接UART读取方式 */
+
+/**
+ * @brief 初始化PPP串口 - 统一缓冲区管理
+ */
+ppp_error_t ppp_serial_init(const ppp_serial_config_t *config)
+{
+    if (!config || g_serial_ctx.initialized) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+
+    PPP_DEBUG_INFO("=== PPP Serial Initialization Start ===");
+    PPP_DEBUG_DEBUG("Initializing PPP serial with unified buffer management");
+    
+    /* 配置参数 - 降级为DEBUG级别 */
+    PPP_DEBUG_DEBUG("Configuration parameters:");
+    PPP_DEBUG_INFO("  - UART Bus: %u", config->uart_bus);
+    PPP_DEBUG_DEBUG("  - IRQ Num: %u", config->irq_num);
+    PPP_DEBUG_INFO("  - Baudrate: %u", config->baudrate);
+    PPP_DEBUG_DEBUG("  - TX Pin: %u", config->tx_pin);
+    PPP_DEBUG_DEBUG("  - RX Pin: %u", config->rx_pin);
+    PPP_DEBUG_DEBUG("  - RX Buffer Size: %u bytes", config->rx_buffer_size);
+    PPP_DEBUG_DEBUG("  - RX Callback: %s", config->rx_callback ? "Set" : "NULL");
+
+    /* 配置UART参数 */
+    g_serial_ctx.uart_bus = config->uart_bus;
+    g_serial_ctx.irq_num = config->irq_num;
+    g_serial_ctx.pin_config.tx_pin = config->tx_pin;
+    g_serial_ctx.pin_config.rx_pin = config->rx_pin;
+    g_serial_ctx.uart_attr.baud_rate = config->baudrate;
+    g_serial_ctx.uart_attr.data_bits = UART_DATA_BIT_8;
+    g_serial_ctx.uart_attr.stop_bits = UART_STOP_BIT_1;
+    g_serial_ctx.uart_attr.parity = UART_PARITY_NONE;
+
+    PPP_DEBUG_DEBUG("UART attributes configured:");
+    PPP_DEBUG_DEBUG("  - Baud Rate: %u", g_serial_ctx.uart_attr.baud_rate);
+    PPP_DEBUG_DEBUG("  - Data Bits: %d", g_serial_ctx.uart_attr.data_bits);
+    PPP_DEBUG_DEBUG("  - Stop Bits: %d", g_serial_ctx.uart_attr.stop_bits);
+    PPP_DEBUG_DEBUG("  - Parity: %d", g_serial_ctx.uart_attr.parity);
+
+    /* 动态分配统一的接收缓冲区 */
+    g_serial_ctx.rx_buffer_size = config->rx_buffer_size;
+    g_serial_ctx.rx_buffer = (uint8_t *)osal_kmalloc(g_serial_ctx.rx_buffer_size, OSAL_GFP_KERNEL);
+    if (g_serial_ctx.rx_buffer == NULL) {
+        PPP_DEBUG_ERROR("Failed to allocate RX buffer (%u bytes)", g_serial_ctx.rx_buffer_size);
+        return PPP_ERR_MEMORY;
+    }
+    PPP_DEBUG_DEBUG("RX buffer allocated: %u bytes at 0x%p", g_serial_ctx.rx_buffer_size, g_serial_ctx.rx_buffer);
+
+    /* 配置UART使用我们分配的接收缓冲区 */
+    g_serial_ctx.buffer_config.rx_buffer = g_serial_ctx.rx_buffer;
+    g_serial_ctx.buffer_config.rx_buffer_size = g_serial_ctx.rx_buffer_size;
+
+    PPP_DEBUG_DEBUG("UART buffer config:");
+    PPP_DEBUG_DEBUG("  - RX Buffer Address: 0x%p", g_serial_ctx.buffer_config.rx_buffer);
+    PPP_DEBUG_DEBUG("  - RX Buffer Size: %u", g_serial_ctx.buffer_config.rx_buffer_size);
+
+    // errcode_t rett = uapi_uart_deinit(g_serial_ctx.uart_bus);
+    // if (rett != ERRCODE_SUCC) {
+    //     PPP_DEBUG_ERROR("Failed to deinitialize UART: error code = %d (0x%x)", rett, rett);
+    //     osal_kfree(g_serial_ctx.rx_buffer);
+    //     g_serial_ctx.rx_buffer = NULL;
+    //     return PPP_ERR_UART;
+    // }
+    // PPP_DEBUG_INFO("UART deinitialized successfully");
+
+    /* 初始化UART */
+    PPP_DEBUG_DEBUG("Calling uapi_uart_init...");
+    
+    // ⚠️ 修复:区分轮询模式和中断模式的UART初始化策略
+    // - 轮询模式(SUPPORT_PPP_SERVICE_POLLING):uart_porting.c中UART_BUS_0的pin=PIN_NONE,
+    //   未在启动时初始化,需要在这里完整初始化UART(但DMA已在chip_init.c中初始化)
+    // - 中断模式(SUPPORT_PPP_SERVICE_INTERRUPT):uart_porting.c中已完整初始化UART,
+    //   这里只需要设置波特率
+    
+    #if defined(SUPPORT_PPP_SERVICE_POLLING)
+        // 轮询模式:完整初始化UART(注意:DMA已在chip_init.c:152-153初始化,不要重复调用)
+        PPP_DEBUG_WARN("Polling mode: Initializing UART for the first time");
+        #if defined(CONFIG_UART_SUPPORT_DMA)
+        g_serial_ctx.extra_attr.tx_dma_enable = UART_DMA_TX_ENABLE;
+        g_serial_ctx.extra_attr.tx_int_threshold = 0;
+        g_serial_ctx.extra_attr.rx_dma_enable = UART_DMA_RX_ENABLE;
+        g_serial_ctx.extra_attr.rx_int_threshold = 0;
+        PPP_DEBUG_WARN("Polling mode with DMA: TX DMA and RX DMA both enabled");
+        errcode_t ret = uapi_uart_init(g_serial_ctx.uart_bus, 
+            &g_serial_ctx.pin_config,
+            &g_serial_ctx.uart_attr, 
+            &g_serial_ctx.extra_attr, 
+            &g_serial_ctx.buffer_config);
+        #else
+        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);
+        #endif
+    #elif defined(SUPPORT_PPP_SERVICE_INTERRUPT) || defined(SUPPORT_N706A_NET)
+        // 中断模式/N706A_NET模式:UART已在uart_porting.c:uart_config_init()中初始化,只设置波特率
+        PPP_DEBUG_WARN("Interrupt/N706A_NET mode: UART already initialized, updating baudrate");
+        errcode_t ret = uapi_uart_set_attr(g_serial_ctx.uart_bus, &g_serial_ctx.uart_attr);
+    #else
+        #error "SUPPORT_PPP_SERVICE_POLLING, SUPPORT_PPP_SERVICE_INTERRUPT, or SUPPORT_N706A_NET must be defined"
+    #endif
+    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", 
+                       g_serial_ctx.uart_bus, config->tx_pin, config->rx_pin, config->baudrate);
+        osal_kfree(g_serial_ctx.rx_buffer);
+        g_serial_ctx.rx_buffer = NULL;
+        return PPP_ERR_UART;
+    }
+    PPP_DEBUG_INFO("UART initialized successfully ");
+
+    // 使能UART_BUS_0 (UART_L) 的唤醒
+    hal_pmu_lpm_wakeup_action_enable(LPM_EVT_ACTION, TURN_ON, PMU_LPM_MCPU_UART_L0_RX_WAKEUP);
+    hal_pmu_lpm_wakeup_action_enable(LPM_INT_ACTION, TURN_ON, PMU_LPM_MCPU_UART_L0_RX_WAKEUP);
+
+    /* 创建同步对象 */
+    PPP_DEBUG_DEBUG("Creating synchronization objects...");
+    if (osal_mutex_init(&g_serial_ctx.rx_mutex) != OSAL_SUCCESS) {
+        PPP_DEBUG_ERROR("Failed to create RX mutex");
+        osal_kfree(g_serial_ctx.rx_buffer);
+        g_serial_ctx.rx_buffer = NULL;
+        uapi_uart_deinit(g_serial_ctx.uart_bus);
+        return PPP_ERR_MEMORY;
+    }
+    PPP_DEBUG_DEBUG("RX mutex created successfully");
+
+    if (osal_sem_init(&g_serial_ctx.rx_semaphore, 0) != OSAL_SUCCESS) {
+        PPP_DEBUG_ERROR("Failed to create RX semaphore");
+        osal_mutex_destroy(&g_serial_ctx.rx_mutex);
+        osal_kfree(g_serial_ctx.rx_buffer);
+        g_serial_ctx.rx_buffer = NULL;
+        uapi_uart_deinit(g_serial_ctx.uart_bus);
+        return PPP_ERR_MEMORY;
+    }
+    PPP_DEBUG_DEBUG("RX semaphore created successfully");
+
+    /* 初始化缓冲区状态 */
+    g_serial_ctx.rx_head = 0;
+    g_serial_ctx.rx_tail = 0;
+    g_serial_ctx.rx_count = 0;
+    g_serial_ctx.rx_callback = config->rx_callback;
+    g_serial_ctx.rx_callback_arg = config->rx_callback_arg;
+
+    g_serial_ctx.initialized = true;
+    g_serial_ctx.current_mode = PPP_SERIAL_MODE_AT;
+
+    /* 重置统计信息 */
+    g_serial_ctx.tx_bytes = 0;
+    g_serial_ctx.rx_bytes = 0;
+    g_serial_ctx.tx_errors = 0;
+    g_serial_ctx.rx_errors = 0;
+    
+    /* 初始化智能flush策略参数 */
+    g_serial_ctx.last_tx_time = ppp_serial_get_current_time_ms();
+    g_serial_ctx.consecutive_small_packets = 0;
+    g_serial_ctx.idle_flush_threshold = 10;  // 10ms空闲超时
+
+    PPP_DEBUG_DEBUG("Buffer state initialized:");
+    PPP_DEBUG_DEBUG("  - RX Head/Tail/Count: %u/%u/%u", g_serial_ctx.rx_head, g_serial_ctx.rx_tail, g_serial_ctx.rx_count);
+    PPP_DEBUG_DEBUG("  - Current Mode: %d (AT)", g_serial_ctx.current_mode);
+    PPP_DEBUG_DEBUG("  - Initialized Flag: %s", g_serial_ctx.initialized ? "true" : "false");
+
+    PPP_DEBUG_INFO("PPP serial initialized successfully with unified buffer (%u bytes)", g_serial_ctx.rx_buffer_size);
+    PPP_DEBUG_INFO("=== PPP Serial Initialization Complete ===");
+    return PPP_ERR_OK;
+}
+
+
+void check_cat1_uart_wakeup(void)
+{
+    PPP_DEBUG_DEBUG("Checking PPP UART wakeup...");
+    // 检测唤醒状态
+    uint16_t status = pmu_lpm_wakeup_get_status(LPM_EVT_ACTION, PMU_LPM_MCPU_UART_L0_RX_WAKEUP);
+    PPP_DEBUG_DEBUG("PPP UART wakeup status = %d", status);
+    if (status != 0) {
+        PPP_DEBUG_WARN("PPP UART wakeup detected, add cat1 sleep veto");
+        if (pm_veto_get_id_cnt(PM_ID_CAT1) == 0) {
+            uapi_pm_add_sleep_veto(PM_ID_CAT1);
+        }
+    }
+}
+
+/* ========== PPP数据模式切换函数已删除 ========== */
+/* N706A_NET 使用纯AT命令模式,始终处于AT模式,无需切换到PPP数据模式 */
+
+/* ========== AT模式切换函数已删除 ========== */
+/* N706A_NET 始终处于AT模式,无需切换功能 */
+/* 如需清空缓冲区,请使用 ppp_serial_flush_rx() */
+
+/**
+ * @brief 发送数据 - 两种模式都直接通过UART发送
+ */
+ppp_error_t ppp_serial_write(const uint8_t *data, uint32_t length)
+{
+    if (!g_serial_ctx.initialized || !data || length == 0) {
+        PPP_DEBUG_ERROR("Invalid parameters: initialized=%s, data=%p, length=%u", 
+                       g_serial_ctx.initialized ? "true" : "false", data, length);
+        return PPP_ERR_INVALID_PARAM;
+    }
+
+    PPP_DEBUG_DEBUG("=== PPP Serial Write Start ===");
+    #if defined(PPP_LOW_POWER_MODE) && (PPP_LOW_POWER_MODE == 1)
+    ppp_api_wakeup_cat1(true);
+    osal_msleep(1);
+    #endif
+    PPP_DEBUG_DEBUG("Write request: %u bytes in mode %d", length, g_serial_ctx.current_mode);
+    PPP_DEBUG_DEBUG("UART Bus: %u", g_serial_ctx.uart_bus);
+
+    ppp_error_t result = PPP_ERR_OK;
+    int32_t write_result = 0;
+    switch (g_serial_ctx.current_mode) {
+        case PPP_SERIAL_MODE_AT:
+            /* AT命令模式:直接使用UART发送 */
+            PPP_DEBUG_DEBUG("Sending %u bytes via UART (AT mode)", length);
+            // PPP_DEBUG_HEXDUMP(data, length);
+            
+            PPP_DEBUG_DEBUG("Calling uapi_uart_write(bus=%u, data=%p, len=%u, timeout=1000)...", 
+                          g_serial_ctx.uart_bus, data, length, 1000);
+            
+            write_result = uapi_uart_write(g_serial_ctx.uart_bus, data, length, 1000);
+            PPP_DEBUG_DEBUG("uapi_uart_write returned: %d (expected: %u)", write_result, length);
+            
+            if (write_result != (int32_t)length) {
+                PPP_DEBUG_ERROR("UART write failed in AT mode: returned %d, expected %u", write_result, length);
+                PPP_DEBUG_ERROR("Possible causes: UART not initialized, hardware error, or timeout");
+                g_serial_ctx.tx_errors++;
+                result = PPP_ERR_UART;
+            } else {
+                g_serial_ctx.tx_bytes += length;
+                PPP_DEBUG_INFO("Sent %u bytes successfully via UART (total tx: %u bytes)", 
+                              length, g_serial_ctx.tx_bytes);
+            }
+            break;
+
+        case PPP_SERIAL_MODE_PPP_DATA:
+            /* PPP数据模式:直接使用UART发送(与AT模式一致) */
+            PPP_DEBUG_INFO("Sending %u bytes via UART (PPP data mode)", length);
+            
+            /* 检查UART状态 */
+            PPP_DEBUG_DEBUG("UART Bus: %u, Mode: PPP_DATA, TX Bytes: %u, TX Errors: %u", 
+                          g_serial_ctx.uart_bus, g_serial_ctx.tx_bytes, g_serial_ctx.tx_errors);
+            
+            /* 打印要发送的数据 */
+            PPP_DEBUG_PRINT("PPP TX Data: ");
+            for (uint32_t i = 0; i < length && i < 16; i++) {
+                PPP_DEBUG_PRINT("%02X ", data[i]);
+            }
+            if (length > 16) {
+                PPP_DEBUG_PRINT("... (total %u bytes)", length);
+            }
+            PPP_DEBUG_PRINT("\n");
+            
+            PPP_DEBUG_DEBUG("Calling uapi_uart_write(bus=%u, data=%p, len=%u, timeout=%d)...", 
+                          g_serial_ctx.uart_bus, data, length, PPP_OPTIMIZED_UART_WRITE_TIMEOUT);
+            
+            /* 优化UART写超时:使用配置的优化值以提高PPP协商速度 */
+            write_result = uapi_uart_write(g_serial_ctx.uart_bus, data, length, PPP_OPTIMIZED_UART_WRITE_TIMEOUT);
+            PPP_DEBUG_INFO("uapi_uart_write returned: %d (expected: %u)", write_result, length);
+            
+            if (write_result != (int32_t)length) {
+                PPP_DEBUG_ERROR("UART write failed in PPP data mode: returned %d, expected %u", write_result, length);
+                PPP_DEBUG_ERROR("UART状态: bus=%u, 总发送字节=%u, 总错误=%u", 
+                              g_serial_ctx.uart_bus, g_serial_ctx.tx_bytes, g_serial_ctx.tx_errors);
+                PPP_DEBUG_ERROR("可能原因: UART未初始化、硬件错误、超时或缓冲区满");
+                g_serial_ctx.tx_errors++;
+                result = PPP_ERR_UART;
+            } else {
+                g_serial_ctx.tx_bytes += length;
+                PPP_DEBUG_INFO("Sent %u bytes successfully via UART (PPP mode, total tx: %u bytes)", 
+                              length, g_serial_ctx.tx_bytes);
+            }
+            break;
+
+        default:
+            PPP_DEBUG_ERROR("Invalid serial mode: %d", g_serial_ctx.current_mode);
+            result = PPP_ERR_INVALID_PARAM;
+            break;
+    }
+
+    PPP_DEBUG_INFO("Write result: %s (error code: %d)", 
+                   result == PPP_ERR_OK ? "SUCCESS" : "FAILED", result);
+    PPP_DEBUG_INFO("Statistics: tx_bytes=%u, tx_errors=%u", g_serial_ctx.tx_bytes, g_serial_ctx.tx_errors);
+    PPP_DEBUG_INFO("=== PPP Serial Write End ===");
+    #if defined(PPP_LOW_POWER_MODE) && (PPP_LOW_POWER_MODE == 1)
+    ppp_api_wakeup_cat1(false);
+    #endif
+
+    return result;
+}
+
+/**
+ * @brief 读取数据 - AT模式直接从UART读取,PPP模式从软件缓冲区读取
+ */
+ppp_error_t ppp_serial_read(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;
+    }
+    #if defined(PPP_LOW_POWER_MODE) && (PPP_LOW_POWER_MODE == 1)
+    ppp_api_wakeup_cat1(true);
+    osal_msleep(1);
+    #endif
+
+    *bytes_read = 0;
+    ppp_error_t result = PPP_ERR_OK;
+
+    switch (g_serial_ctx.current_mode) {
+        case PPP_SERIAL_MODE_AT:
+        /* AT命令模式:直接从UART读取 */
+            {
+
+                #if defined(CONFIG_UART_SUPPORT_DMA)
+                uart_write_dma_config_t dma_cfg = {
+                    .src_width = UART_DMA_WIDTH,
+                    .dest_width = UART_DMA_WIDTH,
+                    .burst_length = UART_DMA_BURST_LENGTH,
+                    .priority = UART_DMA_PRIORITY
+                };
+                int32_t read_result = uapi_uart_read_by_dma(g_serial_ctx.uart_bus, buffer, buffer_size,&dma_cfg);
+                    
+                #else
+                int32_t read_result = uapi_uart_read(g_serial_ctx.uart_bus, buffer, buffer_size, 100);
+                #endif
+                if (read_result > 0) {
+                    *bytes_read = (uint32_t)read_result;
+                    g_serial_ctx.rx_bytes += *bytes_read;
+                    PPP_DEBUG_DEBUG("Read %u bytes via UART (AT mode)", *bytes_read);
+                } else if (read_result < 0) {
+                    PPP_DEBUG_ERROR("UART read error: %d", read_result);
+                    g_serial_ctx.rx_errors++;
+                    result = PPP_ERR_UART;
+                }
+            }
+            break;
+
+        case PPP_SERIAL_MODE_PPP_DATA:
+        /* PPP数据模式:使用优化的直接UART读取,平衡响应性和完整性 */
+            {
+                /* 使用类似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;
+                    
+                    // 使用短超时进行读取,类似sio_tryread的1ms超时
+                    
+                    #if defined(CONFIG_UART_SUPPORT_DMA)
+                    uart_write_dma_config_t dma_cfg = {
+                        .src_width = UART_DMA_WIDTH,
+                        .dest_width = UART_DMA_WIDTH,
+                        .burst_length = UART_DMA_BURST_LENGTH,
+                        .priority = UART_DMA_PRIORITY
+                    };
+                    int32_t read_result = uapi_uart_read_by_dma(g_serial_ctx.uart_bus, current_buffer, 
+                        remaining,&dma_cfg);
+                        
+                    #else
+                    int32_t read_result = uapi_uart_read(g_serial_ctx.uart_bus, current_buffer, 
+                        remaining, batch_count == 0 ? 10 : 1);
+                    #endif
+                    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);
+                            result = PPP_ERR_UART;
+                            break;
+                        }
+                        break;
+                    }
+                }
+                
+                *bytes_read = total_read;
+                
+                if (total_read > 0) {
+                    PPP_DEBUG_DEBUG("PPP optimized read: %u bytes in %u batches", total_read, batch_count);
+                    result = PPP_ERR_OK;
+                    break;
+                } else {
+                    result = PPP_ERR_OK;
+                    break; // 无数据但无错误
+                }
+            }
+            break;
+#if 0
+        case PPP_SERIAL_MODE_PPP_DATA:
+            /* PPP数据模式:从软件环形缓冲区读取 */
+            osal_mutex_lock(&g_serial_ctx.rx_mutex);
+
+            uint32_t available = ppp_serial_buffer_data_count();
+            if (available == 0) {
+                osal_mutex_unlock(&g_serial_ctx.rx_mutex);
+                return PPP_ERR_OK; // 没有数据可读
+            }
+
+            uint32_t to_read = (available < buffer_size) ? available : buffer_size;
+            
+            for (uint32_t i = 0; i < to_read; i++) {
+                buffer[i] = g_serial_ctx.rx_buffer[g_serial_ctx.rx_tail];
+                g_serial_ctx.rx_tail = (g_serial_ctx.rx_tail + 1) % g_serial_ctx.rx_buffer_size;
+                g_serial_ctx.rx_count--;
+            }
+
+            *bytes_read = to_read;
+            osal_mutex_unlock(&g_serial_ctx.rx_mutex);
+
+            PPP_DEBUG_DEBUG("Read %u bytes from software buffer (PPP data mode)", to_read);
+            // PPP_DEBUG_HEXDUMP(buffer, to_read);
+            break;
+#endif
+        default:
+            PPP_DEBUG_ERROR("Invalid serial mode: %d", g_serial_ctx.current_mode);
+            result = PPP_ERR_INVALID_PARAM;
+            break;
+    }
+
+    #if defined(PPP_LOW_POWER_MODE) && (PPP_LOW_POWER_MODE == 1)
+    ppp_api_wakeup_cat1(false);
+    osal_msleep(1);
+    #endif
+    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数据模式:混合策略(先轮询检测,有数据时用 DMA) */
+        #if defined(CONFIG_UART_SUPPORT_DMA)
+        // ⚠️ 核心问题:uapi_uart_read_by_dma 会阻塞 1 秒等待数据,不适合无数据时的轮询
+        // 解决方案:先用普通读取(timeout=0)快速检测,有数据时再用 DMA 批量读取
+        
+        // 第 1 步:非阻塞检测是否有数据(立即返回)
+        uint8_t probe_buf[8];
+        int32_t probe_result = uapi_uart_read(g_serial_ctx.uart_bus, probe_buf, sizeof(probe_buf), 0);
+        
+        int32_t read_result = 0;
+        
+        if (probe_result > 0) {
+            // 有数据!先复制探测数据,再用 DMA 读取剩余数据
+            static uint32_t dma_call_count = 0;
+            static uint32_t dma_success_count = 0;
+            
+            // 复制探测数据
+            if ((uint32_t)probe_result <= buffer_size) {
+                memcpy(buffer, probe_buf, probe_result);
+                read_result = probe_result;
+            }
+            
+            // 如果 buffer 还有空间,尝试用 DMA 批量读取剩余数据
+            if ((uint32_t)probe_result < buffer_size) {
+                uint32_t remaining = buffer_size - probe_result;
+                // DMA 读取策略:既然已确认有数据,就充分利用 DMA 批量传输能力
+                // 只对足够大的块使用 DMA(>=64字节),小块数据用 DMA 开销反而更大
+                uint32_t dma_size = (remaining >= 64) ? remaining : 0;
+                
+                if (dma_size > 0) {
+                    uart_write_dma_config_t dma_cfg = {
+                        .src_width = UART_DMA_WIDTH,
+                        .dest_width = UART_DMA_WIDTH,
+                        .burst_length = UART_DMA_BURST_LENGTH,
+                        .priority = UART_DMA_PRIORITY
+                    };
+                    
+                    dma_call_count++;
+                    if (dma_call_count == 1) {
+                        PPP_DEBUG_WARN("=== Hybrid Mode: Poll + DMA ===");
+                        PPP_DEBUG_WARN("Poll detects data (instant), DMA reads bulk (8-64 bytes)");
+                    }
+                    
+                    int32_t dma_result = uapi_uart_read_by_dma(g_serial_ctx.uart_bus, 
+                                                               buffer + probe_result, 
+                                                               dma_size, &dma_cfg);
+                    
+                    if (dma_result > 0) {
+                        read_result += dma_result;
+                        dma_success_count++;
+                        if (dma_success_count == 1 || dma_success_count % 50 == 0) {
+                            PPP_DEBUG_WARN("DMA Success #%u: poll %d + DMA %d = %d bytes", 
+                                          dma_success_count, probe_result, dma_result, read_result);
+                        }
+                    } else if (dma_result < 0 && dma_call_count <= 5) {
+                        PPP_DEBUG_ERROR("DMA failed (%d), but poll got %d bytes", 
+                                       dma_result, probe_result);
+                    }
+                }
+            }
+        } else {
+            // 没有数据,立即返回(无阻塞)
+            read_result = 0;
+        }
+        
+        #else
+        int32_t read_result = uapi_uart_read(g_serial_ctx.uart_bus, buffer, buffer_size, 0);
+        #endif
+        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 等待数据接收
+ */
+ppp_error_t ppp_serial_wait_data(uint32_t timeout_ms)
+{
+    if (!g_serial_ctx.initialized) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+
+    /* 检查是否已有数据 */
+    osal_mutex_lock(&g_serial_ctx.rx_mutex);
+    bool has_data = (g_serial_ctx.rx_count > 0);
+    osal_mutex_unlock(&g_serial_ctx.rx_mutex);
+
+    if (has_data) {
+        return PPP_ERR_OK;
+    }
+
+    /* 等待数据到达 */
+    if (osal_sem_wait(&g_serial_ctx.rx_semaphore, timeout_ms) != OSAL_SUCCESS) {
+        return PPP_ERR_TIMEOUT;
+    }
+
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 获取可读数据长度
+ */
+uint32_t ppp_serial_available(void)
+{
+    if (!g_serial_ctx.initialized) {
+        return 0;
+    }
+
+    osal_mutex_lock(&g_serial_ctx.rx_mutex);
+    uint32_t count = ppp_serial_buffer_data_count();
+    osal_mutex_unlock(&g_serial_ctx.rx_mutex);
+
+        return count;
+}
+
+/* 智能flush策略实现函数 */
+
+/**
+ * @brief 获取当前时间(毫秒)
+ */
+static uint32_t ppp_serial_get_current_time_ms(void)
+{
+    unsigned long long jiffies = osal_get_jiffies();
+    return (uint32_t)osal_jiffies_to_msecs((unsigned int)jiffies);
+}
+
+/* ========== PPP控制包检测函数已删除 ========== */
+/* N706A_NET 使用纯AT命令模式,不涉及PPP协议包 */
+
+/**
+ * @brief 定时flush检查函数
+ */
+/**
+ * @brief 清空接收缓冲区
+ */
+void ppp_serial_flush_rx(void)
+{
+    if (!g_serial_ctx.initialized) {
+        return;
+    }
+
+    osal_mutex_lock(&g_serial_ctx.rx_mutex);
+    g_serial_ctx.rx_head = 0;
+    g_serial_ctx.rx_tail = 0;
+    g_serial_ctx.rx_count = 0;
+    osal_mutex_unlock(&g_serial_ctx.rx_mutex);
+
+    PPP_DEBUG_DEBUG("RX buffer flushed");
+}
+
+/**
+ * @brief 设置接收回调函数
+ */
+ppp_error_t ppp_serial_set_rx_callback(ppp_serial_rx_callback_t callback, void *arg)
+{
+    if (!g_serial_ctx.initialized) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+
+    g_serial_ctx.rx_callback = callback;
+    g_serial_ctx.rx_callback_arg = arg;
+
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 去初始化PPP串口
+ */
+void ppp_serial_deinit(void)
+{
+    if (!g_serial_ctx.initialized) {
+        return;
+    }
+
+    PPP_DEBUG_INFO("Deinitializing PPP serial, current mode: %d", g_serial_ctx.current_mode);
+
+    /* 取消注册UART接收回调 */
+    if (g_serial_ctx.current_mode == PPP_SERIAL_MODE_PPP_DATA) {
+        uapi_uart_unregister_rx_callback(g_serial_ctx.uart_bus);
+    }
+
+    /* 关闭UART */
+    uapi_uart_deinit(g_serial_ctx.uart_bus);
+
+    /* 释放缓冲区 */
+    if (g_serial_ctx.rx_buffer) {
+        osal_kfree(g_serial_ctx.rx_buffer);
+        g_serial_ctx.rx_buffer = NULL;
+    }
+
+    /* 销毁同步对象 */
+    osal_mutex_destroy(&g_serial_ctx.rx_mutex);
+    osal_sem_destroy(&g_serial_ctx.rx_semaphore);
+
+    /* 清理上下文 */
+    memset_s(&g_serial_ctx, sizeof(g_serial_ctx), 0, sizeof(g_serial_ctx));
+    PPP_DEBUG_INFO("PPP serial deinitialized");
+}
+
+/**
+ * @brief 获取当前串口模式
+ */
+ppp_serial_mode_t ppp_serial_get_mode(void)
+{
+    return g_serial_ctx.current_mode;
+}
+
+/**
+ * @brief 获取统计信息
+ */
+ppp_error_t ppp_serial_get_stats(ppp_serial_stats_t *stats)
+{
+    if (!g_serial_ctx.initialized || !stats) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+
+    stats->tx_bytes = g_serial_ctx.tx_bytes;
+    stats->rx_bytes = g_serial_ctx.rx_bytes;
+    stats->tx_errors = g_serial_ctx.tx_errors;
+    stats->rx_errors = g_serial_ctx.rx_errors;
+    
+    osal_mutex_lock(&g_serial_ctx.rx_mutex);
+    stats->rx_buffer_usage = g_serial_ctx.rx_count;
+    stats->rx_buffer_size = g_serial_ctx.rx_buffer_size;
+    osal_mutex_unlock(&g_serial_ctx.rx_mutex);
+    
+    // TX buffer removed - no longer used (direct UART write)
+    stats->tx_buffer_usage = 0;
+    stats->tx_buffer_size = 0;
+
+    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;
+} 
+
+/* 内部函数实现 */
+
+/**
+ * @brief 串口接收回调函数
+ */
+static void ppp_serial_rx_callback(const void *buffer, uint16_t length, bool remaining)
+{
+    (void)remaining;
+    
+    /* UART接收回调函数:将数据存储到环形缓冲区 */
+    PPP_DEBUG_INFO("UART Callback: Received %u bytes", length);
+    
+    if (!buffer || length == 0) {
+        return;
+    }
+
+    const uint8_t *data = (const uint8_t *)buffer;
+
+    osal_mutex_lock(&g_serial_ctx.rx_mutex);
+
+    /* 检查缓冲区空间 */
+    uint32_t available_space = ppp_serial_buffer_available_space();
+    if (available_space < length) {
+        PPP_DEBUG_WARN("RX buffer overflow, dropping %u bytes", length - available_space);
+        g_serial_ctx.rx_errors++;
+        length = available_space;
+    }
+
+    /* 将数据复制到环形缓冲区 */
+    for (uint16_t i = 0; i < length; i++) {
+        g_serial_ctx.rx_buffer[g_serial_ctx.rx_head] = data[i];
+        g_serial_ctx.rx_head = (g_serial_ctx.rx_head + 1) % g_serial_ctx.rx_buffer_size;
+        g_serial_ctx.rx_count++;
+    }
+
+    g_serial_ctx.rx_bytes += length;
+
+    osal_mutex_unlock(&g_serial_ctx.rx_mutex);
+
+    /* 通知有数据到达 */
+    osal_sem_up(&g_serial_ctx.rx_semaphore);
+
+    /* 调用用户回调函数 */
+    if (g_serial_ctx.rx_callback) {
+        g_serial_ctx.rx_callback(data, length, g_serial_ctx.rx_callback_arg);
+    }
+
+    PPP_DEBUG_INFO("UART Callback: Received %u bytes", length);
+    
+    // 打印前8字节用于调试
+    PPP_DEBUG_PRINT("UART RX Data: ");
+    for (uint16_t i = 0; i < length && i < 8; i++) {
+        PPP_DEBUG_PRINT("%02X ", data[i]);
+    }
+    if (length > 8) {
+        PPP_DEBUG_PRINT("... (total %u bytes)", length);
+    }
+    PPP_DEBUG_PRINT("\n");
+}
+
+/**
+ * @brief 获取缓冲区可用空间
+ */
+static uint32_t ppp_serial_buffer_available_space(void)
+{
+    return g_serial_ctx.rx_buffer_size - g_serial_ctx.rx_count;
+}
+
+/**
+ * @brief 获取缓冲区数据数量
+ */
+static uint32_t ppp_serial_buffer_data_count(void)
+{
+    return g_serial_ctx.rx_count;
+}
+
+/**
+ * @brief 重置串口状态
+ * @note TX buffer 已移除 - 发送改为直接UART写入
+ */
+ppp_error_t ppp_serial_reset(void)
+{
+    PPP_DEBUG_INFO("=== Serial Reset Started ===");
+    
+    if (!g_serial_ctx.initialized) {
+        PPP_DEBUG_WARN("Serial not initialized");
+        return PPP_ERR_INVALID_STATE;
+    }
+    
+    // 1. 清空接收缓冲区
+    PPP_DEBUG_INFO("Clearing RX buffer...");
+    osal_mutex_lock(&g_serial_ctx.rx_mutex);
+    g_serial_ctx.rx_head = 0;
+    g_serial_ctx.rx_tail = 0;
+    g_serial_ctx.rx_count = 0;
+    osal_mutex_unlock(&g_serial_ctx.rx_mutex);
+    
+    // 2. 重置统计信息
+    g_serial_ctx.tx_bytes = 0;
+    g_serial_ctx.rx_bytes = 0;
+    g_serial_ctx.tx_errors = 0;
+    g_serial_ctx.rx_errors = 0;
+    
+    // 3. 强制设置为AT模式
+    g_serial_ctx.current_mode = PPP_SERIAL_MODE_AT;
+    
+    // 4. 短暂延迟让硬件稳定
+    osal_msleep(50);
+    
+    PPP_DEBUG_INFO("=== Serial Reset Completed ===");
+    return PPP_ERR_OK;
+}
+
+/*
+ * 注意:以下IRQ处理函数暂时不使用,因为UART回调机制已经包含了中断处理
+ * 如果需要更底层的中断控制,可以取消注释并调试IRQ冲突问题
+ */
+
+#if 0
+/**
+ * @brief UART中断处理函数
+ */
+static void _ppp_serial_irq_handler(uint32_t irq_num, void *arg)
+{
+    (void)irq_num;
+    (void)arg;
+    
+    /* 调用HAL层的UART中断处理函数 */
+    hal_uart_irq_handler(g_serial_ctx.uart_bus);
+}
+
+/**
+ * @brief 注册UART中断
+ */
+static ppp_error_t ppp_serial_register_irq(void)
+{
+    PPP_DEBUG_INFO("Registering UART IRQ %d for bus %u", SIO_UART_IRQ_NUM, g_serial_ctx.uart_bus);
+    
+    int32_t ret = osal_irq_request(SIO_UART_IRQ_NUM, _ppp_serial_irq_handler, NULL, "ppp_uart", 0);
+    if (ret != 0) {
+        PPP_DEBUG_ERROR("Failed to register UART IRQ %d: %d", SIO_UART_IRQ_NUM, ret);
+        return PPP_ERR_UART;
+    }
+    
+    PPP_DEBUG_INFO("UART IRQ %d registered successfully", SIO_UART_IRQ_NUM);
+
+    osal_irq_set_priority(SIO_UART_IRQ_NUM, irq_prio(SIO_UART_IRQ_NUM));
+    osal_irq_enable(SIO_UART_IRQ_NUM);
+
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 注销UART中断
+ */
+static ppp_error_t ppp_serial_unregister_irq(void)
+{
+    osal_irq_free(SIO_UART_IRQ_NUM, NULL);
+    osal_irq_disable(SIO_UART_IRQ_NUM);
+    PPP_DEBUG_INFO("UART IRQ %d unregistered successfully", SIO_UART_IRQ_NUM);
+    return PPP_ERR_OK;
+}
+#endif 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/example/n706a_http_tcp_example.c b/code/sdk/zhihui/ppp/example/n706a_http_tcp_example.c
deleted file mode 100644 (file)
index 074f609..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-/**
- * @file n706a_http_tcp_example.c
- * @brief N706A HTTP客户端使用示例(基于TCP实现)
- * 
- * 本示例展示如何使用基于TCP的HTTP/HTTPS客户端:
- * - 支持6个并发连接
- * - HTTP使用普通TCP,HTTPS使用SSL TCP
- * - 完全控制HTTP协议
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "n706a_http_client.h"
-#include "ppp_client.h"
-
-/* ========== 示例1:基本HTTP GET请求 ========== */
-void example_http_get(void)
-{
-    printf("\n=== Example 1: Basic HTTP GET ===\n");
-    
-    n706a_http_client_t client;
-    n706a_http_client_data_t data;
-    char response_buf[4096];
-    char header_buf[1024];
-    
-    /* 初始化HTTP客户端(使用socket 0) */
-    n706a_http_client_init(&client, 0);
-    
-    /* 连接到HTTP服务器 */
-    n706a_httpc_result_t ret = n706a_http_client_connect(&client, 
-        "httpbin.org", 
-        80,      // HTTP端口
-        false    // 不使用SSL
-    );
-    
-    if (ret != N706A_HTTP_SUCCESS) {
-        printf("Failed to connect: %d\n", ret);
-        return;
-    }
-    
-    printf("Connected to httpbin.org:80\n");
-    
-    /* 准备响应缓冲区 */
-    memset(&data, 0, sizeof(data));
-    data.responseBuf = response_buf;
-    data.responseBufLen = sizeof(response_buf);
-    data.headerBuf = header_buf;
-    data.headerBufLen = sizeof(header_buf);
-    
-    /* 发送GET请求 */
-    ret = n706a_http_client_get(&client, "/get", &data);
-    
-    if (ret == N706A_HTTP_SUCCESS) {
-        printf("HTTP Status: %d\n", client.response_code);
-        printf("Response Headers:\n%s\n", header_buf);
-        printf("Response Body:\n%s\n", response_buf);
-    } else {
-        printf("GET request failed: %d\n", ret);
-    }
-    
-    /* 关闭连接 */
-    n706a_http_client_close(&client);
-}
-
-/* ========== 示例2:HTTPS GET请求 ========== */
-void example_https_get(void)
-{
-    printf("\n=== Example 2: HTTPS GET ===\n");
-    
-    n706a_http_client_t client;
-    n706a_http_client_data_t data;
-    char response_buf[4096];
-    
-    /* 初始化(使用socket 1) */
-    n706a_http_client_init(&client, 1);
-    
-    /* 连接到HTTPS服务器 */
-    n706a_httpc_result_t ret = n706a_http_client_connect(&client,
-        "api.github.com",
-        443,    // HTTPS端口
-        true    // 使用SSL
-    );
-    
-    if (ret != N706A_HTTP_SUCCESS) {
-        printf("Failed to connect: %d\n", ret);
-        return;
-    }
-    
-    printf("Connected to api.github.com:443 (SSL)\n");
-    
-    /* 准备响应缓冲区 */
-    memset(&data, 0, sizeof(data));
-    data.responseBuf = response_buf;
-    data.responseBufLen = sizeof(response_buf);
-    
-    /* 发送GET请求 */
-    ret = n706a_http_client_get(&client, "/", &data);
-    
-    if (ret == N706A_HTTP_SUCCESS) {
-        printf("HTTP Status: %d\n", client.response_code);
-        printf("Response: %s\n", response_buf);
-    } else {
-        printf("GET request failed: %d\n", ret);
-    }
-    
-    n706a_http_client_close(&client);
-}
-
-/* ========== 示例3:HTTP POST JSON数据 ========== */
-void example_http_post_json(void)
-{
-    printf("\n=== Example 3: HTTP POST with JSON ===\n");
-    
-    n706a_http_client_t client;
-    n706a_http_client_data_t data;
-    char response_buf[4096];
-    
-    /* 初始化 */
-    n706a_http_client_init(&client, 2);
-    
-    /* 连接 */
-    if (n706a_http_client_connect(&client, "httpbin.org", 80, false) != N706A_HTTP_SUCCESS) {
-        printf("Connection failed\n");
-        return;
-    }
-    
-    /* 准备JSON数据 */
-    const char *json_data = "{\"name\":\"N706A\",\"type\":\"4G Module\",\"vendor\":\"Neoway\"}";
-    
-    /* 准备响应缓冲区 */
-    memset(&data, 0, sizeof(data));
-    data.responseBuf = response_buf;
-    data.responseBufLen = sizeof(response_buf);
-    
-    /* 发送POST请求 */
-    n706a_httpc_result_t ret = n706a_http_client_post(&client,
-        "/post",
-        "application/json",
-        json_data,
-        strlen(json_data),
-        &data
-    );
-    
-    if (ret == N706A_HTTP_SUCCESS) {
-        printf("HTTP Status: %d\n", client.response_code);
-        printf("Response: %s\n", response_buf);
-    } else {
-        printf("POST request failed: %d\n", ret);
-    }
-    
-    n706a_http_client_close(&client);
-}
-
-/* ========== 示例4:自定义请求头 ========== */
-void example_custom_headers(void)
-{
-    printf("\n=== Example 4: Custom Headers ===\n");
-    
-    n706a_http_client_t client;
-    n706a_http_client_data_t data;
-    char response_buf[4096];
-    
-    n706a_http_client_init(&client, 0);
-    
-    /* 设置自定义请求头 */
-    n706a_http_client_set_header(&client, 
-        "X-API-Key: your-api-key-here\r\n"
-        "X-Custom-Header: custom-value\r\n"
-    );
-    
-    /* 连接并请求 */
-    if (n706a_http_client_connect(&client, "httpbin.org", 80, false) == N706A_HTTP_SUCCESS) {
-        memset(&data, 0, sizeof(data));
-        data.responseBuf = response_buf;
-        data.responseBufLen = sizeof(response_buf);
-        
-        n706a_http_client_get(&client, "/headers", &data);
-        
-        printf("Response:\n%s\n", response_buf);
-        
-        n706a_http_client_close(&client);
-    }
-}
-
-/* ========== 示例5:基本认证 ========== */
-void example_basic_auth(void)
-{
-    printf("\n=== Example 5: Basic Authentication ===\n");
-    
-    n706a_http_client_t client;
-    n706a_http_client_data_t data;
-    char response_buf[4096];
-    
-    n706a_http_client_init(&client, 0);
-    
-    /* 设置用户名和密码 */
-    n706a_http_client_set_auth(&client, "user", "password");
-    
-    /* 连接并请求 */
-    if (n706a_http_client_connect(&client, "httpbin.org", 80, false) == N706A_HTTP_SUCCESS) {
-        memset(&data, 0, sizeof(data));
-        data.responseBuf = response_buf;
-        data.responseBufLen = sizeof(response_buf);
-        
-        n706a_http_client_get(&client, "/basic-auth/user/password", &data);
-        
-        printf("HTTP Status: %d\n", client.response_code);
-        printf("Response: %s\n", response_buf);
-        
-        n706a_http_client_close(&client);
-    }
-}
-
-/* ========== 示例6:Keep-Alive长连接 ========== */
-void example_keep_alive(void)
-{
-    printf("\n=== Example 6: Keep-Alive Connection ===\n");
-    
-    n706a_http_client_t client;
-    n706a_http_client_data_t data;
-    char response_buf[4096];
-    
-    n706a_http_client_init(&client, 0);
-    
-    /* 启用Keep-Alive */
-    n706a_http_client_set_keepalive(&client, true);
-    
-    /* 连接一次,发送多个请求 */
-    if (n706a_http_client_connect(&client, "httpbin.org", 80, false) == N706A_HTTP_SUCCESS) {
-        memset(&data, 0, sizeof(data));
-        data.responseBuf = response_buf;
-        data.responseBufLen = sizeof(response_buf);
-        
-        /* 第一个请求 */
-        printf("Request 1:\n");
-        n706a_http_client_get(&client, "/get?page=1", &data);
-        printf("Status: %d\n", client.response_code);
-        
-        /* 第二个请求(复用连接) */
-        printf("Request 2:\n");
-        n706a_http_client_get(&client, "/get?page=2", &data);
-        printf("Status: %d\n", client.response_code);
-        
-        /* 第三个请求(复用连接) */
-        printf("Request 3:\n");
-        n706a_http_client_get(&client, "/get?page=3", &data);
-        printf("Status: %d\n", client.response_code);
-        
-        n706a_http_client_close(&client);
-    }
-}
-
-/* ========== 示例7:并发HTTP请求(6个连接) ========== */
-void example_concurrent_requests(void)
-{
-    printf("\n=== Example 7: Concurrent HTTP Requests ===\n");
-    
-    n706a_http_client_t clients[6];
-    n706a_http_client_data_t data[6];
-    char response_bufs[6][2048];
-    const char *urls[] = {
-        "httpbin.org", "httpbin.org", "httpbin.org",
-        "httpbin.org", "httpbin.org", "httpbin.org"
-    };
-    const char *paths[] = {
-        "/get?req=1", "/get?req=2", "/get?req=3",
-        "/get?req=4", "/get?req=5", "/get?req=6"
-    };
-    
-    /* 初始化6个客户端 */
-    for (int i = 0; i < 6; i++) {
-        n706a_http_client_init(&clients[i], i);  // 使用socket 0-5
-        
-        /* 连接 */
-        if (n706a_http_client_connect(&clients[i], urls[i], 80, false) == N706A_HTTP_SUCCESS) {
-            printf("Client %d connected\n", i);
-            
-            /* 准备缓冲区 */
-            memset(&data[i], 0, sizeof(data[i]));
-            data[i].responseBuf = response_bufs[i];
-            data[i].responseBufLen = sizeof(response_bufs[i]);
-            
-            /* 发送请求 */
-            n706a_http_client_get(&clients[i], paths[i], &data[i]);
-            printf("Client %d: Status %d\n", i, clients[i].response_code);
-        }
-    }
-    
-    /* 关闭所有连接 */
-    for (int i = 0; i < 6; i++) {
-        n706a_http_client_close(&clients[i]);
-    }
-}
-
-/* ========== 示例8:简化的URL接口 ========== */
-void example_simple_url_api(void)
-{
-    printf("\n=== Example 8: Simple URL API ===\n");
-    
-    n706a_http_client_t client;
-    n706a_http_client_data_t data;
-    char response_buf[4096];
-    
-    n706a_http_client_init(&client, 0);
-    
-    /* 准备响应缓冲区 */
-    memset(&data, 0, sizeof(data));
-    data.responseBuf = response_buf;
-    data.responseBufLen = sizeof(response_buf);
-    
-    /* 直接使用完整URL(自动解析协议、host、端口、路径) */
-    n706a_httpc_result_t ret = n706a_http_client_get_url(&client,
-        "http://httpbin.org/get",
-        &data
-    );
-    
-    if (ret == N706A_HTTP_SUCCESS) {
-        printf("Status: %d\n", client.response_code);
-        printf("Response: %s\n", response_buf);
-    }
-    
-    n706a_http_client_close(&client);
-    
-    /* HTTPS URL示例 */
-    ret = n706a_http_client_get_url(&client,
-        "https://api.github.com/",
-        &data
-    );
-    
-    if (ret == N706A_HTTP_SUCCESS) {
-        printf("HTTPS Status: %d\n", client.response_code);
-    }
-    
-    n706a_http_client_close(&client);
-}
-
-/* ========== 主函数 ========== */
-int main(void)
-{
-    printf("N706A HTTP Client Examples (TCP-based)\n");
-    printf("======================================\n");
-    
-    /* 1. PPP拨号 */
-    ppp_dial_config_t config = {
-        .apn = "cmnet",
-        .username = "",
-        .password = "",
-        .auth_type = PPP_AUTH_NONE
-    };
-    
-    printf("Starting PPP dial...\n");
-    if (ppp_client_dial(&config) != PPP_SUCCESS) {
-        printf("PPP dial failed\n");
-        return -1;
-    }
-    printf("PPP connected\n\n");
-    
-    /* 2. 运行示例 */
-    example_http_get();              // 基本HTTP GET
-    example_https_get();             // HTTPS GET
-    example_http_post_json();        // HTTP POST JSON
-    example_custom_headers();        // 自定义请求头
-    example_basic_auth();            // 基本认证
-    example_keep_alive();            // Keep-Alive长连接
-    example_concurrent_requests();   // 并发请求(6个)
-    example_simple_url_api();        // 简化URL API
-    
-    printf("\nAll examples completed\n");
-    
-    /* 3. 断开PPP */
-    ppp_client_hangup();
-    
-    return 0;
-}
-
diff --git a/code/sdk/zhihui/ppp/example/n706a_ssl_comparison_example.c b/code/sdk/zhihui/ppp/example/n706a_ssl_comparison_example.c
deleted file mode 100644 (file)
index 64cb65a..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-/**
- * @file n706a_ssl_comparison_example.c
- * @brief N706A SSL实现方式对比示例
- * 
- * 展示两种SSL实现方式的使用:
- * - AT指令实现(N706A_SSL_USE_AT_COMMAND)
- * - mbedtls实现(N706A_SSL_USE_MBEDTLS)
- * 
- * 编译方法:
- *   gcc -DN706A_SSL_USE_AT_COMMAND n706a_ssl_comparison_example.c  # AT指令
- *   gcc -DN706A_SSL_USE_MBEDTLS n706a_ssl_comparison_example.c -lmbedtls  # mbedtls
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "n706a_tcp_client.h"
-#include "ppp_client.h"
-
-/* ========== 示例1:基本SSL连接(两种实现API相同) ========== */
-void example_basic_ssl_connection(void)
-{
-    printf("\n=== Example 1: Basic SSL Connection ===\n");
-    
-#ifdef N706A_SSL_USE_AT_COMMAND
-    printf("Using: AT Command SSL Implementation\n");
-#endif
-#ifdef N706A_SSL_USE_MBEDTLS
-    printf("Using: mbedtls SSL Implementation\n");
-#endif
-    
-    n706a_tcp_socket_t sock;
-    
-    /* 创建socket */
-    n706a_tcp_socket_create(&sock, 0);
-    
-    /* 配置SSL(可选,使用默认也可以) */
-#ifdef N706A_SSL_USE_AT_COMMAND
-    /* AT指令模式:使用文件名 */
-    n706a_tcp_config_ssl(&sock,
-        3,              // TLS 1.2
-        1,              // 服务器认证
-        "ca.crt"        // 证书文件名(已上传到模组)
-    );
-#endif
-
-#ifdef N706A_SSL_USE_MBEDTLS
-    /* mbedtls模式:使用PEM字符串 */
-    const char *ca_pem = 
-        "-----BEGIN CERTIFICATE-----\n"
-        "MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\n"
-        // ... 证书内容 ...
-        "-----END CERTIFICATE-----\n";
-    
-    n706a_tcp_config_ssl(&sock,
-        MBEDTLS_SSL_MINOR_VERSION_3,  // TLS 1.2
-        MBEDTLS_SSL_VERIFY_REQUIRED,  // 必须验证
-        ca_pem                         // PEM字符串
-    );
-#endif
-    
-    /* 建立SSL连接(API完全相同) */
-    n706a_tcp_result_t ret = n706a_tcp_connect(&sock,
-        "www.google.com",
-        443,
-        true,           // 使用SSL
-        30000           // 30秒超时
-    );
-    
-    if (ret == N706A_TCP_SUCCESS) {
-        printf("SSL connected successfully!\n");
-        
-        /* 发送HTTPS GET请求 */
-        const char *request = 
-            "GET / HTTP/1.1\r\n"
-            "Host: www.google.com\r\n"
-            "Connection: close\r\n\r\n";
-        
-        size_t sent;
-        n706a_tcp_send(&sock, (uint8_t*)request, strlen(request), &sent);
-        printf("Sent %zu bytes\n", sent);
-        
-        /* 接收响应 */
-        uint8_t buffer[2048];
-        size_t received;
-        n706a_tcp_recv(&sock, buffer, sizeof(buffer), &received, 10000);
-        printf("Received %zu bytes:\n%.*s\n", received, (int)received, buffer);
-        
-        /* 关闭连接 */
-        n706a_tcp_close(&sock);
-    } else {
-        printf("SSL connection failed: %d\n", ret);
-    }
-}
-
-/* ========== 示例2:性能测试 ========== */
-void example_performance_test(void)
-{
-    printf("\n=== Example 2: Performance Test ===\n");
-    
-#ifdef N706A_SSL_USE_AT_COMMAND
-    printf("Testing AT Command SSL Performance\n");
-#endif
-#ifdef N706A_SSL_USE_MBEDTLS
-    printf("Testing mbedtls SSL Performance\n");
-#endif
-    
-    n706a_tcp_socket_t sock;
-    n706a_tcp_socket_create(&sock, 0);
-    
-    /* 测试SSL握手时间 */
-    uint32_t start_time = get_tick_ms();  // 假设有这个函数
-    
-    n706a_tcp_result_t ret = n706a_tcp_connect(&sock,
-        "www.example.com",
-        443,
-        true,
-        30000
-    );
-    
-    uint32_t handshake_time = get_tick_ms() - start_time;
-    
-    if (ret == N706A_TCP_SUCCESS) {
-        printf("SSL handshake time: %u ms\n", handshake_time);
-        
-        /* 测试数据传输速度 */
-        const char *test_data = "This is a test message for SSL performance!\n";
-        size_t data_len = strlen(test_data);
-        
-        start_time = get_tick_ms();
-        
-        /* 发送100次 */
-        for (int i = 0; i < 100; i++) {
-            size_t sent;
-            n706a_tcp_send(&sock, (uint8_t*)test_data, data_len, &sent);
-        }
-        
-        uint32_t send_time = get_tick_ms() - start_time;
-        float throughput = (data_len * 100 * 1000.0) / send_time / 1024.0;  // KB/s
-        
-        printf("Send throughput: %.2f KB/s\n", throughput);
-        
-        n706a_tcp_close(&sock);
-    }
-}
-
-/* ========== 示例3:内存占用测试 ========== */
-void example_memory_usage(void)
-{
-    printf("\n=== Example 3: Memory Usage ===\n");
-    
-    printf("sizeof(n706a_tcp_socket_t) = %zu bytes\n", sizeof(n706a_tcp_socket_t));
-    
-#ifdef N706A_SSL_USE_AT_COMMAND
-    printf("AT Command mode:\n");
-    printf("  - Socket structure: ~%zu bytes\n", sizeof(n706a_tcp_socket_t));
-    printf("  - Additional heap: ~2KB (estimated)\n");
-    printf("  - Total per connection: ~%zu bytes\n", sizeof(n706a_tcp_socket_t) + 2048);
-#endif
-
-#ifdef N706A_SSL_USE_MBEDTLS
-    printf("mbedtls mode:\n");
-    printf("  - Socket structure: ~%zu bytes\n", sizeof(n706a_tcp_socket_t));
-    printf("  - Includes mbedtls contexts\n");
-    printf("  - Additional buffers: ~20KB (estimated)\n");
-    printf("  - Total per connection: ~%zu bytes\n", sizeof(n706a_tcp_socket_t) + 20480);
-#endif
-    
-    /* 测试6个并发SSL连接的内存 */
-    printf("\n6 concurrent SSL connections:\n");
-    
-#ifdef N706A_SSL_USE_AT_COMMAND
-    size_t total_memory = (sizeof(n706a_tcp_socket_t) + 2048) * 6;
-    printf("  AT Command: ~%zu bytes (%.1f KB)\n", 
-           total_memory, total_memory / 1024.0);
-#endif
-
-#ifdef N706A_SSL_USE_MBEDTLS
-    size_t total_memory = (sizeof(n706a_tcp_socket_t) + 20480) * 6;
-    printf("  mbedtls: ~%zu bytes (%.1f KB)\n", 
-           total_memory, total_memory / 1024.0);
-#endif
-}
-
-/* ========== 示例4:AT指令特有功能 ========== */
-#ifdef N706A_SSL_USE_AT_COMMAND
-void example_at_specific_features(void)
-{
-    printf("\n=== Example 4: AT Command Specific Features ===\n");
-    
-    n706a_tcp_socket_t sock;
-    n706a_tcp_socket_create(&sock, 0);
-    
-    /* AT指令模式可以使用模组文件系统中的证书 */
-    printf("Using certificate from modem file system\n");
-    
-    n706a_tcp_config_ssl(&sock,
-        3,              // TLS 1.2
-        1,              // 服务器认证
-        "ca.crt"        // 文件名
-    );
-    
-    /* 建立连接 */
-    n706a_tcp_result_t ret = n706a_tcp_connect(&sock,
-        "secure.example.com",
-        443,
-        true,
-        30000
-    );
-    
-    if (ret == N706A_TCP_SUCCESS) {
-        printf("Connected using modem SSL hardware acceleration\n");
-        printf("Benefits:\n");
-        printf("  - Fast SSL processing (hardware accelerated)\n");
-        printf("  - Low CPU usage on host MCU\n");
-        printf("  - Small memory footprint\n");
-        
-        n706a_tcp_close(&sock);
-    }
-}
-#endif
-
-/* ========== 示例5:mbedtls特有功能 ========== */
-#ifdef N706A_SSL_USE_MBEDTLS
-void example_mbedtls_specific_features(void)
-{
-    printf("\n=== Example 5: mbedtls Specific Features ===\n");
-    
-    n706a_tcp_socket_t sock;
-    n706a_tcp_socket_create(&sock, 0);
-    
-    /* mbedtls模式:PEM格式证书在内存中 */
-    const char *ca_pem = "-----BEGIN CERTIFICATE-----\n...\n";
-    
-    n706a_tcp_config_ssl(&sock,
-        MBEDTLS_SSL_MINOR_VERSION_3,
-        MBEDTLS_SSL_VERIFY_REQUIRED,
-        ca_pem
-    );
-    
-    /* mbedtls模式可以配置客户端证书(双向认证) */
-    const char *client_cert = "-----BEGIN CERTIFICATE-----\n...\n";
-    const char *client_key = "-----BEGIN RSA PRIVATE KEY-----\n...\n";
-    
-    n706a_tcp_config_ssl_client_cert(&sock, client_cert, client_key);
-    
-    /* 建立连接 */
-    n706a_tcp_result_t ret = n706a_tcp_connect(&sock,
-        "secure.example.com",
-        443,
-        true,
-        30000
-    );
-    
-    if (ret == N706A_TCP_SUCCESS) {
-        printf("Connected using mbedtls\n");
-        printf("Benefits:\n");
-        printf("  - Full control over SSL parameters\n");
-        printf("  - Can customize cipher suites\n");
-        printf("  - Easy debugging (code on host)\n");
-        printf("  - Platform independent\n");
-        
-        /* 可以直接访问SSL上下文进行高级操作 */
-        printf("\nSSL Info:\n");
-        printf("  Protocol: %s\n", mbedtls_ssl_get_version(&sock.ssl));
-        printf("  Cipher: %s\n", mbedtls_ssl_get_ciphersuite(&sock.ssl));
-        
-        /* 自定义密码套件 */
-        const int ciphersuites[] = {
-            MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
-            MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-            0
-        };
-        mbedtls_ssl_conf_ciphersuites(&sock.conf, ciphersuites);
-        printf("  Custom ciphersuites configured\n");
-        
-        n706a_tcp_close(&sock);
-    }
-}
-#endif
-
-/* ========== 示例6:并发SSL连接 ========== */
-void example_concurrent_ssl_connections(void)
-{
-    printf("\n=== Example 6: Concurrent SSL Connections ===\n");
-    
-#ifdef N706A_SSL_USE_AT_COMMAND
-    printf("Testing 6 concurrent SSL connections (AT Command)\n");
-    int max_connections = 6;  // AT指令模式可以支持6个
-#endif
-
-#ifdef N706A_SSL_USE_MBEDTLS
-    printf("Testing 2 concurrent SSL connections (mbedtls)\n");
-    int max_connections = 2;  // mbedtls模式建议最多2个(内存限制)
-#endif
-    
-    n706a_tcp_socket_t socks[6];
-    int connected = 0;
-    
-    /* 尝试建立多个SSL连接 */
-    for (int i = 0; i < max_connections; i++) {
-        n706a_tcp_socket_create(&socks[i], i);
-        
-        n706a_tcp_result_t ret = n706a_tcp_connect(&socks[i],
-            "www.example.com",
-            443,
-            true,
-            30000
-        );
-        
-        if (ret == N706A_TCP_SUCCESS) {
-            connected++;
-            printf("Connection %d: SUCCESS\n", i);
-        } else {
-            printf("Connection %d: FAILED\n", i);
-        }
-    }
-    
-    printf("\nTotal connected: %d/%d\n", connected, max_connections);
-    
-#ifdef N706A_SSL_USE_AT_COMMAND
-    printf("AT Command mode: Can handle 6 concurrent SSL connections easily\n");
-#endif
-
-#ifdef N706A_SSL_USE_MBEDTLS
-    printf("mbedtls mode: Limited by memory, recommend 1-2 connections\n");
-#endif
-    
-    /* 关闭所有连接 */
-    for (int i = 0; i < connected; i++) {
-        n706a_tcp_close(&socks[i]);
-    }
-}
-
-/* ========== 主函数 ========== */
-int main(void)
-{
-    printf("==============================================\n");
-    printf("N706A SSL Implementation Comparison\n");
-    printf("==============================================\n");
-    
-#ifdef N706A_SSL_USE_AT_COMMAND
-    printf("Current build: AT Command SSL Implementation\n");
-    printf("  Recommended for: Standard applications\n");
-    printf("  Pros: Fast, low memory, reliable\n");
-    printf("  Cons: Limited customization\n");
-#endif
-
-#ifdef N706A_SSL_USE_MBEDTLS
-    printf("Current build: mbedtls SSL Implementation\n");
-    printf("  Recommended for: Custom requirements\n");
-    printf("  Pros: Full control, flexible\n");
-    printf("  Cons: Slower, more memory\n");
-#endif
-    
-    printf("==============================================\n\n");
-    
-    /* PPP拨号 */
-    ppp_dial_config_t config = {
-        .apn = "cmnet",
-        .username = "",
-        .password = "",
-        .auth_type = PPP_AUTH_NONE
-    };
-    
-    if (ppp_client_dial(&config) != PPP_SUCCESS) {
-        printf("PPP dial failed\n");
-        return -1;
-    }
-    printf("PPP connected\n\n");
-    
-    /* 运行示例 */
-    example_basic_ssl_connection();
-    example_performance_test();
-    example_memory_usage();
-    
-#ifdef N706A_SSL_USE_AT_COMMAND
-    example_at_specific_features();
-#endif
-
-#ifdef N706A_SSL_USE_MBEDTLS
-    example_mbedtls_specific_features();
-#endif
-    
-    example_concurrent_ssl_connections();
-    
-    printf("\n==============================================\n");
-    printf("All examples completed\n");
-    printf("==============================================\n");
-    
-    /* 断开PPP */
-    ppp_client_hangup();
-    
-    return 0;
-}
-
diff --git a/code/sdk/zhihui/ppp/example/n706a_websocket_example.c b/code/sdk/zhihui/ppp/example/n706a_websocket_example.c
deleted file mode 100644 (file)
index 5c3f792..0000000
+++ /dev/null
@@ -1,397 +0,0 @@
-/**
- * @file n706a_websocket_example.c
- * @brief N706A WebSocket客户端使用示例
- * 
- * 展示如何使用WebSocket客户端:
- * - ws://普通连接
- * - wss://安全连接
- * - 发送文本和二进制消息
- * - 接收消息回调
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include "n706a_websocket.h"
-#include "ppp_client.h"
-
-/* ========== 回调函数 ========== */
-
-void on_open(int client_id)
-{
-    printf("[Client %d] WebSocket connected!\n", client_id);
-}
-
-void on_message(int client_id, const char *data, size_t length, 
-                bool is_finished, bool is_binary)
-{
-    printf("[Client %d] Message received (%zu bytes, %s, %s):\n", 
-           client_id, length,
-           is_binary ? "binary" : "text",
-           is_finished ? "finished" : "partial");
-    
-    if (!is_binary && length < 1024) {
-        printf("  Content: %.*s\n", (int)length, data);
-    } else {
-        printf("  Content: [binary data]\n");
-    }
-}
-
-void on_error(int client_id, int error_code, const char *error_msg)
-{
-    printf("[Client %d] Error %d: %s\n", client_id, error_code, error_msg);
-}
-
-void on_close(int client_id, int close_code, const char *reason)
-{
-    printf("[Client %d] Closed (code=%d, reason=%s)\n", 
-           client_id, close_code, reason ? reason : "none");
-}
-
-/* ========== 示例1:基本WebSocket连接 ========== */
-void example_basic_websocket(void)
-{
-    printf("\n=== Example 1: Basic WebSocket (ws://) ===\n");
-    
-    /* 创建客户端 */
-    int client = n706a_websocket_constructor(
-        on_open,
-        on_message,
-        on_error,
-        on_close
-    );
-    
-    if (client < 0) {
-        printf("Failed to create WebSocket client\n");
-        return;
-    }
-    
-    printf("Client ID: %d\n", client);
-    
-    /* 连接到WebSocket服务器 */
-    int ret = n706a_websocket_connect(client, 
-        "ws://echo.websocket.org/", 
-        NULL
-    );
-    
-    if (ret == N706A_WS_SUCCESS) {
-        printf("Connected to echo server\n");
-        
-        /* 发送文本消息 */
-        n706a_websocket_send_text(client, "Hello WebSocket!", 16);
-        printf("Sent text message\n");
-        
-        /* 等待回显 */
-        sleep(2);
-        
-        /* 发送更多消息 */
-        n706a_websocket_send_text(client, "This is N706A speaking", 22);
-        sleep(2);
-        
-        /* 关闭连接 */
-        n706a_websocket_close(client);
-        sleep(1);
-    } else {
-        printf("Connection failed: %d\n", ret);
-    }
-    
-    /* 销毁客户端 */
-    n706a_websocket_destructor(client);
-}
-
-/* ========== 示例2:安全WebSocket连接(WSS) ========== */
-void example_secure_websocket(void)
-{
-    printf("\n=== Example 2: Secure WebSocket (wss://) ===\n");
-    
-    int client = n706a_websocket_constructor(
-        on_open, on_message, on_error, on_close
-    );
-    
-    if (client < 0) {
-        printf("Failed to create client\n");
-        return;
-    }
-    
-    /* 连接到WSS服务器 */
-    int ret = n706a_websocket_connect(client,
-        "wss://echo.websocket.org/",
-        NULL
-    );
-    
-    if (ret == N706A_WS_SUCCESS) {
-        printf("Secure connection established (SSL/TLS)\n");
-        
-        /* 发送消息 */
-        n706a_websocket_send_text(client, "Secure Hello!", 13);
-        
-        sleep(3);
-        
-        n706a_websocket_close(client);
-        sleep(1);
-    }
-    
-    n706a_websocket_destructor(client);
-}
-
-/* ========== 示例3:发送二进制数据 ========== */
-void example_binary_data(void)
-{
-    printf("\n=== Example 3: Binary Data ===\n");
-    
-    int client = n706a_websocket_constructor(
-        on_open, on_message, on_error, on_close
-    );
-    
-    if (client < 0) return;
-    
-    if (n706a_websocket_connect(client, "ws://echo.websocket.org/", NULL) 
-        == N706A_WS_SUCCESS) {
-        
-        /* 创建二进制数据 */
-        uint8_t binary_data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 
-                                 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
-        
-        /* 发送二进制消息 */
-        n706a_websocket_send_binary(client, binary_data, sizeof(binary_data));
-        printf("Sent binary data (%zu bytes)\n", sizeof(binary_data));
-        
-        sleep(2);
-        
-        n706a_websocket_close(client);
-        sleep(1);
-    }
-    
-    n706a_websocket_destructor(client);
-}
-
-/* ========== 示例4:Ping/Pong ========== */
-void example_ping_pong(void)
-{
-    printf("\n=== Example 4: Ping/Pong ===\n");
-    
-    int client = n706a_websocket_constructor(
-        on_open, on_message, on_error, on_close
-    );
-    
-    if (client < 0) return;
-    
-    if (n706a_websocket_connect(client, "ws://echo.websocket.org/", NULL)
-        == N706A_WS_SUCCESS) {
-        
-        /* 发送Ping */
-        n706a_websocket_send_ping(client, "ping", 4);
-        printf("Sent Ping\n");
-        
-        sleep(1);
-        
-        /* 服务器应该回复Pong */
-        /* 发送普通消息 */
-        n706a_websocket_send_text(client, "After ping", 10);
-        
-        sleep(2);
-        
-        n706a_websocket_close(client);
-        sleep(1);
-    }
-    
-    n706a_websocket_destructor(client);
-}
-
-/* ========== 示例5:多个并发WebSocket连接 ========== */
-void example_multiple_connections(void)
-{
-    printf("\n=== Example 5: Multiple WebSocket Connections ===\n");
-    
-    int clients[3];
-    const char *urls[] = {
-        "ws://echo.websocket.org/",
-        "ws://echo.websocket.org/",
-        "wss://echo.websocket.org/"
-    };
-    
-    /* 创建3个客户端 */
-    for (int i = 0; i < 3; i++) {
-        clients[i] = n706a_websocket_constructor(
-            on_open, on_message, on_error, on_close
-        );
-        
-        if (clients[i] < 0) {
-            printf("Failed to create client %d\n", i);
-            continue;
-        }
-        
-        /* 连接 */
-        int ret = n706a_websocket_connect(clients[i], urls[i], NULL);
-        if (ret == N706A_WS_SUCCESS) {
-            printf("Client %d connected to %s\n", clients[i], urls[i]);
-        } else {
-            printf("Client %d connection failed\n", clients[i]);
-        }
-    }
-    
-    sleep(1);
-    
-    /* 所有客户端发送消息 */
-    for (int i = 0; i < 3; i++) {
-        if (n706a_websocket_is_connected(clients[i])) {
-            char msg[64];
-            snprintf(msg, sizeof(msg), "Message from client %d", clients[i]);
-            n706a_websocket_send_text(clients[i], msg, strlen(msg));
-        }
-    }
-    
-    sleep(3);
-    
-    /* 关闭所有连接 */
-    for (int i = 0; i < 3; i++) {
-        n706a_websocket_close(clients[i]);
-        n706a_websocket_destructor(clients[i]);
-    }
-    
-    sleep(1);
-}
-
-/* ========== 示例6:优雅关闭 ========== */
-void example_graceful_close(void)
-{
-    printf("\n=== Example 6: Graceful Close ===\n");
-    
-    int client = n706a_websocket_constructor(
-        on_open, on_message, on_error, on_close
-    );
-    
-    if (client < 0) return;
-    
-    if (n706a_websocket_connect(client, "ws://echo.websocket.org/", NULL)
-        == N706A_WS_SUCCESS) {
-        
-        /* 发送消息 */
-        n706a_websocket_send_text(client, "Goodbye!", 8);
-        
-        sleep(1);
-        
-        /* 优雅关闭(带原因) */
-        n706a_websocket_close_with_reason(client,
-            N706A_WS_CLOSE_NORMAL,
-            "Client closing normally"
-        );
-        
-        printf("Sent close frame\n");
-        
-        sleep(2);
-    }
-    
-    n706a_websocket_destructor(client);
-}
-
-/* ========== 示例7:实时数据流 ========== */
-void example_realtime_stream(void)
-{
-    printf("\n=== Example 7: Realtime Data Stream ===\n");
-    
-    int client = n706a_websocket_constructor(
-        on_open, on_message, on_error, on_close
-    );
-    
-    if (client < 0) return;
-    
-    /* 连接到实时数据服务器(这里用echo演示) */
-    if (n706a_websocket_connect(client, "ws://echo.websocket.org/", NULL)
-        == N706A_WS_SUCCESS) {
-        
-        printf("Streaming data for 10 seconds...\n");
-        
-        /* 持续发送数据 */
-        for (int i = 0; i < 10; i++) {
-            char data[128];
-            snprintf(data, sizeof(data), 
-                    "{\"seq\":%d,\"timestamp\":%ld,\"value\":%d}", 
-                    i, time(NULL), rand() % 100);
-            
-            n706a_websocket_send_text(client, data, strlen(data));
-            printf("Sent: %s\n", data);
-            
-            sleep(1);
-        }
-        
-        n706a_websocket_close(client);
-        sleep(1);
-    }
-    
-    n706a_websocket_destructor(client);
-}
-
-/* ========== 示例8:指定Socket ID ========== */
-void example_with_specific_socket(void)
-{
-    printf("\n=== Example 8: Specify Socket ID ===\n");
-    
-    /* 使用socket 3 */
-    int client = n706a_websocket_constructor_with_socket(3,
-        on_open, on_message, on_error, on_close
-    );
-    
-    if (client < 0) {
-        printf("Failed to create client with socket 3\n");
-        return;
-    }
-    
-    printf("Created client using socket ID 3\n");
-    
-    if (n706a_websocket_connect(client, "ws://echo.websocket.org/", NULL)
-        == N706A_WS_SUCCESS) {
-        
-        n706a_websocket_send_text(client, "Using socket 3", 14);
-        
-        sleep(2);
-        
-        n706a_websocket_close(client);
-        sleep(1);
-    }
-    
-    n706a_websocket_destructor(client);
-}
-
-/* ========== 主函数 ========== */
-int main(void)
-{
-    printf("==============================================\n");
-    printf("N706A WebSocket Client Examples\n");
-    printf("==============================================\n");
-    
-    /* PPP拨号 */
-    ppp_dial_config_t config = {
-        .apn = "cmnet",
-        .username = "",
-        .password = "",
-        .auth_type = PPP_AUTH_NONE
-    };
-    
-    printf("Starting PPP dial...\n");
-    if (ppp_client_dial(&config) != PPP_SUCCESS) {
-        printf("PPP dial failed\n");
-        return -1;
-    }
-    printf("PPP connected\n\n");
-    
-    /* 运行示例 */
-    example_basic_websocket();           // WS基本连接
-    example_secure_websocket();          // WSS安全连接
-    example_binary_data();               // 二进制数据
-    example_ping_pong();                 // Ping/Pong
-    example_multiple_connections();      // 多连接
-    example_graceful_close();            // 优雅关闭
-    example_realtime_stream();           // 实时数据流
-    example_with_specific_socket();      // 指定Socket ID
-    
-    printf("\n==============================================\n");
-    printf("All examples completed\n");
-    printf("==============================================\n");
-    
-    /* 断开PPP */
-    ppp_client_hangup();
-    
-    return 0;
-}
-
diff --git a/code/sdk/zhihui/ppp/include/n706a_http_client.h b/code/sdk/zhihui/ppp/include/n706a_http_client.h
deleted file mode 100644 (file)
index 919ff4e..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-/**
- * @file n706a_http_client.h
- * @brief N706A HTTP/HTTPS客户端接口(基于TCP实现)
- * 
- * 本实现采用统一的TCP底层架构:
- * - HTTP通过普通TCP连接实现
- * - HTTPS通过SSL TCP连接实现
- * - 手动构造HTTP协议,突破AT+HTTP*单连接限制
- * - 支持6个并发HTTP/HTTPS连接
- * 
- * @version 3.0
- * @date 2025-10-30
- */
-
-#ifndef N706A_HTTP_CLIENT_H
-#define N706A_HTTP_CLIENT_H
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include "n706a_tcp_client.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @brief N706A HTTP请求类型
- */
-typedef enum {
-    N706A_HTTP_DELETE,
-    N706A_HTTP_GET,
-    N706A_HTTP_HEAD,
-    N706A_HTTP_POST,
-    N706A_HTTP_PUT
-} n706a_http_request_type_t;
-
-/**
- * @brief N706A HTTP错误码
- */
-typedef enum {
-    N706A_HTTP_EAGAIN   =  1,  /**< 还有更多数据需要获取 */
-    N706A_HTTP_SUCCESS  =  0,  /**< 操作成功      */
-    N706A_HTTP_ENOBUFS  = -1,  /**< 缓冲区错误           */
-    N706A_HTTP_EARG     = -2,  /**< 非法参数       */
-    N706A_HTTP_ENOTSUPP = -3,  /**< 不支持            */
-    N706A_HTTP_EDNS     = -4,  /**< DNS失败               */
-    N706A_HTTP_ECONN    = -5,  /**< 连接失败           */
-    N706A_HTTP_ESEND    = -6,  /**< 发送数据包失败       */
-    N706A_HTTP_ECLSD    = -7,  /**< 连接已关闭         */
-    N706A_HTTP_ERECV    = -8,  /**< 接收数据包失败       */
-    N706A_HTTP_EPARSE   = -9,  /**< URL解析错误        */
-    N706A_HTTP_EPROTO   = -10, /**< 协议错误         */
-    N706A_HTTP_EUNKOWN  = -11, /**< 未知错误          */
-    N706A_HTTP_ETIMEOUT = -12, /**< 超时                */
-} n706a_httpc_result_t;
-
-/**
- * @brief N706A HTTP客户端结构(基于TCP实现)
- */
-typedef struct {
-    n706a_tcp_socket_t tcp_sock;    /**< 底层TCP socket */
-    int socket_id;                   /**< TCP socket编号(0-5) */
-    bool is_https;                   /**< HTTPS标志(决定是否使用SSL) */
-    uint16_t remote_port;            /**< 远程端口 */
-    int response_code;               /**< HTTP响应码 */
-    char *header;                    /**< 自定义请求头 */
-    char *auth_user;                 /**< 基本认证用户名 */
-    char *auth_password;             /**< 基本认证密码 */
-    char host[256];                  /**< 主机名 */
-    bool connected;                  /**< 连接状态 */
-    bool keepalive;                  /**< 长连接模式 */
-    uint32_t timeout_ms;             /**< 超时时间(毫秒) */
-} n706a_http_client_t;
-
-/**
- * @brief N706A HTTP数据结构
- */
-typedef struct {
-    bool isMore;            /**< 是否还有更多数据需要获取 */
-    bool isChunked;         /**< 响应数据是否分块编码 */
-    int method;             /**< HTTP方法 */
-    int retrieveLen;        /**< 需要获取的内容长度 */
-    int responseContentLen; /**< 响应内容总长度 */
-    int contentBlockLen;    /**< 一个块的内容长度 */
-    int postBufLen;         /**< POST数据长度 */
-    int responseBufLen;     /**< 响应体缓冲区长度 */
-    int headerBufLen;       /**< 响应头缓冲区长度 */
-    char *postContentType;  /**< POST数据的内容类型 */
-    char *postBuf;          /**< 要POST的用户数据 */
-    char *responseBuf;      /**< 存储响应体数据的缓冲区 */
-    char *headerBuf;        /**< 存储响应头数据的缓冲区 */
-    bool isRedirected;      /**< 是否重定向 */
-    char *redirectUrl;      /**< 重定向URL */
-} n706a_http_client_data_t;
-
-/**
- * @brief 初始化N706A HTTP客户端
- * @param client HTTP客户端结构指针
- * @param socket_id TCP socket编号(0-5)
- * @return N706A_HTTP_SUCCESS成功,其他失败
- */
-n706a_httpc_result_t n706a_http_client_init(n706a_http_client_t *client, int socket_id);
-
-/**
- * @brief 连接到HTTP/HTTPS服务器
- * @param client HTTP客户端结构指针
- * @param host 主机名或IP地址
- * @param port 端口号(HTTP默认80,HTTPS默认443)
- * @param use_ssl 是否使用SSL(HTTPS)
- * @return N706A_HTTP_SUCCESS成功,其他失败
- */
-n706a_httpc_result_t n706a_http_client_connect(n706a_http_client_t *client,
-                                               const char *host,
-                                               uint16_t port,
-                                               bool use_ssl);
-
-/**
- * @brief 发送HTTP GET请求
- * @param client HTTP客户端结构指针
- * @param path 请求路径(如"/api/data")
- * @param client_data 响应数据结构指针
- * @return N706A_HTTP_SUCCESS成功,其他失败
- */
-n706a_httpc_result_t n706a_http_client_get(n706a_http_client_t *client,
-                                           const char *path,
-                                           n706a_http_client_data_t *client_data);
-
-/**
- * @brief 发送HTTP POST请求
- * @param client HTTP客户端结构指针
- * @param path 请求路径
- * @param content_type 内容类型(如"application/json")
- * @param body 请求体数据
- * @param body_len 请求体长度
- * @param client_data 响应数据结构指针
- * @return N706A_HTTP_SUCCESS成功,其他失败
- */
-n706a_httpc_result_t n706a_http_client_post(n706a_http_client_t *client,
-                                            const char *path,
-                                            const char *content_type,
-                                            const char *body,
-                                            size_t body_len,
-                                            n706a_http_client_data_t *client_data);
-
-/**
- * @brief 发送HTTP PUT请求
- * @param client HTTP客户端结构指针
- * @param path 请求路径
- * @param content_type 内容类型
- * @param body 请求体数据
- * @param body_len 请求体长度
- * @param client_data 响应数据结构指针
- * @return N706A_HTTP_SUCCESS成功,其他失败
- */
-n706a_httpc_result_t n706a_http_client_put(n706a_http_client_t *client,
-                                           const char *path,
-                                           const char *content_type,
-                                           const char *body,
-                                           size_t body_len,
-                                           n706a_http_client_data_t *client_data);
-
-/**
- * @brief 发送HTTP DELETE请求
- * @param client HTTP客户端结构指针
- * @param path 请求路径
- * @param client_data 响应数据结构指针
- * @return N706A_HTTP_SUCCESS成功,其他失败
- */
-n706a_httpc_result_t n706a_http_client_delete(n706a_http_client_t *client,
-                                              const char *path,
-                                              n706a_http_client_data_t *client_data);
-
-/**
- * @brief 发送HTTP HEAD请求
- * @param client HTTP客户端结构指针
- * @param path 请求路径
- * @param client_data 响应数据结构指针
- * @return N706A_HTTP_SUCCESS成功,其他失败
- */
-n706a_httpc_result_t n706a_http_client_head(n706a_http_client_t *client,
-                                            const char *path,
-                                            n706a_http_client_data_t *client_data);
-
-/**
- * @brief 设置自定义HTTP请求头
- * @param client HTTP客户端结构指针
- * @param header 自定义请求头(如"X-API-Key: abc123\r\n")
- * @return N706A_HTTP_SUCCESS成功,其他失败
- */
-n706a_httpc_result_t n706a_http_client_set_header(n706a_http_client_t *client,
-                                                  const char *header);
-
-/**
- * @brief 设置HTTP基本认证
- * @param client HTTP客户端结构指针
- * @param username 用户名
- * @param password 密码
- * @return N706A_HTTP_SUCCESS成功,其他失败
- */
-n706a_httpc_result_t n706a_http_client_set_auth(n706a_http_client_t *client,
-                                                const char *username,
-                                                const char *password);
-
-/**
- * @brief 设置Keep-Alive模式
- * @param client HTTP客户端结构指针
- * @param keepalive true启用长连接,false关闭
- * @return N706A_HTTP_SUCCESS成功,其他失败
- */
-n706a_httpc_result_t n706a_http_client_set_keepalive(n706a_http_client_t *client,
-                                                     bool keepalive);
-
-/**
- * @brief 关闭HTTP连接
- * @param client HTTP客户端结构指针
- * @return N706A_HTTP_SUCCESS成功,其他失败
- */
-n706a_httpc_result_t n706a_http_client_close(n706a_http_client_t *client);
-
-/**
- * @brief 检查HTTP连接状态
- * @param client HTTP客户端结构指针
- * @return true已连接,false未连接
- */
-bool n706a_http_client_is_connected(n706a_http_client_t *client);
-
-/**
- * @brief 获取最后的HTTP响应码
- * @param client HTTP客户端结构指针
- * @return HTTP响应码(如200, 404等)
- */
-int n706a_http_client_get_response_code(n706a_http_client_t *client);
-
-/* ========== 辅助函数 ========== */
-
-/**
- * @brief 解析完整URL并发起GET请求(便捷函数)
- * @param client HTTP客户端结构指针
- * @param url 完整URL(如"http://api.example.com/data"或"https://secure.com/")
- * @param client_data 响应数据结构指针
- * @return N706A_HTTP_SUCCESS成功,其他失败
- * @note 此函数会自动解析URL、建立连接并发送GET请求
- */
-n706a_httpc_result_t n706a_http_client_get_url(n706a_http_client_t *client,
-                                               const char *url,
-                                               n706a_http_client_data_t *client_data);
-
-/**
- * @brief 解析完整URL并发起POST请求(便捷函数)
- * @param client HTTP客户端结构指针
- * @param url 完整URL
- * @param content_type 内容类型
- * @param body 请求体数据
- * @param body_len 请求体长度
- * @param client_data 响应数据结构指针
- * @return N706A_HTTP_SUCCESS成功,其他失败
- */
-n706a_httpc_result_t n706a_http_client_post_url(n706a_http_client_t *client,
-                                                const char *url,
-                                                const char *content_type,
-                                                const char *body,
-                                                size_t body_len,
-                                                n706a_http_client_data_t *client_data);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // N706A_HTTP_CLIENT_H
-
diff --git a/code/sdk/zhihui/ppp/include/n706a_tcp_client.h b/code/sdk/zhihui/ppp/include/n706a_tcp_client.h
deleted file mode 100644 (file)
index db6a065..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
- *
- * N706A TCP客户端接口
- * 基于N706A AT指令实现TCP socket功能
- * 
- * SSL实现方式:
- *   - N706A_SSL_USE_AT_COMMAND: 使用AT+SSLTCP*指令(默认,推荐)
- *   - N706A_SSL_USE_MBEDTLS: 使用mbedtls库(需要额外库支持)
- */
-
-#ifndef N706A_TCP_CLIENT_H
-#define N706A_TCP_CLIENT_H
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-/* ========== SSL实现方式选择 ========== */
-/**
- * 编译时选择SSL实现方式:
- *   gcc -DN706A_SSL_USE_AT_COMMAND ...  (使用AT指令,默认)
- *   gcc -DN706A_SSL_USE_MBEDTLS ...     (使用mbedtls)
- */
-#if !defined(N706A_SSL_USE_AT_COMMAND) && !defined(N706A_SSL_USE_MBEDTLS)
-    /* 默认使用AT指令实现 */
-    #define N706A_SSL_USE_AT_COMMAND 1
-#endif
-
-#if defined(N706A_SSL_USE_AT_COMMAND) && defined(N706A_SSL_USE_MBEDTLS)
-    #error "Cannot define both N706A_SSL_USE_AT_COMMAND and N706A_SSL_USE_MBEDTLS"
-#endif
-
-/* 如果使用mbedtls,包含相关头文件 */
-#ifdef N706A_SSL_USE_MBEDTLS
-    #include "mbedtls/net_sockets.h"
-    #include "mbedtls/ssl.h"
-    #include "mbedtls/entropy.h"
-    #include "mbedtls/ctr_drbg.h"
-    #include "mbedtls/x509.h"
-    #include "mbedtls/error.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* N706A TCP错误码 */
-typedef enum {
-    N706A_TCP_SUCCESS  = 0,      /**< 操作成功 */
-    N706A_TCP_ERROR    = -1,     /**< 通用错误 */
-    N706A_TCP_EINVAL   = -2,     /**< 参数无效 */
-    N706A_TCP_ENOBUFS  = -3,     /**< 缓冲区不足 */
-    N706A_TCP_ENOTCONN = -4,     /**< 未连接 */
-    N706A_TCP_ECONNREF = -5,     /**< 连接被拒绝 */
-    N706A_TCP_ETIMEDOUT= -6,     /**< 超时 */
-    N706A_TCP_EINPROGRESS = -7,  /**< 操作进行中 */
-} n706a_tcp_result_t;
-
-/* TCP socket状态 */
-typedef enum {
-    N706A_TCP_STATE_CLOSED = 0,    /**< 关闭 */
-    N706A_TCP_STATE_CONNECTING,    /**< 连接中 */
-    N706A_TCP_STATE_CONNECTED,     /**< 已连接 */
-    N706A_TCP_STATE_ERROR          /**< 错误状态 */
-} n706a_tcp_state_t;
-
-/* TCP socket结构 */
-typedef struct {
-    int socket_id;                  /**< socket编号(0-5) */
-    n706a_tcp_state_t state;        /**< 连接状态 */
-    char remote_ip[64];             /**< 远程IP或域名 */
-    uint16_t remote_port;           /**< 远程端口 */
-    bool is_ssl;                    /**< 是否SSL连接 */
-    uint32_t timeout_ms;            /**< 超时时间 */
-    
-    /* SSL相关字段(根据编译宏不同而不同) */
-#ifdef N706A_SSL_USE_AT_COMMAND
-    /* AT指令模式:SSL由模组处理 */
-    int ssl_version;                /**< SSL版本(0-5) */
-    int auth_mode;                  /**< 认证模式(0-2) */
-    char ca_cert_file[64];          /**< CA证书文件名 */
-#endif
-
-#ifdef N706A_SSL_USE_MBEDTLS
-    /* mbedtls模式:需要SSL上下文 */
-    mbedtls_ssl_context ssl;            /**< SSL上下文 */
-    mbedtls_ssl_config conf;            /**< SSL配置 */
-    mbedtls_entropy_context entropy;    /**< 熵源 */
-    mbedtls_ctr_drbg_context ctr_drbg;  /**< 随机数生成器 */
-    mbedtls_x509_crt cacert;            /**< CA证书 */
-    mbedtls_x509_crt clicert;           /**< 客户端证书(可选) */
-    mbedtls_pk_context pkey;            /**< 客户端私钥(可选) */
-    bool ssl_initialized;               /**< SSL是否已初始化 */
-#endif
-} n706a_tcp_socket_t;
-
-/**
- * @brief 创建TCP socket
- * @param sock TCP socket指针
- * @param socket_id socket编号(0-5)
- * @return N706A_TCP_SUCCESS成功,其他值表示失败
- */
-n706a_tcp_result_t n706a_tcp_socket_create(n706a_tcp_socket_t *sock, int socket_id);
-
-/**
- * @brief 连接到TCP服务器
- * @param sock TCP socket指针
- * @param host 主机地址(IP或域名)
- * @param port 端口号
- * @param use_ssl 是否使用SSL连接(用于WSS)
- * @param timeout_ms 超时时间(毫秒)
- * @return N706A_TCP_SUCCESS成功,其他值表示失败
- * @note 使用SSL时会调用AT+SSLTCPSETUP,否则调用AT+TCPSETUP
- */
-n706a_tcp_result_t n706a_tcp_connect(n706a_tcp_socket_t *sock, const char *host, 
-                                     uint16_t port, bool use_ssl, uint32_t timeout_ms);
-
-/**
- * @brief 配置SSL参数(在SSL连接前调用)
- * @param sock TCP socket指针
- * @param ssl_version SSL版本
- *        AT指令模式:0-5 (0=SSL3.0, 1=TLS1.0, 2=TLS1.1, 3=TLS1.2, 4=TLS1.0/1.1/1.2, 5=TLS1.3)
- *        mbedtls模式:使用MBEDTLS_SSL_MINOR_VERSION_*常量
- * @param auth_mode 认证模式
- *        AT指令模式:0=不认证, 1=服务器认证, 2=双向认证
- *        mbedtls模式:MBEDTLS_SSL_VERIFY_NONE/OPTIONAL/REQUIRED
- * @param ca_cert CA证书
- *        AT指令模式:证书文件名(如"ca.crt")
- *        mbedtls模式:证书内容(PEM格式字符串)
- * @return N706A_TCP_SUCCESS成功,其他值表示失败
- */
-n706a_tcp_result_t n706a_tcp_config_ssl(n706a_tcp_socket_t *sock, 
-                                        int ssl_version, 
-                                        int auth_mode,
-                                        const char *ca_cert);
-
-#ifdef N706A_SSL_USE_MBEDTLS
-/**
- * @brief 配置客户端证书和私钥(mbedtls模式,双向认证)
- * @param sock TCP socket指针
- * @param client_cert 客户端证书(PEM格式)
- * @param client_key 客户端私钥(PEM格式)
- * @return N706A_TCP_SUCCESS成功,其他值表示失败
- */
-n706a_tcp_result_t n706a_tcp_config_ssl_client_cert(n706a_tcp_socket_t *sock,
-                                                     const char *client_cert,
-                                                     const char *client_key);
-#endif
-
-/**
- * @brief 发送TCP数据
- * @param sock TCP socket指针
- * @param data 要发送的数据
- * @param len 数据长度
- * @param sent 实际发送的字节数(输出)
- * @return N706A_TCP_SUCCESS成功,其他值表示失败
- */
-n706a_tcp_result_t n706a_tcp_send(n706a_tcp_socket_t *sock, const uint8_t *data, 
-                                  size_t len, size_t *sent);
-
-/**
- * @brief 接收TCP数据
- * @param sock TCP socket指针
- * @param buffer 接收缓冲区
- * @param len 缓冲区大小
- * @param received 实际接收的字节数(输出)
- * @param timeout_ms 超时时间(毫秒)
- * @return N706A_TCP_SUCCESS成功,其他值表示失败
- */
-n706a_tcp_result_t n706a_tcp_recv(n706a_tcp_socket_t *sock, uint8_t *buffer, 
-                                  size_t len, size_t *received, uint32_t timeout_ms);
-
-/**
- * @brief 关闭TCP连接
- * @param sock TCP socket指针
- * @return N706A_TCP_SUCCESS成功,其他值表示失败
- */
-n706a_tcp_result_t n706a_tcp_close(n706a_tcp_socket_t *sock);
-
-/**
- * @brief 检查socket是否已连接
- * @param sock TCP socket指针
- * @return true已连接,false未连接
- */
-bool n706a_tcp_is_connected(const n706a_tcp_socket_t *sock);
-
-/**
- * @brief 获取socket状态
- * @param sock TCP socket指针
- * @return socket状态
- */
-n706a_tcp_state_t n706a_tcp_get_state(const n706a_tcp_socket_t *sock);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* N706A_TCP_CLIENT_H */
-
diff --git a/code/sdk/zhihui/ppp/include/n706a_websocket.h b/code/sdk/zhihui/ppp/include/n706a_websocket.h
deleted file mode 100644 (file)
index b7eb62a..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-/**
- * @file n706a_websocket.h
- * @brief N706A WebSocket客户端接口定义
- * 
- * 基于TCP/SSL TCP实现完整的WebSocket协议(RFC 6455),支持:
- * - ws://协议(普通TCP)
- * - wss://协议(SSL TCP)
- * - 文本和二进制消息
- * - 自动握手和帧封装
- * - 事件回调机制
- * 
- * @version 1.0
- * @date 2025-10-30
- */
-
-#ifndef N706A_WEBSOCKET_H
-#define N706A_WEBSOCKET_H
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include "n706a_tcp_client.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* WebSocket最大客户端数量 */
-#define N706A_WS_MAX_CLIENTS 6
-
-/* WebSocket URL最大长度 */
-#define N706A_WS_MAX_URL_LEN 512
-
-/* WebSocket帧操作码 */
-typedef enum {
-    N706A_WS_OPCODE_CONTINUATION = 0x0,  /**< 继续帧 */
-    N706A_WS_OPCODE_TEXT = 0x1,          /**< 文本帧 */
-    N706A_WS_OPCODE_BINARY = 0x2,        /**< 二进制帧 */
-    N706A_WS_OPCODE_CLOSE = 0x8,         /**< 关闭帧 */
-    N706A_WS_OPCODE_PING = 0x9,          /**< Ping帧 */
-    N706A_WS_OPCODE_PONG = 0xA           /**< Pong帧 */
-} n706a_ws_opcode_t;
-
-/* WebSocket状态 */
-typedef enum {
-    N706A_WS_STATE_CLOSED = 0,      /**< 已关闭 */
-    N706A_WS_STATE_CONNECTING,      /**< 连接中 */
-    N706A_WS_STATE_OPEN,            /**< 已打开 */
-    N706A_WS_STATE_CLOSING          /**< 关闭中 */
-} n706a_ws_state_t;
-
-/* WebSocket关闭状态码 */
-typedef enum {
-    N706A_WS_CLOSE_NORMAL = 1000,           /**< 正常关闭 */
-    N706A_WS_CLOSE_GOING_AWAY = 1001,       /**< 端点离开 */
-    N706A_WS_CLOSE_PROTOCOL_ERROR = 1002,   /**< 协议错误 */
-    N706A_WS_CLOSE_UNSUPPORTED = 1003,      /**< 不支持的数据 */
-    N706A_WS_CLOSE_NO_STATUS = 1005,        /**< 无状态码 */
-    N706A_WS_CLOSE_ABNORMAL = 1006,         /**< 异常关闭 */
-    N706A_WS_CLOSE_INVALID_DATA = 1007,     /**< 无效数据 */
-    N706A_WS_CLOSE_POLICY = 1008,           /**< 策略违反 */
-    N706A_WS_CLOSE_TOO_LARGE = 1009,        /**< 消息过大 */
-    N706A_WS_CLOSE_EXTENSION = 1010,        /**< 扩展协商失败 */
-    N706A_WS_CLOSE_SERVER_ERROR = 1011      /**< 服务器错误 */
-} n706a_ws_close_code_t;
-
-/* WebSocket错误码 */
-typedef enum {
-    N706A_WS_SUCCESS = 0,               /**< 成功 */
-    N706A_WS_ERROR_INVALID_PARAM = -1,  /**< 参数无效 */
-    N706A_WS_ERROR_NO_MEMORY = -2,      /**< 内存不足 */
-    N706A_WS_ERROR_NOT_CONNECTED = -3,  /**< 未连接 */
-    N706A_WS_ERROR_ALREADY_OPEN = -4,   /**< 已经打开 */
-    N706A_WS_ERROR_HANDSHAKE = -5,      /**< 握手失败 */
-    N706A_WS_ERROR_SEND_FAIL = -6,      /**< 发送失败 */
-    N706A_WS_ERROR_RECV_FAIL = -7,      /**< 接收失败 */
-    N706A_WS_ERROR_PROTOCOL = -8,       /**< 协议错误 */
-    N706A_WS_ERROR_TIMEOUT = -9,        /**< 超时 */
-    N706A_WS_ERROR_CLOSED = -10         /**< 连接已关闭 */
-} n706a_ws_result_t;
-
-/* 前置声明 */
-struct n706a_websocket_client;
-
-/**
- * @brief WebSocket连接打开回调
- * @param client_id 客户端ID
- */
-typedef void (*n706a_ws_on_open_callback_t)(int client_id);
-
-/**
- * @brief WebSocket消息接收回调
- * @param client_id 客户端ID
- * @param data 消息数据
- * @param length 数据长度
- * @param is_finished 是否是最后一帧
- * @param is_binary 是否是二进制数据
- */
-typedef void (*n706a_ws_on_message_callback_t)(int client_id, 
-                                                const char *data, 
-                                                size_t length,
-                                                bool is_finished, 
-                                                bool is_binary);
-
-/**
- * @brief WebSocket错误回调
- * @param client_id 客户端ID
- * @param error_code 错误码
- * @param error_msg 错误消息
- */
-typedef void (*n706a_ws_on_error_callback_t)(int client_id, 
-                                              int error_code, 
-                                              const char *error_msg);
-
-/**
- * @brief WebSocket连接关闭回调
- * @param client_id 客户端ID
- * @param close_code 关闭状态码
- * @param reason 关闭原因
- */
-typedef void (*n706a_ws_on_close_callback_t)(int client_id, 
-                                              int close_code, 
-                                              const char *reason);
-
-/**
- * @brief N706A WebSocket客户端结构
- */
-typedef struct n706a_websocket_client {
-    int client_id;                      /**< 客户端ID (0-5) */
-    n706a_tcp_socket_t tcp_sock;        /**< 底层TCP socket */
-    n706a_ws_state_t state;             /**< WebSocket状态 */
-    bool is_ssl;                        /**< 是否WSS连接 */
-    
-    /* URL信息 */
-    char url[N706A_WS_MAX_URL_LEN];     /**< 完整URL */
-    char host[128];                     /**< 主机名 */
-    uint16_t port;                      /**< 端口号 */
-    char path[256];                     /**< 路径 */
-    
-    /* WebSocket协议 */
-    char sec_key[32];                   /**< Sec-WebSocket-Key */
-    char sec_accept[32];                /**< Sec-WebSocket-Accept */
-    
-    /* 接收缓冲区 */
-    uint8_t *recv_buffer;               /**< 接收缓冲区 */
-    size_t recv_buffer_size;            /**< 缓冲区大小 */
-    size_t recv_buffer_len;             /**< 已接收数据长度 */
-    
-    /* 回调函数 */
-    n706a_ws_on_open_callback_t on_open;
-    n706a_ws_on_message_callback_t on_message;
-    n706a_ws_on_error_callback_t on_error;
-    n706a_ws_on_close_callback_t on_close;
-    
-    /* 运行控制 */
-    bool running;                       /**< 接收线程运行标志 */
-    void *recv_thread;                  /**< 接收线程句柄 */
-    
-} n706a_websocket_client_t;
-
-/**
- * @brief 创建WebSocket客户端
- * @param on_open 连接打开回调
- * @param on_message 消息接收回调
- * @param on_error 错误回调
- * @param on_close 连接关闭回调
- * @return 客户端ID (0-5),失败返回-1
- */
-int n706a_websocket_constructor(n706a_ws_on_open_callback_t on_open,
-                                n706a_ws_on_message_callback_t on_message,
-                                n706a_ws_on_error_callback_t on_error,
-                                n706a_ws_on_close_callback_t on_close);
-
-/**
- * @brief 创建WebSocket客户端并指定socket ID
- * @param socket_id TCP socket ID (0-5)
- * @param on_open 连接打开回调
- * @param on_message 消息接收回调
- * @param on_error 错误回调
- * @param on_close 连接关闭回调
- * @return 客户端ID,失败返回-1
- */
-int n706a_websocket_constructor_with_socket(int socket_id,
-                                            n706a_ws_on_open_callback_t on_open,
-                                            n706a_ws_on_message_callback_t on_message,
-                                            n706a_ws_on_error_callback_t on_error,
-                                            n706a_ws_on_close_callback_t on_close);
-
-/**
- * @brief 连接到WebSocket服务器
- * @param client_id 客户端ID
- * @param url WebSocket URL (ws://或wss://)
- * @param option 可选参数(如子协议等),可为NULL
- * @return N706A_WS_SUCCESS成功,其他失败
- */
-int n706a_websocket_connect(int client_id, const char *url, const char *option);
-
-/**
- * @brief 发送文本消息
- * @param client_id 客户端ID
- * @param data 文本数据
- * @param length 数据长度
- * @return N706A_WS_SUCCESS成功,其他失败
- */
-int n706a_websocket_send_text(int client_id, const char *data, size_t length);
-
-/**
- * @brief 发送二进制消息
- * @param client_id 客户端ID
- * @param data 二进制数据
- * @param length 数据长度
- * @return N706A_WS_SUCCESS成功,其他失败
- */
-int n706a_websocket_send_binary(int client_id, const uint8_t *data, size_t length);
-
-/**
- * @brief 发送Ping帧
- * @param client_id 客户端ID
- * @param data Ping数据(可为NULL)
- * @param length 数据长度
- * @return N706A_WS_SUCCESS成功,其他失败
- */
-int n706a_websocket_send_ping(int client_id, const char *data, size_t length);
-
-/**
- * @brief 发送Pong帧
- * @param client_id 客户端ID
- * @param data Pong数据(可为NULL)
- * @param length 数据长度
- * @return N706A_WS_SUCCESS成功,其他失败
- */
-int n706a_websocket_send_pong(int client_id, const char *data, size_t length);
-
-/**
- * @brief 关闭WebSocket连接
- * @param client_id 客户端ID
- * @return N706A_WS_SUCCESS成功,其他失败
- */
-int n706a_websocket_close(int client_id);
-
-/**
- * @brief 关闭WebSocket连接(带状态码和原因)
- * @param client_id 客户端ID
- * @param close_code 关闭状态码
- * @param reason 关闭原因(可为NULL)
- * @return N706A_WS_SUCCESS成功,其他失败
- */
-int n706a_websocket_close_with_reason(int client_id, 
-                                      n706a_ws_close_code_t close_code,
-                                      const char *reason);
-
-/**
- * @brief 获取WebSocket连接状态
- * @param client_id 客户端ID
- * @return WebSocket状态
- */
-n706a_ws_state_t n706a_websocket_get_state(int client_id);
-
-/**
- * @brief 检查WebSocket是否已连接
- * @param client_id 客户端ID
- * @return true已连接,false未连接
- */
-bool n706a_websocket_is_connected(int client_id);
-
-/**
- * @brief 销毁WebSocket客户端
- * @param client_id 客户端ID
- * @return N706A_WS_SUCCESS成功,其他失败
- */
-int n706a_websocket_destructor(int client_id);
-
-/* ========== 内部辅助函数(高级用户可选使用) ========== */
-
-/**
- * @brief 解析WebSocket URL
- * @param url 完整URL
- * @param protocol 协议(输出,"ws"或"wss")
- * @param host 主机名(输出)
- * @param port 端口号(输出)
- * @param path 路径(输出)
- * @return N706A_WS_SUCCESS成功,其他失败
- */
-int n706a_websocket_parse_url(const char *url, 
-                              char *protocol, 
-                              char *host, 
-                              uint16_t *port, 
-                              char *path);
-
-/**
- * @brief 生成WebSocket Sec-WebSocket-Key
- * @param key 输出缓冲区(至少25字节)
- * @return N706A_WS_SUCCESS成功,其他失败
- */
-int n706a_websocket_generate_key(char *key);
-
-/**
- * @brief 计算WebSocket Sec-WebSocket-Accept
- * @param key Sec-WebSocket-Key
- * @param accept 输出缓冲区(至少29字节)
- * @return N706A_WS_SUCCESS成功,其他失败
- */
-int n706a_websocket_calculate_accept(const char *key, char *accept);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* N706A_WEBSOCKET_H */
-
diff --git a/code/sdk/zhihui/ppp/src/n706a_http_client.c b/code/sdk/zhihui/ppp/src/n706a_http_client.c
deleted file mode 100644 (file)
index 649e370..0000000
+++ /dev/null
@@ -1,785 +0,0 @@
-/**
- * @file n706a_http_client.c
- * @brief N706A HTTP/HTTPS客户端实现(基于TCP)
- * 
- * 基于TCP手动构造HTTP协议,支持:
- * - HTTP (普通TCP)
- * - HTTPS (SSL TCP)
- * - 6个并发连接
- * - 所有标准HTTP方法
- */
-
-#include "n706a_http_client.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-/* Base64编码表(用于Basic Auth) */
-static const char base64_table[] = 
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-/* ========== 私有函数声明 ========== */
-
-static int http_build_request(n706a_http_client_t *client,
-                              const char *method,
-                              const char *path,
-                              const char *body,
-                              size_t body_len,
-                              const char *content_type,
-                              char *request_buf,
-                              size_t buf_size);
-
-static n706a_httpc_result_t http_parse_response(const char *response,
-                                                size_t response_len,
-                                                n706a_http_client_t *client,
-                                                n706a_http_client_data_t *data);
-
-static void http_base64_encode(const char *input, size_t len, char *output);
-
-static int http_parse_url(const char *url,
-                          char *protocol,
-                          char *host,
-                          uint16_t *port,
-                          char *path);
-
-/* ========== 公共函数实现 ========== */
-
-/**
- * @brief 初始化HTTP客户端
- */
-n706a_httpc_result_t n706a_http_client_init(n706a_http_client_t *client, int socket_id)
-{
-    if (!client || socket_id < 0 || socket_id > 5) {
-        return N706A_HTTP_EARG;
-    }
-    
-    memset(client, 0, sizeof(n706a_http_client_t));
-    
-    client->socket_id = socket_id;
-    client->is_https = false;
-    client->remote_port = 0;
-    client->response_code = 0;
-    client->connected = false;
-    client->keepalive = false;
-    client->timeout_ms = 10000;  // 默认10秒
-    
-    /* 初始化TCP socket */
-    n706a_tcp_socket_create(&client->tcp_sock, socket_id);
-    
-    return N706A_HTTP_SUCCESS;
-}
-
-/**
- * @brief 连接到HTTP/HTTPS服务器
- */
-n706a_httpc_result_t n706a_http_client_connect(n706a_http_client_t *client,
-                                               const char *host,
-                                               uint16_t port,
-                                               bool use_ssl)
-{
-    if (!client || !host) {
-        return N706A_HTTP_EARG;
-    }
-    
-    /* 保存连接信息 */
-    strncpy(client->host, host, sizeof(client->host) - 1);
-    client->remote_port = port;
-    client->is_https = use_ssl;
-    
-    /* 建立TCP连接 */
-    n706a_tcp_result_t ret = n706a_tcp_connect(&client->tcp_sock,
-                                               host,
-                                               port,
-                                               use_ssl,
-                                               30000);  // SSL握手需要更长时间
-    
-    if (ret == N706A_TCP_SUCCESS) {
-        client->connected = true;
-        return N706A_HTTP_SUCCESS;
-    } else if (ret == N706A_TCP_ETIMEDOUT) {
-        return N706A_HTTP_ETIMEOUT;
-    } else {
-        return N706A_HTTP_ECONN;
-    }
-}
-
-/**
- * @brief 发送HTTP GET请求
- */
-n706a_httpc_result_t n706a_http_client_get(n706a_http_client_t *client,
-                                           const char *path,
-                                           n706a_http_client_data_t *client_data)
-{
-    if (!client || !path || !client_data) {
-        return N706A_HTTP_EARG;
-    }
-    
-    if (!client->connected) {
-        return N706A_HTTP_ECONN;
-    }
-    
-    /* 构造GET请求 */
-    char request_buf[2048];
-    int request_len = http_build_request(client, "GET", path,
-                                        NULL, 0, NULL,
-                                        request_buf, sizeof(request_buf));
-    
-    if (request_len < 0) {
-        return N706A_HTTP_ENOBUFS;
-    }
-    
-    /* 发送请求 */
-    size_t sent;
-    n706a_tcp_result_t ret = n706a_tcp_send(&client->tcp_sock,
-                                            (uint8_t*)request_buf,
-                                            request_len,
-                                            &sent);
-    
-    if (ret != N706A_TCP_SUCCESS || sent != (size_t)request_len) {
-        return N706A_HTTP_ESEND;
-    }
-    
-    /* 接收响应 */
-    uint8_t response_buf[8192];
-    size_t received;
-    
-    ret = n706a_tcp_recv(&client->tcp_sock,
-                        response_buf,
-                        sizeof(response_buf) - 1,
-                        &received,
-                        client->timeout_ms);
-    
-    if (ret != N706A_TCP_SUCCESS) {
-        return N706A_HTTP_ERECV;
-    }
-    
-    response_buf[received] = '\0';
-    
-    /* 解析响应 */
-    return http_parse_response((char*)response_buf, received, client, client_data);
-}
-
-/**
- * @brief 发送HTTP POST请求
- */
-n706a_httpc_result_t n706a_http_client_post(n706a_http_client_t *client,
-                                            const char *path,
-                                            const char *content_type,
-                                            const char *body,
-                                            size_t body_len,
-                                            n706a_http_client_data_t *client_data)
-{
-    if (!client || !path || !client_data) {
-        return N706A_HTTP_EARG;
-    }
-    
-    if (!client->connected) {
-        return N706A_HTTP_ECONN;
-    }
-    
-    /* 构造POST请求 */
-    char request_buf[4096];
-    int request_len = http_build_request(client, "POST", path,
-                                        body, body_len, content_type,
-                                        request_buf, sizeof(request_buf));
-    
-    if (request_len < 0) {
-        return N706A_HTTP_ENOBUFS;
-    }
-    
-    /* 发送请求 */
-    size_t sent;
-    n706a_tcp_result_t ret = n706a_tcp_send(&client->tcp_sock,
-                                            (uint8_t*)request_buf,
-                                            request_len,
-                                            &sent);
-    
-    if (ret != N706A_TCP_SUCCESS) {
-        return N706A_HTTP_ESEND;
-    }
-    
-    /* 接收响应 */
-    uint8_t response_buf[8192];
-    size_t received;
-    
-    ret = n706a_tcp_recv(&client->tcp_sock,
-                        response_buf,
-                        sizeof(response_buf) - 1,
-                        &received,
-                        client->timeout_ms);
-    
-    if (ret != N706A_TCP_SUCCESS) {
-        return N706A_HTTP_ERECV;
-    }
-    
-    response_buf[received] = '\0';
-    
-    return http_parse_response((char*)response_buf, received, client, client_data);
-}
-
-/**
- * @brief 发送HTTP PUT请求
- */
-n706a_httpc_result_t n706a_http_client_put(n706a_http_client_t *client,
-                                           const char *path,
-                                           const char *content_type,
-                                           const char *body,
-                                           size_t body_len,
-                                           n706a_http_client_data_t *client_data)
-{
-    if (!client || !path || !client_data) {
-        return N706A_HTTP_EARG;
-    }
-    
-    if (!client->connected) {
-        return N706A_HTTP_ECONN;
-    }
-    
-    char request_buf[4096];
-    int request_len = http_build_request(client, "PUT", path,
-                                        body, body_len, content_type,
-                                        request_buf, sizeof(request_buf));
-    
-    if (request_len < 0) {
-        return N706A_HTTP_ENOBUFS;
-    }
-    
-    size_t sent;
-    n706a_tcp_send(&client->tcp_sock, (uint8_t*)request_buf, request_len, &sent);
-    
-    uint8_t response_buf[8192];
-    size_t received;
-    n706a_tcp_recv(&client->tcp_sock, response_buf, sizeof(response_buf) - 1,
-                   &received, client->timeout_ms);
-    
-    response_buf[received] = '\0';
-    
-    return http_parse_response((char*)response_buf, received, client, client_data);
-}
-
-/**
- * @brief 发送HTTP DELETE请求
- */
-n706a_httpc_result_t n706a_http_client_delete(n706a_http_client_t *client,
-                                              const char *path,
-                                              n706a_http_client_data_t *client_data)
-{
-    if (!client || !path || !client_data) {
-        return N706A_HTTP_EARG;
-    }
-    
-    if (!client->connected) {
-        return N706A_HTTP_ECONN;
-    }
-    
-    char request_buf[2048];
-    int request_len = http_build_request(client, "DELETE", path,
-                                        NULL, 0, NULL,
-                                        request_buf, sizeof(request_buf));
-    
-    if (request_len < 0) {
-        return N706A_HTTP_ENOBUFS;
-    }
-    
-    size_t sent;
-    n706a_tcp_send(&client->tcp_sock, (uint8_t*)request_buf, request_len, &sent);
-    
-    uint8_t response_buf[8192];
-    size_t received;
-    n706a_tcp_recv(&client->tcp_sock, response_buf, sizeof(response_buf) - 1,
-                   &received, client->timeout_ms);
-    
-    response_buf[received] = '\0';
-    
-    return http_parse_response((char*)response_buf, received, client, client_data);
-}
-
-/**
- * @brief 发送HTTP HEAD请求
- */
-n706a_httpc_result_t n706a_http_client_head(n706a_http_client_t *client,
-                                            const char *path,
-                                            n706a_http_client_data_t *client_data)
-{
-    if (!client || !path || !client_data) {
-        return N706A_HTTP_EARG;
-    }
-    
-    if (!client->connected) {
-        return N706A_HTTP_ECONN;
-    }
-    
-    char request_buf[2048];
-    int request_len = http_build_request(client, "HEAD", path,
-                                        NULL, 0, NULL,
-                                        request_buf, sizeof(request_buf));
-    
-    if (request_len < 0) {
-        return N706A_HTTP_ENOBUFS;
-    }
-    
-    size_t sent;
-    n706a_tcp_send(&client->tcp_sock, (uint8_t*)request_buf, request_len, &sent);
-    
-    uint8_t response_buf[8192];
-    size_t received;
-    n706a_tcp_recv(&client->tcp_sock, response_buf, sizeof(response_buf) - 1,
-                   &received, client->timeout_ms);
-    
-    response_buf[received] = '\0';
-    
-    return http_parse_response((char*)response_buf, received, client, client_data);
-}
-
-/**
- * @brief 设置自定义HTTP请求头
- */
-n706a_httpc_result_t n706a_http_client_set_header(n706a_http_client_t *client,
-                                                  const char *header)
-{
-    if (!client) {
-        return N706A_HTTP_EARG;
-    }
-    
-    if (client->header) {
-        free(client->header);
-    }
-    
-    if (header) {
-        client->header = strdup(header);
-    } else {
-        client->header = NULL;
-    }
-    
-    return N706A_HTTP_SUCCESS;
-}
-
-/**
- * @brief 设置HTTP基本认证
- */
-n706a_httpc_result_t n706a_http_client_set_auth(n706a_http_client_t *client,
-                                                const char *username,
-                                                const char *password)
-{
-    if (!client) {
-        return N706A_HTTP_EARG;
-    }
-    
-    if (client->auth_user) {
-        free(client->auth_user);
-    }
-    if (client->auth_password) {
-        free(client->auth_password);
-    }
-    
-    if (username) {
-        client->auth_user = strdup(username);
-    } else {
-        client->auth_user = NULL;
-    }
-    
-    if (password) {
-        client->auth_password = strdup(password);
-    } else {
-        client->auth_password = NULL;
-    }
-    
-    return N706A_HTTP_SUCCESS;
-}
-
-/**
- * @brief 设置Keep-Alive模式
- */
-n706a_httpc_result_t n706a_http_client_set_keepalive(n706a_http_client_t *client,
-                                                     bool keepalive)
-{
-    if (!client) {
-        return N706A_HTTP_EARG;
-    }
-    
-    client->keepalive = keepalive;
-    
-    return N706A_HTTP_SUCCESS;
-}
-
-/**
- * @brief 关闭HTTP连接
- */
-n706a_httpc_result_t n706a_http_client_close(n706a_http_client_t *client)
-{
-    if (!client) {
-        return N706A_HTTP_EARG;
-    }
-    
-    if (client->connected) {
-        n706a_tcp_close(&client->tcp_sock);
-        client->connected = false;
-    }
-    
-    if (client->header) {
-        free(client->header);
-        client->header = NULL;
-    }
-    
-    if (client->auth_user) {
-        free(client->auth_user);
-        client->auth_user = NULL;
-    }
-    
-    if (client->auth_password) {
-        free(client->auth_password);
-        client->auth_password = NULL;
-    }
-    
-    return N706A_HTTP_SUCCESS;
-}
-
-/**
- * @brief 检查HTTP连接状态
- */
-bool n706a_http_client_is_connected(n706a_http_client_t *client)
-{
-    if (!client) {
-        return false;
-    }
-    
-    return client->connected && n706a_tcp_is_connected(&client->tcp_sock);
-}
-
-/**
- * @brief 获取最后的HTTP响应码
- */
-int n706a_http_client_get_response_code(n706a_http_client_t *client)
-{
-    if (!client) {
-        return 0;
-    }
-    
-    return client->response_code;
-}
-
-/**
- * @brief 解析完整URL并发起GET请求
- */
-n706a_httpc_result_t n706a_http_client_get_url(n706a_http_client_t *client,
-                                               const char *url,
-                                               n706a_http_client_data_t *client_data)
-{
-    if (!client || !url || !client_data) {
-        return N706A_HTTP_EARG;
-    }
-    
-    char protocol[8];
-    char host[256];
-    char path[512];
-    uint16_t port;
-    
-    if (http_parse_url(url, protocol, host, &port, path) != 0) {
-        return N706A_HTTP_EPARSE;
-    }
-    
-    bool use_ssl = (strcmp(protocol, "https") == 0);
-    
-    n706a_httpc_result_t ret = n706a_http_client_connect(client, host, port, use_ssl);
-    if (ret != N706A_HTTP_SUCCESS) {
-        return ret;
-    }
-    
-    return n706a_http_client_get(client, path, client_data);
-}
-
-/**
- * @brief 解析完整URL并发起POST请求
- */
-n706a_httpc_result_t n706a_http_client_post_url(n706a_http_client_t *client,
-                                                const char *url,
-                                                const char *content_type,
-                                                const char *body,
-                                                size_t body_len,
-                                                n706a_http_client_data_t *client_data)
-{
-    if (!client || !url || !client_data) {
-        return N706A_HTTP_EARG;
-    }
-    
-    char protocol[8];
-    char host[256];
-    char path[512];
-    uint16_t port;
-    
-    if (http_parse_url(url, protocol, host, &port, path) != 0) {
-        return N706A_HTTP_EPARSE;
-    }
-    
-    bool use_ssl = (strcmp(protocol, "https") == 0);
-    
-    n706a_httpc_result_t ret = n706a_http_client_connect(client, host, port, use_ssl);
-    if (ret != N706A_HTTP_SUCCESS) {
-        return ret;
-    }
-    
-    return n706a_http_client_post(client, path, content_type, body, body_len, client_data);
-}
-
-/* ========== 私有函数实现 ========== */
-
-/**
- * @brief 构造HTTP请求
- */
-static int http_build_request(n706a_http_client_t *client,
-                              const char *method,
-                              const char *path,
-                              const char *body,
-                              size_t body_len,
-                              const char *content_type,
-                              char *request_buf,
-                              size_t buf_size)
-{
-    int len = 0;
-    
-    /* 请求行 */
-    len += snprintf(request_buf + len, buf_size - len,
-                   "%s %s HTTP/1.1\r\n", method, path);
-    
-    /* Host头 */
-    len += snprintf(request_buf + len, buf_size - len,
-                   "Host: %s\r\n", client->host);
-    
-    /* User-Agent */
-    len += snprintf(request_buf + len, buf_size - len,
-                   "User-Agent: N706A-HTTP-Client/1.0\r\n");
-    
-    /* Accept */
-    len += snprintf(request_buf + len, buf_size - len,
-                   "Accept: */*\r\n");
-    
-    /* Connection */
-    len += snprintf(request_buf + len, buf_size - len,
-                   "Connection: %s\r\n",
-                   client->keepalive ? "keep-alive" : "close");
-    
-    /* Content-Type和Content-Length(POST/PUT) */
-    if (body && body_len > 0) {
-        if (content_type) {
-            len += snprintf(request_buf + len, buf_size - len,
-                           "Content-Type: %s\r\n", content_type);
-        }
-        
-        len += snprintf(request_buf + len, buf_size - len,
-                       "Content-Length: %zu\r\n", body_len);
-    }
-    
-    /* Basic认证 */
-    if (client->auth_user && client->auth_password) {
-        char auth_str[256];
-        char auth_b64[512];
-        
-        snprintf(auth_str, sizeof(auth_str), "%s:%s",
-                client->auth_user, client->auth_password);
-        
-        http_base64_encode(auth_str, strlen(auth_str), auth_b64);
-        
-        len += snprintf(request_buf + len, buf_size - len,
-                       "Authorization: Basic %s\r\n", auth_b64);
-    }
-    
-    /* 自定义请求头 */
-    if (client->header) {
-        len += snprintf(request_buf + len, buf_size - len,
-                       "%s", client->header);
-    }
-    
-    /* 空行 */
-    len += snprintf(request_buf + len, buf_size - len, "\r\n");
-    
-    /* 请求体 */
-    if (body && body_len > 0) {
-        if (len + body_len < buf_size) {
-            memcpy(request_buf + len, body, body_len);
-            len += body_len;
-        } else {
-            return -1;  // 缓冲区不足
-        }
-    }
-    
-    return len;
-}
-
-/**
- * @brief 解析HTTP响应
- */
-static n706a_httpc_result_t http_parse_response(const char *response,
-                                                size_t response_len,
-                                                n706a_http_client_t *client,
-                                                n706a_http_client_data_t *data)
-{
-    if (!response || !client || !data) {
-        return N706A_HTTP_EARG;
-    }
-    
-    /* 解析状态行 */
-    int major, minor, status_code;
-    if (sscanf(response, "HTTP/%d.%d %d", &major, &minor, &status_code) != 3) {
-        return N706A_HTTP_EPROTO;
-    }
-    
-    client->response_code = status_code;
-    
-    /* 查找头尾分界 */
-    const char *header_end = strstr(response, "\r\n\r\n");
-    if (!header_end) {
-        return N706A_HTTP_EPROTO;
-    }
-    
-    /* 提取响应头 */
-    size_t header_len = header_end - response;
-    if (data->headerBuf && data->headerBufLen > 0) {
-        size_t copy_len = (header_len < (size_t)data->headerBufLen - 1) ?
-                         header_len : (size_t)data->headerBufLen - 1;
-        memcpy(data->headerBuf, response, copy_len);
-        data->headerBuf[copy_len] = '\0';
-    }
-    
-    /* 提取Content-Length */
-    const char *content_len_str = strcasestr(response, "Content-Length:");
-    if (content_len_str && content_len_str < header_end) {
-        data->responseContentLen = atoi(content_len_str + 15);
-    } else {
-        data->responseContentLen = 0;
-    }
-    
-    /* 检查是否chunked */
-    if (strcasestr(response, "Transfer-Encoding: chunked")) {
-        data->isChunked = true;
-    } else {
-        data->isChunked = false;
-    }
-    
-    /* 提取响应体 */
-    const char *body = header_end + 4;
-    size_t body_len = response_len - (body - response);
-    
-    if (data->responseBuf && data->responseBufLen > 0) {
-        size_t copy_len = (body_len < (size_t)data->responseBufLen - 1) ?
-                         body_len : (size_t)data->responseBufLen - 1;
-        memcpy(data->responseBuf, body, copy_len);
-        data->responseBuf[copy_len] = '\0';
-        data->contentBlockLen = copy_len;
-    }
-    
-    /* 检查是否还有更多数据 */
-    if (data->responseContentLen > 0 && body_len < (size_t)data->responseContentLen) {
-        data->isMore = true;
-    } else {
-        data->isMore = false;
-    }
-    
-    return N706A_HTTP_SUCCESS;
-}
-
-/**
- * @brief Base64编码
- */
-static void http_base64_encode(const char *input, size_t len, char *output)
-{
-    size_t i = 0, j = 0;
-    unsigned char char_array_3[3];
-    unsigned char char_array_4[4];
-    
-    while (len--) {
-        char_array_3[i++] = *(input++);
-        if (i == 3) {
-            char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
-            char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
-            char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
-            char_array_4[3] = char_array_3[2] & 0x3f;
-            
-            for (i = 0; i < 4; i++) {
-                output[j++] = base64_table[char_array_4[i]];
-            }
-            i = 0;
-        }
-    }
-    
-    if (i) {
-        for (size_t k = i; k < 3; k++) {
-            char_array_3[k] = '\0';
-        }
-        
-        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
-        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
-        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
-        
-        for (size_t k = 0; k < i + 1; k++) {
-            output[j++] = base64_table[char_array_4[k]];
-        }
-        
-        while (i++ < 3) {
-            output[j++] = '=';
-        }
-    }
-    
-    output[j] = '\0';
-}
-
-/**
- * @brief 解析URL
- */
-static int http_parse_url(const char *url,
-                          char *protocol,
-                          char *host,
-                          uint16_t *port,
-                          char *path)
-{
-    if (!url || !protocol || !host || !port || !path) {
-        return -1;
-    }
-    
-    const char *p = url;
-    
-    /* 解析协议 */
-    if (strncmp(p, "https://", 8) == 0) {
-        strcpy(protocol, "https");
-        *port = 443;
-        p += 8;
-    } else if (strncmp(p, "http://", 7) == 0) {
-        strcpy(protocol, "http");
-        *port = 80;
-        p += 7;
-    } else {
-        return -1;
-    }
-    
-    /* 解析host和port */
-    const char *path_start = strchr(p, '/');
-    const char *port_start = strchr(p, ':');
-    
-    if (port_start && (!path_start || port_start < path_start)) {
-        /* 有端口号 */
-        size_t host_len = port_start - p;
-        strncpy(host, p, host_len);
-        host[host_len] = '\0';
-        
-        *port = atoi(port_start + 1);
-        
-        if (path_start) {
-            strcpy(path, path_start);
-        } else {
-            strcpy(path, "/");
-        }
-    } else {
-        /* 没有端口号 */
-        if (path_start) {
-            size_t host_len = path_start - p;
-            strncpy(host, p, host_len);
-            host[host_len] = '\0';
-            strcpy(path, path_start);
-        } else {
-            strcpy(host, p);
-            strcpy(path, "/");
-        }
-    }
-    
-    return 0;
-}
-
diff --git a/code/sdk/zhihui/ppp/src/n706a_tcp_client.c b/code/sdk/zhihui/ppp/src/n706a_tcp_client.c
deleted file mode 100644 (file)
index d7e0684..0000000
+++ /dev/null
@@ -1,659 +0,0 @@
-/**
- * @file n706a_tcp_client.c
- * @brief N706A TCP客户端实现
- * 
- * 支持两种SSL实现方式:
- * - AT指令模式:使用AT+SSLTCP*指令
- * - mbedtls模式:使用mbedtls库
- */
-
-#include "n706a_tcp_client.h"
-#include "ppp_at_handler.h"
-#include "ppp_types.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-/* ========== 私有函数声明 ========== */
-
-#ifdef N706A_SSL_USE_MBEDTLS
-static int tcp_mbedtls_send_callback(void *ctx, const unsigned char *buf, size_t len);
-static int tcp_mbedtls_recv_callback(void *ctx, unsigned char *buf, size_t len);
-static n706a_tcp_result_t tcp_mbedtls_init_ssl(n706a_tcp_socket_t *sock);
-static void tcp_mbedtls_cleanup_ssl(n706a_tcp_socket_t *sock);
-#endif
-
-/* ========== 公共函数实现 ========== */
-
-/**
- * @brief 创建TCP socket
- */
-n706a_tcp_result_t n706a_tcp_socket_create(n706a_tcp_socket_t *sock, int socket_id)
-{
-    if (!sock || socket_id < 0 || socket_id > 5) {
-        return N706A_TCP_EINVAL;
-    }
-    
-    memset(sock, 0, sizeof(n706a_tcp_socket_t));
-    
-    sock->socket_id = socket_id;
-    sock->state = N706A_TCP_STATE_CLOSED;
-    sock->is_ssl = false;
-    sock->timeout_ms = 15000;  // 默认15秒超时
-    
-#ifdef N706A_SSL_USE_AT_COMMAND
-    sock->ssl_version = 3;  // 默认TLS 1.2
-    sock->auth_mode = 1;    // 默认服务器认证
-    memset(sock->ca_cert_file, 0, sizeof(sock->ca_cert_file));
-#endif
-
-#ifdef N706A_SSL_USE_MBEDTLS
-    sock->ssl_initialized = false;
-#endif
-    
-    return N706A_TCP_SUCCESS;
-}
-
-/**
- * @brief 配置SSL参数
- */
-n706a_tcp_result_t n706a_tcp_config_ssl(n706a_tcp_socket_t *sock,
-                                        int ssl_version,
-                                        int auth_mode,
-                                        const char *ca_cert)
-{
-    if (!sock) {
-        return N706A_TCP_EINVAL;
-    }
-    
-#ifdef N706A_SSL_USE_AT_COMMAND
-    /* AT指令模式:保存配置参数 */
-    sock->ssl_version = ssl_version;
-    sock->auth_mode = auth_mode;
-    
-    if (ca_cert) {
-        strncpy(sock->ca_cert_file, ca_cert, sizeof(sock->ca_cert_file) - 1);
-        
-        /* 配置AT指令 */
-        char at_cmd[256];
-        
-        /* 设置SSL版本 */
-        snprintf(at_cmd, sizeof(at_cmd), "AT+SSLTCPCFG=\"sslversion\",%d", ssl_version);
-        ppp_at_response_t response;
-        ppp_at_send_command(at_cmd, NULL, 5000, &response);
-        
-        /* 设置认证模式 */
-        snprintf(at_cmd, sizeof(at_cmd), "AT+SSLTCPCFG=\"authmode\",%d", auth_mode);
-        ppp_at_send_command(at_cmd, NULL, 5000, &response);
-        
-        /* 设置CA证书 */
-        if (ca_cert && strlen(ca_cert) > 0) {
-            snprintf(at_cmd, sizeof(at_cmd), "AT+SSLTCPCFG=\"cacert\",\"%s\"", ca_cert);
-            ppp_at_send_command(at_cmd, NULL, 5000, &response);
-        }
-    }
-#endif
-
-#ifdef N706A_SSL_USE_MBEDTLS
-    /* mbedtls模式:解析CA证书 */
-    if (ca_cert && strlen(ca_cert) > 0) {
-        mbedtls_x509_crt_init(&sock->cacert);
-        
-        int ret = mbedtls_x509_crt_parse(&sock->cacert,
-                                        (const unsigned char *)ca_cert,
-                                        strlen(ca_cert) + 1);
-        if (ret != 0) {
-            return N706A_TCP_ERROR;
-        }
-    }
-    
-    sock->auth_mode = auth_mode;
-#endif
-    
-    return N706A_TCP_SUCCESS;
-}
-
-#ifdef N706A_SSL_USE_MBEDTLS
-/**
- * @brief 配置客户端证书和私钥(mbedtls专用)
- */
-n706a_tcp_result_t n706a_tcp_config_ssl_client_cert(n706a_tcp_socket_t *sock,
-                                                     const char *client_cert,
-                                                     const char *client_key)
-{
-    if (!sock || !client_cert || !client_key) {
-        return N706A_TCP_EINVAL;
-    }
-    
-    /* 解析客户端证书 */
-    mbedtls_x509_crt_init(&sock->clicert);
-    int ret = mbedtls_x509_crt_parse(&sock->clicert,
-                                    (const unsigned char *)client_cert,
-                                    strlen(client_cert) + 1);
-    if (ret != 0) {
-        return N706A_TCP_ERROR;
-    }
-    
-    /* 解析私钥 */
-    mbedtls_pk_init(&sock->pkey);
-    ret = mbedtls_pk_parse_key(&sock->pkey,
-                              (const unsigned char *)client_key,
-                              strlen(client_key) + 1,
-                              NULL, 0);
-    if (ret != 0) {
-        mbedtls_x509_crt_free(&sock->clicert);
-        return N706A_TCP_ERROR;
-    }
-    
-    return N706A_TCP_SUCCESS;
-}
-#endif
-
-/**
- * @brief 连接到TCP服务器
- */
-n706a_tcp_result_t n706a_tcp_connect(n706a_tcp_socket_t *sock,
-                                     const char *host,
-                                     uint16_t port,
-                                     bool use_ssl,
-                                     uint32_t timeout_ms)
-{
-    if (!sock || !host) {
-        return N706A_TCP_EINVAL;
-    }
-    
-    if (sock->state == N706A_TCP_STATE_CONNECTED) {
-        return N706A_TCP_SUCCESS;  // 已连接
-    }
-    
-    /* 保存连接信息 */
-    strncpy(sock->remote_ip, host, sizeof(sock->remote_ip) - 1);
-    sock->remote_port = port;
-    sock->is_ssl = use_ssl;
-    sock->timeout_ms = timeout_ms;
-    
-    char at_cmd[256];
-    ppp_at_response_t response;
-    ppp_error_t ret;
-    
-    sock->state = N706A_TCP_STATE_CONNECTING;
-    
-#ifdef N706A_SSL_USE_AT_COMMAND
-    if (use_ssl) {
-        /* AT指令SSL模式:使用AT+SSLTCPSETUP */
-        snprintf(at_cmd, sizeof(at_cmd),
-                "AT+SSLTCPSETUP=%d,%s,%d,%d",
-                sock->socket_id,
-                host,
-                port,
-                sock->auth_mode);
-        
-        ret = ppp_at_send_command(at_cmd, NULL, timeout_ms, &response);
-        
-        if (ret == PPP_SUCCESS && response.response &&
-            strstr(response.response, "+SSLTCPSETUP:") &&
-            strstr(response.response, ",OK")) {
-            sock->state = N706A_TCP_STATE_CONNECTED;
-            return N706A_TCP_SUCCESS;
-        }
-    } else {
-        /* 普通TCP */
-        snprintf(at_cmd, sizeof(at_cmd),
-                "AT+TCPSETUP=%d,%s,%d",
-                sock->socket_id,
-                host,
-                port);
-        
-        ret = ppp_at_send_command(at_cmd, NULL, timeout_ms, &response);
-        
-        if (ret == PPP_SUCCESS && response.response &&
-            strstr(response.response, "+TCPSETUP:") &&
-            strstr(response.response, ",OK")) {
-            sock->state = N706A_TCP_STATE_CONNECTED;
-            return N706A_TCP_SUCCESS;
-        }
-    }
-#endif
-
-#ifdef N706A_SSL_USE_MBEDTLS
-    /* mbedtls模式:先建立TCP,再进行SSL握手 */
-    
-    /* 1. 先建立普通TCP连接 */
-    snprintf(at_cmd, sizeof(at_cmd),
-            "AT+TCPSETUP=%d,%s,%d",
-            sock->socket_id,
-            host,
-            port);
-    
-    ret = ppp_at_send_command(at_cmd, NULL, timeout_ms, &response);
-    
-    if (ret != PPP_SUCCESS || !response.response ||
-        !strstr(response.response, "+TCPSETUP:") ||
-        !strstr(response.response, ",OK")) {
-        sock->state = N706A_TCP_STATE_ERROR;
-        return N706A_TCP_ECONNREF;
-    }
-    
-    /* 2. 如果使用SSL,进行SSL握手 */
-    if (use_ssl) {
-        n706a_tcp_result_t ssl_ret = tcp_mbedtls_init_ssl(sock);
-        if (ssl_ret != N706A_TCP_SUCCESS) {
-            n706a_tcp_close(sock);
-            return ssl_ret;
-        }
-        
-        /* 设置主机名(用于SNI) */
-        mbedtls_ssl_set_hostname(&sock->ssl, host);
-        
-        /* 执行SSL握手 */
-        int handshake_ret;
-        while ((handshake_ret = mbedtls_ssl_handshake(&sock->ssl)) != 0) {
-            if (handshake_ret != MBEDTLS_ERR_SSL_WANT_READ &&
-                handshake_ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
-                /* 握手失败 */
-                tcp_mbedtls_cleanup_ssl(sock);
-                n706a_tcp_close(sock);
-                sock->state = N706A_TCP_STATE_ERROR;
-                return N706A_TCP_ERROR;
-            }
-        }
-        
-        /* 验证证书 */
-        uint32_t flags = mbedtls_ssl_get_verify_result(&sock->ssl);
-        if (flags != 0 && sock->auth_mode != MBEDTLS_SSL_VERIFY_NONE) {
-            /* 证书验证失败 */
-            tcp_mbedtls_cleanup_ssl(sock);
-            n706a_tcp_close(sock);
-            sock->state = N706A_TCP_STATE_ERROR;
-            return N706A_TCP_ERROR;
-        }
-    }
-#endif
-    
-    sock->state = N706A_TCP_STATE_CONNECTED;
-    return N706A_TCP_SUCCESS;
-    
-error:
-    sock->state = N706A_TCP_STATE_ERROR;
-    return N706A_TCP_ECONNREF;
-}
-
-/**
- * @brief 发送TCP数据
- */
-n706a_tcp_result_t n706a_tcp_send(n706a_tcp_socket_t *sock,
-                                  const uint8_t *data,
-                                  size_t len,
-                                  size_t *sent)
-{
-    if (!sock || !data || len == 0 || !sent) {
-        return N706A_TCP_EINVAL;
-    }
-    
-    if (sock->state != N706A_TCP_STATE_CONNECTED) {
-        return N706A_TCP_ENOTCONN;
-    }
-    
-#ifdef N706A_SSL_USE_MBEDTLS
-    /* mbedtls模式:通过SSL发送 */
-    if (sock->is_ssl && sock->ssl_initialized) {
-        int ret = mbedtls_ssl_write(&sock->ssl, data, len);
-        if (ret > 0) {
-            *sent = ret;
-            return N706A_TCP_SUCCESS;
-        } else {
-            return N706A_TCP_ERROR;
-        }
-    }
-#endif
-    
-    /* AT指令模式或普通TCP */
-    char at_cmd[64];
-    ppp_at_response_t response;
-    
-#ifdef N706A_SSL_USE_AT_COMMAND
-    if (sock->is_ssl) {
-        snprintf(at_cmd, sizeof(at_cmd), "AT+SSLTCPSEND=%d,%zu",
-                sock->socket_id, len);
-    } else
-#endif
-    {
-        snprintf(at_cmd, sizeof(at_cmd), "AT+TCPSEND=%d,%zu",
-                sock->socket_id, len);
-    }
-    
-    /* 发送命令,等待'>'提示符 */
-    ppp_error_t ret = ppp_at_send_command(at_cmd, NULL, 5000, &response);
-    if (ret != PPP_SUCCESS) {
-        return N706A_TCP_ERROR;
-    }
-    
-    /* 发送实际数据 */
-    ret = ppp_at_send_raw_data(data, len, sock->timeout_ms);
-    if (ret != PPP_SUCCESS) {
-        return N706A_TCP_ERROR;
-    }
-    
-    *sent = len;
-    return N706A_TCP_SUCCESS;
-}
-
-/**
- * @brief 接收TCP数据
- */
-n706a_tcp_result_t n706a_tcp_recv(n706a_tcp_socket_t *sock,
-                                  uint8_t *buffer,
-                                  size_t len,
-                                  size_t *received,
-                                  uint32_t timeout_ms)
-{
-    if (!sock || !buffer || len == 0 || !received) {
-        return N706A_TCP_EINVAL;
-    }
-    
-    if (sock->state != N706A_TCP_STATE_CONNECTED) {
-        return N706A_TCP_ENOTCONN;
-    }
-    
-#ifdef N706A_SSL_USE_MBEDTLS
-    /* mbedtls模式:通过SSL接收 */
-    if (sock->is_ssl && sock->ssl_initialized) {
-        mbedtls_ssl_conf_read_timeout(&sock->conf, timeout_ms);
-        
-        int ret = mbedtls_ssl_read(&sock->ssl, buffer, len);
-        if (ret > 0) {
-            *received = ret;
-            return N706A_TCP_SUCCESS;
-        } else if (ret == 0 || ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
-            *received = 0;
-            return N706A_TCP_SUCCESS;
-        } else {
-            return N706A_TCP_ERROR;
-        }
-    }
-#endif
-    
-    /* AT指令模式或普通TCP */
-    char at_cmd[64];
-    ppp_at_response_t response;
-    
-#ifdef N706A_SSL_USE_AT_COMMAND
-    if (sock->is_ssl) {
-        snprintf(at_cmd, sizeof(at_cmd), "AT+SSLTCPREAD=%d,%zu",
-                sock->socket_id, len);
-    } else
-#endif
-    {
-        snprintf(at_cmd, sizeof(at_cmd), "AT+TCPREAD=%d,%zu",
-                sock->socket_id, len);
-    }
-    
-    ppp_error_t ret = ppp_at_send_command(at_cmd, NULL, timeout_ms, &response);
-    if (ret != PPP_SUCCESS) {
-        return N706A_TCP_ETIMEDOUT;
-    }
-    
-    /* 解析响应,提取数据 */
-    if (response.response) {
-        /* 查找数据部分 */
-        const char *data_start = strstr(response.response, "\r\n");
-        if (data_start) {
-            data_start += 2;  // 跳过\r\n
-            size_t data_len = response.response_len - (data_start - response.response);
-            
-            if (data_len > len) {
-                data_len = len;
-            }
-            
-            memcpy(buffer, data_start, data_len);
-            *received = data_len;
-            return N706A_TCP_SUCCESS;
-        }
-    }
-    
-    *received = 0;
-    return N706A_TCP_SUCCESS;
-}
-
-/**
- * @brief 关闭TCP连接
- */
-n706a_tcp_result_t n706a_tcp_close(n706a_tcp_socket_t *sock)
-{
-    if (!sock) {
-        return N706A_TCP_EINVAL;
-    }
-    
-    if (sock->state == N706A_TCP_STATE_CLOSED) {
-        return N706A_TCP_SUCCESS;
-    }
-    
-#ifdef N706A_SSL_USE_MBEDTLS
-    /* mbedtls模式:清理SSL上下文 */
-    if (sock->is_ssl && sock->ssl_initialized) {
-        mbedtls_ssl_close_notify(&sock->ssl);
-        tcp_mbedtls_cleanup_ssl(sock);
-    }
-#endif
-    
-    /* 发送关闭命令 */
-    char at_cmd[32];
-    ppp_at_response_t response;
-    
-#ifdef N706A_SSL_USE_AT_COMMAND
-    if (sock->is_ssl) {
-        snprintf(at_cmd, sizeof(at_cmd), "AT+SSLTCPCLOSE=%d", sock->socket_id);
-    } else
-#endif
-    {
-        snprintf(at_cmd, sizeof(at_cmd), "AT+TCPCLOSE=%d", sock->socket_id);
-    }
-    
-    ppp_at_send_command(at_cmd, NULL, 5000, &response);
-    
-    sock->state = N706A_TCP_STATE_CLOSED;
-    sock->is_ssl = false;
-    
-    return N706A_TCP_SUCCESS;
-}
-
-/**
- * @brief 检查socket是否已连接
- */
-bool n706a_tcp_is_connected(const n706a_tcp_socket_t *sock)
-{
-    if (!sock) {
-        return false;
-    }
-    
-    return (sock->state == N706A_TCP_STATE_CONNECTED);
-}
-
-/**
- * @brief 获取socket状态
- */
-n706a_tcp_state_t n706a_tcp_get_state(const n706a_tcp_socket_t *sock)
-{
-    if (!sock) {
-        return N706A_TCP_STATE_ERROR;
-    }
-    
-    return sock->state;
-}
-
-/* ========== mbedtls私有函数实现 ========== */
-
-#ifdef N706A_SSL_USE_MBEDTLS
-
-/**
- * @brief 初始化mbedtls SSL
- */
-static n706a_tcp_result_t tcp_mbedtls_init_ssl(n706a_tcp_socket_t *sock)
-{
-    if (!sock) {
-        return N706A_TCP_EINVAL;
-    }
-    
-    /* 初始化SSL上下文 */
-    mbedtls_ssl_init(&sock->ssl);
-    mbedtls_ssl_config_init(&sock->conf);
-    mbedtls_entropy_init(&sock->entropy);
-    mbedtls_ctr_drbg_init(&sock->ctr_drbg);
-    
-    /* 初始化随机数生成器 */
-    const char *pers = "n706a_tcp_client";
-    int ret = mbedtls_ctr_drbg_seed(&sock->ctr_drbg,
-                                   mbedtls_entropy_func,
-                                   &sock->entropy,
-                                   (const unsigned char *)pers,
-                                   strlen(pers));
-    if (ret != 0) {
-        return N706A_TCP_ERROR;
-    }
-    
-    /* 配置SSL */
-    ret = mbedtls_ssl_config_defaults(&sock->conf,
-                                     MBEDTLS_SSL_IS_CLIENT,
-                                     MBEDTLS_SSL_TRANSPORT_STREAM,
-                                     MBEDTLS_SSL_PRESET_DEFAULT);
-    if (ret != 0) {
-        return N706A_TCP_ERROR;
-    }
-    
-    /* 设置认证模式 */
-    mbedtls_ssl_conf_authmode(&sock->conf, sock->auth_mode);
-    
-    /* 设置随机数生成器 */
-    mbedtls_ssl_conf_rng(&sock->conf,
-                        mbedtls_ctr_drbg_random,
-                        &sock->ctr_drbg);
-    
-    /* 设置CA证书 */
-    mbedtls_ssl_conf_ca_chain(&sock->conf, &sock->cacert, NULL);
-    
-    /* 设置客户端证书(如果有) */
-    if (sock->clicert.version != 0) {
-        mbedtls_ssl_conf_own_cert(&sock->conf, &sock->clicert, &sock->pkey);
-    }
-    
-    /* 应用配置 */
-    ret = mbedtls_ssl_setup(&sock->ssl, &sock->conf);
-    if (ret != 0) {
-        return N706A_TCP_ERROR;
-    }
-    
-    /* 设置发送/接收回调 */
-    mbedtls_ssl_set_bio(&sock->ssl,
-                       sock,
-                       tcp_mbedtls_send_callback,
-                       tcp_mbedtls_recv_callback,
-                       NULL);
-    
-    sock->ssl_initialized = true;
-    
-    return N706A_TCP_SUCCESS;
-}
-
-/**
- * @brief 清理mbedtls SSL
- */
-static void tcp_mbedtls_cleanup_ssl(n706a_tcp_socket_t *sock)
-{
-    if (!sock || !sock->ssl_initialized) {
-        return;
-    }
-    
-    mbedtls_ssl_free(&sock->ssl);
-    mbedtls_ssl_config_free(&sock->conf);
-    mbedtls_ctr_drbg_free(&sock->ctr_drbg);
-    mbedtls_entropy_free(&sock->entropy);
-    
-    if (sock->cacert.version != 0) {
-        mbedtls_x509_crt_free(&sock->cacert);
-    }
-    
-    if (sock->clicert.version != 0) {
-        mbedtls_x509_crt_free(&sock->clicert);
-    }
-    
-    if (sock->pkey.pk_info != NULL) {
-        mbedtls_pk_free(&sock->pkey);
-    }
-    
-    sock->ssl_initialized = false;
-}
-
-/**
- * @brief mbedtls发送回调(通过AT命令发送)
- */
-static int tcp_mbedtls_send_callback(void *ctx, const unsigned char *buf, size_t len)
-{
-    n706a_tcp_socket_t *sock = (n706a_tcp_socket_t *)ctx;
-    
-    if (!sock || !buf || len == 0) {
-        return MBEDTLS_ERR_NET_SEND_FAILED;
-    }
-    
-    /* 通过AT+TCPSEND发送加密后的数据 */
-    char at_cmd[64];
-    snprintf(at_cmd, sizeof(at_cmd), "AT+TCPSEND=%d,%zu",
-            sock->socket_id, len);
-    
-    ppp_at_response_t response;
-    ppp_error_t ret = ppp_at_send_command(at_cmd, NULL, 5000, &response);
-    if (ret != PPP_SUCCESS) {
-        return MBEDTLS_ERR_NET_SEND_FAILED;
-    }
-    
-    /* 发送数据 */
-    ret = ppp_at_send_raw_data(buf, len, sock->timeout_ms);
-    if (ret != PPP_SUCCESS) {
-        return MBEDTLS_ERR_NET_SEND_FAILED;
-    }
-    
-    return len;
-}
-
-/**
- * @brief mbedtls接收回调(通过AT命令接收)
- */
-static int tcp_mbedtls_recv_callback(void *ctx, unsigned char *buf, size_t len)
-{
-    n706a_tcp_socket_t *sock = (n706a_tcp_socket_t *)ctx;
-    
-    if (!sock || !buf || len == 0) {
-        return MBEDTLS_ERR_NET_RECV_FAILED;
-    }
-    
-    /* 通过AT+TCPREAD接收加密数据 */
-    char at_cmd[64];
-    snprintf(at_cmd, sizeof(at_cmd), "AT+TCPREAD=%d,%zu",
-            sock->socket_id, len);
-    
-    ppp_at_response_t response;
-    ppp_error_t ret = ppp_at_send_command(at_cmd, NULL, sock->timeout_ms, &response);
-    if (ret != PPP_SUCCESS) {
-        return MBEDTLS_ERR_NET_RECV_FAILED;
-    }
-    
-    /* 解析数据 */
-    if (response.response) {
-        const char *data_start = strstr(response.response, "\r\n");
-        if (data_start) {
-            data_start += 2;
-            size_t data_len = response.response_len - (data_start - response.response);
-            
-            if (data_len > len) {
-                data_len = len;
-            }
-            
-            memcpy(buf, data_start, data_len);
-            return data_len;
-        }
-    }
-    
-    return 0;  // 没有数据
-}
-
-#endif /* N706A_SSL_USE_MBEDTLS */
-
diff --git a/code/sdk/zhihui/ppp/src/n706a_websocket.c b/code/sdk/zhihui/ppp/src/n706a_websocket.c
deleted file mode 100644 (file)
index 70b86a2..0000000
+++ /dev/null
@@ -1,843 +0,0 @@
-/**
- * @file n706a_websocket.c
- * @brief N706A WebSocket客户端实现(基于TCP)
- * 
- * 完整实现RFC 6455 WebSocket协议:
- * - ws:// (普通TCP)
- * - wss:// (SSL TCP)
- * - 握手
- * - 帧封装/解封装
- * - Ping/Pong
- * - 分片传输
- */
-
-#include "n706a_websocket.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-
-/* WebSocket GUID(RFC 6455) */
-#define WS_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
-
-/* WebSocket帧标志 */
-#define WS_FIN_BIT      0x80
-#define WS_MASK_BIT     0x80
-#define WS_OPCODE_MASK  0x0F
-#define WS_PAYLOAD_MASK 0x7F
-
-/* 全局WebSocket客户端数组 */
-static n706a_websocket_client_t *g_ws_clients[N706A_WS_MAX_CLIENTS] = {NULL};
-
-/* ========== 私有函数声明 ========== */
-
-static int ws_perform_handshake(n706a_websocket_client_t *client);
-static int ws_send_frame(n706a_websocket_client_t *client,
-                        n706a_ws_opcode_t opcode,
-                        const uint8_t *data,
-                        size_t length,
-                        bool fin);
-static int ws_recv_frame(n706a_websocket_client_t *client);
-static void ws_generate_mask_key(uint8_t *mask_key);
-static void ws_mask_data(uint8_t *data, size_t len, const uint8_t *mask_key);
-static void *ws_recv_thread_func(void *arg);
-static int ws_parse_url(const char *url, char *protocol, char *host,
-                       uint16_t *port, char *path);
-
-/* SHA-1哈希(简化实现,用于WebSocket握手) */
-static void sha1_simple(const unsigned char *input, size_t len, unsigned char output[20]);
-
-/* Base64编码 */
-static void base64_encode(const unsigned char *input, size_t len, char *output);
-
-/* ========== 公共函数实现 ========== */
-
-/**
- * @brief 创建WebSocket客户端
- */
-int n706a_websocket_constructor(n706a_ws_on_open_callback_t on_open,
-                                n706a_ws_on_message_callback_t on_message,
-                                n706a_ws_on_error_callback_t on_error,
-                                n706a_ws_on_close_callback_t on_close)
-{
-    /* 查找空闲slot */
-    int client_id = -1;
-    for (int i = 0; i < N706A_WS_MAX_CLIENTS; i++) {
-        if (g_ws_clients[i] == NULL) {
-            client_id = i;
-            break;
-        }
-    }
-    
-    if (client_id < 0) {
-        return -1;  // 没有可用slot
-    }
-    
-    /* 分配客户端结构 */
-    n706a_websocket_client_t *client = 
-        (n706a_websocket_client_t *)malloc(sizeof(n706a_websocket_client_t));
-    
-    if (!client) {
-        return -1;
-    }
-    
-    memset(client, 0, sizeof(n706a_websocket_client_t));
-    
-    client->client_id = client_id;
-    client->state = N706A_WS_STATE_CLOSED;
-    client->is_ssl = false;
-    
-    /* 初始化TCP socket */
-    n706a_tcp_socket_create(&client->tcp_sock, client_id);
-    
-    /* 设置回调 */
-    client->on_open = on_open;
-    client->on_message = on_message;
-    client->on_error = on_error;
-    client->on_close = on_close;
-    
-    /* 分配接收缓冲区 */
-    client->recv_buffer_size = 8192;
-    client->recv_buffer = (uint8_t *)malloc(client->recv_buffer_size);
-    if (!client->recv_buffer) {
-        free(client);
-        return -1;
-    }
-    
-    client->recv_buffer_len = 0;
-    client->running = false;
-    
-    g_ws_clients[client_id] = client;
-    
-    return client_id;
-}
-
-/**
- * @brief 创建WebSocket客户端(指定socket ID)
- */
-int n706a_websocket_constructor_with_socket(int socket_id,
-                                            n706a_ws_on_open_callback_t on_open,
-                                            n706a_ws_on_message_callback_t on_message,
-                                            n706a_ws_on_error_callback_t on_error,
-                                            n706a_ws_on_close_callback_t on_close)
-{
-    if (socket_id < 0 || socket_id >= N706A_WS_MAX_CLIENTS) {
-        return -1;
-    }
-    
-    if (g_ws_clients[socket_id] != NULL) {
-        return -1;  // 已被占用
-    }
-    
-    n706a_websocket_client_t *client = 
-        (n706a_websocket_client_t *)malloc(sizeof(n706a_websocket_client_t));
-    
-    if (!client) {
-        return -1;
-    }
-    
-    memset(client, 0, sizeof(n706a_websocket_client_t));
-    
-    client->client_id = socket_id;
-    client->state = N706A_WS_STATE_CLOSED;
-    
-    n706a_tcp_socket_create(&client->tcp_sock, socket_id);
-    
-    client->on_open = on_open;
-    client->on_message = on_message;
-    client->on_error = on_error;
-    client->on_close = on_close;
-    
-    client->recv_buffer_size = 8192;
-    client->recv_buffer = (uint8_t *)malloc(client->recv_buffer_size);
-    if (!client->recv_buffer) {
-        free(client);
-        return -1;
-    }
-    
-    g_ws_clients[socket_id] = client;
-    
-    return socket_id;
-}
-
-/**
- * @brief 连接到WebSocket服务器
- */
-int n706a_websocket_connect(int client_id, const char *url, const char *option)
-{
-    if (client_id < 0 || client_id >= N706A_WS_MAX_CLIENTS) {
-        return N706A_WS_ERROR_INVALID_PARAM;
-    }
-    
-    n706a_websocket_client_t *client = g_ws_clients[client_id];
-    if (!client) {
-        return N706A_WS_ERROR_INVALID_PARAM;
-    }
-    
-    if (client->state != N706A_WS_STATE_CLOSED) {
-        return N706A_WS_ERROR_ALREADY_OPEN;
-    }
-    
-    /* 解析URL */
-    char protocol[8];
-    
-    if (ws_parse_url(url, protocol, client->host, &client->port, client->path) != 0) {
-        if (client->on_error) {
-            client->on_error(client_id, N706A_WS_ERROR_INVALID_PARAM, "Invalid URL");
-        }
-        return N706A_WS_ERROR_INVALID_PARAM;
-    }
-    
-    strncpy(client->url, url, sizeof(client->url) - 1);
-    
-    /* 判断是否WSS */
-    client->is_ssl = (strcmp(protocol, "wss") == 0);
-    
-    client->state = N706A_WS_STATE_CONNECTING;
-    
-    /* 建立TCP连接 */
-    n706a_tcp_result_t ret = n706a_tcp_connect(&client->tcp_sock,
-                                               client->host,
-                                               client->port,
-                                               client->is_ssl,
-                                               30000);
-    
-    if (ret != N706A_TCP_SUCCESS) {
-        client->state = N706A_WS_STATE_CLOSED;
-        if (client->on_error) {
-            client->on_error(client_id, N706A_WS_ERROR_HANDSHAKE, "TCP connection failed");
-        }
-        return N706A_WS_ERROR_HANDSHAKE;
-    }
-    
-    /* WebSocket握手 */
-    if (ws_perform_handshake(client) != 0) {
-        n706a_tcp_close(&client->tcp_sock);
-        client->state = N706A_WS_STATE_CLOSED;
-        if (client->on_error) {
-            client->on_error(client_id, N706A_WS_ERROR_HANDSHAKE, "WebSocket handshake failed");
-        }
-        return N706A_WS_ERROR_HANDSHAKE;
-    }
-    
-    client->state = N706A_WS_STATE_OPEN;
-    
-    /* 启动接收线程 */
-    client->running = true;
-    // TODO: 创建接收线程
-    // pthread_create(&client->recv_thread, NULL, ws_recv_thread_func, client);
-    
-    /* 调用on_open回调 */
-    if (client->on_open) {
-        client->on_open(client_id);
-    }
-    
-    return N706A_WS_SUCCESS;
-}
-
-/**
- * @brief 发送文本消息
- */
-int n706a_websocket_send_text(int client_id, const char *data, size_t length)
-{
-    if (client_id < 0 || client_id >= N706A_WS_MAX_CLIENTS) {
-        return N706A_WS_ERROR_INVALID_PARAM;
-    }
-    
-    n706a_websocket_client_t *client = g_ws_clients[client_id];
-    if (!client || client->state != N706A_WS_STATE_OPEN) {
-        return N706A_WS_ERROR_NOT_CONNECTED;
-    }
-    
-    return ws_send_frame(client, N706A_WS_OPCODE_TEXT, (const uint8_t *)data, length, true);
-}
-
-/**
- * @brief 发送二进制消息
- */
-int n706a_websocket_send_binary(int client_id, const uint8_t *data, size_t length)
-{
-    if (client_id < 0 || client_id >= N706A_WS_MAX_CLIENTS) {
-        return N706A_WS_ERROR_INVALID_PARAM;
-    }
-    
-    n706a_websocket_client_t *client = g_ws_clients[client_id];
-    if (!client || client->state != N706A_WS_STATE_OPEN) {
-        return N706A_WS_ERROR_NOT_CONNECTED;
-    }
-    
-    return ws_send_frame(client, N706A_WS_OPCODE_BINARY, data, length, true);
-}
-
-/**
- * @brief 发送Ping帧
- */
-int n706a_websocket_send_ping(int client_id, const char *data, size_t length)
-{
-    if (client_id < 0 || client_id >= N706A_WS_MAX_CLIENTS) {
-        return N706A_WS_ERROR_INVALID_PARAM;
-    }
-    
-    n706a_websocket_client_t *client = g_ws_clients[client_id];
-    if (!client || client->state != N706A_WS_STATE_OPEN) {
-        return N706A_WS_ERROR_NOT_CONNECTED;
-    }
-    
-    return ws_send_frame(client, N706A_WS_OPCODE_PING, (const uint8_t *)data, length, true);
-}
-
-/**
- * @brief 发送Pong帧
- */
-int n706a_websocket_send_pong(int client_id, const char *data, size_t length)
-{
-    if (client_id < 0 || client_id >= N706A_WS_MAX_CLIENTS) {
-        return N706A_WS_ERROR_INVALID_PARAM;
-    }
-    
-    n706a_websocket_client_t *client = g_ws_clients[client_id];
-    if (!client || client->state != N706A_WS_STATE_OPEN) {
-        return N706A_WS_ERROR_NOT_CONNECTED;
-    }
-    
-    return ws_send_frame(client, N706A_WS_OPCODE_PONG, (const uint8_t *)data, length, true);
-}
-
-/**
- * @brief 关闭WebSocket连接
- */
-int n706a_websocket_close(int client_id)
-{
-    return n706a_websocket_close_with_reason(client_id, N706A_WS_CLOSE_NORMAL, NULL);
-}
-
-/**
- * @brief 关闭WebSocket连接(带原因)
- */
-int n706a_websocket_close_with_reason(int client_id,
-                                      n706a_ws_close_code_t close_code,
-                                      const char *reason)
-{
-    if (client_id < 0 || client_id >= N706A_WS_MAX_CLIENTS) {
-        return N706A_WS_ERROR_INVALID_PARAM;
-    }
-    
-    n706a_websocket_client_t *client = g_ws_clients[client_id];
-    if (!client) {
-        return N706A_WS_ERROR_INVALID_PARAM;
-    }
-    
-    if (client->state == N706A_WS_STATE_OPEN) {
-        /* 发送关闭帧 */
-        uint8_t close_data[128];
-        size_t close_len = 2;
-        
-        close_data[0] = (close_code >> 8) & 0xFF;
-        close_data[1] = close_code & 0xFF;
-        
-        if (reason) {
-            size_t reason_len = strlen(reason);
-            if (reason_len > sizeof(close_data) - 2) {
-                reason_len = sizeof(close_data) - 2;
-            }
-            memcpy(close_data + 2, reason, reason_len);
-            close_len += reason_len;
-        }
-        
-        ws_send_frame(client, N706A_WS_OPCODE_CLOSE, close_data, close_len, true);
-        
-        client->state = N706A_WS_STATE_CLOSING;
-    }
-    
-    /* 停止接收线程 */
-    client->running = false;
-    // TODO: 等待线程结束
-    // pthread_join(client->recv_thread, NULL);
-    
-    /* 关闭TCP连接 */
-    n706a_tcp_close(&client->tcp_sock);
-    
-    client->state = N706A_WS_STATE_CLOSED;
-    
-    /* 调用on_close回调 */
-    if (client->on_close) {
-        client->on_close(client_id, close_code, reason);
-    }
-    
-    return N706A_WS_SUCCESS;
-}
-
-/**
- * @brief 获取WebSocket状态
- */
-n706a_ws_state_t n706a_websocket_get_state(int client_id)
-{
-    if (client_id < 0 || client_id >= N706A_WS_MAX_CLIENTS) {
-        return N706A_WS_STATE_CLOSED;
-    }
-    
-    n706a_websocket_client_t *client = g_ws_clients[client_id];
-    if (!client) {
-        return N706A_WS_STATE_CLOSED;
-    }
-    
-    return client->state;
-}
-
-/**
- * @brief 检查WebSocket是否已连接
- */
-bool n706a_websocket_is_connected(int client_id)
-{
-    return (n706a_websocket_get_state(client_id) == N706A_WS_STATE_OPEN);
-}
-
-/**
- * @brief 销毁WebSocket客户端
- */
-int n706a_websocket_destructor(int client_id)
-{
-    if (client_id < 0 || client_id >= N706A_WS_MAX_CLIENTS) {
-        return N706A_WS_ERROR_INVALID_PARAM;
-    }
-    
-    n706a_websocket_client_t *client = g_ws_clients[client_id];
-    if (!client) {
-        return N706A_WS_SUCCESS;
-    }
-    
-    /* 确保连接已关闭 */
-    if (client->state != N706A_WS_STATE_CLOSED) {
-        n706a_websocket_close(client_id);
-    }
-    
-    /* 释放资源 */
-    if (client->recv_buffer) {
-        free(client->recv_buffer);
-    }
-    
-    free(client);
-    g_ws_clients[client_id] = NULL;
-    
-    return N706A_WS_SUCCESS;
-}
-
-/* ========== 私有函数实现 ========== */
-
-/**
- * @brief 执行WebSocket握手
- */
-static int ws_perform_handshake(n706a_websocket_client_t *client)
-{
-    char handshake_req[1024];
-    char sec_key[25];
-    
-    /* 生成Sec-WebSocket-Key */
-    n706a_websocket_generate_key(sec_key);
-    strncpy(client->sec_key, sec_key, sizeof(client->sec_key) - 1);
-    
-    /* 构造握手请求 */
-    int len = snprintf(handshake_req, sizeof(handshake_req),
-        "GET %s HTTP/1.1\r\n"
-        "Host: %s\r\n"
-        "Upgrade: websocket\r\n"
-        "Connection: Upgrade\r\n"
-        "Sec-WebSocket-Key: %s\r\n"
-        "Sec-WebSocket-Version: 13\r\n"
-        "\r\n",
-        client->path,
-        client->host,
-        sec_key
-    );
-    
-    /* 发送握手请求 */
-    size_t sent;
-    n706a_tcp_result_t ret = n706a_tcp_send(&client->tcp_sock,
-                                            (uint8_t *)handshake_req,
-                                            len,
-                                            &sent);
-    
-    if (ret != N706A_TCP_SUCCESS) {
-        return -1;
-    }
-    
-    /* 接收握手响应 */
-    uint8_t response[2048];
-    size_t received;
-    
-    ret = n706a_tcp_recv(&client->tcp_sock,
-                        response,
-                        sizeof(response) - 1,
-                        &received,
-                        10000);
-    
-    if (ret != N706A_TCP_SUCCESS || received == 0) {
-        return -1;
-    }
-    
-    response[received] = '\0';
-    
-    /* 验证响应 */
-    if (!strstr((char *)response, "HTTP/1.1 101") ||
-        !strstr((char *)response, "Upgrade: websocket") ||
-        !strstr((char *)response, "Connection: Upgrade")) {
-        return -1;
-    }
-    
-    /* 验证Sec-WebSocket-Accept */
-    const char *accept_start = strstr((char *)response, "Sec-WebSocket-Accept:");
-    if (accept_start) {
-        accept_start += 21;  // 跳过"Sec-WebSocket-Accept:"
-        while (*accept_start == ' ') accept_start++;
-        
-        char expected_accept[29];
-        n706a_websocket_calculate_accept(sec_key, expected_accept);
-        
-        if (strncmp(accept_start, expected_accept, strlen(expected_accept)) != 0) {
-            return -1;  // Accept值不匹配
-        }
-    }
-    
-    return 0;
-}
-
-/**
- * @brief 发送WebSocket帧
- */
-static int ws_send_frame(n706a_websocket_client_t *client,
-                        n706a_ws_opcode_t opcode,
-                        const uint8_t *data,
-                        size_t length,
-                        bool fin)
-{
-    uint8_t frame[14];  // 最大帧头长度
-    size_t frame_len = 0;
-    
-    /* 第一字节:FIN + RSV + Opcode */
-    frame[frame_len++] = (fin ? WS_FIN_BIT : 0) | (opcode & WS_OPCODE_MASK);
-    
-    /* 第二字节:MASK + Payload length */
-    if (length < 126) {
-        frame[frame_len++] = WS_MASK_BIT | (length & WS_PAYLOAD_MASK);
-    } else if (length < 65536) {
-        frame[frame_len++] = WS_MASK_BIT | 126;
-        frame[frame_len++] = (length >> 8) & 0xFF;
-        frame[frame_len++] = length & 0xFF;
-    } else {
-        frame[frame_len++] = WS_MASK_BIT | 127;
-        for (int i = 7; i >= 0; i--) {
-            frame[frame_len++] = (length >> (i * 8)) & 0xFF;
-        }
-    }
-    
-    /* Masking key */
-    uint8_t mask_key[4];
-    ws_generate_mask_key(mask_key);
-    memcpy(frame + frame_len, mask_key, 4);
-    frame_len += 4;
-    
-    /* 发送帧头 */
-    size_t sent;
-    n706a_tcp_send(&client->tcp_sock, frame, frame_len, &sent);
-    
-    /* 发送payload(掩码后) */
-    if (data && length > 0) {
-        uint8_t *masked_data = (uint8_t *)malloc(length);
-        if (masked_data) {
-            memcpy(masked_data, data, length);
-            ws_mask_data(masked_data, length, mask_key);
-            
-            n706a_tcp_send(&client->tcp_sock, masked_data, length, &sent);
-            
-            free(masked_data);
-        }
-    }
-    
-    return N706A_WS_SUCCESS;
-}
-
-/**
- * @brief 接收WebSocket帧
- */
-static int ws_recv_frame(n706a_websocket_client_t *client)
-{
-    uint8_t header[2];
-    size_t received;
-    
-    /* 接收帧头前2字节 */
-    n706a_tcp_result_t ret = n706a_tcp_recv(&client->tcp_sock,
-                                            header,
-                                            2,
-                                            &received,
-                                            5000);
-    
-    if (ret != N706A_TCP_SUCCESS || received < 2) {
-        return -1;
-    }
-    
-    bool fin = (header[0] & WS_FIN_BIT) != 0;
-    n706a_ws_opcode_t opcode = (n706a_ws_opcode_t)(header[0] & WS_OPCODE_MASK);
-    bool masked = (header[1] & WS_MASK_BIT) != 0;
-    uint64_t payload_len = header[1] & WS_PAYLOAD_MASK;
-    
-    /* 扩展payload长度 */
-    if (payload_len == 126) {
-        uint8_t len_buf[2];
-        n706a_tcp_recv(&client->tcp_sock, len_buf, 2, &received, 5000);
-        payload_len = (len_buf[0] << 8) | len_buf[1];
-    } else if (payload_len == 127) {
-        uint8_t len_buf[8];
-        n706a_tcp_recv(&client->tcp_sock, len_buf, 8, &received, 5000);
-        payload_len = 0;
-        for (int i = 0; i < 8; i++) {
-            payload_len = (payload_len << 8) | len_buf[i];
-        }
-    }
-    
-    /* 接收payload */
-    if (payload_len > 0) {
-        uint8_t *payload = (uint8_t *)malloc(payload_len + 1);
-        if (!payload) {
-            return -1;
-        }
-        
-        n706a_tcp_recv(&client->tcp_sock, payload, payload_len, &received, 10000);
-        payload[payload_len] = '\0';
-        
-        /* 处理不同类型的帧 */
-        switch (opcode) {
-            case N706A_WS_OPCODE_TEXT:
-            case N706A_WS_OPCODE_BINARY:
-                if (client->on_message) {
-                    client->on_message(client->client_id,
-                                     (char *)payload,
-                                     payload_len,
-                                     fin,
-                                     opcode == N706A_WS_OPCODE_BINARY);
-                }
-                break;
-                
-            case N706A_WS_OPCODE_PING:
-                /* 自动回复Pong */
-                ws_send_frame(client, N706A_WS_OPCODE_PONG, payload, payload_len, true);
-                break;
-                
-            case N706A_WS_OPCODE_PONG:
-                /* 忽略Pong */
-                break;
-                
-            case N706A_WS_OPCODE_CLOSE:
-                /* 服务器关闭连接 */
-                client->state = N706A_WS_STATE_CLOSING;
-                
-                uint16_t close_code = N706A_WS_CLOSE_NO_STATUS;
-                if (payload_len >= 2) {
-                    close_code = (payload[0] << 8) | payload[1];
-                }
-                
-                if (client->on_close) {
-                    client->on_close(client->client_id, close_code,
-                                   payload_len > 2 ? (char *)(payload + 2) : NULL);
-                }
-                break;
-                
-            default:
-                break;
-        }
-        
-        free(payload);
-    }
-    
-    return 0;
-}
-
-/**
- * @brief 生成mask key
- */
-static void ws_generate_mask_key(uint8_t *mask_key)
-{
-    for (int i = 0; i < 4; i++) {
-        mask_key[i] = rand() & 0xFF;
-    }
-}
-
-/**
- * @brief 掩码数据
- */
-static void ws_mask_data(uint8_t *data, size_t len, const uint8_t *mask_key)
-{
-    for (size_t i = 0; i < len; i++) {
-        data[i] ^= mask_key[i % 4];
-    }
-}
-
-/**
- * @brief 解析WebSocket URL
- */
-static int ws_parse_url(const char *url, char *protocol, char *host,
-                       uint16_t *port, char *path)
-{
-    if (!url || !protocol || !host || !port || !path) {
-        return -1;
-    }
-    
-    const char *p = url;
-    
-    /* 解析协议 */
-    if (strncmp(p, "wss://", 6) == 0) {
-        strcpy(protocol, "wss");
-        *port = 443;
-        p += 6;
-    } else if (strncmp(p, "ws://", 5) == 0) {
-        strcpy(protocol, "ws");
-        *port = 80;
-        p += 5;
-    } else {
-        return -1;
-    }
-    
-    /* 解析host */
-    const char *path_start = strchr(p, '/');
-    const char *port_start = strchr(p, ':');
-    
-    if (port_start && (!path_start || port_start < path_start)) {
-        size_t host_len = port_start - p;
-        strncpy(host, p, host_len);
-        host[host_len] = '\0';
-        
-        *port = atoi(port_start + 1);
-        
-        if (path_start) {
-            strcpy(path, path_start);
-        } else {
-            strcpy(path, "/");
-        }
-    } else {
-        if (path_start) {
-            size_t host_len = path_start - p;
-            strncpy(host, p, host_len);
-            host[host_len] = '\0';
-            strcpy(path, path_start);
-        } else {
-            strcpy(host, p);
-            strcpy(path, "/");
-        }
-    }
-    
-    return 0;
-}
-
-/**
- * @brief 生成WebSocket Key
- */
-int n706a_websocket_generate_key(char *key)
-{
-    if (!key) {
-        return -1;
-    }
-    
-    /* 生成16字节随机数 */
-    unsigned char random_bytes[16];
-    srand(time(NULL));
-    for (int i = 0; i < 16; i++) {
-        random_bytes[i] = rand() & 0xFF;
-    }
-    
-    /* Base64编码 */
-    base64_encode(random_bytes, 16, key);
-    
-    return 0;
-}
-
-/**
- * @brief 计算WebSocket Accept
- */
-int n706a_websocket_calculate_accept(const char *key, char *accept)
-{
-    if (!key || !accept) {
-        return -1;
-    }
-    
-    /* 拼接key和GUID */
-    char concat[128];
-    snprintf(concat, sizeof(concat), "%s%s", key, WS_GUID);
-    
-    /* SHA-1哈希 */
-    unsigned char hash[20];
-    sha1_simple((unsigned char *)concat, strlen(concat), hash);
-    
-    /* Base64编码 */
-    base64_encode(hash, 20, accept);
-    
-    return 0;
-}
-
-/* ========== 辅助函数 ========== */
-
-/**
- * @brief 简化的SHA-1实现(仅用于WebSocket握手)
- * 注意:这是简化版,生产环境建议使用成熟的加密库
- */
-static void sha1_simple(const unsigned char *input, size_t len, unsigned char output[20])
-{
-    /* 这里应该是完整的SHA-1实现 */
-    /* 为了简化,这里仅做占位 */
-    /* 生产环境应使用mbedtls_sha1或OpenSSL的SHA1函数 */
-    
-    /* TODO: 集成真实的SHA-1实现 */
-    memset(output, 0, 20);
-    
-    /* 临时:使用简单哈希作为占位符 */
-    for (size_t i = 0; i < len && i < 20; i++) {
-        output[i % 20] ^= input[i];
-    }
-}
-
-/**
- * @brief Base64编码
- */
-static void base64_encode(const unsigned char *input, size_t len, char *output)
-{
-    static const char base64_table[] =
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-    
-    size_t i = 0, j = 0;
-    unsigned char char_array_3[3];
-    unsigned char char_array_4[4];
-    
-    while (len--) {
-        char_array_3[i++] = *(input++);
-        if (i == 3) {
-            char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
-            char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
-            char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
-            char_array_4[3] = char_array_3[2] & 0x3f;
-            
-            for (i = 0; i < 4; i++) {
-                output[j++] = base64_table[char_array_4[i]];
-            }
-            i = 0;
-        }
-    }
-    
-    if (i) {
-        for (size_t k = i; k < 3; k++) {
-            char_array_3[k] = '\0';
-        }
-        
-        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
-        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
-        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
-        
-        for (size_t k = 0; k < i + 1; k++) {
-            output[j++] = base64_table[char_array_4[k]];
-        }
-        
-        while (i++ < 3) {
-            output[j++] = '=';
-        }
-    }
-    
-    output[j] = '\0';
-}
-
index b5c0808..b567a58 100644 (file)
 #include "time.h"
 
 #include "uart.h"
+
+#ifdef SUPPORT_N706A_NET
+#include "n706a_net_example.h"
+#endif
+
 /* Define time structures to avoid musl dependency */
 typedef long suseconds_t;  /* microseconds (signed) */
 
@@ -699,6 +704,11 @@ void startup_post_init_task(void)
     if(baudrate != 0)
         set_ppp_baudrate(baudrate);
     ppp_env_init();
+#elif defined(SUPPORT_N706A_NET)
+    uint32_t baudrate = get_ppp_baudrate_from_config_model();   
+    if(baudrate != 0)
+        set_n706a_baudrate(baudrate);  // N706A使用自己的波特率设置函数
+    n706a_net_env_init();
 #endif
 
 #endif
diff --git a/code/sdk/zhihui/zhihui_net/adapter/zhihui_net_openharmony_adapter.c b/code/sdk/zhihui/zhihui_net/adapter/zhihui_net_openharmony_adapter.c
deleted file mode 100644 (file)
index 3096831..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-/**
- * @file zhihui_net_openharmony_adapter.c
- * @brief OpenHarmony网络实现适配器实现
- * 
- * 将统一接口转换为OpenHarmony的httpclient和net_websocket接口
- */
-
-#include "zhihui_net_openharmony_adapter.h"
-#include "httpclient.h"
-#include "net_websocket.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-/* ========== HTTP接口适配 ========== */
-
-/* 将ZhihuiHttpClient转换为OpenHarmony HttpClient */
-static void convert_to_openharmony_http_client(ZhihuiHttpClient *src, HttpClient *dst)
-{
-    memset(dst, 0, sizeof(HttpClient));
-    dst->socket = src->socket;
-    dst->remotePort = src->remotePort;
-    dst->responseCode = src->responseCode;
-    dst->header = src->header;
-    dst->authUser = src->authUser;
-    dst->authPassword = src->authPassword;
-    dst->isHttp = src->isHttp;
-}
-
-/* 将OpenHarmony HttpClient转换回ZhihuiHttpClient */
-static void convert_from_openharmony_http_client(HttpClient *src, ZhihuiHttpClient *dst)
-{
-    dst->socket = src->socket;
-    dst->remotePort = src->remotePort;
-    dst->responseCode = src->responseCode;
-    dst->header = src->header;
-    dst->authUser = src->authUser;
-    dst->authPassword = src->authPassword;
-    dst->isHttp = src->isHttp;
-}
-
-/* 将ZhihuiHttpClientData转换为OpenHarmony HttpClientData */
-static void convert_to_openharmony_http_data(ZhihuiHttpClientData *src, HttpClientData *dst)
-{
-    memset(dst, 0, sizeof(HttpClientData));
-    dst->isMore = src->isMore;
-    dst->isChunked = src->isChunked;
-    dst->method = src->method;
-    dst->retrieveLen = src->retrieveLen;
-    dst->responseContentLen = src->responseContentLen;
-    dst->contentBlockLen = src->contentBlockLen;
-    dst->postBufLen = src->postBufLen;
-    dst->responseBufLen = src->responseBufLen;
-    dst->headerBufLen = src->headerBufLen;
-    dst->postContentType = src->postContentType;
-    dst->postBuf = src->postBuf;
-    dst->responseBuf = src->responseBuf;
-    dst->headerBuf = src->headerBuf;
-    dst->isRedirected = src->isRedirected;
-    dst->redirectUrl = src->redirectUrl;
-}
-
-/* 将OpenHarmony HttpClientData转换回ZhihuiHttpClientData */
-static void convert_from_openharmony_http_data(HttpClientData *src, ZhihuiHttpClientData *dst)
-{
-    dst->isMore = src->isMore;
-    dst->isChunked = src->isChunked;
-    dst->method = src->method;
-    dst->retrieveLen = src->retrieveLen;
-    dst->responseContentLen = src->responseContentLen;
-    dst->contentBlockLen = src->contentBlockLen;
-    dst->postBufLen = src->postBufLen;
-    dst->responseBufLen = src->responseBufLen;
-    dst->headerBufLen = src->headerBufLen;
-    dst->postContentType = src->postContentType;
-    dst->postBuf = src->postBuf;
-    dst->responseBuf = src->responseBuf;
-    dst->headerBuf = src->headerBuf;
-    dst->isRedirected = src->isRedirected;
-    dst->redirectUrl = src->redirectUrl;
-}
-
-int ZhihuiNetOpenHarmonyHttpGet(ZhihuiHttpClient *client, const char *url,
-                                ZhihuiHttpClientData *data)
-{
-    HttpClient oh_client;
-    HttpClientData oh_data;
-    int ret;
-    
-    convert_to_openharmony_http_client(client, &oh_client);
-    convert_to_openharmony_http_data(data, &oh_data);
-    
-    ret = HttpClientGetRequest(&oh_client, url, &oh_data);
-    
-    convert_from_openharmony_http_client(&oh_client, client);
-    convert_from_openharmony_http_data(&oh_data, data);
-    
-    return ret;
-}
-
-int ZhihuiNetOpenHarmonyHttpPost(ZhihuiHttpClient *client, const char *url,
-                                 ZhihuiHttpClientData *data)
-{
-    HttpClient oh_client;
-    HttpClientData oh_data;
-    int ret;
-    
-    convert_to_openharmony_http_client(client, &oh_client);
-    convert_to_openharmony_http_data(data, &oh_data);
-    
-    ret = HttpClientPostRequest(&oh_client, url, &oh_data);
-    
-    convert_from_openharmony_http_client(&oh_client, client);
-    convert_from_openharmony_http_data(&oh_data, data);
-    
-    return ret;
-}
-
-int ZhihuiNetOpenHarmonyHttpHead(ZhihuiHttpClient *client, const char *url,
-                                 ZhihuiHttpClientData *data)
-{
-    HttpClient oh_client;
-    HttpClientData oh_data;
-    int ret;
-    
-    convert_to_openharmony_http_client(client, &oh_client);
-    convert_to_openharmony_http_data(data, &oh_data);
-    
-    ret = HttpClientHeadRequest(&oh_client, url, &oh_data);
-    
-    convert_from_openharmony_http_client(&oh_client, client);
-    convert_from_openharmony_http_data(&oh_data, data);
-    
-    return ret;
-}
-
-int ZhihuiNetOpenHarmonyHttpPut(ZhihuiHttpClient *client, const char *url,
-                                ZhihuiHttpClientData *data)
-{
-    HttpClient oh_client;
-    HttpClientData oh_data;
-    int ret;
-    
-    convert_to_openharmony_http_client(client, &oh_client);
-    convert_to_openharmony_http_data(data, &oh_data);
-    
-    ret = HttpClientPutRequest(&oh_client, url, &oh_data);
-    
-    convert_from_openharmony_http_client(&oh_client, client);
-    convert_from_openharmony_http_data(&oh_data, data);
-    
-    return ret;
-}
-
-int ZhihuiNetOpenHarmonyHttpDelete(ZhihuiHttpClient *client, const char *url,
-                                   ZhihuiHttpClientData *data)
-{
-    HttpClient oh_client;
-    HttpClientData oh_data;
-    int ret;
-    
-    convert_to_openharmony_http_client(client, &oh_client);
-    convert_to_openharmony_http_data(data, &oh_data);
-    
-    ret = HttpClientDeleteRequest(&oh_client, url, &oh_data);
-    
-    convert_from_openharmony_http_client(&oh_client, client);
-    convert_from_openharmony_http_data(&oh_data, data);
-    
-    return ret;
-}
-
-/* ========== WebSocket接口适配 ========== */
-
-/* 回调函数适配器 */
-typedef struct {
-    ZhihuiWebSocketOnOpenCallback zhihui_on_open;
-    ZhihuiWebSocketOnMessageCallback zhihui_on_message;
-    ZhihuiWebSocketOnErrorCallback zhihui_on_error;
-    ZhihuiWebSocketOnCloseCallback zhihui_on_close;
-} ws_callback_adapter_t;
-
-#define MAX_WS_CLIENTS 8
-static ws_callback_adapter_t g_ws_adapters[MAX_WS_CLIENTS];
-
-/* OpenHarmony回调转发到Zhihui回调 */
-static void oh_ws_on_open(int client)
-{
-    if (client >= 0 && client < MAX_WS_CLIENTS) {
-        if (g_ws_adapters[client].zhihui_on_open) {
-            g_ws_adapters[client].zhihui_on_open(client);
-        }
-    }
-}
-
-static void oh_ws_on_message(int client, const char *data, size_t length, bool isFinished)
-{
-    if (client >= 0 && client < MAX_WS_CLIENTS) {
-        if (g_ws_adapters[client].zhihui_on_message) {
-            /* OpenHarmony不区分文本/二进制,默认作为文本 */
-            g_ws_adapters[client].zhihui_on_message(client, data, length, isFinished, false);
-        }
-    }
-}
-
-static void oh_ws_on_error(int client, int errorCode, const char *errorMsg)
-{
-    if (client >= 0 && client < MAX_WS_CLIENTS) {
-        if (g_ws_adapters[client].zhihui_on_error) {
-            g_ws_adapters[client].zhihui_on_error(client, errorCode, errorMsg);
-        }
-    }
-}
-
-static void oh_ws_on_close(int client, int closeCode, const char *reason)
-{
-    if (client >= 0 && client < MAX_WS_CLIENTS) {
-        if (g_ws_adapters[client].zhihui_on_close) {
-            g_ws_adapters[client].zhihui_on_close(client, closeCode, reason);
-        }
-    }
-}
-
-int ZhihuiNetOpenHarmonyWsConstructor(ZhihuiWebSocketOnOpenCallback onOpen,
-                                      ZhihuiWebSocketOnMessageCallback onMessage,
-                                      ZhihuiWebSocketOnErrorCallback onError,
-                                      ZhihuiWebSocketOnCloseCallback onClose)
-{
-    int client = WebSocketClientConstructor(oh_ws_on_open, oh_ws_on_message,
-                                            oh_ws_on_error, oh_ws_on_close);
-    
-    if (client >= 0 && client < MAX_WS_CLIENTS) {
-        g_ws_adapters[client].zhihui_on_open = onOpen;
-        g_ws_adapters[client].zhihui_on_message = onMessage;
-        g_ws_adapters[client].zhihui_on_error = onError;
-        g_ws_adapters[client].zhihui_on_close = onClose;
-    }
-    
-    return client;
-}
-
-int ZhihuiNetOpenHarmonyWsConnect(int client, const char *url, const char *option)
-{
-    return WebSocketClientConnect(client, url, option);
-}
-
-int ZhihuiNetOpenHarmonyWsSendText(int client, const char *text, size_t length)
-{
-    return WebSocketClientSendText(client, text, length);
-}
-
-int ZhihuiNetOpenHarmonyWsSendBinStart(int client, const char *data, size_t length)
-{
-    return WebSocketClientSendBinStart(client, data, length);
-}
-
-int ZhihuiNetOpenHarmonyWsSendBinContinue(int client, const char *data, size_t length)
-{
-    return WebSocketClientSendBinContinue(client, data, length);
-}
-
-int ZhihuiNetOpenHarmonyWsSendBinEnd(int client, const char *data, size_t length)
-{
-    return WebSocketClientSendBinEnd(client, data, length);
-}
-
-int ZhihuiNetOpenHarmonyWsClose(int client)
-{
-    return WebSocketClientClose(client);
-}
-
-int ZhihuiNetOpenHarmonyWsDestructor(int client)
-{
-    int ret = WebSocketClientDestructor(client);
-    
-    /* 清除适配器 */
-    if (client >= 0 && client < MAX_WS_CLIENTS) {
-        memset(&g_ws_adapters[client], 0, sizeof(ws_callback_adapter_t));
-    }
-    
-    return ret;
-}
-
-/* ========== 初始化/清理 ========== */
-
-int ZhihuiNetOpenHarmonyInit(void)
-{
-    printf("[ZhihuiNet][OpenHarmony] Adapter initialized\n");
-    memset(g_ws_adapters, 0, sizeof(g_ws_adapters));
-    return 0;
-}
-
-int ZhihuiNetOpenHarmonyDeinit(void)
-{
-    printf("[ZhihuiNet][OpenHarmony] Adapter deinitialized\n");
-    return 0;
-}
-
diff --git a/code/sdk/zhihui/zhihui_net/adapter/zhihui_net_openharmony_adapter.h b/code/sdk/zhihui/zhihui_net/adapter/zhihui_net_openharmony_adapter.h
deleted file mode 100644 (file)
index 29b467c..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * @file zhihui_net_openharmony_adapter.h
- * @brief OpenHarmony网络实现适配器
- */
-
-#ifndef ZHIHUI_NET_OPENHARMONY_ADAPTER_H
-#define ZHIHUI_NET_OPENHARMONY_ADAPTER_H
-
-#include "zhihui_net.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* HTTP接口 */
-int ZhihuiNetOpenHarmonyHttpGet(ZhihuiHttpClient *client, const char *url, 
-                                ZhihuiHttpClientData *data);
-int ZhihuiNetOpenHarmonyHttpPost(ZhihuiHttpClient *client, const char *url,
-                                 ZhihuiHttpClientData *data);
-int ZhihuiNetOpenHarmonyHttpHead(ZhihuiHttpClient *client, const char *url,
-                                 ZhihuiHttpClientData *data);
-int ZhihuiNetOpenHarmonyHttpPut(ZhihuiHttpClient *client, const char *url,
-                                ZhihuiHttpClientData *data);
-int ZhihuiNetOpenHarmonyHttpDelete(ZhihuiHttpClient *client, const char *url,
-                                   ZhihuiHttpClientData *data);
-
-/* WebSocket接口 */
-int ZhihuiNetOpenHarmonyWsConstructor(ZhihuiWebSocketOnOpenCallback onOpen,
-                                      ZhihuiWebSocketOnMessageCallback onMessage,
-                                      ZhihuiWebSocketOnErrorCallback onError,
-                                      ZhihuiWebSocketOnCloseCallback onClose);
-int ZhihuiNetOpenHarmonyWsConnect(int client, const char *url, const char *option);
-int ZhihuiNetOpenHarmonyWsSendText(int client, const char *text, size_t length);
-int ZhihuiNetOpenHarmonyWsSendBinStart(int client, const char *data, size_t length);
-int ZhihuiNetOpenHarmonyWsSendBinContinue(int client, const char *data, size_t length);
-int ZhihuiNetOpenHarmonyWsSendBinEnd(int client, const char *data, size_t length);
-int ZhihuiNetOpenHarmonyWsClose(int client);
-int ZhihuiNetOpenHarmonyWsDestructor(int client);
-
-/* 初始化/清理 */
-int ZhihuiNetOpenHarmonyInit(void);
-int ZhihuiNetOpenHarmonyDeinit(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ZHIHUI_NET_OPENHARMONY_ADAPTER_H */
-
diff --git a/code/sdk/zhihui/zhihui_net/adapter/zhihui_net_ppp_adapter.c b/code/sdk/zhihui/zhihui_net/adapter/zhihui_net_ppp_adapter.c
deleted file mode 100644 (file)
index bbdc372..0000000
+++ /dev/null
@@ -1,445 +0,0 @@
-/**
- * @file zhihui_net_ppp_adapter.c
- * @brief N706A PPP网络实现适配器实现
- * 
- * 将统一接口转换为N706A PPP的接口
- */
-
-#include "zhihui_net_ppp_adapter.h"
-#include "n706a_http_client.h"
-#include "n706a_websocket.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-/* ========== HTTP接口适配 ========== */
-
-int ZhihuiNetPppHttpGet(ZhihuiHttpClient *client, const char *url,
-                        ZhihuiHttpClientData *data)
-{
-    n706a_http_client_t *ppp_client = (n706a_http_client_t *)client->impl_data;
-    
-    /* 如果还未初始化PPP客户端,则初始化 */
-    if (ppp_client == NULL) {
-        ppp_client = (n706a_http_client_t *)malloc(sizeof(n706a_http_client_t));
-        if (ppp_client == NULL) {
-            return -1;
-        }
-        
-        n706a_httpc_result_t ret = n706a_http_client_init(ppp_client, 0);
-        if (ret != N706A_HTTP_SUCCESS) {
-            free(ppp_client);
-            return -1;
-        }
-        
-        client->impl_data = ppp_client;
-    }
-    
-    /* 解析URL获取host和path */
-    char host[256] = {0};
-    char path[256] = {0};
-    uint16_t port = 80;
-    bool use_ssl = false;
-    
-    if (strncmp(url, "https://", 8) == 0) {
-        use_ssl = true;
-        port = 443;
-        sscanf(url + 8, "%255[^/]%255s", host, path);
-    } else if (strncmp(url, "http://", 7) == 0) {
-        sscanf(url + 7, "%255[^/]%255s", host, path);
-    } else {
-        return -1;
-    }
-    
-    if (strlen(path) == 0) {
-        strcpy(path, "/");
-    }
-    
-    /* 连接 */
-    n706a_httpc_result_t ret = n706a_http_client_connect(ppp_client, host, port, use_ssl);
-    if (ret != N706A_HTTP_SUCCESS) {
-        return -1;
-    }
-    
-    /* 准备数据结构 */
-    n706a_http_client_data_t ppp_data = {0};
-    ppp_data.responseBuf = data->responseBuf;
-    ppp_data.responseBufLen = data->responseBufLen;
-    ppp_data.headerBuf = data->headerBuf;
-    ppp_data.headerBufLen = data->headerBufLen;
-    
-    /* 执行GET请求 */
-    ret = n706a_http_client_get(ppp_client, path, &ppp_data);
-    
-    /* 设置响应码 */
-    client->responseCode = ppp_client->response_code;
-    data->responseContentLen = ppp_data.responseContentLen;
-    
-    return (ret == N706A_HTTP_SUCCESS) ? 0 : -1;
-}
-
-int ZhihuiNetPppHttpPost(ZhihuiHttpClient *client, const char *url,
-                         ZhihuiHttpClientData *data)
-{
-    n706a_http_client_t *ppp_client = (n706a_http_client_t *)client->impl_data;
-    
-    if (ppp_client == NULL) {
-        ppp_client = (n706a_http_client_t *)malloc(sizeof(n706a_http_client_t));
-        if (ppp_client == NULL) {
-            return -1;
-        }
-        
-        n706a_httpc_result_t ret = n706a_http_client_init(ppp_client, 0);
-        if (ret != N706A_HTTP_SUCCESS) {
-            free(ppp_client);
-            return -1;
-        }
-        
-        client->impl_data = ppp_client;
-    }
-    
-    /* 解析URL */
-    char host[256] = {0};
-    char path[256] = {0};
-    uint16_t port = 80;
-    bool use_ssl = false;
-    
-    if (strncmp(url, "https://", 8) == 0) {
-        use_ssl = true;
-        port = 443;
-        sscanf(url + 8, "%255[^/]%255s", host, path);
-    } else if (strncmp(url, "http://", 7) == 0) {
-        sscanf(url + 7, "%255[^/]%255s", host, path);
-    } else {
-        return -1;
-    }
-    
-    if (strlen(path) == 0) {
-        strcpy(path, "/");
-    }
-    
-    /* 连接 */
-    n706a_httpc_result_t ret = n706a_http_client_connect(ppp_client, host, port, use_ssl);
-    if (ret != N706A_HTTP_SUCCESS) {
-        return -1;
-    }
-    
-    /* 准备数据结构 */
-    n706a_http_client_data_t ppp_data = {0};
-    ppp_data.responseBuf = data->responseBuf;
-    ppp_data.responseBufLen = data->responseBufLen;
-    ppp_data.headerBuf = data->headerBuf;
-    ppp_data.headerBufLen = data->headerBufLen;
-    
-    /* 执行POST请求 */
-    const char *content_type = data->postContentType ? data->postContentType : "application/json";
-    ret = n706a_http_client_post(ppp_client, path, content_type, 
-                                      data->postBuf, data->postBufLen, &ppp_data);
-    
-    client->responseCode = ppp_client->response_code;
-    data->responseContentLen = ppp_data.responseContentLen;
-    
-    return (ret == N706A_HTTP_SUCCESS) ? 0 : -1;
-}
-
-int ZhihuiNetPppHttpHead(ZhihuiHttpClient *client, const char *url,
-                         ZhihuiHttpClientData *data)
-{
-    /* N706A暂不直接支持HEAD,使用GET实现 */
-    return ZhihuiNetPppHttpGet(client, url, data);
-}
-
-int ZhihuiNetPppHttpPut(ZhihuiHttpClient *client, const char *url,
-                        ZhihuiHttpClientData *data)
-{
-    n706a_http_client_t *ppp_client = (n706a_http_client_t *)client->impl_data;
-    
-    if (ppp_client == NULL) {
-        ppp_client = (n706a_http_client_t *)malloc(sizeof(n706a_http_client_t));
-        if (ppp_client == NULL) {
-            return -1;
-        }
-        
-        n706a_httpc_result_t ret = n706a_http_client_init(ppp_client, 0);
-        if (ret != N706A_HTTP_SUCCESS) {
-            free(ppp_client);
-            return -1;
-        }
-        
-        client->impl_data = ppp_client;
-    }
-    
-    /* 解析URL */
-    char host[256] = {0};
-    char path[256] = {0};
-    uint16_t port = 80;
-    bool use_ssl = false;
-    
-    if (strncmp(url, "https://", 8) == 0) {
-        use_ssl = true;
-        port = 443;
-        sscanf(url + 8, "%255[^/]%255s", host, path);
-    } else if (strncmp(url, "http://", 7) == 0) {
-        sscanf(url + 7, "%255[^/]%255s", host, path);
-    } else {
-        return -1;
-    }
-    
-    if (strlen(path) == 0) {
-        strcpy(path, "/");
-    }
-    
-    /* 连接 */
-    n706a_httpc_result_t ret = n706a_http_client_connect(ppp_client, host, port, use_ssl);
-    if (ret != N706A_HTTP_SUCCESS) {
-        return -1;
-    }
-    
-    /* 准备数据结构 */
-    n706a_http_client_data_t ppp_data = {0};
-    ppp_data.responseBuf = data->responseBuf;
-    ppp_data.responseBufLen = data->responseBufLen;
-    ppp_data.headerBuf = data->headerBuf;
-    ppp_data.headerBufLen = data->headerBufLen;
-    
-    /* 执行PUT请求 */
-    const char *content_type = data->postContentType ? data->postContentType : "application/json";
-    ret = n706a_http_client_put(ppp_client, path, content_type,
-                                     data->postBuf, data->postBufLen, &ppp_data);
-    
-    client->responseCode = ppp_client->response_code;
-    data->responseContentLen = ppp_data.responseContentLen;
-    
-    return (ret == N706A_HTTP_SUCCESS) ? 0 : -1;
-}
-
-int ZhihuiNetPppHttpDelete(ZhihuiHttpClient *client, const char *url,
-                           ZhihuiHttpClientData *data)
-{
-    n706a_http_client_t *ppp_client = (n706a_http_client_t *)client->impl_data;
-    
-    if (ppp_client == NULL) {
-        ppp_client = (n706a_http_client_t *)malloc(sizeof(n706a_http_client_t));
-        if (ppp_client == NULL) {
-            return -1;
-        }
-        
-        n706a_httpc_result_t ret = n706a_http_client_init(ppp_client, 0);
-        if (ret != N706A_HTTP_SUCCESS) {
-            free(ppp_client);
-            return -1;
-        }
-        
-        client->impl_data = ppp_client;
-    }
-    
-    /* 解析URL */
-    char host[256] = {0};
-    char path[256] = {0};
-    uint16_t port = 80;
-    bool use_ssl = false;
-    
-    if (strncmp(url, "https://", 8) == 0) {
-        use_ssl = true;
-        port = 443;
-        sscanf(url + 8, "%255[^/]%255s", host, path);
-    } else if (strncmp(url, "http://", 7) == 0) {
-        sscanf(url + 7, "%255[^/]%255s", host, path);
-    } else {
-        return -1;
-    }
-    
-    if (strlen(path) == 0) {
-        strcpy(path, "/");
-    }
-    
-    /* 连接 */
-    n706a_httpc_result_t ret = n706a_http_client_connect(ppp_client, host, port, use_ssl);
-    if (ret != N706A_HTTP_SUCCESS) {
-        return -1;
-    }
-    
-    /* 准备数据结构 */
-    n706a_http_client_data_t ppp_data = {0};
-    ppp_data.responseBuf = data->responseBuf;
-    ppp_data.responseBufLen = data->responseBufLen;
-    ppp_data.headerBuf = data->headerBuf;
-    ppp_data.headerBufLen = data->headerBufLen;
-    
-    /* 执行DELETE请求 */
-    ret = n706a_http_client_delete(ppp_client, path, &ppp_data);
-    
-    client->responseCode = ppp_client->response_code;
-    data->responseContentLen = ppp_data.responseContentLen;
-    
-    return (ret == N706A_HTTP_SUCCESS) ? 0 : -1;
-}
-
-/* ========== WebSocket接口适配 ========== */
-
-#define MAX_WS_CLIENTS 6  /* N706A支持最多6个并发连接 */
-
-typedef struct {
-    int client_id;
-    bool in_use;
-    ZhihuiWebSocketOnOpenCallback zhihui_on_open;
-    ZhihuiWebSocketOnMessageCallback zhihui_on_message;
-    ZhihuiWebSocketOnErrorCallback zhihui_on_error;
-    ZhihuiWebSocketOnCloseCallback zhihui_on_close;
-} ppp_ws_adapter_t;
-
-static ppp_ws_adapter_t g_ppp_ws_adapters[MAX_WS_CLIENTS];
-
-/* PPP回调转发到Zhihui回调 */
-static void ppp_ws_on_open(int client_id)
-{
-    if (client_id >= 0 && client_id < MAX_WS_CLIENTS) {
-        if (g_ppp_ws_adapters[client_id].in_use && 
-            g_ppp_ws_adapters[client_id].zhihui_on_open) {
-            g_ppp_ws_adapters[client_id].zhihui_on_open(client_id);
-        }
-    }
-}
-
-static void ppp_ws_on_message(int client_id, const char *data, size_t length,
-                               bool isFinished, bool isBinary)
-{
-    if (client_id >= 0 && client_id < MAX_WS_CLIENTS) {
-        if (g_ppp_ws_adapters[client_id].in_use && 
-            g_ppp_ws_adapters[client_id].zhihui_on_message) {
-            g_ppp_ws_adapters[client_id].zhihui_on_message(client_id, data,
-                                                            length, isFinished, isBinary);
-        }
-    }
-}
-
-static void ppp_ws_on_error(int client_id, int errorCode, const char *errorMsg)
-{
-    if (client_id >= 0 && client_id < MAX_WS_CLIENTS) {
-        if (g_ppp_ws_adapters[client_id].in_use && 
-            g_ppp_ws_adapters[client_id].zhihui_on_error) {
-            g_ppp_ws_adapters[client_id].zhihui_on_error(client_id, errorCode, errorMsg);
-        }
-    }
-}
-
-static void ppp_ws_on_close(int client_id, int closeCode, const char *reason)
-{
-    if (client_id >= 0 && client_id < MAX_WS_CLIENTS) {
-        if (g_ppp_ws_adapters[client_id].in_use && 
-            g_ppp_ws_adapters[client_id].zhihui_on_close) {
-            g_ppp_ws_adapters[client_id].zhihui_on_close(client_id, closeCode, reason);
-        }
-    }
-}
-
-int ZhihuiNetPppWsConstructor(ZhihuiWebSocketOnOpenCallback onOpen,
-                              ZhihuiWebSocketOnMessageCallback onMessage,
-                              ZhihuiWebSocketOnErrorCallback onError,
-                              ZhihuiWebSocketOnCloseCallback onClose)
-{
-    int client_id = n706a_websocket_constructor(
-        ppp_ws_on_open,
-        ppp_ws_on_message,
-        ppp_ws_on_error,
-        ppp_ws_on_close
-    );
-    
-    if (client_id >= 0 && client_id < MAX_WS_CLIENTS) {
-        g_ppp_ws_adapters[client_id].client_id = client_id;
-        g_ppp_ws_adapters[client_id].in_use = true;
-        g_ppp_ws_adapters[client_id].zhihui_on_open = onOpen;
-        g_ppp_ws_adapters[client_id].zhihui_on_message = onMessage;
-        g_ppp_ws_adapters[client_id].zhihui_on_error = onError;
-        g_ppp_ws_adapters[client_id].zhihui_on_close = onClose;
-    }
-    
-    return client_id;
-}
-
-int ZhihuiNetPppWsConnect(int client, const char *url, const char *option)
-{
-    if (client < 0 || client >= MAX_WS_CLIENTS || !g_ppp_ws_adapters[client].in_use) {
-        return -1;
-    }
-    
-    return n706a_websocket_connect(client, url, option);
-}
-
-int ZhihuiNetPppWsSendText(int client, const char *text, size_t length)
-{
-    if (client < 0 || client >= MAX_WS_CLIENTS || !g_ppp_ws_adapters[client].in_use) {
-        return -1;
-    }
-    
-    return n706a_websocket_send_text(client, text, length);
-}
-
-int ZhihuiNetPppWsSendBinStart(int client, const char *data, size_t length)
-{
-    if (client < 0 || client >= MAX_WS_CLIENTS || !g_ppp_ws_adapters[client].in_use) {
-        return -1;
-    }
-    
-    return n706a_websocket_send_binary(client, (const uint8_t *)data, length);
-}
-
-int ZhihuiNetPppWsSendBinContinue(int client, const char *data, size_t length)
-{
-    /* N706A一次发送完整帧,不支持分段 */
-    return 0;
-}
-
-int ZhihuiNetPppWsSendBinEnd(int client, const char *data, size_t length)
-{
-    /* N706A一次发送完整帧,不支持分段 */
-    return 0;
-}
-
-int ZhihuiNetPppWsClose(int client)
-{
-    if (client < 0 || client >= MAX_WS_CLIENTS || !g_ppp_ws_adapters[client].in_use) {
-        return -1;
-    }
-    
-    return n706a_websocket_close(client);
-}
-
-int ZhihuiNetPppWsDestructor(int client)
-{
-    if (client < 0 || client >= MAX_WS_CLIENTS || !g_ppp_ws_adapters[client].in_use) {
-        return -1;
-    }
-    
-    int ret = n706a_websocket_destructor(client);
-    
-    if (ret == 0) {
-        memset(&g_ppp_ws_adapters[client], 0, sizeof(ppp_ws_adapter_t));
-        g_ppp_ws_adapters[client].in_use = false;
-    }
-    
-    return ret;
-}
-
-/* ========== 初始化/清理 ========== */
-
-int ZhihuiNetPppInit(void)
-{
-    printf("[ZhihuiNet][PPP] Adapter initialized\n");
-    memset(g_ppp_ws_adapters, 0, sizeof(g_ppp_ws_adapters));
-    return 0;
-}
-
-int ZhihuiNetPppDeinit(void)
-{
-    printf("[ZhihuiNet][PPP] Adapter deinitialized\n");
-    
-    /* 清理所有WebSocket客户端 */
-    for (int i = 0; i < MAX_WS_CLIENTS; i++) {
-        if (g_ppp_ws_adapters[i].in_use) {
-            ZhihuiNetPppWsDestructor(i);
-        }
-    }
-    
-    return 0;
-}
diff --git a/code/sdk/zhihui/zhihui_net/adapter/zhihui_net_ppp_adapter.h b/code/sdk/zhihui/zhihui_net/adapter/zhihui_net_ppp_adapter.h
deleted file mode 100644 (file)
index 08bf64f..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * @file zhihui_net_ppp_adapter.h
- * @brief N706A PPP网络实现适配器
- */
-
-#ifndef ZHIHUI_NET_PPP_ADAPTER_H
-#define ZHIHUI_NET_PPP_ADAPTER_H
-
-#include "zhihui_net.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* HTTP接口 */
-int ZhihuiNetPppHttpGet(ZhihuiHttpClient *client, const char *url,
-                        ZhihuiHttpClientData *data);
-int ZhihuiNetPppHttpPost(ZhihuiHttpClient *client, const char *url,
-                         ZhihuiHttpClientData *data);
-int ZhihuiNetPppHttpHead(ZhihuiHttpClient *client, const char *url,
-                         ZhihuiHttpClientData *data);
-int ZhihuiNetPppHttpPut(ZhihuiHttpClient *client, const char *url,
-                        ZhihuiHttpClientData *data);
-int ZhihuiNetPppHttpDelete(ZhihuiHttpClient *client, const char *url,
-                           ZhihuiHttpClientData *data);
-
-/* WebSocket接口 */
-int ZhihuiNetPppWsConstructor(ZhihuiWebSocketOnOpenCallback onOpen,
-                              ZhihuiWebSocketOnMessageCallback onMessage,
-                              ZhihuiWebSocketOnErrorCallback onError,
-                              ZhihuiWebSocketOnCloseCallback onClose);
-int ZhihuiNetPppWsConnect(int client, const char *url, const char *option);
-int ZhihuiNetPppWsSendText(int client, const char *text, size_t length);
-int ZhihuiNetPppWsSendBinStart(int client, const char *data, size_t length);
-int ZhihuiNetPppWsSendBinContinue(int client, const char *data, size_t length);
-int ZhihuiNetPppWsSendBinEnd(int client, const char *data, size_t length);
-int ZhihuiNetPppWsClose(int client);
-int ZhihuiNetPppWsDestructor(int client);
-
-/* 初始化/清理 */
-int ZhihuiNetPppInit(void);
-int ZhihuiNetPppDeinit(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ZHIHUI_NET_PPP_ADAPTER_H */
-
index c31f871..eced455 100644 (file)
@@ -1,14 +1,22 @@
 /**
  * @file zhihui_net.h
  * @brief 智慧网络统一接口层 - 总入口
- * 
+ *
  * 设计原则:
  * 1. 拆分 HTTP 和 WebSocket 接口到独立的头文件
  * 2. HTTP 接口:基于 OpenHarmony 的 httpclient.h
  * 3. WebSocket 接口:基于 haisi_websocket.h
- * 4. 支持运行时动态切换实现(OpenHarmony/haisi_websocket vs PPP)
- * 
- * @version 4.0.0
+ * 4. 支持运行时动态切换实现(OpenHarmony/haisi_websocket vs N706A AT)
+ *
+ * 模式自动检测:
+ * - 定义 SUPPORT_N706A_NET → 使用 N706A AT 模式(不拨号,纯AT指令)
+ * - 未定义 SUPPORT_N706A_NET → 使用 OpenHarmony 模式(PPP拨号 + lwIP)
+ *
+ * SSL实现(仅影响N706A内部):
+ * - N706A_SSL_USE_MBEDTLS → n706a_net 内部使用 mbedtls 实现SSL
+ * - N706A_SSL_USE_AT_COMMAND → n706a_net 内部使用 AT 指令实现SSL
+ *
+ * @version 5.1.0
  * @date 2025-10-31
  */
 
@@ -30,13 +38,27 @@ extern "C" {
 /* ========== 网络实现类型 ========== */
 
 typedef enum {
-    ZHIHUI_NET_IMPL_OPENHARMONY = 0,  /**< OpenHarmony实现(PPP拨号 + lwIP + haisi_websocket)默认 */
+    ZHIHUI_NET_IMPL_OPENHARMONY = 0,  /**< OpenHarmony实现(PPP拨号 + lwIP + haisi_websocket)*/
     ZHIHUI_NET_IMPL_N706A_AT = 1      /**< N706A AT指令实现(不拨号,纯AT指令)*/
 } zhihui_net_impl_type_t;
 
 /* 为了兼容性保留旧名称 */
 #define ZHIHUI_NET_IMPL_N706A_PPP ZHIHUI_NET_IMPL_OPENHARMONY
 
+/* ========== 自动模式检测(基于 SUPPORT_N706A_NET 宏)========== */
+/**
+ * 根据 SUPPORT_N706A_NET 宏自动选择网络模式:
+ * - 定义了 SUPPORT_N706A_NET → N706A AT 模式(不拨号PPP)
+ * - 未定义 SUPPORT_N706A_NET → OpenHarmony 模式(PPP拨号 + lwIP)
+ */
+#ifdef SUPPORT_N706A_NET
+    #define ZHIHUI_NET_DEFAULT_MODE ZHIHUI_NET_IMPL_N706A_AT
+    #define ZHIHUI_NET_MODE_DESC "N706A AT Command (no PPP dial)"
+#else
+    #define ZHIHUI_NET_DEFAULT_MODE ZHIHUI_NET_IMPL_OPENHARMONY
+    #define ZHIHUI_NET_MODE_DESC "OpenHarmony (PPP + lwIP)"
+#endif
+
 /* ========== 配置接口 ========== */
 
 /**
index 4d973a9..b20db55 100644 (file)
@@ -3,6 +3,9 @@
  * @brief 智慧网络统一接口层 - 配置实现
  * 
  * 负责管理网络实现类型的配置和切换
+ * 根据 SUPPORT_N706A_NET 宏自动选择默认模式:
+ * - 定义了 SUPPORT_N706A_NET → N706A AT 模式(不拨号PPP)
+ * - 未定义 SUPPORT_N706A_NET → OpenHarmony 模式(PPP拨号 + lwIP)
  */
 
 #include "zhihui_net.h"
@@ -10,8 +13,8 @@
 #include <string.h>
 #include <stdlib.h>
 
-/* 当前使用的实现类型 */
-static zhihui_net_impl_type_t g_current_impl = ZHIHUI_NET_IMPL_OPENHARMONY;
+/* 当前使用的实现类型(自动根据 SUPPORT_N706A_NET 宏设置默认值) */
+static zhihui_net_impl_type_t g_current_impl = ZHIHUI_NET_DEFAULT_MODE;
 
 /* ========== 配置接口实现 ========== */
 
@@ -34,9 +37,13 @@ zhihui_net_impl_type_t ZhihuiNetGetImplementation(void)
 
 int ZhihuiNetInit(void)
 {
-    /* 初始化网络模块 */
-    printf("[ZhihuiNet] Initialized with %s implementation\n",
-           (g_current_impl == ZHIHUI_NET_IMPL_OPENHARMONY) ? "OpenHarmony" : "PPP");
+    /* 初始化网络模块,显示当前模式 */
+    const char *mode_str = (g_current_impl == ZHIHUI_NET_IMPL_OPENHARMONY) ? 
+                           "OpenHarmony (PPP + lwIP)" : "N706A AT Command";
+    
+    printf("[ZhihuiNet] Initialized with %s implementation\n", mode_str);
+    printf("[ZhihuiNet] Auto-detected mode: %s\n", ZHIHUI_NET_MODE_DESC);
+    
     return 0;
 }