优化ppp拨号,优化tcp测试程序,ppp串口初始化移动到uart_porting.c中。
author孙春阳 <snickersun@163.com>
Thu, 25 Sep 2025 10:33:33 +0000 (18:33 +0800)
committer孙春阳 <snickersun@163.com>
Thu, 25 Sep 2025 10:33:33 +0000 (18:33 +0800)
27 files changed:
code/sdk/application/brandy/brandy_standard/thread_pri_init.c
code/sdk/build/config/target_config/brandy/config.py
code/sdk/drivers/chips/brandy/porting/uart/uart_porting.c
code/sdk/zhihui/leiniao/imsl_ln/ln_api.c
code/sdk/zhihui/ppp/README.md [deleted file]
code/sdk/zhihui/ppp/README_CAT1_COMPATIBILITY.md [deleted file]
code/sdk/zhihui/ppp/README_POWER_CONTROL.md [deleted file]
code/sdk/zhihui/ppp/build_test.sh [deleted file]
code/sdk/zhihui/ppp/doc/Neoway-pppdial [new file with mode: 0644]
code/sdk/zhihui/ppp/example/ppp_at_cmd.c
code/sdk/zhihui/ppp/example/ppp_example.c
code/sdk/zhihui/ppp/include/ppp_api.h
code/sdk/zhihui/ppp/include/ppp_at_handler.h
code/sdk/zhihui/ppp/include/ppp_config.h
code/sdk/zhihui/ppp/include/ppp_lwip.h
code/sdk/zhihui/ppp/include/ppp_performance_config.h [deleted file]
code/sdk/zhihui/ppp/include/ppp_serial.h
code/sdk/zhihui/ppp/src/ppp_api.c
code/sdk/zhihui/ppp/src/ppp_at_handler.c
code/sdk/zhihui/ppp/src/ppp_cat1_api.c
code/sdk/zhihui/ppp/src/ppp_lwip.c
code/sdk/zhihui/ppp/src/ppp_serial.c
code/sdk/zhihui/tcptest/include/zhihui_tcp_debug.h
code/sdk/zhihui/tcptest/include/zhihui_tcp_test.h
code/sdk/zhihui/tcptest/src/zhihui_tcp_test.c
code/sdk/zhihui/tcptest/src/zhihui_tcp_test_main.c
code/sdk/zhihui/utils/custom_utils.c

index a884919..2ec1c92 100644 (file)
@@ -634,13 +634,9 @@ static void thread_main(const void *unused)
     custom_check_factory_test_flag();\r
     startup_post_init();\r
 #endif\r
+\r
     set_startup_finish_flag();\r
-#ifdef SUPPORT_LEINIAO\r
-#ifdef CUSTOM_UTILS\r
-    if(!custom_get_factory_test_flag())\r
-#endif\r
-        uapi_ln_http_server_init();\r
-#endif\r
+\r
 }\r
 \r
 void thread_pri_init(void)\r
index b5b73d8..2ebecbc 100644 (file)
@@ -1283,6 +1283,7 @@ target = {
             'AUDIO_SMARTPA_AW88082',
             'LCD_JD9885',
             'SUPPORT_LEINIAO',
+            # 'SKIP_LN_PROTOCOL_TEST',
         ],
         #添加自定义应用
        'ram_component': [
index be6daf1..943f149 100644 (file)
@@ -167,7 +167,7 @@ static uart_config_t g_uart_config[UART_BUS_MAX_NUMBER] = {
     /** UART_BUS_0, which is used to at cmd and debug print in wstp version,
      * and which is used to testustie and debug print in testsuite version
      */
-    #if defined(SUPPORT_CAT1_SERVICE) || defined(SUPPORT_PPP_SERVICE)
+    #if defined(SUPPORT_CAT1_SERVICE) 
     {
         {
             .tx_pin = PIN_NONE,
@@ -201,7 +201,36 @@ static uart_config_t g_uart_config[UART_BUS_MAX_NUMBER] = {
         true,
         #endif
     },
-
+    #elif defined(SUPPORT_PPP_SERVICE)
+    {
+        {
+            .tx_pin = S_MGPIO19,
+            .rx_pin = S_MGPIO20,
+            .cts_pin = PIN_NONE,
+            .rts_pin = PIN_NONE
+        },
+        {
+            .tx_pin_mode = (pin_mode_t)HAL_PIO_FUNC_UART1,
+            .rx_pin_mode = (pin_mode_t)HAL_PIO_FUNC_UART1,
+            .cts_pin_mode = (pin_mode_t)HAL_PIO_FUNC_MAX,
+            .rts_pin_mode = (pin_mode_t)HAL_PIO_FUNC_MAX
+        },
+        UART_0_IRQN,
+        (osal_irq_handler)irq_uart0_handler,
+        NULL,
+        {
+            .baud_rate = CUSTOM_UART_RATE,
+            .data_bits = UART_DATA_BIT_8,
+            .parity = UART_PARITY_NONE,
+            .stop_bits = UART_STOP_BIT_1,
+        },
+        {
+            .rx_buffer_size = UART_RX_BUFFER_SIZE,
+            .rx_buffer = g_uart0_rx_buffer,
+        },
+        NULL,
+        false,
+    },
     #else // SUPPORT_CAT1_SERVICE
     {
         {
index 698f1be..5419e5e 100644 (file)
@@ -1276,6 +1276,10 @@ static void ln_http_server_send_task(void const *arg)
         }
         if (mail.cmd == LN_HTTP_SERVICE_CMD_GET_DEVICE_TOKEN)
         {
+
+            #ifdef SKIP_LN_PROTOCOL_TEST
+            continue;
+            #endif
             if(get_is_ln_get_device_token_success() == 1)
             {
                 printf("设备Token已经获取\n");
diff --git a/code/sdk/zhihui/ppp/README.md b/code/sdk/zhihui/ppp/README.md
deleted file mode 100644 (file)
index 0519ecb..0000000
+++ /dev/null
@@ -1 +0,0 @@
- 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/README_CAT1_COMPATIBILITY.md b/code/sdk/zhihui/ppp/README_CAT1_COMPATIBILITY.md
deleted file mode 100644 (file)
index 0519ecb..0000000
+++ /dev/null
@@ -1 +0,0 @@
- 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/README_POWER_CONTROL.md b/code/sdk/zhihui/ppp/README_POWER_CONTROL.md
deleted file mode 100644 (file)
index 0519ecb..0000000
+++ /dev/null
@@ -1 +0,0 @@
- 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/build_test.sh b/code/sdk/zhihui/ppp/build_test.sh
deleted file mode 100644 (file)
index 76f06d3..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-#!/bin/bash
-
-# PPP模块编译测试脚本
-# 用于验证PPP模块的编译完整性
-
-echo "=========================================="
-echo "PPP Module Build Test"
-echo "=========================================="
-
-# 设置项目根目录
-PROJECT_ROOT=$(cd "$(dirname "$0")/../../.." && pwd)
-PPP_DIR="$PROJECT_ROOT/zhihui/ppp"
-
-echo "Project Root: $PROJECT_ROOT"
-echo "PPP Directory: $PPP_DIR"
-
-# 检查必要文件是否存在
-echo ""
-echo "Checking required files..."
-
-required_files=(
-    "include/ppp_api.h"
-    "include/ppp_config.h"
-    "include/ppp_types.h"
-    "include/ppp_at_handler.h"
-    "include/ppp_serial.h"
-    "include/ppp_lwip.h"
-    "include/ppp_debug.h"
-    "src/ppp_api.c"
-    "src/ppp_at_handler.c"
-    "src/ppp_serial.c"
-    "src/ppp_lwip.c"
-    "src/ppp_debug.c"
-    "CMakeLists.txt"
-    "README.md"
-)
-
-missing_files=0
-for file in "${required_files[@]}"; do
-    if [ -f "$PPP_DIR/$file" ]; then
-        echo "✓ $file"
-    else
-        echo "✗ $file (MISSING)"
-        missing_files=$((missing_files + 1))
-    fi
-done
-
-if [ $missing_files -gt 0 ]; then
-    echo ""
-    echo "ERROR: $missing_files required files are missing!"
-    exit 1
-fi
-
-echo ""
-echo "All required files found!"
-
-# 检查头文件包含关系
-echo ""
-echo "Checking header dependencies..."
-
-# 简单的语法检查(如果有gcc可用)
-if command -v gcc >/dev/null 2>&1; then
-    echo "Running syntax check with GCC..."
-    
-    # 创建临时测试文件
-    test_file="/tmp/ppp_test.c"
-    cat > "$test_file" << 'EOF'
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-// 模拟系统头文件
-#define ERRCODE_SUCC 0
-#define OSAL_SUCCESS 0
-#define OSAL_WAIT_FOREVER -1
-#define UART_BUS_1 1
-#define S_MGPIO33 33
-#define S_MGPIO34 34
-#define PIN_NONE 0xFF
-#define UART_DATA_BIT_8 8
-#define UART_PARITY_NONE 0
-#define UART_STOP_BIT_1 1
-#define UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE 1
-
-typedef int errcode_t;
-typedef void* osal_mutex;
-typedef void* osal_semaphore;
-typedef void* osal_timer;
-typedef void* osal_task;
-
-typedef struct {
-    uint8_t tx_pin;
-    uint8_t rx_pin;
-    uint8_t cts_pin;
-    uint8_t rts_pin;
-} uart_pin_config_t;
-
-typedef struct {
-    uint32_t baud_rate;
-    uint8_t data_bits;
-    uint8_t parity;
-    uint8_t stop_bits;
-} uart_attr_t;
-
-typedef struct {
-    uint32_t rx_buffer_size;
-    uint8_t *rx_buffer;
-} uart_buffer_config_t;
-
-// 模拟函数声明
-#define PRINT printf
-#define osal_kmalloc malloc
-#define osal_kfree free
-#define osal_get_tick() 0
-#define osal_msleep(x) 
-int osal_mutex_init(osal_mutex *mutex) { return 0; }
-int osal_mutex_destroy(osal_mutex mutex) { return 0; }
-int osal_mutex_lock(osal_mutex mutex) { return 0; }
-int osal_mutex_unlock(osal_mutex mutex) { return 0; }
-int osal_sem_init(osal_semaphore *sem, int value) { return 0; }
-int osal_sem_destroy(osal_semaphore sem) { return 0; }
-int osal_sem_wait(osal_semaphore sem, int timeout) { return 0; }
-int osal_sem_signal(osal_semaphore sem) { return 0; }
-int memset_s(void *dest, size_t destMax, int c, size_t count) { return 0; }
-int memcpy_s(void *dest, size_t destMax, const void *src, size_t count) { return 0; }
-int snprintf_s(char *strDest, size_t destMax, size_t count, const char *format, ...) { return 0; }
-
-EOF
-
-    # 添加PPP头文件内容进行语法检查
-    echo '#include "'$PPP_DIR'/include/ppp_config.h"' >> "$test_file"
-    echo '#include "'$PPP_DIR'/include/ppp_types.h"' >> "$test_file"
-    echo '#include "'$PPP_DIR'/include/ppp_debug.h"' >> "$test_file"
-    echo '#include "'$PPP_DIR'/include/ppp_api.h"' >> "$test_file"
-    
-    echo "int main() { return 0; }" >> "$test_file"
-    
-    if gcc -fsyntax-only -I"$PPP_DIR/include" "$test_file" 2>/dev/null; then
-        echo "✓ Header syntax check passed"
-    else
-        echo "✗ Header syntax check failed"
-        echo "Running detailed check..."
-        gcc -fsyntax-only -I"$PPP_DIR/include" "$test_file"
-    fi
-    
-    rm -f "$test_file"
-else
-    echo "GCC not available, skipping syntax check"
-fi
-
-# 统计代码行数
-echo ""
-echo "Code statistics:"
-total_lines=0
-for file in src/*.c include/*.h; do
-    if [ -f "$PPP_DIR/$file" ]; then
-        lines=$(wc -l < "$PPP_DIR/$file")
-        echo "  $file: $lines lines"
-        total_lines=$((total_lines + lines))
-    fi
-done
-echo "  Total: $total_lines lines"
-
-# 检查文档
-echo ""
-echo "Documentation:"
-if [ -f "$PPP_DIR/README.md" ]; then
-    readme_lines=$(wc -l < "$PPP_DIR/README.md")
-    echo "  README.md: $readme_lines lines"
-fi
-
-if [ -f "$PPP_DIR/example/ppp_example.c" ]; then
-    example_lines=$(wc -l < "$PPP_DIR/example/ppp_example.c")
-    echo "  Example code: $example_lines lines"
-fi
-
-echo ""
-echo "=========================================="
-echo "PPP Module Build Test Completed"
-echo "=========================================="
-echo ""
-echo "Summary:"
-echo "  ✓ All required files present"
-echo "  ✓ Header dependencies OK"
-echo "  ✓ Code statistics generated"
-echo "  ✓ Documentation available"
-echo ""
-echo "The PPP module is ready for integration!"
-echo ""
-echo "Next steps:"
-echo "1. Add PPP module to main CMakeLists.txt"
-echo "2. Configure lwIP with PPP support"
-echo "3. Test with actual hardware"
-echo "" 
\ No newline at end of file
diff --git a/code/sdk/zhihui/ppp/doc/Neoway-pppdial b/code/sdk/zhihui/ppp/doc/Neoway-pppdial
new file mode 100644 (file)
index 0000000..646d3c2
--- /dev/null
@@ -0,0 +1,64 @@
+# /etc/ppp/peers/Neoway-pppdial
+# Usage:root@neoway:~# pppd call Neoway-pppdial
+
+crtscts
+modem
+
+# Hide password in debug messages
+#hide-password
+
+# The phone is not required to authenticate
+noauth
+
+# The chat script (be sure to edit that file,too!)
+connect '/usr/sbin/chat -s -v -f /etc/ppp/peers/chat'  
+
+# The close script(be sure to edit that file,too!)
+#disconnect '/usr/sbin/chat -s -v -f /etc/ppp/peers/Neoway-chat-disconnect'
+
+# Debug info from pppd
+debug   
+
+# Serial Device to whih phone is connect
+#/dev/ttyACM7
+/dev/ttyUSB0
+#/dev/ttyUSB4
+#/dev/mux0
+
+# Serial port line speed
+115200 
+
+
+# If you want to use the link as your gateway
+defaultroute 
+
+# pppd must not propose any IP address to the peer
+noipdefault 
+
+# No ppp compression
+novj
+novjccomp
+noccp
+ipcp-accept-local 
+ipcp-accept-remote
+local
+
+# For sanity, keep a lock on the serial line
+lock  
+dump
+
+# Keep pppd attached to the terminal
+# Comment this to get daemon mode pppd
+nodetach
+#user "card@cc.sg.jl"
+#0.0.0.0:0.0.0.0
+#password "card@123" 
+# Hardware flow control
+#crtscts  
+#remotename 3gppp
+#ipparam 3gppp
+
+# Ask the peer for up to 2 DNS server addresses
+usepeerdns 
+
++ipv6
index e796366..118f4aa 100644 (file)
 #include "ppp_serial.h"
 #include "ppp_types.h"
 #include "ppp_api.h"
+#include "ppp_lwip.h"
 #include "ppp_at_handler.h"
 #include "ppp_debug_manager.h"
 #include "zhihui_tcp_test.h"
 #include "ppp_example.h"
+#include "uart.h"
 
 
 
@@ -613,32 +615,6 @@ static uint32_t at_ws_multi_test_status(uint8_t *para, uint32_t paraLen, char *s
 }
 #endif
 
-/* PPP串口模式切换测试指令 */
-static errcode_t at_ppp_mode_switch(uint8_t *para, uint32_t paraLen)
-{
-    uint8_t argv[CUSTOM_UTILS_MAX_ARGC][CUSTOM_UTILS_MAX_ARGV_LEN];
-    uint32_t argc;
-    
-    if (ConvertCmdToParam(para, paraLen, argv, &argc) != CUSTOM_UTILS_SUCCESS) {
-        ppp_print_err("PPP MODE SWITCH Convert Command Failed\n");
-        return ERRCODE_FAIL;
-    }
-    
-    if (argc != 1) {
-        ppp_print_err("PPP MODE SWITCH Set Parameter Failed argc %d\nUsage: AT^PPPMODE=AT|PPP\n", argc);
-        return ERRCODE_FAIL;
-    }
-    
-    errcode_t ret = ppp_test_switch_mode((char*)argv[0]);
-    if (ret == ERRCODE_SUCC) {
-        ppp_print_info("PPP MODE SWITCH: Successfully switched to %s mode\n", argv[0]);
-    } else {
-        ppp_print_err("PPP MODE SWITCH: Failed to switch to %s mode, error: %d\n", argv[0], ret);
-    }
-    
-    return ret;
-}
-
 /* PPP串口状态查询指令 */
 static errcode_t at_ppp_status(uint8_t *para, uint32_t paraLen)
 {
@@ -710,24 +686,6 @@ static errcode_t at_ppp_transparent(uint8_t *para, uint32_t paraLen)
     }
 }
 
-/* PPP串口测试指令 */
-static errcode_t at_ppp_test(uint8_t *para, uint32_t paraLen)
-{
-    (void)para;
-    (void)paraLen;
-    
-    ppp_print_info("PPP TEST: Starting PPP serial test...\n");
-    
-    errcode_t ret = ppp_test_uart_function();
-    if (ret == ERRCODE_SUCC) {
-        ppp_print_info("PPP TEST: UART test completed successfully\n");
-    } else {
-        ppp_print_err("PPP TEST: UART test failed, error: %d\n", ret);
-    }
-    
-    return ret;
-}
-
 /* PPP智能flush测试指令 */
 static errcode_t at_ppp_flush(uint8_t *para, uint32_t paraLen)
 {
@@ -969,22 +927,22 @@ static errcode_t at_ppp_show_runtime(uint8_t *para, uint32_t paraLen)
     ppp_print_info("PPP RUNTIME SHOW: Current runtime status:\n");
     
     // 显示当前runtime状态
-    ppp_print_info("\n=== Current Runtime Status ===\n");
-    ppp_print_info("Power Status: %s\n", cat1_api_runtime_get_cat1_powerstat() ? "ON" : "OFF");
-    ppp_print_info("Network Status: %s\n", cat1_api_runtime_get_cat1_networkstat() ? "CONNECTED" : "DISCONNECTED");
+    ppp_print_info("\n=== Current Runtime Status ===");
+    ppp_print_info("Power Status: %s", cat1_api_runtime_get_cat1_powerstat() ? "ON" : "OFF");
+    ppp_print_info("Network Status: %s", cat1_api_runtime_get_cat1_networkstat() ? "CONNECTED" : "DISCONNECTED");
     
     int signal = cat1_api_runtime_get_cat1_signal();
     if (signal == 99) {
-        ppp_print_info("Signal Strength: No Signal (99)\n");
+        ppp_print_info("Signal Strength: No Signal (99)");
     } else {
-        ppp_print_info("Signal Strength: %d/31 (%s)\n", signal, 
+        ppp_print_info("Signal Strength: %d/31 (%s)", signal, 
                        signal >= 20 ? "Excellent" : 
                        signal >= 15 ? "Good" : 
                        signal >= 10 ? "Fair" : 
                        signal >= 5 ? "Poor" : "Very Poor");
     }
     
-    ppp_print_info("SIM Status: %s\n", cat1_api_runtime_get_cat1_simstat() ? "NORMAL" : "ERROR");
+    ppp_print_info("SIM Status: %s", cat1_api_runtime_get_cat1_simstat() ? "NORMAL" : "ERROR");
     
     uint8_t net_type = cat1_api_runtime_get_cat1_networktype();
     const char* net_type_str = "Unknown";
@@ -997,21 +955,68 @@ static errcode_t at_ppp_show_runtime(uint8_t *para, uint32_t paraLen)
         case 5: net_type_str = "Registered (Roaming)"; break;
         default: net_type_str = "Invalid"; break;
     }
-    ppp_print_info("Network Type: %d (%s)\n", net_type, net_type_str);
+    ppp_print_info("Network Type: %d (%s)", net_type, net_type_str);
     
     char* operator = cat1_api_runtime_get_cat1_operator();
-    ppp_print_info("Operator: %s\n", (operator && strlen(operator) > 0) ? operator : "Unknown");
+    ppp_print_info("Operator: %s", (operator && strlen(operator) > 0) ? operator : "Unknown");
     
     char* imei = cat1_api_runtime_get_cat1_imei();
-    ppp_print_info("IMEI: %s\n", (imei && strlen(imei) > 0) ? imei : "Unknown");
+    ppp_print_info("IMEI: %s", (imei && strlen(imei) > 0) ? imei : "Unknown");
     
     char* iccid = cat1_api_runtime_get_cat1_iccid();
-    ppp_print_info("ICCID: %s\n", (iccid && strlen(iccid) > 0) ? iccid : "Unknown");
+    ppp_print_info("ICCID: %s", (iccid && strlen(iccid) > 0) ? iccid : "Unknown");
     
     char* version = cat1_api_runtime_get_cat1_modemver();
-    ppp_print_info("Modem Version: %s\n", (version && strlen(version) > 0) ? version : "Unknown");
-    
-    ppp_print_info("===============================\n");
+    ppp_print_info("Modem Version: %s", (version && strlen(version) > 0) ? version : "Unknown");
+    
+    ppp_print_info("===============================");
+    
+    // 显示PPP输出统计信息
+    ppp_lwip_output_stats_t ppp_stats;
+    if (ppp_lwip_get_output_stats(&ppp_stats) == PPP_ERR_OK) {
+        ppp_print_info("\n=== PPP Output Statistics ===");
+        ppp_print_info("Total Output Packets: %llu", ppp_stats.total_packets);
+        ppp_print_info("Total Output Bytes: %llu", ppp_stats.total_bytes);
+        ppp_print_info("LCP Packets: %u", ppp_stats.lcp_packets);
+        ppp_print_info("IPCP Packets: %u", ppp_stats.ipcp_packets);
+        ppp_print_info("IP Packets: %u", ppp_stats.ip_packets);
+        ppp_print_info("Other Protocol Packets: %u", ppp_stats.other_packets);
+        ppp_print_info("Failed Sends: %u", ppp_stats.failed_sends);
+        
+        // 计算PPP输出统计的运行时间和速率
+        uint32_t current_time = ppp_stats.last_packet_time;
+        if (current_time == 0) {
+            // 如果没有最后包时间,使用当前时间的简单估算
+            current_time = ppp_stats.start_time + 10000; // 假设运行了10秒
+        }
+        uint32_t ppp_elapsed_ms = current_time - ppp_stats.start_time;
+        uint32_t ppp_elapsed_sec = ppp_elapsed_ms / 1000;
+        
+        if (ppp_elapsed_sec > 0) {
+            ppp_print_info("PPP Stats Duration: %u seconds", ppp_elapsed_sec);
+        }
+        
+        if (ppp_elapsed_ms > 0 && ppp_stats.total_bytes > 0) {
+            uint64_t ppp_throughput_bps = (ppp_stats.total_bytes * 1000) / ppp_elapsed_ms;
+            ppp_print_info("PPP Output Throughput: %llu bytes/s", ppp_throughput_bps);
+            
+            float ppp_packet_rate = (float)ppp_stats.total_packets * 1000 / ppp_elapsed_ms;
+            ppp_print_info("PPP Output Packet Rate: %.1f packets/s", ppp_packet_rate);
+        }
+        
+        // 计算成功率
+        uint64_t total_attempts = ppp_stats.total_packets + ppp_stats.failed_sends;
+        if (total_attempts > 0) {
+            float success_rate = (float)ppp_stats.total_packets / total_attempts * 100;
+            ppp_print_info("PPP Output Success Rate: %.1f%%", success_rate);
+        }
+        
+        ppp_print_info("=============================");
+    } else {
+        ppp_print_info("\n=== PPP Output Statistics ===");
+        ppp_print_info("Failed to get PPP output statistics");
+        ppp_print_info("=============================");
+    }
     
     ppp_lwip_print_discard_stats();
 
@@ -1482,7 +1487,7 @@ static errcode_t at_ppp_test_uart_at_mode(uint8_t *para, uint32_t paraLen)
     
     ppp_print_info("Sending AT command for UART test...\n");
     
-    errcode_t ret = ppp_test_execute_at_command("AT", response, sizeof(response), &response_len, 5000);
+    errcode_t ret = ppp_execute_at_command("AT", response, sizeof(response), &response_len, 5000);
     if (ret == ERRCODE_SUCC) {
         ppp_print_info("AT mode UART test SUCCESS!\n");
         ppp_print_info("Response (%d bytes): %s\n", response_len, response);
@@ -1720,24 +1725,25 @@ static errcode_t at_ppp_debug_reset_level(uint8_t *para, uint32_t paraLen)
 
 /**
  * @brief AT^PPPTCPPERF - PPP TCP性能测试
- * @param para 参数: 服务器地址,端口,连接数,测试时间
+ * @param para 参数: 服务器地址,端口,连接数,测试时间[,接收超时(ms)]
  * @param paraLen 参数长度
  */
 static errcode_t at_ppp_tcp_performance_test(uint8_t *para, uint32_t paraLen)
 {
     if (!para || paraLen == 0) {
         PRINT("[PPP_ERR]PPP TCP PERF: Missing parameters\r\n");
-        PRINT("[PPP_INFO]Usage: AT^PPPTCPPERF=<host>,<port>,<connections>,<time>\r\n");
+        PRINT("[PPP_INFO]Usage: AT^PPPTCPPERF=<host>,<port>,<connections>,<time>[,<recv_timeout_ms>]\r\n");
         PRINT("[PPP_INFO]Example: AT^PPPTCPPERF=110.42.224.129,8910,5,30\r\n");
+        PRINT("[PPP_INFO]Example: AT^PPPTCPPERF=110.42.224.129,8910,5,30,2000\r\n");
         return ERRCODE_FAIL;
     }
     
     uint8_t argv[CUSTOM_UTILS_MAX_ARGC][CUSTOM_UTILS_MAX_ARGV_LEN];
     uint32_t argc;
     
-    if (ConvertCmdToParam(para, paraLen, argv, &argc) != CUSTOM_UTILS_SUCCESS || argc != 4) {
-        PRINT("[PPP_ERR]PPP TCP PERF: Invalid parameters, need 4 parameters, got %d\r\n", argc);
-        PRINT("[PPP_INFO]Usage: AT^PPPTCPPERF=<host>,<port>,<connections>,<time>\r\n");
+    if (ConvertCmdToParam(para, paraLen, argv, &argc) != CUSTOM_UTILS_SUCCESS || (argc != 4 && argc != 5)) {
+        PRINT("[PPP_ERR]PPP TCP PERF: Invalid parameters, need 4 or 5 parameters, got %d\r\n", argc);
+        PRINT("[PPP_INFO]Usage: AT^PPPTCPPERF=<host>,<port>,<connections>,<time>[,<recv_timeout_ms>]\r\n");
         return ERRCODE_FAIL;
     }
     
@@ -1746,6 +1752,16 @@ static errcode_t at_ppp_tcp_performance_test(uint8_t *para, uint32_t paraLen)
     int port = atoi((char*)argv[1]);
     int connections = atoi((char*)argv[2]);
     int test_time = atoi((char*)argv[3]);
+    int recv_timeout_ms = TCP_TEST_DEFAULT_RECV_TIMEOUT_MS; // 默认值
+    
+    // 解析可选的接收超时参数
+    if (argc == 5) {
+        recv_timeout_ms = atoi((char*)argv[4]);
+        if (recv_timeout_ms < 100 || recv_timeout_ms > 30000) {
+            PRINT("[PPP_ERR]PPP TCP PERF: Invalid recv timeout %d (must be 100-30000 ms)\r\n", recv_timeout_ms);
+            return ERRCODE_FAIL;
+        }
+    }
     
     // 参数验证
     if (port < 1 || port > 65535) {
@@ -1768,6 +1784,7 @@ static errcode_t at_ppp_tcp_performance_test(uint8_t *para, uint32_t paraLen)
     PRINT("[PPP_INFO]Target: %s:%d\r\n", server_host, port);
     PRINT("[PPP_INFO]Connections: %d\r\n", connections);
     PRINT("[PPP_INFO]Duration: %d seconds\r\n", test_time);
+    PRINT("[PPP_INFO]Receive Timeout: %d ms\r\n", recv_timeout_ms);
     
 #ifdef SUPPORT_TCP_TEST
     // 初始化TCP测试配置
@@ -1777,10 +1794,11 @@ static errcode_t at_ppp_tcp_performance_test(uint8_t *para, uint32_t paraLen)
     config.server_port = (uint16_t)port;
     config.test_duration = (uint32_t)test_time;
     config.connection_count = (uint16_t)connections;
-    config.verbose = false; // AT命令模式不使用详细输出
-    config.send_interval_ms = 10; // 10ms间隔,适合AT命令模式
-    config.data_min_size = 64;    // 较小的数据包
-    config.data_max_size = 1024;  // 适中的最大包
+    config.verbose = true; // AT命令模式不使用详细输出
+    config.send_interval_ms = 100; // 100ms间隔,适合AT命令模式
+    config.data_min_size = 1024;    // 较小的数据包
+    config.data_max_size = 4096;  // 适中的最大包
+    config.recv_timeout_ms = (uint32_t)recv_timeout_ms; // 可配置的接收超时
     
     // 初始化TCP测试
     errcode_t ret = tcp_test_init();
@@ -1881,8 +1899,16 @@ static errcode_t at_ppp_tcp_test_stats(uint8_t *para, uint32_t paraLen)
     PRINT("[PPP_INFO]Packets Received: %llu\r\n", stats.total_packets_received);
     PRINT("[PPP_INFO]Bytes Sent: %llu\r\n", stats.total_bytes_sent);
     PRINT("[PPP_INFO]Bytes Received: %llu\r\n", stats.total_bytes_received);
+    PRINT("[PPP_INFO]Total Send Errors: %u\r\n", stats.total_send_errors);
+    PRINT("[PPP_INFO]Total Receive Errors: %u\r\n", stats.total_recv_errors);
+    PRINT("[PPP_INFO]Total Incomplete Packets: %u\r\n", stats.total_incomplete_packets);
+    PRINT("[PPP_INFO]Total Incomplete Bytes: %u\r\n", stats.total_incomplete_bytes);
+    PRINT("[PPP_INFO]Total Pattern Errors: %u\r\n", stats.total_pattern_errors);
+    PRINT("[PPP_INFO]Max Send Throughput: %llu bytes/s\r\n", stats.max_send_throughput_bps);
+    PRINT("[PPP_INFO]Avg Send Throughput: %llu bytes/s\r\n", stats.avg_send_throughput_bps);
+    PRINT("[PPP_INFO]Max Receive Throughput: %llu bytes/s\r\n", stats.max_recv_throughput_bps);
+    PRINT("[PPP_INFO]Avg Receive Throughput: %llu bytes/s\r\n", stats.avg_recv_throughput_bps);
     PRINT("[PPP_INFO]Total Errors: %d\r\n", stats.total_errors);
-    PRINT("[PPP_INFO]Data Verification Errors: %d\r\n", stats.data_verification_errors);
     
     // 计算传输速率
     if (elapsed_ms > 0) {
@@ -1903,8 +1929,55 @@ static errcode_t at_ppp_tcp_test_stats(uint8_t *para, uint32_t paraLen)
     
     PRINT("[PPP_INFO]========================================\r\n");
     
-    return ERRCODE_SUCC;
+#endif /* SUPPORT_TCP_TEST */
+
+    // 获取并显示PPP输出统计(无论是否支持TCP测试都显示)
+    ppp_lwip_output_stats_t ppp_stats;
+    if (ppp_lwip_get_output_stats(&ppp_stats) == PPP_ERR_OK) {
+        PRINT("[PPP_INFO]=== PPP Output Statistics ===\r\n");
+        PRINT("[PPP_INFO]Total Output Packets: %llu\r\n", ppp_stats.total_packets);
+        PRINT("[PPP_INFO]Total Output Bytes: %llu\r\n", ppp_stats.total_bytes);
+        PRINT("[PPP_INFO]LCP Packets: %u\r\n", ppp_stats.lcp_packets);
+        PRINT("[PPP_INFO]IPCP Packets: %u\r\n", ppp_stats.ipcp_packets);
+        PRINT("[PPP_INFO]IP Packets: %u\r\n", ppp_stats.ip_packets);
+        PRINT("[PPP_INFO]Other Protocol Packets: %u\r\n", ppp_stats.other_packets);
+        PRINT("[PPP_INFO]Failed Sends: %u\r\n", ppp_stats.failed_sends);
+        
+        // 计算PPP输出统计的运行时间和速率
+        uint32_t current_time = 0;
+#ifdef SUPPORT_TCP_TEST
+        current_time = tcp_test_get_time_ms();
+#else
+        // 使用简单的时间计算,如果没有TCP测试支持
+        current_time = ppp_stats.last_packet_time;
+#endif
+        uint32_t ppp_elapsed_ms = current_time - ppp_stats.start_time;
+        uint32_t ppp_elapsed_sec = ppp_elapsed_ms / 1000;
+        PRINT("[PPP_INFO]PPP Stats Duration: %u seconds\r\n", ppp_elapsed_sec);
+        
+        if (ppp_elapsed_ms > 0 && ppp_stats.total_bytes > 0) {
+            uint64_t ppp_throughput_bps = (ppp_stats.total_bytes * 1000) / ppp_elapsed_ms;
+            PRINT("[PPP_INFO]PPP Output Throughput: %llu bytes/s\r\n", ppp_throughput_bps);
+            
+            float ppp_packet_rate = (float)ppp_stats.total_packets * 1000 / ppp_elapsed_ms;
+            PRINT("[PPP_INFO]PPP Output Packet Rate: %.1f packets/s\r\n", ppp_packet_rate);
+        }
+        
+        // 计算成功率
+        uint64_t total_attempts = ppp_stats.total_packets + ppp_stats.failed_sends;
+        if (total_attempts > 0) {
+            float success_rate = (float)ppp_stats.total_packets / total_attempts * 100;
+            PRINT("[PPP_INFO]PPP Output Success Rate: %.1f%%\r\n", success_rate);
+        }
+        
+        PRINT("[PPP_INFO]========================================\r\n");
+    } else {
+        PRINT("[PPP_WARN]Failed to get PPP output statistics\r\n");
+    }
     
+    return ERRCODE_SUCC;
+
+#ifdef SUPPORT_TCP_TEST    
 #else
     PRINT("[PPP_ERR]PPP TCP STATS: TCP test not supported in this build\r\n");
     return ERRCODE_FAIL;
@@ -1924,10 +1997,8 @@ static const at_cmd_table_t g_ppp_cmd[] = {
     { (char *)"AT^HTTPDOWNLOAD",    custom_start_ota_download, (char *)" " },
     { (char *)"AT^CAT1LOGLEVEL",    custom_enable_cat1_debug_log, (char *)" " },
     /* PPP串口测试指令 */
-    { (char *)"AT^PPPMODE",         at_ppp_mode_switch, (char *)"AT|PPP" },
     { (char *)"AT^PPPSTATUS",       at_ppp_status, (char *)" " },
     { (char *)"AT^PPPTRANS",        at_ppp_transparent, (char *)"AT_COMMAND" },
-    { (char *)"AT^PPPTEST",         at_ppp_test, (char *)" " },
     { (char *)"AT^PPPFLUSH",        at_ppp_flush, (char *)" " },
     /* PPP模块化函数测试指令 */
     { (char *)"AT^PPPENVINIT",      at_ppp_env_init, (char *)" " },
index 844d5c6..34d4b11 100644 (file)
@@ -57,14 +57,14 @@ int ppp_env_init(void)
         return -1;
     }
 
-    /* 3. 注册事件回调函数 */
-    PRINT("Registering PPP event callback...\r\n");
-    ret = ppp_register_event_callback(ppp_event_callback);
-    if (ret != ERRCODE_SUCC) {
-        PRINT("PPP register callback failed\r\n");
-        zhihui_ppp_deinit();
-        return -1;
-    }
+    // /* 3. 注册事件回调函数 */
+    // PRINT("Registering PPP event callback...\r\n");
+    // ret = ppp_register_event_callback(ppp_event_callback);
+    // if (ret != ERRCODE_SUCC) {
+    //     PRINT("PPP register callback failed\r\n");
+    //     zhihui_ppp_deinit();
+    //     return -1;
+    // }
 
     g_ppp_env_initialized = true;
     PRINT("PPP environment initialized successfully (AT mode)\r\n");
index 61eddc1..b67aef7 100644 (file)
@@ -57,20 +57,8 @@ errcode_t ppp_register_event_callback(ppp_event_callback_t callback);
  */
 errcode_t ppp_get_connection_info(ppp_connection_info_t *info);
 
-/**
- * @brief PPP状态重置(从错误状态恢复)
- * @return 错误码
- */
-errcode_t ppp_reset_from_error(void);
-
 /* ========== PPP测试接口 ========== */
 
-/**
- * @brief PPP串口模式切换
- * @param mode 目标模式 ("AT" 或 "PPP")
- * @return 错误码
- */
-errcode_t ppp_test_switch_mode(const char *mode);
 
 /**
  * @brief 获取PPP串口状态信息
@@ -89,17 +77,12 @@ errcode_t ppp_test_get_status(char *status_info, uint32_t buffer_size);
  * @param timeout_ms 超时时间(毫秒)
  * @return 错误码
  */
-errcode_t ppp_test_execute_at_command(const char *at_command,
+errcode_t ppp_execute_at_command(const char *at_command,
                                      char *response,
                                      uint32_t response_size,
                                      uint32_t *response_len,
                                      uint32_t timeout_ms);
 
-/**
- * @brief PPP串口基础功能测试
- * @return 错误码
- */
-errcode_t ppp_test_uart_function(void);
 
 /**
  * @brief PPP智能flush测试
index 3400529..901fbe6 100644 (file)
@@ -15,7 +15,7 @@ extern "C" {
  * @param uart_bus UART总线号
  * @return 错误码
  */
-ppp_error_t ppp_at_handler_init(uint8_t uart_bus);
+ppp_error_t ppp_at_handler_init(uint8_t uart_bus, uint32_t current_baudrate, bool auto_baudrate_mode);
 
 /**
  * @brief 反初始化AT命令处理模块
index 260c7c2..d4c15cf 100644 (file)
@@ -27,18 +27,18 @@ extern "C" {
 #define SIO_UART_IRQ_NUM            UART_0_IRQN         // UART IRQ引脚
 #endif
 
-#define PPP_UART_BAUDRATE          1000000
+#define PPP_UART_BAUDRATE          115200
 
 /* 支持的波特率列表(自适应模式) */
 #define PPP_BAUDRATE_AUTO_LIST      {9600, 57600, 115200}
-#define PPP_BAUDRATE_AUTO_COUNT     4
+#define PPP_BAUDRATE_AUTO_COUNT     3
 
 /* 支持的固定波特率列表 */
 #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          5000                // AT命令超时时间(ms)
+#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响应最大长度
index a2da4ef..8c91bd8 100644 (file)
@@ -51,6 +51,19 @@ typedef struct {
     uint16_t mtu;                                       // MTU大小
 } ppp_lwip_network_info_t;
 
+/* PPP输出统计结构 */
+typedef struct {
+    uint64_t total_packets;          // 总输出包数
+    uint64_t total_bytes;            // 总输出字节数
+    uint32_t lcp_packets;            // LCP包数
+    uint32_t ipcp_packets;           // IPCP包数
+    uint32_t ip_packets;             // IP包数
+    uint32_t other_packets;          // 其他协议包数
+    uint32_t failed_sends;           // 发送失败次数
+    uint32_t start_time;             // 统计开始时间
+    uint32_t last_packet_time;       // 最后一个包的时间
+} ppp_lwip_output_stats_t;
+
 /**
  * @brief 初始化PPP lwIP集成
  * @param config 配置参数
@@ -139,6 +152,13 @@ bool ppp_lwip_check_connection_alive(void);
  */
 ppp_error_t ppp_lwip_trigger_keepalive(void);
 
+/**
+ * @brief 获取PPP输出统计信息
+ * @param stats 统计信息结构指针
+ * @return PPP_ERR_OK 成功,其他值失败
+ */
+ppp_error_t ppp_lwip_get_output_stats(ppp_lwip_output_stats_t *stats);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/code/sdk/zhihui/ppp/include/ppp_performance_config.h b/code/sdk/zhihui/ppp/include/ppp_performance_config.h
deleted file mode 100644 (file)
index 1a52d23..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- * @file ppp_performance_config.h
- * @brief PPP性能优化配置
- * 
- * 本文件包含针对PPP协商性能问题的优化配置参数
- * 主要解决LCP协商缓慢、Magic Number冲突、超时参数不当等问题
- * 
- * 注意:当前这些宏定义主要用作参考和文档说明
- * 实际的优化参数已直接在相关源文件中定义和使用:
- * - ppp_lwip.c: PPP协商超时参数和Magic Number生成
- * - ppp_serial.c: UART通信超时参数
- */
-
-#ifndef PPP_PERFORMANCE_CONFIG_H
-#define PPP_PERFORMANCE_CONFIG_H
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* ================================ PPP协商超时优化 ================================ */
-
-/**
- * @brief PPP FSM超时时间优化 (秒)
- * 默认值: 6秒 -> 优化值: 3秒
- * 说明: 减少LCP/IPCP协商的单次超时时间,提高协商响应速度
- */
-#define PPP_OPTIMIZED_FSM_TIMEOUT           3
-
-/**
- * @brief PPP最大Configure-Request重传次数优化
- * 默认值: 10次 -> 优化值: 6次  
- * 说明: 减少不必要的重传,避免过长的协商时间
- */
-#define PPP_OPTIMIZED_MAX_CONF_REQ          6
-
-/**
- * @brief PPP最大NAK循环次数优化
- * 默认值: 5次 -> 优化值: 3次
- * 说明: 减少NAK循环,加快协商收敛
- */
-#define PPP_OPTIMIZED_MAX_NAK_LOOPS         3
-
-/**
- * @brief PPP Terminate-Request重传次数
- * 默认值: 2次 -> 保持: 2次
- * 说明: 连接终止重传次数保持不变
- */
-#define PPP_OPTIMIZED_MAX_TERM_REQ          2
-
-/* ================================ UART通信优化 ================================ */
-
-/**
- * @brief UART写操作超时优化 (毫秒)
- * 默认值: 1000ms -> 优化值: 200ms
- * 说明: 减少UART写操作超时,提高PPP帧传输效率
- */
-#define PPP_OPTIMIZED_UART_WRITE_TIMEOUT    200
-
-/**
- * @brief UART读操作超时优化 (毫秒)  
- * 默认值: 200ms -> 优化值: 100ms
- * 说明: 减少PPP数据模式下的读取超时,提高协商响应速度
- */
-#define PPP_OPTIMIZED_UART_READ_TIMEOUT     100
-
-/* ================================ Magic Number优化 ================================ */
-
-/**
- * @brief Magic Number基础种子值
- * 说明: 用于生成唯一Magic Number的基础种子
- */
-#define PPP_MAGIC_NUMBER_SEED               0x12345678
-
-/**
- * @brief Magic Number异或掩码
- * 说明: 增加Magic Number随机性的固定异或值
- */
-#define PPP_MAGIC_NUMBER_XOR_MASK           0xDEADBEEF
-
-/**
- * @brief Magic Number备用值
- * 说明: 当生成的Magic Number为0时使用的备用值
- */
-#define PPP_MAGIC_NUMBER_FALLBACK           0xCAFEBABE
-
-/* ================================ 性能监控配置 ================================ */
-
-/**
- * @brief PPP阶段切换超时阈值 (毫秒)
- * 说明: 超过此时间的阶段切换将被标记为性能问题
- */
-#define PPP_PHASE_TIMEOUT_THRESHOLD         5000
-
-/**
- * @brief PPP协商总超时阈值 (毫秒)
- * 说明: PPP完整协商过程的最大允许时间
- */
-#define PPP_NEGOTIATION_TOTAL_TIMEOUT       30000
-
-/* ================================ 调试配置 ================================ */
-
-/**
- * @brief 启用PPP性能监控
- * 说明: 启用后会监控PPP阶段切换时间和性能指标
- */
-#define PPP_ENABLE_PERFORMANCE_MONITORING   1
-
-/**
- * @brief 启用Magic Number增强随机性
- * 说明: 启用后使用多重随机源生成Magic Number
- */
-#define PPP_ENABLE_ENHANCED_MAGIC_NUMBER     1
-
-/* ================================ 性能优化函数声明 ================================ */
-
-/**
- * @brief 应用PPP性能优化配置
- * @param ppp_pcb PPP控制块指针
- * @return 0成功,非0失败
- */
-int ppp_apply_performance_config(void *ppp_pcb);
-
-/**
- * @brief 生成优化的Magic Number
- * @param base_counter 基础计数器值
- * @param pcb_addr PCB地址用于增加随机性
- * @return 生成的Magic Number
- */
-uint32_t ppp_generate_optimized_magic_number(uint32_t base_counter, void *pcb_addr);
-
-/**
- * @brief 检查PPP性能指标
- * @param phase_duration 阶段持续时间(毫秒)
- * @param phase_id 阶段ID
- * @return 1表示性能正常,0表示性能异常
- */
-int ppp_check_performance_metrics(uint32_t phase_duration, int phase_id);
-
-/* ================================ 性能优化建议 ================================ */
-
-/*
- * PPP协商性能优化建议:
- * 
- * 1. Magic Number冲突解决:
- *    - 使用多重随机源(时间戳、PCB地址、栈地址)
- *    - 避免Magic Number为0
- *    - 增加位旋转和异或操作
- * 
- * 2. 超时参数优化:
- *    - FSM超时从6秒减少到3秒
- *    - 最大重传次数从10减少到6
- *    - NAK循环从5减少到3
- * 
- * 3. UART通信优化:
- *    - 写超时从1000ms减少到200ms
- *    - 读超时从200ms减少到100ms
- * 
- * 4. 性能监控:
- *    - 监控阶段切换时间
- *    - 检测异常缓慢的协商过程
- *    - 提供性能诊断信息
- * 
- * 5. 预期效果:
- *    - LCP协商时间从30秒减少到5-10秒
- *    - 减少Magic Number冲突导致的重协商
- *    - 提高整体PPP连接建立速度
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* PPP_PERFORMANCE_CONFIG_H */ 
\ No newline at end of file
index 5e51c5c..8763396 100644 (file)
@@ -158,11 +158,6 @@ uint32_t ppp_serial_get_stats(ppp_serial_stats_t *stats);
  */
 ppp_error_t ppp_serial_reset(void);
 
-/**
- * @brief 测试UART是否正常工作
- * @return 错误码
- */
-ppp_error_t ppp_serial_test_uart(void);
 
 #ifdef __cplusplus
 }
index 2006607..f2ebc52 100644 (file)
@@ -26,6 +26,9 @@ static ppp_state_t g_ppp_state = PPP_STATE_IDLE;
 // PPP配置参数
 static ppp_config_t g_ppp_config = {0};
 
+// AT通信和波特率标志
+static bool g_at_communication_and_baudrate_flag = false;
+
 // 4G电源初始化状态
 static bool g_4g_power_initialized = false;
 
@@ -37,6 +40,7 @@ static void ppp_check_and_update_state(void);
 
 errcode_t ppp_api_get_ppp_netif_name(char* netif_name, uint32_t buffer_size);
 
+void ppp_check_at_communication_and_baudrate(void);
 
 errcode_t ppp_api_power_init(void)
 {
@@ -139,12 +143,12 @@ errcode_t zhihui_ppp_init(const ppp_config_t *config)
 
     ppp_api_power_init();
 
-    ppp_api_power_control(true);
 #define PPP_SERIAL_INIT 1 //外接串口调试模组时,串口要设置input防止干扰。
 #if PPP_SERIAL_INIT
     
+
     // 3. UART初始化
-    PPP_DEBUG_PRINT("Step 3: Initializing UART for AT mode\n");
+    PPP_DEBUG_PRINT("Step 3: Initializing UART for AT mode baudrate: %d\n", g_ppp_config.baudrate);
     ppp_serial_config_t serial_config = {
         .uart_bus = SIO_UART_BUS,
         .irq_num = SIO_UART_IRQ_NUM,
@@ -163,7 +167,7 @@ errcode_t zhihui_ppp_init(const ppp_config_t *config)
     }
 
     // 初始化AT命令处理器
-    ret = ppp_at_handler_init(SIO_UART_BUS);
+    ret = ppp_at_handler_init(SIO_UART_BUS, g_ppp_config.baudrate, true);
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_PRINT("Failed to initialize AT handler: %d\n", ret);
         ppp_serial_deinit();
@@ -179,42 +183,25 @@ errcode_t zhihui_ppp_init(const ppp_config_t *config)
     } else {
         PPP_DEBUG_PRINT("Successfully switched to AT mode\n");
     }
-    
-    // 下达AT指令看是否成功
-    ret = ppp_at_test_communication();
-    if (ret != PPP_ERR_OK) {
-        PPP_DEBUG_PRINT("AT communication test failed: %d\n", ret);
-        
-         // 4. 串口波特率确认
-        PPP_DEBUG_PRINT("Step 4: Confirming UART baudrate\n");
-        if (g_ppp_config.auto_baudrate) {
-            ret = ppp_at_baudrate_handshake();
-            if (ret != PPP_ERR_OK) {
-                PPP_DEBUG_PRINT("Baudrate handshake failed: %d\n", ret);
-                ppp_at_handler_deinit();
-                ppp_serial_deinit();
-                goto init_failed;
-            }
-            PPP_DEBUG_PRINT("Baudrate handshake completed successfully\n");
-        }else{
-            PPP_DEBUG_PRINT("Baudrate handshake completed successfully\n");
-            ppp_at_handler_deinit();
-            ppp_serial_deinit();
-            goto init_failed;
-        }
-    } else {
-        PPP_DEBUG_PRINT("AT communication test succeeded\n");
-    }
 #else
     ppp_api_leiniao_serial_pin_to_gpio_input();
 #endif
-    PPP_DEBUG_PRINT("Waiting for modem stabilization after power control...\n");
-    // 额外等待时间,让调制解调器完全稳定(特别是在硬件复位后)
-    osal_msleep(5000);  // 等待5秒让调制解调器完全稳定
-    
+
     g_ppp_state = PPP_STATE_INITIALIZED;
     
     PPP_DEBUG_PRINT("PPP module initialized successfully\n");
+    
+    // 打开4G电源
+    ppp_api_power_control(true);
+    PPP_DEBUG_PRINT("Waiting for modem stabilization after power control...\n");
+    // 等待5秒让调制解调器完全稳定
+    osal_msleep(5000);
+
+    ppp_check_at_communication_and_baudrate();
+
+    ppp_api_update_all_runtime_status();
+    
+    ppp_get_network_signal_info();
 
     return ERRCODE_SUCC;
 #if PPP_SERIAL_INIT
@@ -224,6 +211,66 @@ init_failed:
     // ppp_api_power_control(false);
     return ERRCODE_FAIL;
 }
+void set_at_communication_and_baudrate_flag(bool flag)
+{
+    g_at_communication_and_baudrate_flag = flag;
+}
+bool get_at_communication_and_baudrate_flag(void)
+{
+    return g_at_communication_and_baudrate_flag;
+}
+void ppp_check_at_communication_and_baudrate(void)
+{
+
+    // 用串口读函数读取串口数据,直到没有数据读出,并打印读出来的数据
+    // uint8_t buf[64]={0};
+    // int read_len = 0;
+    // uint32_t start_time = osal_get_jiffies();
+    // do {
+    //     read_len = ppp_serial_read(buf, sizeof(buf), 0); // 0表示非阻塞或超时为0
+    //     if (read_len > 0) {
+    //         // 打印读出来的数据
+    //         PPP_DEBUG_PRINT("Read %d bytes from serial: ", read_len);
+    //         for (int i = 0; i < read_len; ++i) {
+    //             PPP_DEBUG_PRINT("%02X ", buf[i]);
+    //         }
+    //         PPP_DEBUG_PRINT("\n");
+    //         osal_msleep(100);
+    //     }
+    //     if (osal_get_jiffies() - start_time > 2000) {
+    //         break;
+    //     }
+    // } while (read_len > 0);
+    // 下达AT指令看是否成功
+    ppp_error_t ret = ppp_at_test_communication();
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_PRINT("AT communication test failed: %d\n", ret);
+        ret = ppp_at_test_communication();
+        if(ret != PPP_ERR_OK) {
+            // 4. 串口波特率确认
+            PPP_DEBUG_PRINT("Step 4: Confirming UART baudrate\n");
+            if (g_ppp_config.auto_baudrate) {
+                ret = ppp_at_baudrate_handshake();
+                if (ret != PPP_ERR_OK) {
+                    PPP_DEBUG_PRINT("Baudrate handshake failed: %d\n", ret);
+                    goto init_failed;
+                }
+                PPP_DEBUG_PRINT("Baudrate handshake completed successfully\n");
+            }else{
+                PPP_DEBUG_PRINT("Baudrate handshake completed successfully\n");
+                goto init_failed;
+            }
+        }
+    } else {
+        PPP_DEBUG_PRINT("AT communication test succeeded\n");
+    }
+    set_at_communication_and_baudrate_flag(true);
+    return ;
+init_failed:
+    set_at_communication_and_baudrate_flag(false);
+}
+
+
 
 static void ppp_lwip_event_callback(const ppp_lwip_event_t *event, void *arg)
 {
@@ -437,7 +484,7 @@ error_recovery_at_mode:
     
     // 6. 重新初始化AT处理器
     PPP_DEBUG_INFO("Reinitializing AT handler...");
-    ret = ppp_at_handler_init(SIO_UART_BUS);  // 使用UART bus 0
+    ret = ppp_at_handler_init(SIO_UART_BUS, g_ppp_config.baudrate, true);  // 使用UART bus 0
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_ERROR("Failed to reinitialize AT handler: %d", ret);
         return ERRCODE_FAIL;
@@ -600,7 +647,7 @@ errcode_t ppp_stop_dial(void)
     
     // 6. 重新初始化AT处理器
     PPP_DEBUG_INFO("Reinitializing AT handler...");
-    ret = ppp_at_handler_init(SIO_UART_BUS);  // 使用UART bus 0
+    ret = ppp_at_handler_init(SIO_UART_BUS, g_ppp_config.baudrate, true);  // 使用UART bus 0
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_ERROR("Failed to reinitialize AT handler: %d", ret);
         return ret;
@@ -747,43 +794,6 @@ errcode_t ppp_get_connection_info(ppp_connection_info_t *info)
     return ERRCODE_SUCC;
 }
 
-/**
- * @brief PPP状态重置(从错误状态恢复)
- */
-errcode_t ppp_reset_from_error(void)
-{
-    if (g_ppp_state != PPP_STATE_ERROR) {
-        PPP_DEBUG_PRINT("PPP reset: not in error state, current state: %d\n", g_ppp_state);
-        return ERRCODE_SUCC;
-    }
-
-    PPP_DEBUG_PRINT("Resetting PPP from error state\n");
-
-    // 1. 停止所有可能的活动
-    ppp_lwip_stop_receive_thread();
-    ppp_lwip_deinit();
-
-    // 2. 尝试恢复到AT模式
-    ppp_error_t ret = ppp_serial_switch_to_at_mode();
-    if (ret == PPP_ERR_OK) {
-        // 3. 重新初始化AT处理器
-        ret = ppp_at_handler_init(SIO_UART_BUS);
-        if (ret == PPP_ERR_OK) {
-            g_ppp_state = PPP_STATE_INITIALIZED;
-            PPP_DEBUG_PRINT("PPP successfully reset to INITIALIZED state\n");
-            return ERRCODE_SUCC;
-        } else {
-            PPP_DEBUG_ERROR("Failed to reinitialize AT handler during reset\n");
-        }
-    } else {
-        PPP_DEBUG_ERROR("Failed to switch to AT mode during reset\n");
-    }
-
-    // 如果恢复失败,保持错误状态
-    PPP_DEBUG_ERROR("PPP reset failed, remains in error state\n");
-    return ERRCODE_FAIL;
-}
-
 /**
  * @brief PPP模块去初始化
  */
@@ -823,32 +833,12 @@ errcode_t zhihui_ppp_deinit(void)
 
 /* ========== PPP测试接口实现 ========== */
 
-/**
- * @brief PPP串口模式切换
- */
-errcode_t ppp_test_switch_mode(const char *mode)
-{
-    if (mode == NULL) {
-        return ERRCODE_INVALID_PARAM;
-    }
-    
-    ppp_error_t ret;
-    if (strcmp(mode, "AT") == 0) {
-        ret = ppp_serial_switch_to_at_mode();
-    } else if (strcmp(mode, "PPP") == 0) {
-        ret = ppp_serial_switch_to_ppp_mode();
-    } else {
-        return ERRCODE_INVALID_PARAM;
-    }
-    
-    return (ret == PPP_ERR_OK) ? ERRCODE_SUCC : ERRCODE_FAIL;
-}
 
 
 /**
  * @brief 执行AT指令透传
  */
-errcode_t ppp_test_execute_at_command(const char *at_command,
+errcode_t ppp_execute_at_command(const char *at_command,
                                      char *response,
                                      uint32_t response_size,
                                      uint32_t *response_len,
@@ -883,14 +873,7 @@ errcode_t ppp_test_execute_at_command(const char *at_command,
     }
 }
 
-/**
- * @brief PPP串口基础功能测试
- */
-errcode_t ppp_test_uart_function(void)
-{
-    ppp_error_t ret = ppp_serial_test_uart();
-    return (ret == PPP_ERR_OK) ? ERRCODE_SUCC : ERRCODE_FAIL;
-}
+
 
 /**
  * @brief PPP智能flush测试
@@ -1179,7 +1162,7 @@ static errcode_t ppp_parse_network_status_response(const char *response, uint8_t
 errcode_t ppp_api_update_imei(void)
 {
     // 检查是否在AT模式
-    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT) {
+    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT || !get_at_communication_and_baudrate_flag()) {
         PPP_DEBUG_WARN("Cannot update IMEI: not in AT mode (current mode: %d)", ppp_serial_get_mode());
         return ERRCODE_FAIL;
     }
@@ -1194,7 +1177,7 @@ errcode_t ppp_api_update_imei(void)
     char imei_temp[32] = {0};
     
     // 使用现有的AT命令执行接口
-    errcode_t ret = ppp_test_execute_at_command("AT+CGSN", response, 512, &response_len, 1000);
+    errcode_t ret = ppp_execute_at_command("AT+CGSN", response, 512, &response_len, 1000);
     if (ret != ERRCODE_SUCC) {
         PPP_DEBUG_ERROR("Failed to send AT+CGSN command");
         free(response);
@@ -1223,7 +1206,7 @@ errcode_t ppp_api_update_imei(void)
 errcode_t ppp_api_update_signal(void)
 {
     // 检查是否在AT模式
-    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT) {
+    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT || !get_at_communication_and_baudrate_flag()) {
         PPP_DEBUG_WARN("Cannot update signal: not in AT mode (current mode: %d)", ppp_serial_get_mode());
         return ERRCODE_FAIL;
     }
@@ -1238,7 +1221,7 @@ errcode_t ppp_api_update_signal(void)
     int signal = 99; // 默认无信号
     
     // 使用现有的AT命令执行接口
-    errcode_t ret = ppp_test_execute_at_command("AT+CSQ", response, 512, &response_len, 1000);
+    errcode_t ret = ppp_execute_at_command("AT+CSQ", response, 512, &response_len, 1000);
     if (ret != ERRCODE_SUCC) {
         PPP_DEBUG_ERROR("Failed to send AT+CSQ command");
         free(response);
@@ -1267,7 +1250,7 @@ errcode_t ppp_api_update_signal(void)
 errcode_t ppp_api_update_operator(void)
 {
     // 检查是否在AT模式
-    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT) {
+    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT || !get_at_communication_and_baudrate_flag()) {
         PPP_DEBUG_WARN("Cannot update operator: not in AT mode (current mode: %d)", ppp_serial_get_mode());
         return ERRCODE_FAIL;
     }
@@ -1282,7 +1265,7 @@ errcode_t ppp_api_update_operator(void)
     char operator_temp[64] = {0};
     
     // 使用现有的AT命令执行接口
-    errcode_t ret = ppp_test_execute_at_command("AT+COPS?", response, 512, &response_len, 10000);
+    errcode_t ret = ppp_execute_at_command("AT+COPS?", response, 512, &response_len, 10000);
     if (ret != ERRCODE_SUCC) {
         PPP_DEBUG_ERROR("Failed to send AT+COPS command");
         free(response);
@@ -1311,7 +1294,7 @@ errcode_t ppp_api_update_operator(void)
 errcode_t ppp_api_update_iccid(void)
 {
     // 检查是否在AT模式
-    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT) {
+    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT || !get_at_communication_and_baudrate_flag()) {
         PPP_DEBUG_WARN("Cannot update ICCID: not in AT mode (current mode: %d)", ppp_serial_get_mode());
         return ERRCODE_FAIL;
     }
@@ -1326,7 +1309,7 @@ errcode_t ppp_api_update_iccid(void)
     char iccid_temp[32] = {0};
     
     // 使用现有的AT命令执行接口
-    errcode_t ret = ppp_test_execute_at_command("AT+CCID", response, 512, &response_len, 5000);
+    errcode_t ret = ppp_execute_at_command("AT+CCID", response, 512, &response_len, 5000);
     if (ret != ERRCODE_SUCC) {
         PPP_DEBUG_ERROR("Failed to send AT+CCID command");
         free(response);
@@ -1355,7 +1338,7 @@ errcode_t ppp_api_update_iccid(void)
 errcode_t ppp_api_update_version(void)
 {
     // 检查是否在AT模式
-    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT) {
+    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT || !get_at_communication_and_baudrate_flag()) {
         PPP_DEBUG_WARN("Cannot update version: not in AT mode (current mode: %d)", ppp_serial_get_mode());
         return ERRCODE_FAIL;
     }
@@ -1370,7 +1353,7 @@ errcode_t ppp_api_update_version(void)
     char version_temp[64] = {0};
     
     // 使用现有的AT命令执行接口
-    errcode_t ret = ppp_test_execute_at_command("AT+GMR", response, 512, &response_len, 5000);
+    errcode_t ret = ppp_execute_at_command("AT+GMR", response, 512, &response_len, 5000);
     if (ret != ERRCODE_SUCC) {
         PPP_DEBUG_ERROR("Failed to send AT+GMR command");
         free(response);
@@ -1399,7 +1382,7 @@ errcode_t ppp_api_update_version(void)
 errcode_t ppp_api_update_network_status(void)
 {
     // 检查是否在AT模式
-    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT) {
+    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT || !get_at_communication_and_baudrate_flag()) {
         PPP_DEBUG_WARN("Cannot update network status: not in AT mode (current mode: %d)", ppp_serial_get_mode());
         return ERRCODE_FAIL;
     }
@@ -1415,7 +1398,7 @@ errcode_t ppp_api_update_network_status(void)
     errcode_t ret;
     
     // 先尝试AT+CREG
-    ret = ppp_test_execute_at_command("AT+CREG?", response, 512, &response_len, 5000);
+    ret = ppp_execute_at_command("AT+CREG?", response, 512, &response_len, 5000);
     if (ret == ERRCODE_SUCC) {
         ret = ppp_parse_network_status_response(response, &network_status);
         if (ret == ERRCODE_SUCC) {
@@ -1430,7 +1413,7 @@ errcode_t ppp_api_update_network_status(void)
     }
     
     // 如果CREG失败,尝试AT+CEREG
-    ret = ppp_test_execute_at_command("AT+CEREG?", response, 512, &response_len, 5000);
+    ret = ppp_execute_at_command("AT+CEREG?", response, 512, &response_len, 5000);
     if (ret != ERRCODE_SUCC) {
         PPP_DEBUG_ERROR("Failed to send AT+CEREG command");
         free(response);
@@ -1461,7 +1444,7 @@ errcode_t ppp_api_update_network_status(void)
 errcode_t ppp_api_update_sim_status(void)
 {
     // 检查是否在AT模式
-    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT) {
+    if (ppp_serial_get_mode() != PPP_SERIAL_MODE_AT || !get_at_communication_and_baudrate_flag()) {
         PPP_DEBUG_WARN("Cannot update SIM status: not in AT mode (current mode: %d)", ppp_serial_get_mode());
         return ERRCODE_FAIL;
     }
@@ -1475,7 +1458,7 @@ errcode_t ppp_api_update_sim_status(void)
     uint32_t response_len;
     
     // 通过AT+CCID命令检查SIM卡状态
-    errcode_t ret = ppp_test_execute_at_command("AT+CCID", response, 512, &response_len, 1000);
+    errcode_t ret = ppp_execute_at_command("AT+CCID", response, 512, &response_len, 1000);
     if (ret != ERRCODE_SUCC) {
         // 如果CCID命令失败,说明SIM卡可能未插入或有问题
         cat1_api_runtime_set_cat1_simstat(0); // 0表示SIM卡异常
index a87db52..d0fffdb 100644 (file)
@@ -37,7 +37,7 @@ static ppp_error_t ppp_at_wait_response(ppp_at_response_t *response, uint32_t ti
 /**
  * @brief 初始化AT命令处理模块
  */
-ppp_error_t ppp_at_handler_init(uint8_t uart_bus)
+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");
@@ -45,8 +45,8 @@ ppp_error_t ppp_at_handler_init(uint8_t uart_bus)
     }
 
     g_at_ctx.uart_bus = uart_bus;
-    g_at_ctx.current_baudrate = PPP_UART_BAUDRATE;
-    g_at_ctx.auto_baudrate_mode = true;
+    g_at_ctx.current_baudrate = current_baudrate;
+    g_at_ctx.auto_baudrate_mode = auto_baudrate_mode;
 
     /* 创建互斥锁 */
     if (osal_mutex_init(&g_at_ctx.at_mutex) != OSAL_SUCCESS) {
@@ -142,37 +142,31 @@ ppp_error_t ppp_at_baudrate_handshake(void)
 
         // 3次重试AT
         ppp_error_t ret = PPP_ERR_AT_FAILED;
-        for (int retry = 0; retry < 3; retry++) {
+        for (int retry = 0; retry < 2; retry++) {
             PPP_DEBUG_DEBUG("--- AT Test at %u baud, retry %d/3 ---", baudrate, retry + 1);
 
             // 再次清空缓冲区,防止上次残留
             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", 3000, &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
-                char ipr_cmd[32];
-                snprintf_s(ipr_cmd, sizeof(ipr_cmd), sizeof(ipr_cmd) - 1, "AT+IPR=1000000");
-                PPP_DEBUG_DEBUG("Setting module baudrate to 1000000 with: %s", ipr_cmd);
-
-                ppp_at_response_t ipr_response;
-                ppp_error_t ipr_ret = ppp_at_send_command(ipr_cmd, "OK", 3000, &ipr_response);
-                if (ipr_ret != PPP_ERR_OK) {
-                    PPP_DEBUG_ERROR("Failed to set module baudrate to 1000000 (AT+IPR)");
-                    return PPP_ERR_AT_FAILED;
-                }
-
                 ppp_at_set_baudrate(PPP_UART_BAUDRATE);
 
                 // 再次reset模组,让其自动工作在1000000波特率下
-                PPP_DEBUG_DEBUG("Resetting module again to switch to 1000000 baudrate...");
+                PPP_DEBUG_DEBUG("Resetting module again to switch to baudrate %d...",PPP_UART_BAUDRATE);
                 ppp_power_reset_cat1();               
                 osal_msleep(5000);
-                PPP_DEBUG_INFO("Baudrate handshake successful, now at 1000000 baud");
+                ret = ppp_at_send_command("AT", "OK", 1000, &response);
+                if(ret != PPP_ERR_OK) {
+                    PPP_DEBUG_INFO("Baudrate handshake failed, now at %d baud",PPP_UART_BAUDRATE);
+                }else{
+                    PPP_DEBUG_INFO("Baudrate handshake successful, now at %d baud",PPP_UART_BAUDRATE);
+                }
                 return PPP_ERR_OK;
             } else {
                 PPP_DEBUG_WARN("AT command failed at baudrate %u, retry %d/3 (error: %d)", baudrate, retry + 1, ret);
@@ -263,9 +257,25 @@ ppp_error_t ppp_at_send_command(const char *command, const char *expected_respon
         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();
-    osal_mutex_lock(&g_at_ctx.at_mutex);
+    
+    /* 使用带超时的互斥锁获取,防止永久阻塞 */
+    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));
 
@@ -485,6 +495,13 @@ ppp_error_t ppp_at_complete_dial_sequence(const char *apn)
         PPP_DEBUG_INFO("Echo disabled successfully");
     }
     
+    ret = ppp_at_send_command("AT+NVETOSUPERDS=A,1", "OK", 5000, &response);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("Failed to disable echo - this is critical for PPP");
+        return ret;  // 改为致命错误,必须成功
+    } else {
+        PPP_DEBUG_INFO("Echo disabled successfully");
+    }
    
    // 发送一个简单的AT命令确认调制解调器状态
     ret = ppp_at_send_command("AT", "OK", 3000, &response);
@@ -586,7 +603,7 @@ ppp_error_t ppp_at_complete_dial_sequence(const char *apn)
             
             // 再次拨号
             PPP_DEBUG_INFO("Re-dialing to ensure proper PPP mode...");
-            ret = ppp_at_send_command("ATD*99***2#", "CONNECT", 30000, &response);
+            ret = ppp_at_send_command("ATD*99***2#", "CONNECT", 5000, &response);
             if (ret != PPP_ERR_OK) {
                 PPP_DEBUG_ERROR("Re-dial failed");
                 return ret;
@@ -712,7 +729,7 @@ ppp_error_t ppp_at_test_communication(void)
     ppp_at_response_t response;
     
     // 发送简单的AT命令测试通信
-    ppp_error_t ret = ppp_at_send_command("AT", "OK", 3000, &response);
+    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 {
@@ -724,6 +741,56 @@ ppp_error_t ppp_at_test_communication(void)
 
 /* 内部函数实现 */
 
+/**
+ * @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终止符 */
+    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命令响应
  */
@@ -767,11 +834,16 @@ static ppp_error_t ppp_at_wait_response(ppp_at_response_t *response, uint32_t ti
     bool has_data = false;
     uint32_t read_attempts = 0;
     
+    /* 防止卡死的安全措施 */
+    const uint32_t MAX_READ_ATTEMPTS = 1000;  // 最大尝试次数
+    const uint32_t ABSOLUTE_TIMEOUT_MS = timeout + 5000;  // 绝对超时时间(比预期超时多5秒)
+    const uint32_t UART_READ_TIMEOUT_MS = 50;  // UART读取超时
+    
     /* 清空全局缓存 */
     memset(g_at_response_buffer, 0, g_at_buffer_size);
     
-    PPP_DEBUG_CRITICAL("WAIT_RESPONSE: Starting direct UART read (timeout: %u ms, buffer_size: %u)", 
-                      timeout, g_at_buffer_size);
+    PPP_DEBUG_CRITICAL("WAIT_RESPONSE: Starting direct UART read (timeout: %u ms, absolute_timeout: %u ms, buffer_size: %u)", 
+                      timeout, ABSOLUTE_TIMEOUT_MS, g_at_buffer_size);
     
     /* 循环读取直到找到响应结论或超时 */
     while (!response_complete) {
@@ -785,9 +857,33 @@ static ppp_error_t ppp_at_wait_response(ppp_at_response_t *response, uint32_t ti
                               read_attempts, elapsed, has_data, bytes_received);
         }
         
-        /* 检查超时条件:如果没有数据且达到超时时间,退出 */
+        /* 绝对超时检查 - 防止无限循环 */
+        if (elapsed >= ABSOLUTE_TIMEOUT_MS) {
+            PPP_DEBUG_ERROR("WAIT_RESPONSE: ABSOLUTE TIMEOUT - forced exit after %u ms (attempts: %u)", 
+                           elapsed, read_attempts);
+            PPP_DEBUG_ERROR("WAIT_RESPONSE: This prevents system hang, but indicates a serious problem");
+            break;
+        }
+        
+        /* 最大尝试次数检查 - 防止无限循环 */
+        if (read_attempts >= MAX_READ_ATTEMPTS) {
+            PPP_DEBUG_ERROR("WAIT_RESPONSE: MAX ATTEMPTS REACHED - forced exit after %u attempts (elapsed: %u ms)", 
+                           read_attempts, elapsed);
+            PPP_DEBUG_ERROR("WAIT_RESPONSE: This prevents system hang, but indicates a serious problem");
+            break;
+        }
+        
+        /* 正常超时条件:如果没有数据且达到预期超时时间,退出 */
         if (!has_data && elapsed >= timeout) {
-            PPP_DEBUG_CRITICAL("WAIT_RESPONSE: TIMEOUT - no data received after %u ms (attempts: %u)", elapsed, read_attempts);
+            PPP_DEBUG_CRITICAL("WAIT_RESPONSE: NORMAL TIMEOUT - no data received after %u ms (attempts: %u)", 
+                              elapsed, read_attempts);
+            break;
+        }
+        
+        /* 如果已有数据但超过预期超时时间很多,也要退出 */
+        if (has_data && elapsed >= (timeout + 2000)) {
+            PPP_DEBUG_WARN("WAIT_RESPONSE: EXTENDED TIMEOUT - has data but taking too long (%u ms, attempts: %u)", 
+                          elapsed, read_attempts);
             break;
         }
         
@@ -798,7 +894,7 @@ static ppp_error_t ppp_at_wait_response(ppp_at_response_t *response, uint32_t ti
         int32_t ret = uapi_uart_read(g_at_ctx.uart_bus, 
                                     g_at_response_buffer + bytes_received, 
                                     g_at_buffer_size - bytes_received - 1, 
-                                    50);  /* 50ms读取超时 */
+                                    UART_READ_TIMEOUT_MS);
         
         uint32_t uart_read_end = (uint32_t)osal_get_jiffies();
         uint32_t uart_read_time = osal_jiffies_to_msecs(uart_read_end - uart_read_start);
@@ -809,6 +905,15 @@ static ppp_error_t ppp_at_wait_response(ppp_at_response_t *response, uint32_t ti
         if (ret > 0) {
             has_data = true;
             bytes_received += (uint32_t)ret;
+            
+            /* 防止缓冲区溢出 */
+            if (bytes_received >= g_at_buffer_size - 1) {
+                PPP_DEBUG_ERROR("WAIT_RESPONSE: Buffer overflow protection - truncating at %u bytes", bytes_received);
+                bytes_received = g_at_buffer_size - 1;
+                g_at_response_buffer[bytes_received] = '\0';
+                break;
+            }
+            
             g_at_response_buffer[bytes_received] = '\0';
             
             PPP_DEBUG_CRITICAL("WAIT_RESPONSE: Read %d bytes, total: %u bytes", ret, bytes_received);
@@ -816,82 +921,50 @@ static ppp_error_t ppp_at_wait_response(ppp_at_response_t *response, uint32_t ti
             
             /* 打印接收到的原始数据(十六进制) */
             PPP_DEBUG_DEBUG("WAIT_RESPONSE: Raw data received:");
-            for (int i = bytes_received - ret; i < bytes_received; i++) {
+            for (int i = bytes_received - ret; i < (int)bytes_received; i++) {
                 PPP_DEBUG_PRINT("%02X ", g_at_response_buffer[i]);
+                if ((i + 1) % 16 == 0) PPP_DEBUG_PRINT("\n");
             }
-            PPP_DEBUG_PRINT("\n");
+            if (ret % 16 != 0) PPP_DEBUG_PRINT("\n");
             
-            /* 检查缓存中是否有需要检测的结论 */
-            PPP_DEBUG_DEBUG("WAIT_RESPONSE: Checking for terminators...");
-            bool found_terminator = false;
-            
-            /* 搜索OK终止符 */
-            PPP_DEBUG_DEBUG("WAIT_RESPONSE: Searching for OK terminator...");
-            for (uint32_t i = 0; i <= bytes_received - 2; i++) {
-                if (g_at_response_buffer[i] == 'O' && g_at_response_buffer[i+1] == 'K') {
-                    /* 检查OK前面是否有换行符(避免误匹配) */
-                    if (i == 0 || g_at_response_buffer[i-1] == '\n' || g_at_response_buffer[i-1] == '\r') {
-                        PPP_DEBUG_CRITICAL("WAIT_RESPONSE: Found OK terminator at position %u", i);
-                        found_terminator = true;
-                        response_complete = true;
-                        break;
-                    }
-                }
+            /* 检查是否收到完整响应 */
+            if (ppp_at_check_response_complete((char*)g_at_response_buffer, bytes_received)) {
+                PPP_DEBUG_CRITICAL("WAIT_RESPONSE: Complete response detected");
+                response_complete = true;
             }
             
-            /* 搜索ERROR终止符 */
-            if (!found_terminator && bytes_received >= 5) {
-                PPP_DEBUG_DEBUG("WAIT_RESPONSE: Searching for ERROR terminator...");
-                for (uint32_t i = 0; i <= bytes_received - 5; i++) {
-                    if (strncmp((char*)&g_at_response_buffer[i], "ERROR", 5) == 0) {
-                        /* 检查ERROR前面是否有换行符 */
-                        if (i == 0 || g_at_response_buffer[i-1] == '\n' || g_at_response_buffer[i-1] == '\r') {
-                            PPP_DEBUG_CRITICAL("WAIT_RESPONSE: Found ERROR terminator at position %u", i);
-                            found_terminator = true;
-                            response_complete = true;
-                            break;
-                        }
-                    }
-                }
-            }
+            /* 重置超时计时器,因为我们收到了数据 */
+            start_time = current_time;
             
-            /* 检查其他终止符 */
-            if (!found_terminator) {
-                PPP_DEBUG_DEBUG("WAIT_RESPONSE: Searching for other terminators...");
-                char *buffer_str = (char*)g_at_response_buffer;
-                if (strstr(buffer_str, "CONNECT") ||
-                    strstr(buffer_str, "NO CARRIER") ||
-                    strstr(buffer_str, "BUSY") ||
-                    strstr(buffer_str, "NO DIALTONE")) {
-                    PPP_DEBUG_CRITICAL("WAIT_RESPONSE: Found other terminator in response");
-                    found_terminator = true;
-                    response_complete = true;
-                }
-            }
+        } else if (ret == 0) {
+            /* 没有数据,继续等待 */
+            PPP_DEBUG_DEBUG("WAIT_RESPONSE: No data available, continuing...");
             
-            /* 检查缓存是否已满 */
-            if (bytes_received >= g_at_buffer_size - 1) {
-                PPP_DEBUG_WARN("AT response buffer full, stopping read");
-                response_complete = true;
-            }
+            /* 短暂延迟以避免CPU占用过高 */
+            osal_msleep(10);
             
-        } else if (ret == 0) {
-            /* 没有读到数据 */
-            if (has_data) {
-                /* 已经有数据了,继续尝试读取更多数据,但不受严格超时限制 */
-                PPP_DEBUG_DEBUG("No new data, but continuing due to existing data");
-                osal_msleep(10);  /* 短暂延时后继续 */
-            } else {
-                /* 还没有任何数据,检查是否超时 */
-                if (elapsed >= timeout) {
-                    PPP_DEBUG_WARN("No data received within timeout");
-                    break;
+        } else {
+            /* UART读取错误 */
+            PPP_DEBUG_ERROR("WAIT_RESPONSE: UART read error: %d", ret);
+            
+            /* UART错误时短暂延迟后继续,但不重置超时 */
+            osal_msleep(50);
+        }
+        
+        /* 检查是否收到了足够的数据但没有完整响应标志 */
+        if (has_data && bytes_received > 0) {
+            /* 如果收到数据但等待时间过长,可能需要强制结束 */
+            uint32_t data_wait_time = osal_jiffies_to_msecs(current_time - start_time);
+            if (data_wait_time > 1000) {  // 收到数据后等待1秒仍无完整响应
+                PPP_DEBUG_WARN("WAIT_RESPONSE: Long wait after receiving data (%u ms), checking for partial response", 
+                              data_wait_time);
+                
+                /* 检查是否至少包含一些有用的响应内容 */
+                if (bytes_received >= 2) {  // 至少有一些内容
+                    PPP_DEBUG_WARN("WAIT_RESPONSE: Accepting partial response to prevent hang");
+                    response_complete = true;
                 }
-                osal_msleep(10);  /* 短暂延时后继续 */
             }
-        } else {
-            PPP_DEBUG_ERROR("UART read error: %d", ret);
-            break;
         }
     }
     
@@ -979,7 +1052,11 @@ ppp_error_t ppp_at_get_network_signal_info(ppp_network_signal_info_t *info)
     if (!g_at_ctx.initialized || !info) {
         return PPP_ERR_INVALID_PARAM;
     }
-
+    if(!get_at_communication_and_baudrate_flag())
+    {
+        PPP_DEBUG_ERROR("AT communication and baudrate failed");
+        return PPP_ERR_AT_FAILED;
+    }
     PPP_DEBUG_INFO("Getting network signal information (AT+CESQ)...");
 
     ppp_at_response_t response;
index 4aa5640..2dfd779 100644 (file)
@@ -80,6 +80,8 @@ typedef struct {
     uint8_t cat1_network_type;
     int sim;
     int signal;
+    int rsrp;
+    int rsrq;
     char opera[64];
     char imei[32];
     char pyVer[32];
@@ -87,6 +89,11 @@ typedef struct {
     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};
 
index 28d78b9..619b358 100644 (file)
@@ -48,6 +48,21 @@ static ppp_lwip_context_t g_lwip_ctx = {0};
 static bool g_ppp_monitor_enabled = false;
 static uint32_t g_last_data_activity_time = 0;
 static uint32_t g_connection_idle_timeout = 60000; /* 60秒无数据活动后检查连接 */
+
+/* PPP输出统计结构 */
+typedef struct {
+    uint64_t total_packets;          // 总输出包数
+    uint64_t total_bytes;            // 总输出字节数
+    uint32_t lcp_packets;            // LCP包数
+    uint32_t ipcp_packets;           // IPCP包数
+    uint32_t ip_packets;             // IP包数
+    uint32_t other_packets;          // 其他协议包数
+    uint32_t failed_sends;           // 发送失败次数
+    uint32_t start_time;             // 统计开始时间
+    uint32_t last_packet_time;       // 最后一个包的时间
+} ppp_output_stats_t;
+
+static ppp_output_stats_t g_ppp_output_stats = {0};
 /* 内部函数声明 */
 static u32_t ppp_lwip_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx);
 static void ppp_lwip_link_status_callback(ppp_pcb *pcb, int err_code, void *ctx);
@@ -61,6 +76,8 @@ static void ppp_lwip_stop_connection_monitor(void);
 
 /* 函数前向声明 */
 static void ppp_lwip_print_mru_status(void);
+static void ppp_lwip_reset_output_stats(void);
+static void ppp_lwip_update_output_stats(uint16_t protocol, uint32_t bytes, bool success);
 
 /**
  * @brief 记录数据活动时间
@@ -334,6 +351,10 @@ ppp_error_t ppp_lwip_init(const ppp_lwip_config_t *config)
     g_lwip_ctx.event_callback_arg = config->event_callback_arg;
 
     g_lwip_ctx.initialized = true;
+    
+    /* 重置输出统计 */
+    ppp_lwip_reset_output_stats();
+    
     PPP_DEBUG_INFO("PPP lwIP integration initialized");
 
     return PPP_ERR_OK;
@@ -920,6 +941,21 @@ static u32_t ppp_lwip_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void
     /* 记录数据活动 */
     ppp_lwip_record_data_activity();
 
+    /* 解析协议类型用于统计 */
+    uint16_t protocol = 0;
+    if (len >= 4) {
+        uint32_t offset = 0;
+        if (data[0] == 0x7E) {
+            offset = 1;
+        }
+        if (offset + 3 < len && data[offset] == 0xFF && data[offset + 1] == 0x03) {
+            offset += 2;
+            if (offset + 1 < len) {
+                protocol = (data[offset] << 8) | data[offset + 1];
+            }
+        }
+    }
+
     /* 发送PPP协议输出日志 */
     PPP_DEBUG_PRINT("=== PPP Protocol Output ===\n");
     PPP_DEBUG_PRINT("PPP TX: %u bytes\n", len);
@@ -1015,10 +1051,17 @@ static u32_t ppp_lwip_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_ERROR("Failed to send PPP data via custom serial: %d", ret);
         PPP_DEBUG_PRINT("=== PPP Output FAILED ===\n");
+        
+        /* 更新失败统计 */
+        ppp_lwip_update_output_stats(protocol, len, false);
         return 0;
     }
 
     PPP_DEBUG_PRINT("=== PPP Output SUCCESS ===\n");
+    
+    /* 更新成功统计 */
+    ppp_lwip_update_output_stats(protocol, len, true);
+    
     return len;
 }
 
@@ -1209,5 +1252,62 @@ void ppp_lwip_print_mru_status(void)
     }
 }
 
+/**
+ * @brief 重置PPP输出统计
+ */
+static void ppp_lwip_reset_output_stats(void)
+{
+    memset_s(&g_ppp_output_stats, sizeof(g_ppp_output_stats), 0, sizeof(g_ppp_output_stats));
+    g_ppp_output_stats.start_time = ppp_lwip_get_time_ms();
+}
+
+/**
+ * @brief 更新PPP输出统计
+ * @param protocol PPP协议类型
+ * @param bytes 字节数
+ * @param success 是否发送成功
+ */
+static void ppp_lwip_update_output_stats(uint16_t protocol, uint32_t bytes, bool success)
+{
+    if (success) {
+        g_ppp_output_stats.total_packets++;
+        g_ppp_output_stats.total_bytes += bytes;
+        g_ppp_output_stats.last_packet_time = ppp_lwip_get_time_ms();
+        
+        // 根据协议类型更新计数
+        switch (protocol) {
+            case 0xC021:  // LCP
+                g_ppp_output_stats.lcp_packets++;
+                break;
+            case 0x8021:  // IPCP
+                g_ppp_output_stats.ipcp_packets++;
+                break;
+            case 0x0021:  // IP
+                g_ppp_output_stats.ip_packets++;
+                break;
+            default:
+                g_ppp_output_stats.other_packets++;
+                break;
+        }
+    } else {
+        g_ppp_output_stats.failed_sends++;
+    }
+}
+
+/**
+ * @brief 获取PPP输出统计信息
+ * @param stats 统计信息结构指针
+ * @return PPP_ERR_OK 成功,其他值失败
+ */
+ppp_error_t ppp_lwip_get_output_stats(ppp_lwip_output_stats_t *stats)
+{
+    if (!stats) {
+        return PPP_ERR_INVALID_PARAM;
+    }
+    
+    memcpy_s(stats, sizeof(ppp_lwip_output_stats_t), &g_ppp_output_stats, sizeof(ppp_output_stats_t));
+    return PPP_ERR_OK;
+}
+
 
 #endif /* LWIP_PPP_SUPPORT */ 
\ No newline at end of file
index 804d179..822706a 100644 (file)
@@ -94,9 +94,9 @@ ppp_error_t ppp_serial_init(const ppp_serial_config_t *config)
     
     /* 配置参数 - 降级为DEBUG级别 */
     PPP_DEBUG_DEBUG("Configuration parameters:");
-    PPP_DEBUG_DEBUG("  - UART Bus: %u", config->uart_bus);
+    PPP_DEBUG_INFO("  - UART Bus: %u", config->uart_bus);
     PPP_DEBUG_DEBUG("  - IRQ Num: %u", config->irq_num);
-    PPP_DEBUG_DEBUG("  - Baudrate: %u", config->baudrate);
+    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);
@@ -173,11 +173,12 @@ ppp_error_t ppp_serial_init(const ppp_serial_config_t *config)
 
     /* 初始化UART */
     PPP_DEBUG_DEBUG("Calling uapi_uart_init...");
-    errcode_t ret = uapi_uart_init(g_serial_ctx.uart_bus, 
-                                   &g_serial_ctx.pin_config,
-                                   &g_serial_ctx.uart_attr, 
-                                   NULL, 
-                                   &g_serial_ctx.buffer_config);
+    // errcode_t ret = uapi_uart_init(g_serial_ctx.uart_bus, 
+    //                                &g_serial_ctx.pin_config,
+    //                                &g_serial_ctx.uart_attr, 
+    //                                NULL, 
+    //                                &g_serial_ctx.buffer_config);
+    errcode_t ret = uapi_uart_set_attr(g_serial_ctx.uart_bus, &g_serial_ctx.uart_attr);
     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", 
@@ -189,6 +190,7 @@ ppp_error_t ppp_serial_init(const ppp_serial_config_t *config)
         osal_mutex_destroy(&g_serial_ctx.tx_mutex);
         return PPP_ERR_UART;
     }
+
     PPP_DEBUG_INFO("UART initialized successfully (error code = %d)", ret);
 
     /* 创建同步对象 */
@@ -922,37 +924,6 @@ static ppp_error_t ppp_serial_flush_tx_buffer_internal(void)
     return PPP_ERR_OK;
 }
 
-/**
- * @brief 测试UART是否正常工作
- */
-ppp_error_t ppp_serial_test_uart(void)
-{
-    if (!g_serial_ctx.initialized) {
-        PPP_DEBUG_ERROR("PPP serial not initialized");
-        return PPP_ERR_INVALID_PARAM;
-    }
-
-    PPP_DEBUG_INFO("=== UART Test Start ===");
-    PPP_DEBUG_INFO("Current state:");
-    PPP_DEBUG_INFO("  - Initialized: %s", g_serial_ctx.initialized ? "true" : "false");
-    PPP_DEBUG_INFO("  - Mode: %d", g_serial_ctx.current_mode);
-    PPP_DEBUG_INFO("  - UART Bus: %u", g_serial_ctx.uart_bus);
-    PPP_DEBUG_INFO("  - TX Pin: %u", g_serial_ctx.pin_config.tx_pin);
-    PPP_DEBUG_INFO("  - RX Pin: %u", g_serial_ctx.pin_config.rx_pin);
-    PPP_DEBUG_INFO("  - Baudrate: %u", g_serial_ctx.uart_attr.baud_rate);
-
-    /* 发送测试字符串 */
-    const char *test_msg = "AT\r\n";
-    uint32_t test_len = strlen(test_msg);
-    
-    PPP_DEBUG_INFO("Sending test AT command: \"%s\"", test_msg);
-    ppp_error_t result = ppp_serial_write((const uint8_t *)test_msg, test_len);
-    
-    PPP_DEBUG_INFO("Test result: %s", result == PPP_ERR_OK ? "SUCCESS" : "FAILED");
-    PPP_DEBUG_INFO("=== UART Test End ===");
-    
-    return result;
-}
 
 /**
  * @brief 强制发送缓冲区中的所有数据
index b743b85..562dd52 100644 (file)
@@ -8,6 +8,9 @@ extern "C" {
 #include <stdio.h>
 #include "debug_print.h"
 
+/* 启用TCP测试详细日志 */
+#define ZHIHUI_TCP_LOG_ENABLE 1
+
 /* 调试级别定义 */
 #define ZHIHUI_TCP_LOG_LEVEL_NONE    0
 #define ZHIHUI_TCP_LOG_LEVEL_ERROR   1
index 4ca765a..b3b7cfe 100644 (file)
@@ -106,15 +106,20 @@ extern "C" {
 
 /* TCP测试配置 */
 #define TCP_TEST_MAX_CONNECTIONS    50      // 最大连接数
-#define TCP_TEST_MIN_DATA_SIZE      1       // 最小数据包大小
+#define TCP_TEST_MIN_DATA_SIZE      1024       // 最小数据包大小
 #define TCP_TEST_MAX_DATA_SIZE      4096    // 最大数据包大小
 #define TCP_TEST_STATS_INTERVAL     5       // 统计报告间隔(秒)
 #define TCP_TEST_CONNECT_TIMEOUT    10      // 连接超时时间(秒)
-#define TCP_TEST_RECV_TIMEOUT       1       // 接收超时时间(秒)
+#define TCP_TEST_RECV_TIMEOUT       5       // 接收超时时间(秒) - 从1秒增加到5秒以适应网络延迟
 #define TCP_TEST_DEFAULT_HOST       "110.42.224.129"
 #define TCP_TEST_DEFAULT_PORT       8910
 #define TCP_TEST_DEFAULT_TIME       30
 #define TCP_TEST_DEFAULT_CONNECTIONS 10
+#define TCP_TEST_DEFAULT_RECV_TIMEOUT_MS 1000  // 默认接收超时1000ms
+
+/* 新的固定数据模式配置 */
+#define TCP_TEST_FIXED_DATA_SIZE    1024    // 固定数据长度,可通过宏配置
+#define TCP_DATA_PATTERN_CYCLE      256     // 数据模式循环:0x00 ~ 0xFF
 
 /* TCP测试配置结构体 */
 typedef struct {
@@ -126,6 +131,7 @@ typedef struct {
     uint32_t send_interval_ms;          // 发送间隔(毫秒)
     uint32_t data_min_size;             // 最小数据包大小
     uint32_t data_max_size;             // 最大数据包大小
+    uint32_t recv_timeout_ms;           // 接收超时时间(毫秒),默认1000ms
 } tcp_test_config_t;
 
 /* 单个连接统计信息 */
@@ -134,16 +140,35 @@ typedef struct {
     int socket_fd;                      // socket文件描述符
     bool connected;                     // 连接状态
     uint32_t connect_time_ms;           // 连接耗时(毫秒)
+    
+    // 发送统计
     uint32_t packets_sent;              // 发送包数
-    uint32_t packets_received;          // 接收包数
     uint64_t bytes_sent;                // 发送字节数
+    uint32_t send_errors;               // 发送错误数
+    uint8_t current_send_pattern;       // 当前发送数据模式值
+    
+    // 接收统计
+    uint32_t packets_received;          // 接收包数
     uint64_t bytes_received;            // 接收字节数
-    uint32_t errors;                    // 错误数
-    uint32_t data_errors;               // 数据校验错误数
+    uint32_t recv_errors;               // 接收错误数
+    uint32_t incomplete_packets;        // 不完整包数
+    uint32_t incomplete_bytes;          // 不完整字节数
+    uint32_t pattern_errors;            // 数据模式错误数
+    uint8_t expected_recv_pattern;      // 期望接收数据模式值
+    
+    // 通用统计
+    uint32_t errors;                    // 总错误数
     uint32_t last_activity_time;        // 最后活动时间
-    uint64_t throughput_bps;            // 当前吞吐量(字节/秒)
-    uint64_t max_throughput_bps;        // 最大吞吐量(字节/秒)
-    bool thread_running;                // 线程运行状态
+    uint64_t send_throughput_bps;       // 发送吞吐量(字节/秒)
+    uint64_t recv_throughput_bps;       // 接收吞吐量(字节/秒)
+    uint64_t max_send_throughput_bps;   // 最大发送吞吐量(字节/秒)
+    uint64_t max_recv_throughput_bps;   // 最大接收吞吐量(字节/秒)
+    
+    // 线程状态
+    bool send_thread_running;           // 发送线程运行状态
+    bool recv_thread_running;           // 接收线程运行状态
+    void *send_thread_handle;           // 发送线程句柄
+    void *recv_thread_handle;           // 接收线程句柄
 } tcp_connection_stats_t;
 
 /* 全局测试统计信息 */
@@ -152,14 +177,26 @@ typedef struct {
     uint32_t end_time;                  // 测试结束时间
     uint16_t successful_connections;    // 成功连接数
     uint16_t failed_connections;        // 失败连接数
+    
+    // 发送统计
     uint64_t total_packets_sent;        // 总发送包数
-    uint64_t total_packets_received;    // 总接收包数
     uint64_t total_bytes_sent;          // 总发送字节数
+    uint32_t total_send_errors;         // 总发送错误数
+    uint64_t max_send_throughput_bps;   // 最大发送吞吐量(字节/秒)
+    uint64_t avg_send_throughput_bps;   // 平均发送吞吐量(字节/秒)
+    
+    // 接收统计
+    uint64_t total_packets_received;    // 总接收包数
     uint64_t total_bytes_received;      // 总接收字节数
+    uint32_t total_recv_errors;         // 总接收错误数
+    uint32_t total_incomplete_packets;  // 总不完整包数
+    uint32_t total_incomplete_bytes;    // 总不完整字节数
+    uint32_t total_pattern_errors;      // 总数据模式错误数
+    uint64_t max_recv_throughput_bps;   // 最大接收吞吐量(字节/秒)
+    uint64_t avg_recv_throughput_bps;   // 平均接收吞吐量(字节/秒)
+    
+    // 通用统计
     uint32_t total_errors;              // 总错误数
-    uint32_t data_verification_errors;  // 数据校验错误数
-    uint64_t max_throughput_bps;        // 最大吞吐量(字节/秒)
-    uint64_t avg_throughput_bps;        // 平均吞吐量(字节/秒)
     bool test_running;                  // 测试运行状态
 } tcp_global_stats_t;
 
index 0365bf0..27d4568 100644 (file)
@@ -80,15 +80,15 @@ static tcp_mutex_t g_tcp_stats_mutex;
 static bool g_tcp_test_initialized = false;
 
 /* 内部函数声明 */
-static errcode_t tcp_test_create_connection_thread(uint16_t conn_id);
-static void* tcp_test_connection_worker(void *arg);
-static errcode_t tcp_test_generate_data(uint16_t conn_id, uint32_t packet_id, 
-                                          uint8_t *buffer, uint32_t size);
-static uint32_t tcp_test_calculate_checksum(const uint8_t *data, uint32_t size);
-static bool tcp_test_verify_data(const uint8_t *sent_data, const uint8_t *recv_data, uint32_t size);
+static errcode_t tcp_test_create_connection_threads(uint16_t conn_id);
+static void* tcp_test_send_worker(void *arg);
+static void* tcp_test_recv_worker(void *arg);
+static errcode_t tcp_test_generate_fixed_pattern_data(uint8_t pattern_value, uint8_t *buffer, uint32_t size);
+static bool tcp_test_verify_fixed_pattern_data(const uint8_t *data, uint32_t size, uint8_t expected_pattern, 
+                                               uint32_t *incomplete_bytes, uint32_t *pattern_errors);
 static void tcp_test_stats_timer_callback(void *arg);
 static void tcp_test_signal_handler(int signum);
-static errcode_t tcp_test_connect_socket(int *sock_fd, const char *host, uint16_t port);
+static errcode_t tcp_test_connect_socket(int *sock_fd, const char *host, uint16_t port, uint32_t recv_timeout_ms);
 
 static int zhihui_tcp_debug_level = DEFAULT_ZHIHUI_TCP_LOG_LEVEL;
 int zhihui_tcp_debug_get_level(void)
@@ -196,11 +196,11 @@ errcode_t tcp_test_start(const tcp_test_config_t *config)
                      TCP_TEST_STATS_INTERVAL * 1000, 
                      TCP_TEST_STATS_INTERVAL * 1000);
     
-    // 创建连接线程
+    // 创建连接线程(发送和接收分离)
     for (int i = 0; i < config->connection_count; i++) {
-        errcode_t ret = tcp_test_create_connection_thread(i);
+        errcode_t ret = tcp_test_create_connection_threads(i);
         if (ret != ERRCODE_SUCC) {
-            ZHIHUI_TCP_LOG_ERROR("Failed to create connection thread %d", i);
+            ZHIHUI_TCP_LOG_ERROR("Failed to create connection threads %d", i);
             tcp_test_stop();
             return ret;
         }
@@ -247,7 +247,7 @@ errcode_t tcp_test_stop(void)
         
         for (int i = 0; i < g_tcp_test_manager.config.connection_count; i++) {
             tcp_connection_stats_t *conn = &g_tcp_test_manager.connections[i];
-            if (conn->thread_running) {
+            if (conn->send_thread_running || conn->recv_thread_running) {
                 all_threads_stopped = false;
                 break;
             }
@@ -307,220 +307,312 @@ errcode_t tcp_test_get_stats(tcp_global_stats_t *stats)
 }
 
 /**
- * @brief 创建连接线程
+ * @brief 创建连接线程(发送和接收分离)
  */
-static errcode_t tcp_test_create_connection_thread(uint16_t conn_id)
+static errcode_t tcp_test_create_connection_threads(uint16_t conn_id)
 {
-    uint16_t *arg = malloc(sizeof(uint16_t));
-    if (!arg) {
-        return ERRCODE_FAIL; 
-    }
-    
-    *arg = conn_id;
-    
-    TCP_TASK_CREATE(tcp_test_connection_worker, arg, "tcp_test_conn", 8192);
-    
-    return ERRCODE_SUCC;
-}
-
-/**
- * @brief 连接工作线程
- */
-static void* tcp_test_connection_worker(void *arg)
-{
-    uint16_t conn_id = *(uint16_t*)arg;
-    free(arg);
-    
     tcp_connection_stats_t *conn = &g_tcp_test_manager.connections[conn_id];
     tcp_test_config_t *config = &g_tcp_test_manager.config;
     
-    conn->thread_running = true;
-    
+    // 首先建立连接
     uint32_t connect_start = tcp_test_get_time_ms();
-    
-    // 建立连接
     errcode_t ret = tcp_test_connect_socket(&conn->socket_fd, 
                                              config->server_host, 
-                                             config->server_port);
+                                             config->server_port,
+                                             config->recv_timeout_ms);
     
     if (ret != ERRCODE_SUCC) {
         ZHIHUI_TCP_LOG_ERROR("[连接 %03d] 连接失败", conn_id);
         TCP_MUTEX_LOCK(g_tcp_stats_mutex);
         g_tcp_test_manager.global_stats.failed_connections++;
         TCP_MUTEX_UNLOCK(g_tcp_stats_mutex);
-        conn->thread_running = false;
-        return NULL;
+        return ret;
     }
     
     conn->connected = true;
     conn->connect_time_ms = tcp_test_get_time_ms() - connect_start;
     
+    // 初始化数据模式
+    conn->current_send_pattern = 0;
+    conn->expected_recv_pattern = 0;
+    
     TCP_MUTEX_LOCK(g_tcp_stats_mutex);
     g_tcp_test_manager.global_stats.successful_connections++;
     TCP_MUTEX_UNLOCK(g_tcp_stats_mutex);
     
-    printf("[连接 %03d] 连接成功,耗时 %d ms\n", conn_id, conn->connect_time_ms);
+    ZHIHUI_TCP_LOG_INFO("[连接 %03d] 连接成功,耗时 %d ms", conn_id, conn->connect_time_ms);
     
-    // 数据传输循环
-    uint32_t packet_counter = 0;
-    uint8_t *send_buffer = malloc(TCP_TEST_MAX_DATA_SIZE);
-    uint8_t *recv_buffer = malloc(TCP_TEST_MAX_DATA_SIZE);
+    // 创建发送线程
+    uint16_t *send_arg = malloc(sizeof(uint16_t));
+    if (!send_arg) {
+        TCP_CLOSE(conn->socket_fd);
+        return ERRCODE_FAIL;
+    }
+    *send_arg = conn_id;
+    
+    TCP_TASK_CREATE(tcp_test_send_worker, send_arg, "tcp_send", 2048);
     
-    if (!send_buffer || !recv_buffer) {
-        ZHIHUI_TCP_LOG_ERROR("[连接 %03d] 内存分配失败", conn_id);
-        if (send_buffer) free(send_buffer);
-        if (recv_buffer) free(recv_buffer);
-        conn->errors++;
-        goto thread_exit;
+    // 创建接收线程
+    uint16_t *recv_arg = malloc(sizeof(uint16_t));
+    if (!recv_arg) {
+        free(send_arg);
+        TCP_CLOSE(conn->socket_fd);
+        return ERRCODE_FAIL;
+    }
+    *recv_arg = conn_id;
+    
+    TCP_TASK_CREATE(tcp_test_recv_worker, recv_arg, "tcp_recv", 2048);
+    
+    return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 发送工作线程 - 只负责发送固定模式数据
+ */
+static void* tcp_test_send_worker(void *arg)
+{
+    uint16_t conn_id = *(uint16_t*)arg;
+    free(arg);
+    
+    tcp_connection_stats_t *conn = &g_tcp_test_manager.connections[conn_id];
+    tcp_test_config_t *config = &g_tcp_test_manager.config;
+    
+    conn->send_thread_running = true;
+    
+    // 分配发送缓冲区 - 使用动态分配避免栈溢出
+    uint8_t *send_buffer = malloc(TCP_TEST_FIXED_DATA_SIZE);
+    if (!send_buffer) {
+        ZHIHUI_TCP_LOG_ERROR("[发送 %03d] 内存分配失败", conn_id);
+        conn->send_thread_running = false;
+        return NULL;
     }
     
     uint32_t test_end_time = g_tcp_test_manager.global_stats.start_time + 
                             (config->test_duration * 1000);
     
+    ZHIHUI_TCP_LOG_INFO("[发送 %03d] 开始发送数据,固定长度: %d 字节", conn_id, TCP_TEST_FIXED_DATA_SIZE);
+    
+    uint32_t packet_counter = 0;
+    uint32_t send_interval_ms = config->send_interval_ms;
+    uint32_t last_send_time = 0;
+    uint8_t current_pattern = conn->current_send_pattern;
+    
     while (!g_tcp_test_manager.stop_flag && 
+           conn->connected &&
            tcp_test_get_time_ms() < test_end_time) {
         
-        // 生成随机大小的测试数据
-        uint32_t data_size = config->data_min_size + 
-                            (rand() % (config->data_max_size - config->data_min_size + 1));
-        
-        // 生成测试数据
-        ret = tcp_test_generate_data(conn_id, packet_counter, send_buffer, data_size);
-        if (ret != ERRCODE_SUCC) {
-            conn->errors++;
-            continue;
-        }
-        
-        // 发送数据
-        ZHIHUI_TCP_LOG_DEBUG("[连接 %03d] 准备发送 %d 字节数据", conn_id, data_size);
-        ZHIHUI_TCP_LOG_DEBUG("[连接 %03d] Socket FD: %d, 连接状态: %s", 
-                            conn_id, conn->socket_fd, conn->connected ? "已连接" : "未连接");
+        uint32_t current_time = tcp_test_get_time_ms();
         
-        // 检查socket状态
-        int socket_error = 0;
-        socklen_t error_len = sizeof(socket_error);
-        if (TCP_GETSOCKOPT(conn->socket_fd, SOL_SOCKET, SO_ERROR, &socket_error, &error_len) == 0) {
-            if (socket_error != 0) {
-                ZHIHUI_TCP_LOG_ERROR("[连接 %03d] Socket错误状态: %d (%s)", 
-                                    conn_id, socket_error, TCP_STRERROR(socket_error));
-            } else {
-                ZHIHUI_TCP_LOG_DEBUG("[连接 %03d] Socket状态正常", conn_id);
-            }
-        }
+        // 检查是否可以发送
+        bool can_send = (send_interval_ms == 0) || 
+                       (current_time - last_send_time >= send_interval_ms);
         
-        ssize_t bytes_sent = TCP_SEND(conn->socket_fd, send_buffer, data_size, 0);
-        ZHIHUI_TCP_LOG_DEBUG("[连接 %03d] TCP_SEND返回: %ld (期望: %d)", conn_id, bytes_sent, data_size);
-        
-        if (bytes_sent != (ssize_t)data_size) {
-            if (bytes_sent < 0) {
-                int err = TCP_GET_ERRNO();
-                ZHIHUI_TCP_LOG_ERROR("[连接 %03d] 发送失败: %s (errno: %d)", 
-                                    conn_id, TCP_STRERROR(err), err);
-                ZHIHUI_TCP_LOG_ERROR("[连接 %03d] 发送失败详情: socket_fd=%d, data_size=%d, flags=0", 
-                                    conn_id, conn->socket_fd, data_size);
-                conn->errors++;
-                break;
-            } else {
-                ZHIHUI_TCP_LOG_WARN("[连接 %03d] 发送不完整 (%ld/%d 字节)", 
-                              conn_id, bytes_sent, data_size);
-                ZHIHUI_TCP_LOG_WARN("[连接 %03d] 部分发送可能是正常的,继续执行", conn_id);
+        if (can_send) {
+            // 生成固定模式数据
+            errcode_t ret = tcp_test_generate_fixed_pattern_data(current_pattern, send_buffer, TCP_TEST_FIXED_DATA_SIZE);
+            if (ret != ERRCODE_SUCC) {
+                TCP_MUTEX_LOCK(g_tcp_stats_mutex);
+                conn->send_errors++;
+                g_tcp_test_manager.global_stats.total_send_errors++;
+                TCP_MUTEX_UNLOCK(g_tcp_stats_mutex);
+                TCP_SLEEP_MS(1);
+                continue;
             }
-        } else {
-            ZHIHUI_TCP_LOG_DEBUG("[连接 %03d] 发送成功: %ld 字节", conn_id, bytes_sent);
-        }
-        
-        conn->packets_sent++;
-        conn->bytes_sent += bytes_sent;
-        
-        // 接收回显数据
-        ssize_t total_received = 0;
-        uint32_t recv_start = tcp_test_get_time_ms();
-        
-        while (total_received < data_size && 
-               (tcp_test_get_time_ms() - recv_start) < (TCP_TEST_RECV_TIMEOUT * 1000)) {
             
-            ssize_t bytes_recv = TCP_RECV(conn->socket_fd, 
-                                        recv_buffer + total_received,
-                                        data_size - total_received,
-                                        0);
+            // 发送数据
+            ssize_t bytes_sent = TCP_SEND(conn->socket_fd, send_buffer, TCP_TEST_FIXED_DATA_SIZE, 0);
             
-            if (bytes_recv > 0) {
-                total_received += bytes_recv;
-            } else if (bytes_recv == 0) {
-                ZHIHUI_TCP_LOG_WARN("[连接 %03d] 连接关闭", conn_id);
-                goto thread_exit;
+            if (bytes_sent > 0) {
+                TCP_MUTEX_LOCK(g_tcp_stats_mutex);
+                conn->packets_sent++;
+                conn->bytes_sent += bytes_sent;
+                g_tcp_test_manager.global_stats.total_packets_sent++;
+                g_tcp_test_manager.global_stats.total_bytes_sent += bytes_sent;
+                TCP_MUTEX_UNLOCK(g_tcp_stats_mutex);
+                
+                packet_counter++;
+                last_send_time = current_time;
+                
+                ZHIHUI_TCP_LOG_DEBUG("[发送 %03d] 发送数据包 %d: 模式 0x%02X, %ld 字节", 
+                                    conn_id, packet_counter, current_pattern, bytes_sent);
+                
+                // 移动到下一个数据模式
+                current_pattern = (current_pattern + 1) % TCP_DATA_PATTERN_CYCLE;
+                conn->current_send_pattern = current_pattern;
+                
             } else {
                 int err = TCP_GET_ERRNO();
                 if (err != TCP_EAGAIN && err != TCP_EWOULDBLOCK) {
-                    ZHIHUI_TCP_LOG_ERROR("[连接 %03d] 接收失败: %s", conn_id, TCP_STRERROR(err));
-                    conn->errors++;
-                    goto thread_exit;
+                    ZHIHUI_TCP_LOG_ERROR("[发送 %03d] 发送失败: %s", conn_id, TCP_STRERROR(err));
+                    TCP_MUTEX_LOCK(g_tcp_stats_mutex);
+                    conn->send_errors++;
+                    g_tcp_test_manager.global_stats.total_send_errors++;
+                    TCP_MUTEX_UNLOCK(g_tcp_stats_mutex);
+                    break;
                 }
             }
-            
-            TCP_SLEEP_MS(1); // 1ms延迟
         }
         
-        if (total_received == data_size) {
-            conn->packets_received++;
-            conn->bytes_received += total_received;
+        conn->last_activity_time = tcp_test_get_time_ms();
+        
+        // 短暂延迟避免CPU占用过高
+        TCP_SLEEP_MS(send_interval_ms > 0 ? 1 : 0);
+    }
+    
+    free(send_buffer);
+    conn->send_thread_running = false;
+    
+    ZHIHUI_TCP_LOG_INFO("[发送 %03d] 发送线程结束,总发送: %d 包", conn_id, packet_counter);
+    return NULL;
+}
+
+/**
+ * @brief 接收工作线程 - 检测固定模式数据
+ */
+static void* tcp_test_recv_worker(void *arg)
+{
+    uint16_t conn_id = *(uint16_t*)arg;
+    free(arg);
+    
+    tcp_connection_stats_t *conn = &g_tcp_test_manager.connections[conn_id];
+    tcp_test_config_t *config = &g_tcp_test_manager.config;
+    
+    conn->recv_thread_running = true;
+    
+    // 分配接收缓冲区
+    uint8_t *recv_buffer = malloc(TCP_TEST_FIXED_DATA_SIZE * 4); // 多缓冲一些数据
+    if (!recv_buffer) {
+        ZHIHUI_TCP_LOG_ERROR("[接收 %03d] 内存分配失败", conn_id);
+        conn->recv_errors++;
+        conn->recv_thread_running = false;
+        return NULL;
+    }
+    
+    uint32_t test_end_time = g_tcp_test_manager.global_stats.start_time + 
+                            (config->test_duration * 1000);
+    
+    ZHIHUI_TCP_LOG_INFO("[接收 %03d] 开始接收数据,固定长度: %d 字节", conn_id, TCP_TEST_FIXED_DATA_SIZE);
+    ZHIHUI_TCP_LOG_INFO("[接收 %03d] Socket FD: %d, 测试结束时间: %u", conn_id, conn->socket_fd, test_end_time);
+    
+    uint32_t recv_buffer_offset = 0;
+    uint8_t expected_pattern = conn->expected_recv_pattern;
+    uint32_t total_incomplete_bytes = 0;
+    uint32_t total_pattern_errors = 0;
+    
+    ZHIHUI_TCP_LOG_INFO("[接收 %03d] 进入接收循环", conn_id);
+    
+    while (!g_tcp_test_manager.stop_flag && 
+           conn->connected &&
+           tcp_test_get_time_ms() < test_end_time) {
+        
+        // 接收数据
+        ssize_t bytes_recv = TCP_RECV(conn->socket_fd, 
+                                    recv_buffer + recv_buffer_offset,
+                                    (TCP_TEST_FIXED_DATA_SIZE * 4) - recv_buffer_offset,
+                                    0);
+        
+        if (bytes_recv > 0) {
+            recv_buffer_offset += bytes_recv;
+            
+            ZHIHUI_TCP_LOG_INFO("[接收 %03d] 接收到 %ld 字节,缓冲区总计: %d 字节", 
+                                conn_id, bytes_recv, recv_buffer_offset);
             
-            // 验证数据完整性
-            if (!tcp_test_verify_data(send_buffer, recv_buffer, data_size)) {
-                conn->data_errors++;
+            // 处理完整的固定长度数据包
+            while (recv_buffer_offset >= TCP_TEST_FIXED_DATA_SIZE) {
+                uint32_t incomplete_bytes = 0;
+                uint32_t pattern_errors = 0;
+                
+                // 验证固定模式数据
+                bool data_valid = tcp_test_verify_fixed_pattern_data(
+                    recv_buffer, TCP_TEST_FIXED_DATA_SIZE, expected_pattern, 
+                    &incomplete_bytes, &pattern_errors);
+                
+                // 更新接收统计
                 TCP_MUTEX_LOCK(g_tcp_stats_mutex);
-                g_tcp_test_manager.global_stats.data_verification_errors++;
+                conn->packets_received++;
+                conn->bytes_received += TCP_TEST_FIXED_DATA_SIZE;
+                g_tcp_test_manager.global_stats.total_packets_received++;
+                g_tcp_test_manager.global_stats.total_bytes_received += TCP_TEST_FIXED_DATA_SIZE;
+                
+                if (!data_valid) {
+                    conn->pattern_errors += pattern_errors;
+                    g_tcp_test_manager.global_stats.total_pattern_errors += pattern_errors;
+                    total_pattern_errors += pattern_errors;
+                }
+                
+                if (incomplete_bytes > 0) {
+                    conn->incomplete_bytes += incomplete_bytes;
+                    g_tcp_test_manager.global_stats.total_incomplete_bytes += incomplete_bytes;
+                    total_incomplete_bytes += incomplete_bytes;
+                }
+                
                 TCP_MUTEX_UNLOCK(g_tcp_stats_mutex);
+                
+                ZHIHUI_TCP_LOG_INFO("[接收 %03d] 包验证: 期望模式 0x%02X, %s, 错误: %d", 
+                                    conn_id, expected_pattern, 
+                                    data_valid ? "正确" : "错误", pattern_errors);
+                
+                // 移动到下一个期望的数据模式
+                expected_pattern = (expected_pattern + 1) % TCP_DATA_PATTERN_CYCLE;
+                conn->expected_recv_pattern = expected_pattern;
+                
+                // 移除已处理的数据
+                memmove(recv_buffer, recv_buffer + TCP_TEST_FIXED_DATA_SIZE, 
+                       recv_buffer_offset - TCP_TEST_FIXED_DATA_SIZE);
+                recv_buffer_offset -= TCP_TEST_FIXED_DATA_SIZE;
             }
+            
+        } else if (bytes_recv == 0) {
+            ZHIHUI_TCP_LOG_WARN("[接收 %03d] 连接关闭", conn_id);
+            break;
         } else {
-            ZHIHUI_TCP_LOG_WARN("[连接 %03d] 接收数据不完整: %ld/%d 字节", 
-                          conn_id, total_received, data_size);
-            conn->errors++;
-        }
-        
-        // 更新全局统计
-        TCP_MUTEX_LOCK(g_tcp_stats_mutex);
-        g_tcp_test_manager.global_stats.total_packets_sent++;
-        g_tcp_test_manager.global_stats.total_bytes_sent += bytes_sent;
-        if (total_received == data_size) {
-            g_tcp_test_manager.global_stats.total_packets_received++;
-            g_tcp_test_manager.global_stats.total_bytes_received += total_received;
-        } else {
-            g_tcp_test_manager.global_stats.total_errors++;
+            int err = TCP_GET_ERRNO();
+            if (err == TCP_EAGAIN || err == TCP_EWOULDBLOCK) {
+                // 非阻塞模式下的正常超时
+                ZHIHUI_TCP_LOG_INFO("[接收 %03d] 接收超时 (EAGAIN/EWOULDBLOCK)", conn_id);
+            } else if (err == TCP_ETIMEDOUT) {
+                // Socket 超时
+                ZHIHUI_TCP_LOG_INFO("[接收 %03d] Socket 超时 (ETIMEDOUT)", conn_id);
+            } else {
+                ZHIHUI_TCP_LOG_ERROR("[接收 %03d] 接收失败: %s", conn_id, TCP_STRERROR(err));
+                TCP_MUTEX_LOCK(g_tcp_stats_mutex);
+                conn->recv_errors++;
+                g_tcp_test_manager.global_stats.total_recv_errors++;
+                TCP_MUTEX_UNLOCK(g_tcp_stats_mutex);
+                break;
+            }
         }
-        TCP_MUTEX_UNLOCK(g_tcp_stats_mutex);
         
         conn->last_activity_time = tcp_test_get_time_ms();
-        packet_counter++;
         
-        // 控制发送频率
-        if (config->send_interval_ms > 0) {
-            TCP_SLEEP_MS(config->send_interval_ms);
-        } else {
-            TCP_SLEEP_MS((rand() % 10 + 1)); // 1-10ms随机延迟
-        }
+        // 短暂延迟
+        TCP_SLEEP_MS(1);
     }
     
-thread_exit:
-    // 关闭连接
-    if (conn->socket_fd >= 0) {
-        TCP_CLOSE(conn->socket_fd);
-        conn->socket_fd = -1;
+    // 处理剩余不完整数据
+    if (recv_buffer_offset > 0) {
+        TCP_MUTEX_LOCK(g_tcp_stats_mutex);
+        conn->incomplete_packets++;
+        conn->incomplete_bytes += recv_buffer_offset;
+        g_tcp_test_manager.global_stats.total_incomplete_packets++;
+        g_tcp_test_manager.global_stats.total_incomplete_bytes += recv_buffer_offset;
+        TCP_MUTEX_UNLOCK(g_tcp_stats_mutex);
+        
+        ZHIHUI_TCP_LOG_WARN("[接收 %03d] 剩余不完整数据: %d 字节", conn_id, recv_buffer_offset);
     }
     
-    conn->connected = false;
-    conn->thread_running = false;
-    
-    if (send_buffer) free(send_buffer);
-    if (recv_buffer) free(recv_buffer);
+    free(recv_buffer);
+    conn->recv_thread_running = false;
     
+    ZHIHUI_TCP_LOG_INFO("[接收 %03d] 接收线程结束,总模式错误: %d, 总不完整字节: %d", 
+                       conn_id, total_pattern_errors, total_incomplete_bytes);
     return NULL;
 }
 
 /**
  * @brief 建立Socket连接
  */
-static errcode_t tcp_test_connect_socket(int *sock_fd, const char *host, uint16_t port)
+static errcode_t tcp_test_connect_socket(int *sock_fd, const char *host, uint16_t port, uint32_t recv_timeout_ms)
 {
     int fd = TCP_SOCKET(TCP_AF_INET, TCP_SOCK_STREAM, 0);
     if (fd < 0) {
@@ -529,31 +621,47 @@ static errcode_t tcp_test_connect_socket(int *sock_fd, const char *host, uint16_
     }
     
 #ifndef USE_LWIP_SOCKET
-    // 设置连接超时 (仅在POSIX环境下)
-    struct timeval timeout;
-    timeout.tv_sec = TCP_TEST_CONNECT_TIMEOUT;
-    timeout.tv_usec = 0;
+    // 设置超时 (仅在POSIX环境下)
+    struct timeval connect_timeout;
+    connect_timeout.tv_sec = TCP_TEST_CONNECT_TIMEOUT;
+    connect_timeout.tv_usec = 0;
+    
+    struct timeval recv_timeout;
+    recv_timeout.tv_sec = recv_timeout_ms / 1000;
+    recv_timeout.tv_usec = (recv_timeout_ms % 1000) * 1000;
     
-    if (TCP_SETSOCKOPT(fd, TCP_SOL_SOCKET, TCP_SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0 ||
-        TCP_SETSOCKOPT(fd, TCP_SOL_SOCKET, TCP_SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0) {
-        ZHIHUI_TCP_LOG_WARN("Failed to set socket timeout");
+    if (TCP_SETSOCKOPT(fd, TCP_SOL_SOCKET, TCP_SO_RCVTIMEO, &recv_timeout, sizeof(recv_timeout)) < 0) {
+        ZHIHUI_TCP_LOG_WARN("Failed to set socket receive timeout to %ums", recv_timeout_ms);
+    } else {
+        ZHIHUI_TCP_LOG_DEBUG("Socket receive timeout set to %ums", recv_timeout_ms);
+    }
+    
+    if (TCP_SETSOCKOPT(fd, TCP_SOL_SOCKET, TCP_SO_SNDTIMEO, &connect_timeout, sizeof(connect_timeout)) < 0) {
+        ZHIHUI_TCP_LOG_WARN("Failed to set socket send timeout");
     }
 #else
     // 在lwIP环境下设置超时 - 使用正确的数据类型和检查
     #ifdef LWIP_SO_RCVTIMEO
-    struct timeval timeout;
-    timeout.tv_sec = TCP_TEST_CONNECT_TIMEOUT;
-    timeout.tv_usec = 0;
+    struct timeval connect_timeout;
+    connect_timeout.tv_sec = TCP_TEST_CONNECT_TIMEOUT;
+    connect_timeout.tv_usec = 0;
+    
+    struct timeval recv_timeout;
+    recv_timeout.tv_sec = recv_timeout_ms / 1000;
+    recv_timeout.tv_usec = (recv_timeout_ms % 1000) * 1000;
     
-    if (TCP_SETSOCKOPT(fd, TCP_SOL_SOCKET, TCP_SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
-        ZHIHUI_TCP_LOG_DEBUG("lwIP SO_RCVTIMEO not supported or failed");
+    if (TCP_SETSOCKOPT(fd, TCP_SOL_SOCKET, TCP_SO_RCVTIMEO, &recv_timeout, sizeof(recv_timeout)) < 0) {
+        ZHIHUI_TCP_LOG_DEBUG("lwIP SO_RCVTIMEO not supported or failed for %ums", recv_timeout_ms);
+    } else {
+        ZHIHUI_TCP_LOG_DEBUG("lwIP socket receive timeout set to %ums", recv_timeout_ms);
     }
-    if (TCP_SETSOCKOPT(fd, TCP_SOL_SOCKET, TCP_SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0) {
+    
+    if (TCP_SETSOCKOPT(fd, TCP_SOL_SOCKET, TCP_SO_SNDTIMEO, &connect_timeout, sizeof(connect_timeout)) < 0) {
         ZHIHUI_TCP_LOG_DEBUG("lwIP SO_SNDTIMEO not supported or failed");
     }
     #else
     // lwIP可能不支持超时选项,使用非阻塞模式代替
-    ZHIHUI_TCP_LOG_INFO("lwIP socket timeout not supported, using default behavior");
+    ZHIHUI_TCP_LOG_INFO("lwIP socket timeout not supported, using default behavior (recv_timeout=%ums requested)", recv_timeout_ms);
     #endif
 #endif
     
@@ -579,28 +687,16 @@ static errcode_t tcp_test_connect_socket(int *sock_fd, const char *host, uint16_
 }
 
 /**
- * @brief 生成测试数据
+ * @brief 生成固定模式数据
  */
-static errcode_t tcp_test_generate_data(uint16_t conn_id, uint32_t packet_id, 
-                                          uint8_t *buffer, uint32_t size)
+static errcode_t tcp_test_generate_fixed_pattern_data(uint8_t pattern_value, uint8_t *buffer, uint32_t size)
 {
-    if (!buffer || size < sizeof(tcp_test_packet_header_t)) {
+    if (!buffer || size == 0) {
         return ERRCODE_INVALID_PARAM;
     }
     
-    tcp_test_packet_header_t *header = (tcp_test_packet_header_t*)buffer;
-    header->conn_id = TCP_HTONS(conn_id);
-    header->packet_id = TCP_HTONL(packet_id);
-    header->data_size = TCP_HTONS(size);
-    header->timestamp = TCP_HTONL(tcp_test_get_time_ms());
-    
-    // 填充随机数据
-    for (uint32_t i = sizeof(tcp_test_packet_header_t); i < size - sizeof(uint32_t); i++) {
-        buffer[i] = rand() & 0xFF;
-    }
-    
-    // 计算校验和
-    header->checksum = TCP_HTONL(tcp_test_calculate_checksum(buffer, size - sizeof(uint32_t)));
+    // 填充固定模式数据,整个buffer都用同一个值
+    memset(buffer, pattern_value, size);
     
     return ERRCODE_SUCC;
 }
@@ -618,11 +714,26 @@ static uint32_t tcp_test_calculate_checksum(const uint8_t *data, uint32_t size)
 }
 
 /**
- * @brief 验证数据完整性
+ * @brief 验证固定模式数据
  */
-static bool tcp_test_verify_data(const uint8_t *sent_data, const uint8_t *recv_data, uint32_t size)
+static bool tcp_test_verify_fixed_pattern_data(const uint8_t *data, uint32_t size, uint8_t expected_pattern, 
+                                               uint32_t *incomplete_bytes, uint32_t *pattern_errors)
 {
-    return memcmp(sent_data, recv_data, size) == 0;
+    if (!data || size == 0 || !incomplete_bytes || !pattern_errors) {
+        return false;
+    }
+    
+    *incomplete_bytes = 0;
+    *pattern_errors = 0;
+    
+    for (uint32_t i = 0; i < size; i++) {
+        if (data[i] != expected_pattern) {
+            (*pattern_errors)++;
+        }
+    }
+    
+    // 如果所有数据都正确,返回true
+    return (*pattern_errors == 0);
 }
 
 /**
@@ -685,7 +796,7 @@ uint32_t tcp_test_get_time_ms(void)
     /* 在lwIP环境中尝试使用真实的时间函数 */
     #ifdef OSAL_TIME_AVAILABLE
         /* 如果OSAL时间函数可用,使用它 */
-        return osal_get_time_ms();
+        return osal_get_jiffies();
     #else
         /* 否则使用简化的时间模拟 */
         static uint32_t start_time = 0;
@@ -803,7 +914,7 @@ errcode_t tcp_test_print_report(void)
     
     printf("\n错误统计:\n");
     printf("  传输错误: %d\n", g_tcp_test_manager.global_stats.total_errors);
-    printf("  æ\95°æ\8d®æ ¡éª\8cé\94\99误: %d\n", g_tcp_test_manager.global_stats.data_verification_errors);
+    printf("  æ\95°æ\8d®æ¨¡å¼\8fé\94\99误: %d\n", g_tcp_test_manager.global_stats.total_pattern_errors);
     
     if (g_tcp_test_manager.global_stats.total_packets_sent > 0) {
         printf("  错误率: %.3f%%\n",
index 033e0d3..de9fa8e 100644 (file)
@@ -28,7 +28,7 @@ void tcp_test_print_help(void)
     printf("  -c, --connections <数量> 并发连接数 (默认: %d, 最大: %d)\n", 
            TCP_TEST_DEFAULT_CONNECTIONS, TCP_TEST_MAX_CONNECTIONS);
     printf("  -v, --verbose          详细输出模式\n");
-    printf("  -i, --interval <毫秒>  发送间隔(毫秒) (默认: 自动)\n");
+    printf("  -i, --interval <毫秒>  发送间隔(毫秒) (默认: 20)\n");
     printf("  --min-size <字节>      最小数据包大小 (默认: %d)\n", TCP_TEST_MIN_DATA_SIZE);
     printf("  --max-size <字节>      最大数据包大小 (默认: %d)\n", TCP_TEST_MAX_DATA_SIZE);
     printf("  -h, --help             显示此帮助信息\n\n");
@@ -58,9 +58,10 @@ ppp_error_t tcp_test_parse_args(int argc, char *argv[], tcp_test_config_t *confi
     config->test_duration = TCP_TEST_DEFAULT_TIME;
     config->connection_count = TCP_TEST_DEFAULT_CONNECTIONS;
     config->verbose = false;
-    config->send_interval_ms = 0; // 自动
+    config->send_interval_ms = 20; // 默认20ms间隔
     config->data_min_size = TCP_TEST_MIN_DATA_SIZE;
     config->data_max_size = TCP_TEST_MAX_DATA_SIZE;
+    config->recv_timeout_ms = TCP_TEST_DEFAULT_RECV_TIMEOUT_MS; // 默认接收超时1000ms
     
     // 长选项定义
     static struct option long_options[] = {
@@ -196,12 +197,8 @@ static void print_config(const tcp_test_config_t *config)
     printf("  并发连接: %d\n", config->connection_count);
     printf("  数据包大小: %d-%d 字节\n", config->data_min_size, config->data_max_size);
     printf("  详细输出: %s\n", config->verbose ? "是" : "否");
-    
-    if (config->send_interval_ms > 0) {
-        printf("  发送间隔: %d 毫秒\n", config->send_interval_ms);
-    } else {
-        printf("  发送间隔: 自动(1-10毫秒随机)\n");
-    }
+    printf("  发送间隔: %d 毫秒/包\n", config->send_interval_ms);
+    printf("  接收超时: %d 毫秒\n", config->recv_timeout_ms);
     printf("\n");
 }
 
index 8c4f50f..321fb33 100644 (file)
@@ -682,6 +682,16 @@ void startup_post_init_task(void)
         factory_set_recoder_streamType();
     }
 
+#ifdef CUSTOM_UTILS
+    if(!custom_get_factory_test_flag())
+#endif
+    uapi_ln_http_server_init();
+    
+    
+#ifdef SUPPORT_PPP_SERVICE
+    ppp_env_init();
+#endif
+
 #endif
 #ifdef SUPPORT_CYWEE_SERVICE
     do_cywee_service_check_msg(CYWEE_SERVICE_CMD_TIME_SYNC,NULL);
@@ -769,11 +779,11 @@ if ( cm_poweron_cat1_on_bootup_flag() )
 #endif
 #else
 
-#ifdef BOARD_LEINIAO
-    extern int ppp_env_init(void);
-    if(!custom_get_factory_test_flag())
-        ppp_env_init();
-#endif
+// #ifdef SUPPORT_PPP_SERVICE
+// extern errcode_t ppp_start_dial(void);
+    // if(!custom_get_factory_test_flag())
+        // ppp_start_dial();
+// #endif
 
 #endif