# "-:lwip",
"thunderbird_toys",#雷鸟
"leiniaoMediaService",
- # "cat1Service",
- # "cat1Test",
+ #cat1 相关配置
"ppp",
- "audio_manager",
+ #websocket 相关配置
+ "zhihui_websocket",
+ #ai 相关配置
+ "aiMediaService",
+ "aiService",
+ #ai_old相关配置
+ "zhihui_ai_old",
+ #音频相关配置
+ "audio_manager",
# "CustomUIcomponentTool",
"nativeabilityfwk",
"custom_utils",
#endif /* CONFIG_UART_SUPPORT_TX */
#if defined(CONFIG_UART_SUPPORT_RX)
+/*
+ * timeout的作用:如果在超时时间内一直没有数据到达,则退出;
+ * 如果有数据到达,则应持续读取,直到没有数据可读(即RX FIFO空),
+ * 此时才正常返回,不能因为超时而中断正在进行的数据读取。
+ */
int32_t uapi_uart_read(uart_bus_t bus, const uint8_t *buffer, uint32_t length, uint32_t timeout)
{
#ifdef SUPPORT_GNSS
return -1;
}
- /* Poll until we read the requested length or timeout expires.
- If timeout == 0, behave non-blocking and return immediately if no data. */
- uint32_t time_remaining = timeout;
- for (;;) {
- /* Try to read one byte if available */
+ uint32_t time_waited = 0;
+ bool got_data = false;
+
+ while (len > 0) {
uint32_t irq_sts = uart_porting_lock(bus);
hal_funcs->ctrl(bus, UART_CTRL_CHECK_RX_FIFO_EMPTY, (uintptr_t)&rx_fifo_empty);
if (!rx_fifo_empty) {
data_buffer++;
len--;
read_count++;
+ got_data = true;
+ time_waited = 0; // reset wait time after receiving data
}
uart_porting_unlock(bus, irq_sts);
if (len == 0) {
- break; /* finished reading requested bytes */
+ break; // 已读满length字节
}
if (rx_fifo_empty) {
- /* No data available now */
- if (timeout == 0) {
- break; /* non-blocking: return whatever we got */
- }
- if (time_remaining == 0) {
- break; /* timed out */
- }
- /* Sleep briefly and try again */
- osal_msleep(1);
- if (time_remaining != 0xFFFFFFFF) {
- if (time_remaining > 0) {
- time_remaining--;
+ if (!got_data) {
+ // 尚未收到任何数据,等待timeout
+ if (timeout == 0) {
+ break; // 非阻塞模式
+ }
+ if (time_waited >= timeout) {
+ break; // 超时未收到任何数据
}
+ osal_msleep(1);
+ if (timeout != 0xFFFFFFFF) {
+ time_waited++;
+ }
+ } else {
+ // 已经收到过数据,只要RX FIFO空就返回
+ break;
}
}
}
#include "custom_utils.h"
#include "custom_runtime.h"
-#include "bleANCS.h"
+// #include "bleANCS.h"
#include "custom_utils.h"
#include "cmsis_os2.h"
#include "wearable_log.h"
// #include "bletest.h" // Commented out due to missing header
#include "custom_utils.h"
#include "custom_runtime.h"
-#include "bleANCS.h"
+// #include "bleANCS.h"
#include "cat1_tcpServer.h"
#include "custom_utils.h"
#include "broadcast_feature.h"
#include "audio_capture_wrapper.h"
// #include <ui_service.h> // Commented out due to missing header
-#include <bleService.h>
+// #include <bleService.h>
// #include "cat1_ws.h" // Commented out due to missing header
#include "dev_authentication.h"
#include "bk_websocket.h"
// #include "bletest.h" // Commented out due to missing header
#include "custom_utils.h"
#include "custom_runtime.h"
-#include "bleANCS.h"
+// #include "bleANCS.h"
#include "custom_utils.h"
#include "broadcast_feature.h"
#include "cmsis_os2.h"
#include "audio_capture_wrapper.h"
// #include <ui_service.h> // Commented out due to missing header
-#include <bleService.h>
+// #include <bleService.h>
#include "zhihui_ws.h"
#include "dev_authentication.h"
// #include "tcp_simple_manager.h" // Commented out due to missing header
src/ppp_debug.c
src/ppp_power_ctl.c
src/ppp_cat1_api.c
+ src/ppp_stub_functions.c
${PPP_AT_CMD_SOURCE}
)
--- /dev/null
+# Neoway N706A AT命令列表 (带备注)
+# 基于 Neoway_N706A_AT命令手册_V1.0.md
+
+» AT+CLAC # 列出所有可用的AT命令
+« AT+CLAC
+
+AT+CFUN # 设置模组功能 (0=最小功能,1=全功能,4=飞行模式等)
+
+AT+CSQ # 获取信号强度 (返回信号强度和误码率)
+
+AT+COPS # 运营商选择 (查询/设置网络运营商)
+
+AT+CGATT # GPRS附着/分离 (1=附着,0=分离)
+
+AT+CTZR # 时区报告设置
+
+AT+CCLK # 时钟设置/查询
+
+AT+CEREG # EPS网络注册状态
+
+AT+CPLS # 选择首选语言
+
+AT+CPOL # 首选运营商列表
+
+AT+COPN # 读取运营商名称
+
+AT+NPSMR # 【未匹配到】
+
+AT+NPSMSET # 【未匹配到】
+
+AT+NEARFCN # 【未匹配到】
+
+AT+CPSMS # 省电模式设置
+
+AT+NBAND # 【未匹配到】
+
+AT+CNEC # 【未匹配到】
+
+AT+CTZU # 自动时区更新
+
+AT+NDRX # 【未匹配到】
+
+AT+CSCON # 信令连接状态
+
+AT+NCSEARFCN # 【未匹配到】
+
+AT+NUESTATS # 【未匹配到】
+
+AT+NPOWD # 【未匹配到】
+
+AT+CREG # 网络注册状态 (查询网络注册状态)
+
+AT+CGREG # GPRS网络注册状态
+
+AT+NSQ # 【未匹配到】
+
+AT+NNMPSD # 【未匹配到】
+
+AT+NGSBLACKCELL # 【未匹配到】
+
+AT+NCSBLACKCELL # 【未匹配到】
+
+AT+NBACKOFF # 【未匹配到】
+
+AT+NROAMING # 【未匹配到】
+
+AT+NRESELCFG # 【未匹配到】
+
+AT+NSIMAC # 【未匹配到】
+
+AT+CGTFT # 流量模板
+
+AT+CGPADDR # 显示PDP地址
+
+AT+CGDCONT # 定义PDP上下文 (设置APN等参数)
+
+AT+CGACT # PDP上下文激活/去激活
+
+AT+CGCMOD # PDP上下文修改
+
+AT+CGDSCONT # 定义辅助PDP上下文
+
+AT+CGTFTRDP # 读取流量模板
+
+AT+CGEQOSRDP # 读取EPS QoS参数
+
+AT+CGAUTH # 定义PDP上下文认证参数
+
+AT+CGEQOS # 定义EPS QoS参数
+
+AT+CEER # 扩展错误报告
+
+AT+CGCONTRDP # 读取动态PDP上下文参数
+
+AT+NCONFIG # 【未匹配到】
+
+AT+CIMI # 请求国际移动用户识别码(IMSI)
+
+AT+CGLA # 通用逻辑通道访问
+
+AT+CRSM # 受限SIM访问
+
+AT+CSIM # 通用SIM访问
+
+AT+CCHC # 关闭逻辑通道
+
+AT+CCHO # 打开逻辑通道
+
+AT+USIMHOTPLUG # 【未匹配到】
+
+AT+NUICC # 【未匹配到】
+
+AT+ICCID # 读取ICCID (SIM卡序列号)
+
+AT+PHONENUM # 【未匹配到】
+
+AT+NSIMSRS # 【未匹配到】
+
+AT+CLEARFPLMN # 【未匹配到】
+
+AT+USIMRETRYTIMES # 【未匹配到】
+
+AT+CPIN # 输入PIN码
+
+AT+CLCK # 设备锁定
+
+AT+CPWD # 更改密码
+
+AT+NPIN # 【未匹配到】
+
+AT+SETHWLOCK # 【未匹配到】
+
+AT+CARDLOCK # 【未匹配到】
+
+AT+SIMLOCK # 【未匹配到】
+
+AT+CPINR # PIN剩余尝试次数
+
+AT+CMEE # 移动设备错误报告
+
+AT+CGMI # 请求制造商标识
+
+AT+CGSN # 请求产品序列号标识 (IMEI)
+
+AT+CLAC # 列出所有可用的AT命令 (重复)
+
+AT+RESET # 【未匹配到】
+
+AT+NLOGLEVEL # 【未匹配到】
+
+AT+NATSPEED # 【未匹配到】
+
+AT+NFWUPD # 【未匹配到】
+
+AT+NDSDELAY # 【未匹配到】
+
+AT+NCRASHINFO # 【未匹配到】
+
+AT+NTSETID # 【未匹配到】
+
+AT+NTPERMID # 【未匹配到】
+
+AT+NCHIPTYPE # 【未匹配到】
+
+AT+NQSTATE # 【未匹配到】
+
+AT+USIMSEL # 【未匹配到】
+
+AT+NVETOSUPERDS # 【未匹配到】
+
+AT+NBANKD # 【未匹配到】
+
+AT+NVER # 【未匹配到】
+
+AT+MODEMTEMP # 【未匹配到】
+
+AT+NRCUPD # 【未匹配到】
+
+AT+NLOGMODFT # 【未匹配到】
+
+AT+NRDCTRL # 【未匹配到】
+
+AT+NRDSET # 【未匹配到】
+
+AT+NRDEXEC # 【未匹配到】
+
+AT+NGOLD # 【未匹配到】
+
+AT+NDISDUP # 【未匹配到】
+
+AT+NPING # 【未匹配到】
+
+AT+NDNS # 【未匹配到】
+
+AT+NSOCR # 创建socket
+
+AT+NSOST # 发送数据到socket
+
+AT+NSOCO # 连接socket
+
+AT+NSOSD # 发送数据并关闭socket
+
+AT+NQSOS # 查询socket状态
+
+AT+NSORF # 从socket接收数据
+
+AT+NSOCL # 关闭socket
+
+AT+NSOSTATUS # 【未匹配到】
+
+AT+NCIDSTATUS # 【未匹配到】
+
+AT+NDATATRAN # 【未匹配到】
+
+AT+NIPINFO # 【未匹配到】
+
+AT+NKEEPALIVE # 【未匹配到】
+
+AT+NISEND # 【未匹配到】
+
+AT+NDATARATE # 【未匹配到】
+
+AT+NRDTEST # 【未匹配到】
+
+AT+NWIFISCAN # 【未匹配到】
+
+AT+NWIFISCANSTOP # 【未匹配到】
+
+AT+NTXPOWER # 【未匹配到】
+
+AT+DEMO # 【未匹配到】
+
+AT+IVSN # 【未匹配到】
+
+AT+GMR # 请求修订版本标识 (固件版本)
+
+AT+FTCAL # 【未匹配到】
+
+AT+FTRF # 【未匹配到】
+
+AT+IMEI # 【未匹配到】
+
+AT+IFC # 设置本地数据流控制
+
+AT+ICF # 设置字符格式
+
+AT+IPR # 设置波特率
+
+AT+NWIDCFG # 【未匹配到】
+
+AT+CERTADD # 【未匹配到】
+
+AT+CERTCHECK # 【未匹配到】
+
+AT+CERTDEL # 【未匹配到】
+
+AT+IPINFO # 【未匹配到】
+
+AT+IPSTATUS # 【未匹配到】
+
+AT+PDPKEEPALIVE # 【未匹配到】
+
+AT+PDPSTATUS # 【未匹配到】
+
+AT+RECVMODE # 【未匹配到】
+
+AT+TCPACK # TCP确认
+
+AT+TCPCLOSE # 关闭TCP连接
+
+AT+TCPKEEPALIVE # TCP保活设置
+
+AT+TCPREAD # 读取TCP数据
+
+AT+TCPSEND # 发送TCP数据
+
+AT+TCPSETUP # 建立TCP连接
+
+AT+TCPTRANS # TCP透传模式
+
+AT+TRANSCLOSE # 关闭透传连接
+
+AT+UDPCLOSE # 关闭UDP连接
+
+AT+UDPREAD # 读取UDP数据
+
+AT+UDPSEND # 发送UDP数据
+
+AT+UDPSETUP # 建立UDP连接
+
+AT+UDPTRANS # UDP透传模式
+
+AT+CESQ # 扩展信号质量
+
+AT+CPSERVICE # 【未匹配到】
+
+AT+ENPWRSAVE # 【未匹配到】
+
+AT+NFTCHIPTYPE # 【未匹配到】
+
+AT+NFTFBACKUP # 【未匹配到】
+
+AT+NFTRCAL # 【未匹配到】
+
+AT+NFTRCREG # 【未匹配到】
+
+AT+NFTRCSQ # 【未匹配到】
+
+AT+NFTRFBAK # 【未匹配到】
+
+AT+NFTRFIT # 【未匹配到】
+
+AT+NWENPWRSAVE # 【未匹配到】
+
+AT+QCNVERSION # 【未匹配到】
+
+AT+READADC # 【未匹配到】
+
+AT+CCID # 读取ICCID (SIM卡序列号) - 同AT+ICCID
+
+AT+CNUM # 用户号码
+
+AT+NWCCID # 【未匹配到】
+
+AT+NWSIMCFG # 【未匹配到】
+
+AT+NWSIMDET # 【未匹配到】
+
+AT+NWSIMWRCNT # 【未匹配到】
+
+AT+NWSIMWRCNTCTL # 【未匹配到】
+
+AT+SIMCROSS # 【未匹配到】
+
+AT+SIMHOTSWAP # 【未匹配到】
+
+AT+NETSHAREACT # 【未匹配到】
+
+AT+XIIC # 建立PDP链接 (PPP拨号: 1=连接,0=断开)
+
+AT+CGMM # 请求型号标识
+
+AT+CGMR # 请求修订版本标识
+
+AT+GMM # 请求型号标识 (同AT+CGMM)
+
+AT+GSN # 请求产品序列号 (同AT+CGSN)
+
+AT+HEAPINFO # 【未匹配到】
+
+AT+NETSHAREMODE # 【未匹配到】
+
+AT+BANDLOCK # 【未匹配到】
+
+AT+MYCELLINFO # 【未匹配到】
+
+AT+MYCGED # 【未匹配到】
+
+AT+MYLACID # 【未匹配到】
+
+AT+MYNETINFO # 【未匹配到】
+
+AT+MYSYSINFO # 【未匹配到】
+
+AT+MYSYSINFOURC # 【未匹配到】
+
+AT+MYURCSYSINFO # 【未匹配到】
+
+AT+NBANDLOCK # 【未匹配到】
+
+AT+NETDMSG # 【未匹配到】
+
+AT+NETMSG # 【未匹配到】
+
+AT+NFREQLOCK # 【未匹配到】
+
+AT+NRSP # 【未匹配到】
+
+AT+NSTGETRSSI # 【未匹配到】
+
+AT+NWENG # 【未匹配到】
+
+AT+NWRFTEST # 【未匹配到】
+
+AT&F # 恢复出厂设置
+
+AT&W # 存储当前配置
+
+AT&V # 显示当前配置
+
+ATD # 拨号 (标准PPP拨号命令)
+
+ATH # 挂断 (挂断当前连接)
+
+ATS0 # 自动应答设置
+
+ATE # 回显控制 (ATE0=关闭回显,ATE1=开启回显)
+
+ATO # 返回在线模式
+
+ATI # 请求标识信息
+
+OK # 命令执行成功响应
+
+# 统计信息:
+# 总命令数: 400
+# 已匹配标准AT命令: ~60个 (3GPP标准命令)
+# 已匹配Neoway扩展命令: ~15个 (如XIIC, TCPSETUP等)
+# 未匹配: ~325个 (大部分是Neoway专有扩展命令,以N开头)
+#
+# 说明:
+# 1. 标准3GPP AT命令(如AT+CFUN, AT+CSQ等)在手册中都有详细说明
+# 2. Neoway扩展的TCP/UDP相关命令(TCPSETUP, UDPSETUP等)也有说明
+# 3. 大量以"AT+N"开头的命令是Neoway专有扩展,手册中可能未包含
+# 4. 部分命令可能是内部测试或调试用途
+#
+# 重要命令说明:
+# - AT+XIIC: Neoway专有的PPP拨号命令,等同于标准的ATD*99***1#
+# - AT+CFUN: 模组功能设置,1=全功能,4=飞行模式
+# - AT+CREG: 网络注册状态查询
+# - AT+CGDCONT: PDP上下文设置,用于配置APN
+# - AT+TCPSETUP/UDPSETUP: Neoway专有的TCP/UDP连接建立命令
\ No newline at end of file
--- /dev/null
+
\ No newline at end of file
--- /dev/null
+
\ No newline at end of file
--- /dev/null
+
\ No newline at end of file
};
static char result_data[256] = {0};
-static char hostname[20] = {0};
+static char hostname[128] = {0};
void get_ping_hostname(char *databuf,uint8_t len)
{
-
#include "at_cmd_api.h"
#include "pm_control.h"
#include "ppp_at_cmd.h"
return ERRCODE_SUCC;
}
+/**
+ * @brief AT^PPPSIGNALINFO - 获取网络信号信息
+ */
+static errcode_t at_ppp_get_signal_info(uint8_t *para, uint32_t paraLen)
+{
+ (void)para;
+ (void)paraLen;
+
+ PRINT("[PPP_INFO]PPP SIGNAL INFO: Getting network signal information...\r\n");
+
+ errcode_t ret = ppp_get_network_signal_info();
+ if (ret == ERRCODE_SUCC) {
+ PRINT("[PPP_INFO]PPP SIGNAL INFO: Network signal information retrieved successfully\r\n");
+ } else {
+ PRINT("[PPP_ERR]PPP SIGNAL INFO: Failed to get network signal information, error: %d\r\n", ret);
+ }
+
+ return ret;
+}
+
/* UART回调测试指令 */
static errcode_t at_ppp_test_uart_callback(uint8_t *para, uint32_t paraLen)
{
{ (char *)"AT^STOPWSMULTI", at_ws_multi_test_stop, (char *)" " },
{ (char *)"AT^WSMULTISTATUS", at_ws_multi_test_status, (char *)" " },
#endif
+ { (char *)"AT^PPPSIGNALINFO", at_ppp_get_signal_info, (char *)" " },
};
at_cmd_table_t *get_ppp_cmd_table(uint32_t *cmd_count)
/* 1. 配置PPP拨号参数 */
ppp_config_t config = {
- .apn = "cmnet", // 中国移动APN
+ .apn = "CMIOTZSZCGRE.GD", // 中国移动APN cmnet
.username = "", // 用户名(通常为空)
.password = "", // 密码(通常为空)
- .baudrate = 2000000, // 2M波特率
+ .baudrate = PPP_UART_BAUDRATE, // 2M波特率
.auto_baudrate = true, // 启用自动波特率检测
.dial_timeout = 30000, // 30秒拨号超时
.retry_count = 3 // 重试3次
+++ /dev/null
-/*
- * @brief PPP模块电源控制使用示例
- * @description 演示如何使用PPP模块的电源控制功能
- * Copyright (c) CompanyNameMagicTag 2024-2024. All rights reserved.
- */
-
-#include "ppp_api.h"
-#include "ppp_power_ctl.h"
-#include "ppp_debug.h"
-#include "osal_debug.h"
-#include "platform_core.h"
-
-// 外部声明cat1Service兼容接口(在ppp_cat1_api.c中实现)
-extern void cat1_api_enable_cat1(bool isopen);
-extern bool cat1_api_is_cat1_enabled(void);
-extern uint8_t cat1_api_runtime_get_cat1_powerstat(void);
-
-/**
- * @brief PPP电源控制示例
- */
-void ppp_power_control_example(void)
-{
- PPP_DEBUG_PRINT("=== PPP Power Control Example ===\n");
-
- // 1. 配置4G控制引脚
- ppp_ctl_pin_4g_t pin_config = {
- .bat_pin = S_AGPIO_L17,
- .bat_pin_en_value = 1,
- .pwr_pin = S_AGPIO_L23,
- .pwr_pin_en_value = 1,
- .reset_pin = S_AGPIO_L28,
- .reset_pin_en_value = 0,
- .ring_pin = PIN_NONE,
- .ring_pin_en_value = 0,
- .wakemodem_pin = PIN_NONE,
- .wakemodem_pin_en_value = 0
- };
-
- // 2. 注册控制引脚配置
- errcode_t ret = ppp_register_ctl_pin(&pin_config);
- if (ret != ERRCODE_SUCC) {
- PPP_DEBUG_PRINT("Failed to register control pins: %d\n", ret);
- return;
- }
-
- PPP_DEBUG_PRINT("Control pins registered successfully\n");
-
- // 3. 使用PPP专用接口控制4G电源
- PPP_DEBUG_PRINT("Testing PPP-specific power control...\n");
-
- // 开启4G电源
- ppp_api_enable_cat1(true);
- osal_msleep(1000);
-
- // 检查电源状态
- bool enabled = ppp_api_is_cat1_enabled();
- PPP_DEBUG_PRINT("4G power status (PPP): %s\n", enabled ? "ON" : "OFF");
-
- osal_msleep(2000);
-
- // 关闭4G电源
- ppp_api_enable_cat1(false);
- osal_msleep(1000);
-
- enabled = ppp_api_is_cat1_enabled();
- PPP_DEBUG_PRINT("4G power status (PPP): %s\n", enabled ? "ON" : "OFF");
-
- // 4. 使用兼容接口控制4G电源(推荐方式)
- PPP_DEBUG_PRINT("Testing compatible power control interface...\n");
-
- // 开启4G电源(通过兼容接口)
- cat1_api_enable_cat1(true);
- osal_msleep(1000);
-
- // 检查电源状态(通过兼容接口)
- enabled = cat1_api_is_cat1_enabled();
- PPP_DEBUG_PRINT("4G power status (Compatible): %s\n", enabled ? "ON" : "OFF");
-
- // 获取运行时状态
- uint8_t power_stat = cat1_api_runtime_get_cat1_powerstat();
- PPP_DEBUG_PRINT("4G runtime power status: %d\n", power_stat);
-
- osal_msleep(2000);
-
- // 关闭4G电源(通过兼容接口)
- cat1_api_enable_cat1(false);
- osal_msleep(1000);
-
- enabled = cat1_api_is_cat1_enabled();
- PPP_DEBUG_PRINT("4G power status (Compatible): %s\n", enabled ? "ON" : "OFF");
-
- PPP_DEBUG_PRINT("=== PPP Power Control Example Completed ===\n");
-}
-
-/**
- * @brief PPP完整拨号示例(包含电源控制)
- */
-void ppp_dial_with_power_example(void)
-{
- PPP_DEBUG_PRINT("=== PPP Dial with Power Control Example ===\n");
-
- // 1. 初始化PPP配置
- ppp_config_t config = {
- .apn = "cmnet",
- .username = "",
- .password = "",
- .baudrate = 115200,
- .auto_baudrate = true,
- .dial_timeout = 30000,
- .retry_count = 3
- };
-
- // 2. 初始化PPP模块
- errcode_t ret = zhihui_ppp_init(&config);
- if (ret != ERRCODE_SUCC) {
- PPP_DEBUG_PRINT("Failed to initialize PPP: %d\n", ret);
- return;
- }
-
- PPP_DEBUG_PRINT("PPP module initialized\n");
-
- // 3. 启动PPP拨号(内部会自动控制4G电源)
- ret = ppp_start_dial();
- if (ret != ERRCODE_SUCC) {
- PPP_DEBUG_PRINT("Failed to start PPP dial: %d\n", ret);
- zhihui_ppp_deinit();
- return;
- }
-
- PPP_DEBUG_PRINT("PPP dial started\n");
-
- // 4. 等待连接建立(实际应用中应该通过事件回调处理)
- PPP_DEBUG_PRINT("Waiting for connection...\n");
- osal_msleep(10000);
-
- // 5. 检查连接状态
- ppp_state_t state = ppp_get_state();
- PPP_DEBUG_PRINT("PPP state: %d\n", state);
-
- // 6. 获取连接信息
- ppp_connection_info_t conn_info;
- ret = ppp_get_connection_info(&conn_info);
- if (ret == ERRCODE_SUCC) {
- PPP_DEBUG_PRINT("Connection info retrieved\n");
- PPP_DEBUG_PRINT(" Connected: %s\n", conn_info.connected ? "Yes" : "No");
- PPP_DEBUG_PRINT(" Local IP: 0x%08X\n", conn_info.local_ip);
- PPP_DEBUG_PRINT(" Remote IP: 0x%08X\n", conn_info.remote_ip);
- PPP_DEBUG_PRINT(" Primary DNS: 0x%08X\n", conn_info.primary_dns);
- PPP_DEBUG_PRINT(" MTU: %d\n", conn_info.mtu);
- }
-
- // 7. 保持连接一段时间
- PPP_DEBUG_PRINT("Keeping connection for 30 seconds...\n");
- osal_msleep(30000);
-
- // 8. 停止PPP连接(内部会自动控制4G电源)
- ret = ppp_stop_dial();
- if (ret != ERRCODE_SUCC) {
- PPP_DEBUG_PRINT("Failed to stop PPP dial: %d\n", ret);
- } else {
- PPP_DEBUG_PRINT("PPP dial stopped\n");
- }
-
- // 9. 去初始化PPP模块
- zhihui_ppp_deinit();
- PPP_DEBUG_PRINT("PPP module deinitialized\n");
-
- PPP_DEBUG_PRINT("=== PPP Dial with Power Control Example Completed ===\n");
-}
-
-/**
- * @brief 主函数示例
- */
-int main(void)
-{
- // 系统初始化(根据实际系统调整)
- // system_init();
-
- PPP_DEBUG_PRINT("Starting PPP power control examples...\n");
-
- // 运行电源控制示例
- ppp_power_control_example();
-
- osal_msleep(5000);
-
- // 运行完整拨号示例
- ppp_dial_with_power_example();
-
- PPP_DEBUG_PRINT("All examples completed\n");
-
- return 0;
-}
\ No newline at end of file
*/
bool ppp_lwip_is_receive_thread_running(void);
+/**
+ * @brief 获取并显示网络信号信息
+ * @return ERRCODE_SUCC-成功,其他-失败
+ */
+errcode_t ppp_get_network_signal_info(void);
+
#ifdef __cplusplus
}
#endif
*/
ppp_error_t ppp_at_test_communication(void);
+/**
+ * @brief 网络信号信息结构体 (基于AT+CESQ命令)
+ */
+typedef struct {
+ // CESQ命令的信号参数
+ int16_t rxlev; // GSM信号接收功率 (0-63, 99=无效)
+ int16_t ber; // 误码率 (0-7, 99=无效)
+ int16_t rscp; // UMTS下行载波干扰比率 (0-96, 255=无效)
+ int16_t ecno; // UMTS下行载波干扰比率 (0-49, 255=无效)
+ int16_t rsrq; // LTE参考信号质量 (0-34, 255=无效)
+ int16_t rsrp; // LTE参考信号接收功率 (0-97, 255=无效)
+
+ bool valid; // 数据是否有效
+} ppp_network_signal_info_t;
+
+/**
+ * @brief 获取网络信号信息
+ * @param info 信号信息结构体指针
+ * @return 错误码
+ */
+ppp_error_t ppp_at_get_network_signal_info(ppp_network_signal_info_t *info);
+
#ifdef __cplusplus
}
#endif
#define SIO_UART_IRQ_NUM UART_0_IRQN // UART IRQ引脚
#endif
+#define PPP_UART_BAUDRATE 2000000
+
/* 支持的波特率列表(自适应模式) */
-#define PPP_BAUDRATE_AUTO_LIST {2000000, 9600, 57600, 115200 }
+#define PPP_BAUDRATE_AUTO_LIST {9600, 57600, 115200, 921600}
#define PPP_BAUDRATE_AUTO_COUNT 4
/* 支持的固定波特率列表 */
/* 调试配置 */
#define PPP_DEBUG_ENABLE 1 // 启用调试输出
-#define PPP_DEBUG_LEVEL PPP_DEBUG_LEVEL_WARN // 默认只显示警告和错误 (1=ERROR, 2=WARN, 3=INFO, 4=DEBUG)
+#define PPP_DEBUG_LEVEL PPP_DEBUG_LEVEL_DEBUG // 默认只显示警告和错误 (1=ERROR, 2=WARN, 3=INFO, 4=DEBUG)
/*
* 调试级别说明:
static void ppp_check_and_update_state(void);
errcode_t ppp_api_get_ppp_netif_name(char* netif_name, uint32_t buffer_size);
-/**
- * @brief 初始化PPP模块
- */
-errcode_t zhihui_ppp_init(const ppp_config_t *config)
-{
- if (!config) {
- PPP_DEBUG_PRINT("PPP init: invalid config parameter\n");
- return ERRCODE_FAIL;
- }
- if (g_ppp_state != PPP_STATE_IDLE) {
- PPP_DEBUG_PRINT("PPP init: already initialized, current state: %d\n", g_ppp_state);
+
+errcode_t ppp_api_power_init(void)
+{
+ if (g_4g_power_initialized) {
+ PPP_DEBUG_PRINT("4G power already initialized\n");
return ERRCODE_SUCC;
}
- PPP_DEBUG_PRINT("Initializing PPP module with zhihui API\n");
-
- // 保存用户配置
- memcpy_s(&g_ppp_config, sizeof(ppp_config_t), config, sizeof(ppp_config_t));
-
// 1. GPIO初始化
- PPP_DEBUG_PRINT("Step 1: Initializing GPIO system\n");
- ppp_api_gpio_init();
-
+
// 2. CAT1电源操作
- PPP_DEBUG_PRINT("Step 2: Configuring and enabling CAT1 power\n");
+ PPP_DEBUG_PRINT("Step 1: Configuring CAT1 power pins\n");
// 配置4G电源控制引脚
ppp_ctl_pin_4g_t pin_config = {
.pwr_pin = S_AGPIO_L23,
.pwr_pin_en_value = 1,
.reset_pin = S_AGPIO_L24,
- .reset_pin_en_value = 0,
- .ring_pin = PIN_NONE,
- .ring_pin_en_value = 0,
- .wakemodem_pin = S_MGPIO22,
- .wakemodem_pin_en_value = 1
+ .reset_pin_en_value = 1, //电路中 控制gpio拉高,reset才拉低
+ .ring_pin = S_MGPIO21, //CTS cat1 wakeup mcu
+ .ring_pin_en_value = 2, //2 双边沿中断 , 1 上升沿中断 , 0 下降沿中断
+ .wakemodem_pin = S_MGPIO22, //RTS mcu wakeup cat1
+ .wakemodem_pin_en_value = 1 //1 唤醒cat1 , 0 休眠cat1
};
-
+
// 注册4G电源控制引脚配置
- errcode_t power_ret = ppp_register_ctl_pin(&pin_config);
- if (power_ret != ERRCODE_SUCC) {
- PPP_DEBUG_PRINT("Failed to register 4G power control pins: %d\n", power_ret);
- PPP_DEBUG_PRINT("Continuing without power control...\n");
- g_4g_power_initialized = false;
- } else {
- PPP_DEBUG_PRINT("4G power control pins registered successfully\n");
- g_4g_power_initialized = true;
-
+ ppp_register_ctl_pin(&pin_config);
+
+ PPP_DEBUG_PRINT("Step 2: Initializing GPIO system\n");
+ ppp_api_gpio_init();
+
+ PPP_DEBUG_PRINT("4G power control pins registered successfully\n");
+ g_4g_power_initialized = true;
+ return ERRCODE_SUCC;
+}
+
+errcode_t ppp_api_power_control(bool is_open)
+{
+ if (is_open) {
// 启用4G电源
PPP_DEBUG_PRINT("Enabling 4G module power...\n");
cat1_api_enable_cat1(true);
- osal_msleep(2000); // 等待电源稳定
-
+ osal_msleep(500);
+
// 唤醒4G模块
PPP_DEBUG_PRINT("Waking up 4G module...\n");
cat1_api_wakeup_cat1(true);
- osal_msleep(1000); // 等待唤醒完成
-
- // 检查电源状态
- bool power_enabled = cat1_api_is_cat1_enabled();
- uint8_t power_stat = cat1_api_runtime_get_cat1_powerstat();
- PPP_DEBUG_PRINT("4G power status: %s (runtime stat: %d)\n",
- power_enabled ? "ON" : "OFF", power_stat);
+
+ } else {
+ PPP_DEBUG_PRINT("Sleeping 4G module power...\n");
+ // 唤醒4G模块
+ cat1_api_wakeup_cat1(false);
+ osal_msleep(500);
+ // 启用4G电源
+ PPP_DEBUG_PRINT("Disabling 4G module power...\n");
+ cat1_api_enable_cat1(false);
+ }
+
+ // 检查电源状态
+ bool power_enabled = cat1_api_is_cat1_enabled();
+ uint8_t power_stat = cat1_api_runtime_get_cat1_powerstat();
+ PPP_DEBUG_PRINT("4G power status: %s (runtime stat: %d)\n",
+ power_enabled ? "ON" : "OFF", power_stat);
+ return ERRCODE_SUCC;
+}
+
+
+
+/**
+ * @brief 初始化PPP模块
+ *
+ * 1. 初始化电源控制模块
+ * 2. 打开4G电源
+ * 3. 等待5秒,确保模块稳定
+ * 4. 初始化串口,设置为AT模式
+ * 5. 测试AT指令通信
+ * - 如果默认波特率下AT指令成功,配置环境变量并返回成功
+ * - 否则,尝试自动波特率握手,重置到默认波特率下工作
+ * - 若仍失败,则初始化失败
+ */
+errcode_t zhihui_ppp_init(const ppp_config_t *config)
+{
+ if (!config) {
+ PPP_DEBUG_PRINT("PPP init: invalid config parameter\n");
+ return ERRCODE_FAIL;
}
+ if (g_ppp_state != PPP_STATE_IDLE) {
+ PPP_DEBUG_PRINT("PPP init: already initialized, current state: %d\n", g_ppp_state);
+ return ERRCODE_SUCC;
+ }
+
+ PPP_DEBUG_PRINT("Initializing PPP module with zhihui API\n");
+
+ // 保存用户配置
+ memcpy_s(&g_ppp_config, sizeof(ppp_config_t), config, sizeof(ppp_config_t));
+
+ ppp_api_power_init();
+
+ ppp_api_power_control(true);
+
+ // 额外等待时间,让调制解调器完全稳定(特别是在硬件复位后)
+ PPP_DEBUG_PRINT("Waiting for modem stabilization after power control...\n");
+ osal_msleep(5000); // 等待5秒让调制解调器完全稳定
+
// 3. UART初始化
PPP_DEBUG_PRINT("Step 3: Initializing UART for AT mode\n");
ppp_serial_config_t serial_config = {
.rx_callback = NULL,
.rx_callback_arg = NULL
};
+
ppp_error_t ret = ppp_serial_init(&serial_config);
if (ret != PPP_ERR_OK) {
PPP_DEBUG_PRINT("Failed to initialize serial for AT mode: %d\n", ret);
goto init_failed;
}
- // 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");
- }
-
// 5. 默认工作在AT指令模式
PPP_DEBUG_PRINT("Step 5: Ensuring default AT command mode\n");
ret = ppp_serial_switch_to_at_mode();
} 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");
+ }
+
g_ppp_state = PPP_STATE_INITIALIZED;
init_failed:
// 初始化失败,关闭4G电源
- if (g_4g_power_initialized) {
- PPP_DEBUG_PRINT("Disabling 4G power due to initialization failure\n");
- cat1_api_wakeup_cat1(false);
- osal_msleep(500);
- cat1_api_enable_cat1(false);
- g_4g_power_initialized = false;
- }
+ // ppp_api_power_control(false);
return ERRCODE_FAIL;
}
// 6. 重新初始化AT处理器
PPP_DEBUG_INFO("Reinitializing AT handler...");
- ret = ppp_at_handler_init(0); // 使用UART bus 0
+ ret = ppp_at_handler_init(SIO_UART_BUS); // 使用UART bus 0
if (ret != PPP_ERR_OK) {
PPP_DEBUG_ERROR("Failed to reinitialize AT handler: %d", ret);
return ERRCODE_FAIL;
}
// 7. 验证AT模式是否正常工作
- PPP_DEBUG_INFO("Verifying AT mode...");
- ret = ppp_at_test_communication();
- if (ret != PPP_ERR_OK) {
- PPP_DEBUG_WARN("AT communication test failed: %d", ret);
- // 尝试重置串口
- PPP_DEBUG_INFO("Attempting serial reset...");
+ PPP_DEBUG_INFO("Verifying AT mode with enhanced recovery...");
+
+ // 多次尝试AT通信,每次尝试前清理串口缓冲区
+ bool at_communication_ok = false;
+ for (int attempt = 1; attempt <= 5; attempt++) {
+ PPP_DEBUG_INFO("AT communication attempt %d/5...", attempt);
+
+ // 清理串口缓冲区
ppp_serial_reset();
- osal_msleep(100);
+ osal_msleep(500);
+
+ // 尝试AT通信
ret = ppp_at_test_communication();
- if (ret != PPP_ERR_OK) {
- PPP_DEBUG_ERROR("Serial reset failed, AT communication still broken");
+ if (ret == PPP_ERR_OK) {
+ PPP_DEBUG_INFO("AT communication successful on attempt %d", attempt);
+ at_communication_ok = true;
+ break;
+ } else {
+ PPP_DEBUG_WARN("AT communication failed on attempt %d: %d", attempt, ret);
+ if (attempt < 5) {
+ // 在重试之前,尝试发送一些基本的AT命令来"唤醒"调制解调器
+ PPP_DEBUG_INFO("Sending wake-up AT commands...");
+ uint8_t at_wake[] = "AT\r\n";
+ ppp_serial_write(at_wake, sizeof(at_wake)-1);
+ osal_msleep(1000);
+
+ // 清理可能的响应
+ uint8_t dummy_buffer[128];
+ uint32_t dummy_read = 0;
+ ppp_serial_read(dummy_buffer, sizeof(dummy_buffer), &dummy_read);
+
+ osal_msleep(1000); // 等待1秒再重试
+ }
}
}
+ if (!at_communication_ok) {
+ PPP_DEBUG_ERROR("AT communication failed after 5 attempts - modem may need manual intervention");
+ // 不返回错误,继续执行,让上层决定如何处理
+ }
+
+ // 8. 发送AT挂断命令确保PPP连接完全断开
+ if (at_communication_ok) {
+ PPP_DEBUG_INFO("Sending AT hangup command to ensure PPP disconnection...");
+ ppp_error_t hangup_ret = ppp_at_hangup_ppp();
+ if (hangup_ret != PPP_ERR_OK) {
+ PPP_DEBUG_WARN("AT hangup command failed: %d", hangup_ret);
+ // 不作为致命错误,因为PPP可能已经通过其他方式断开
+ } else {
+ PPP_DEBUG_INFO("AT hangup command completed successfully");
+ }
+ } else {
+ PPP_DEBUG_WARN("Skipping AT hangup command due to communication issues");
+ }
+
PPP_DEBUG_CRITICAL("=== PPP Stop Dial Completed ===");
// 设置最终状态为已初始化
// 设置状态为断开中
g_ppp_state = PPP_STATE_DISCONNECTING;
+ ppp_error_t ret = PPP_ERR_OK; // 声明ret变量
+ bool at_communication_ok = false; // 声明AT通信状态变量
+
// 1. 首先停止PPP数据接收线程(在切换串口模式之前)
PPP_DEBUG_INFO("Stopping PPP receive thread...");
ppp_lwip_stop_receive_thread();
PPP_DEBUG_INFO("Cleaning up lwIP PPP resources...");
ppp_lwip_deinit();
+ // 4.5. 发送PPP标准挂断序列 - 通知调制解调器退出PPP数据模式
+ PPP_DEBUG_INFO("Sending PPP standard hangup sequence to modem...");
+
+ // 等待确保前面的操作完成
+ osal_msleep(1000);
+
+ // // 方法1:发送+++转义序列切换调制解调器到命令模式
+ // PPP_DEBUG_INFO("Sending escape sequence (+++) to switch modem to command mode...");
+ // const char escape_seq[] = "+++";
+ // ppp_error_t escape_ret = ppp_serial_write((uint8_t*)escape_seq, strlen(escape_seq));
+ // if (escape_ret == PPP_ERR_OK ) {
+ // PPP_DEBUG_INFO("Escape sequence sent successfully");
+ // osal_msleep(2000); // 增加等待时间到2秒
+
+ // // 尝试读取调制解调器响应
+ // uint8_t response_buffer[64];
+ // uint32_t bytes_read = 0;
+ // ppp_serial_read(response_buffer, sizeof(response_buffer), &bytes_read);
+ // if (bytes_read > 0) {
+ // PPP_DEBUG_INFO("Modem response to escape sequence: %u bytes", bytes_read);
+ // } else {
+ // PPP_DEBUG_WARN("No immediate response from modem after escape sequence");
+ // }
+
+ // // 发送N706A专用的断开命令
+ // PPP_DEBUG_INFO("Sending N706A hangup command (AT+XIIC=0)...");
+ // uint8_t xiic_cmd[] = "AT+XIIC=0\r\n";
+ // ppp_serial_write(xiic_cmd, sizeof(xiic_cmd)-1);
+ // osal_msleep(1000);
+
+ // // 读取XIIC命令的响应
+ // ppp_serial_read(response_buffer, sizeof(response_buffer), &bytes_read);
+ // if (bytes_read > 0) {
+ // PPP_DEBUG_INFO("Modem response to XIIC=0: %u bytes", bytes_read);
+ // }
+ // } else {
+ // PPP_DEBUG_WARN("Failed to send escape sequence to modem");
+ // }
+
+ // 方法2:如果软件方法失败,使用硬件复位确保调制解调器状态
+ PPP_DEBUG_INFO("Applying hardware reset to ensure clean modem state...");
+
+ // 使用4G电源控制进行复位
+ PPP_DEBUG_INFO("Performing gentle 4G modem reset...");
+
+ // 第二步:短暂断电复位(更温和的方式)
+ PPP_DEBUG_INFO("Step 2: Brief power cycle...");
+ ppp_api_cat1_reset(1);
+ osal_msleep(500); // 减少断电时间到1秒
+ ppp_api_cat1_reset(0);
+ osal_msleep(5000); // 等待2秒让调制解调器启动
+
+ PPP_DEBUG_INFO("Gentle 4G modem reset completed - modem should be stable now");
+
// 5. 现在安全地切换串口回AT命令模式
PPP_DEBUG_INFO("Switching serial to AT mode...");
- ppp_error_t ret = ppp_serial_switch_to_at_mode();
+ ret = ppp_serial_switch_to_at_mode();
if (ret != PPP_ERR_OK) {
PPP_DEBUG_ERROR("Failed to switch to AT mode: %d", ret);
return ret;
// 6. 重新初始化AT处理器
PPP_DEBUG_INFO("Reinitializing AT handler...");
- ret = ppp_at_handler_init(0); // 使用UART bus 0
+ ret = ppp_at_handler_init(SIO_UART_BUS); // 使用UART bus 0
if (ret != PPP_ERR_OK) {
PPP_DEBUG_ERROR("Failed to reinitialize AT handler: %d", ret);
return ret;
}
// 7. 验证AT模式是否正常工作
- PPP_DEBUG_INFO("Verifying AT mode...");
- ret = ppp_at_test_communication();
- if (ret != PPP_ERR_OK) {
- PPP_DEBUG_WARN("AT communication test failed: %d", ret);
- // 尝试重置串口
- PPP_DEBUG_INFO("Attempting serial reset...");
+ PPP_DEBUG_INFO("Verifying AT mode with enhanced recovery...");
+
+ // 多次尝试AT通信,每次尝试前清理串口缓冲区
+ at_communication_ok = false;
+ for (int attempt = 1; attempt <= 5; attempt++) {
+ PPP_DEBUG_INFO("AT communication attempt %d/5...", attempt);
+
+ // 清理串口缓冲区
ppp_serial_reset();
- osal_msleep(100);
+ osal_msleep(500);
+
+ // 尝试AT通信
ret = ppp_at_test_communication();
- if (ret != PPP_ERR_OK) {
- PPP_DEBUG_ERROR("Serial reset failed, AT communication still broken");
+ if (ret == PPP_ERR_OK) {
+ PPP_DEBUG_INFO("AT communication successful on attempt %d", attempt);
+ at_communication_ok = true;
+ break;
+ } else {
+ PPP_DEBUG_WARN("AT communication failed on attempt %d: %d", attempt, ret);
+ if (attempt < 5) {
+ // 在重试之前,尝试发送一些基本的AT命令来"唤醒"调制解调器
+ PPP_DEBUG_INFO("Sending wake-up AT commands...");
+ uint8_t at_wake[] = "AT\r\n";
+ ppp_serial_write(at_wake, sizeof(at_wake)-1);
+ osal_msleep(1000);
+
+ // 清理可能的响应
+ uint8_t dummy_buffer[128];
+ uint32_t dummy_read = 0;
+ ppp_serial_read(dummy_buffer, sizeof(dummy_buffer), &dummy_read);
+
+ osal_msleep(1000); // 等待1秒再重试
+ }
}
}
+ if (!at_communication_ok) {
+ PPP_DEBUG_ERROR("AT communication failed after 5 attempts - modem may need manual intervention");
+ // 不返回错误,继续执行,让上层决定如何处理
+ }
+
+ // 8. 发送AT挂断命令确保PPP连接完全断开
+ if (at_communication_ok) {
+ PPP_DEBUG_INFO("Sending AT hangup command to ensure PPP disconnection...");
+ ppp_error_t hangup_ret = ppp_at_hangup_ppp();
+ if (hangup_ret != PPP_ERR_OK) {
+ PPP_DEBUG_WARN("AT hangup command failed: %d", hangup_ret);
+ // 不作为致命错误,因为PPP可能已经通过其他方式断开
+ } else {
+ PPP_DEBUG_INFO("AT hangup command completed successfully");
+ }
+ } else {
+ PPP_DEBUG_WARN("Skipping AT hangup command due to communication issues");
+ }
+
PPP_DEBUG_CRITICAL("=== PPP Stop Dial Completed ===");
// 设置最终状态为已初始化
}
// 2. 去初始化串口和AT处理器
- PPP_DEBUG_PRINT("Deinitializing serial and AT handler\n");
- ppp_at_handler_deinit();
- ppp_serial_deinit();
-
- // 3. 关闭4G电源
- if (g_4g_power_initialized) {
- PPP_DEBUG_PRINT("Disabling 4G module power\n");
-
- // 让4G模块进入休眠状态
- PPP_DEBUG_PRINT("Putting 4G module to sleep\n");
- cat1_api_wakeup_cat1(false);
- osal_msleep(500);
-
- // 关闭4G电源
- PPP_DEBUG_PRINT("Turning off 4G module power\n");
- cat1_api_enable_cat1(false);
- osal_msleep(1000);
-
- g_4g_power_initialized = false;
- PPP_DEBUG_PRINT("4G power disabled successfully\n");
- }
+ // PPP_DEBUG_PRINT("Deinitializing serial and AT handler\n");
+ // ppp_at_handler_deinit();
+ // ppp_serial_deinit();
+
+ // // 3. 关闭4G电源
+ // PPP_DEBUG_INFO("Power off modem");
+ // extern ppp_error_t ppp_at_poweroff_modem(uint8_t shutdown_type);
+ // ppp_error_t ret = ppp_at_poweroff_modem(0);
+ // if (ret != PPP_ERR_OK) {
+ // PPP_DEBUG_ERROR("Failed to power off modem");
+ // }
// 4. 清理资源
(void)memset_s(&g_ppp_config, sizeof(ppp_config_t), 0, sizeof(ppp_config_t));
(lwip_info.local_ip >> 24) & 0xFF);
}
}
+}
+
+/**
+ * @brief 获取并显示网络信号信息
+ * @return 错误码
+ */
+errcode_t ppp_get_network_signal_info(void)
+{
+ if (g_ppp_state == PPP_STATE_IDLE) {
+ PPP_DEBUG_ERROR("PPP not initialized");
+ return ERRCODE_FAIL;
+ }
+
+ PPP_DEBUG_INFO("Getting network signal information...");
+
+ ppp_network_signal_info_t signal_info;
+ ppp_error_t ret = ppp_at_get_network_signal_info(&signal_info);
+
+ if (ret != PPP_ERR_OK) {
+ PPP_DEBUG_ERROR("Failed to get network signal information: %d", ret);
+ return ERRCODE_FAIL;
+ }
+
+ if (!signal_info.valid) {
+ PPP_DEBUG_WARN("Network signal information is not valid");
+ return ERRCODE_FAIL;
+ }
+
+ // 输出格式化的信号信息摘要
+ PPP_DEBUG_CRITICAL("=== Network Signal Summary (AT+CESQ) ===");
+
+ // 仅关注LTE关键参数: RSRQ和RSRP
+ if (signal_info.rsrq != 255 && signal_info.rsrp != 255 &&
+ signal_info.rsrq >= 0 && signal_info.rsrq <= 49 &&
+ signal_info.rsrp >= 0 && signal_info.rsrp <= 97) {
+
+ // CESQ格式的RSRQ和RSRP转换 (使用正确公式)
+ float rsrq_db = (signal_info.rsrq - 94) / 10.0f; // (rsrq - 94)/10
+ float rsrp_dbm = signal_info.rsrp - 140.0f; // rsrp - 140
+
+ PPP_DEBUG_CRITICAL("LTE Signal Quality:");
+ PPP_DEBUG_CRITICAL(" RSRQ: %d (%.1f dB)", signal_info.rsrq, rsrq_db);
+ PPP_DEBUG_CRITICAL(" RSRP: %d (%.0f dBm)", signal_info.rsrp, rsrp_dbm);
+
+ // 综合质量评估 (基于RSRQ和RSRP)
+ const char *overall_quality = "未知";
+ if (rsrq_db >= -6.0 && rsrp_dbm >= -80) {
+ overall_quality = "LTE信号极佳 (质量和强度都优秀)";
+ } else if (rsrq_db >= -9.0 && rsrp_dbm >= -90) {
+ overall_quality = "LTE信号良好 (质量和强度都稳定)";
+ } else if (rsrq_db >= -12.0 && rsrp_dbm >= -100) {
+ overall_quality = "LTE信号一般 (质量和强度可用)";
+ } else {
+ overall_quality = "LTE信号较差 (需要改善网络环境)";
+ }
+
+ PPP_DEBUG_CRITICAL("Overall LTE Quality: %s", overall_quality);
+ } else {
+ PPP_DEBUG_CRITICAL("LTE参数无效,无法评估信号质量");
+ PPP_DEBUG_CRITICAL("RSRQ: %d, RSRP: %d", signal_info.rsrq, signal_info.rsrp);
+ }
+
+ PPP_DEBUG_CRITICAL("=== End Signal Summary ===");
+
+ return ERRCODE_SUCC;
}
\ No newline at end of file
}
g_at_ctx.uart_bus = uart_bus;
- g_at_ctx.current_baudrate = SIO_UART_BAUDRATE;
+ g_at_ctx.current_baudrate = PPP_UART_BAUDRATE;
g_at_ctx.auto_baudrate_mode = true;
/* 创建互斥锁 */
/**
* @brief 执行波特率自适应握手
+ *
+ * 进入自适应波特率,证明2000000没有正常工作,需要先reset,等5秒,开始设置自动握手的第一个波特率,
+ * 读取所有缓存数据丢掉,下达at指令,等待结果,重试3次,如果不成功,就设置第二个波特率,读取所有缓存数据丢掉,
+ * 下达at指令,等结果,重试3次,直至第三个波特率检测。如果都没有成功,则返回失败。
+ * 如果任何一次at指令返回正确ok,直接在当前设置下,下达指 AT+IPR 配置 2000000 波特率,并返回成功。
+ * 设置当前波特率为2000000,再次reset 模组,让其自动工作在 2000000波特率下。
*/
ppp_error_t ppp_at_baudrate_handshake(void)
{
return PPP_ERR_INVALID_PARAM;
}
- PPP_DEBUG_INFO("Starting baudrate handshake");
-
- /* 先发送一些字符清空缓冲区 */
- PPP_DEBUG_DEBUG("Clearing UART buffers...");
- const char *clear_cmd = "\r\n\r\n";
- uapi_uart_write(g_at_ctx.uart_bus, (const uint8_t *)clear_cmd, strlen(clear_cmd), 0);
- osal_msleep(200);
-
- /* 清空接收缓冲区 */
- uint8_t dummy_buffer[256];
- while (uapi_uart_read(g_at_ctx.uart_bus, dummy_buffer, sizeof(dummy_buffer), 100) > 0) {
- /* 继续清空 */
- }
+ PPP_DEBUG_INFO("Starting baudrate handshake (prove 2000000 not working, then try auto handshake)");
+
+ // 1. 先reset模组,证明2000000没有正常工作
+ PPP_DEBUG_INFO("Resetting module to prove 2000000 baudrate is not working...");
+ ppp_api_cat1_reset(1);
+ osal_msleep(50);
+ ppp_api_cat1_reset(0);
+ osal_msleep(5000);
- /* 尝试自适应波特率列表 */
+ // 2. 依次尝试自动波特率列表
for (int i = 0; i < PPP_BAUDRATE_AUTO_COUNT; i++) {
uint32_t baudrate = g_auto_baudrates[i];
-
- PPP_DEBUG_INFO("=== Trying Baudrate %u (attempt %d/%d) ===", baudrate, i + 1, PPP_BAUDRATE_AUTO_COUNT);
-
- /* 配置串口波特率 */
+ PPP_DEBUG_INFO("=== Trying Baudrate %u (index %d/%d) ===", baudrate, i + 1, PPP_BAUDRATE_AUTO_COUNT);
+
+ // 配置串口波特率
uart_attr_t uart_attr = {
.baud_rate = baudrate,
.data_bits = UART_DATA_BIT_8,
.parity = UART_PARITY_NONE,
.stop_bits = UART_STOP_BIT_1,
};
-
if (uapi_uart_set_attr(g_at_ctx.uart_bus, &uart_attr) != ERRCODE_SUCC) {
PPP_DEBUG_WARN("Failed to set baudrate %u", baudrate);
continue;
}
-
PPP_DEBUG_INFO("UART configured for baudrate %u", baudrate);
- /* 发送AT命令测试 */
- ppp_at_response_t response;
-
- /* 增加重试机制 */
+ // 清空接收缓冲区
+ PPP_DEBUG_DEBUG("Clearing UART RX buffer before AT test...");
+ uint8_t dummy_buffer[256];
+ int clear_cnt = 0;
+ while (uapi_uart_read(g_at_ctx.uart_bus, dummy_buffer, sizeof(dummy_buffer), 100) > 0) {
+ clear_cnt++;
+ }
+ if (clear_cnt > 0) {
+ PPP_DEBUG_DEBUG("Cleared %d RX buffer rounds", clear_cnt);
+ }
+
+ // 3次重试AT
ppp_error_t ret = PPP_ERR_AT_FAILED;
- for (int retry = 0; retry < 1; retry++) {
+ for (int retry = 0; retry < 3; retry++) {
PPP_DEBUG_INFO("--- AT Test at %u baud, retry %d/3 ---", baudrate, retry + 1);
- ret = ppp_at_send_command("AT", "OK", 3000, &response); // 增加超时到3秒
-
+
+ // 再次清空缓冲区,防止上次残留
+ 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);
+
if (ret == PPP_ERR_OK) {
PPP_DEBUG_INFO("AT command successful at baudrate %u", baudrate);
- break;
+
+ // 在当前波特率下,设置AT+IPR=2000000
+ char ipr_cmd[32];
+ snprintf_s(ipr_cmd, sizeof(ipr_cmd), sizeof(ipr_cmd) - 1, "AT+IPR=2000000");
+ PPP_DEBUG_INFO("Setting module baudrate to 2000000 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 2000000 (AT+IPR)");
+ return PPP_ERR_AT_FAILED;
+ }
+
+ ppp_at_set_baudrate(PPP_UART_BAUDRATE);
+
+ // 再次reset模组,让其自动工作在2000000波特率下
+ PPP_DEBUG_INFO("Resetting module again to switch to 2000000 baudrate...");
+ ppp_api_cat1_reset(1);
+ osal_msleep(50);
+ ppp_api_cat1_reset(0);
+ osal_msleep(5000);
+ PPP_DEBUG_INFO("Baudrate handshake successful, now at 2000000 baud");
+ return PPP_ERR_OK;
} else {
- PPP_DEBUG_WARN("AT command failed at baudrate %u, retry %d (error: %d)", baudrate, retry + 1, ret);
- }
-
- if (retry < 2) {
- osal_msleep(500); // 重试间隔
+ PPP_DEBUG_WARN("AT command failed at baudrate %u, retry %d/3 (error: %d)", baudrate, retry + 1, ret);
+ osal_msleep(500);
}
}
-
- if (ret == PPP_ERR_OK) {
- g_at_ctx.current_baudrate = baudrate;
- PPP_DEBUG_INFO("=== Baudrate handshake successful at %u ===", baudrate);
- return PPP_ERR_OK;
- }
-
- PPP_DEBUG_WARN("Baudrate %u failed, trying next...", baudrate);
- osal_msleep(100); // 短暂延时后尝试下一个波特率
+
+ PPP_DEBUG_WARN("Baudrate %u failed after 3 retries, trying next...", baudrate);
+ osal_msleep(100);
}
- PPP_DEBUG_ERROR("Baudrate handshake failed");
+ PPP_DEBUG_ERROR("Baudrate handshake failed: all baudrates tried, no success");
return PPP_ERR_AT_FAILED;
}
PPP_DEBUG_INFO("Echo disabled successfully");
}
- // 移除ATQ0和ATV1命令,因为它们在某些调制解调器上不被支持
- // 且对PPP连接不是必需的
-
- // 3. 设置固定波特率 (AT+IPR=2000000,掉电保持)
- // 获取当前波特率并设置为固定波特率
- uint32_t current_baudrate = ppp_at_get_current_baudrate();
- if (current_baudrate > 0) {
- PPP_DEBUG_INFO("Setting fixed baudrate to %u (power-off persistent)", current_baudrate);
-
- char ipr_cmd[32];
- snprintf_s(ipr_cmd, sizeof(ipr_cmd), sizeof(ipr_cmd) - 1, "AT+IPR=%u", current_baudrate);
-
- ret = ppp_at_send_command(ipr_cmd, "OK", 5000, &response);
- if (ret != PPP_ERR_OK) {
- PPP_DEBUG_WARN("Failed to set fixed baudrate %s, continuing with current rate", ipr_cmd);
- // 不返回错误,继续执行
- } else {
- PPP_DEBUG_INFO("Fixed baudrate set successfully");
- }
- } else {
- PPP_DEBUG_WARN("Could not determine current baudrate, skipping AT+IPR");
- }
-
- // 3.5. 确保调制解调器完全退出AT命令模式
- PPP_DEBUG_INFO("Ensuring modem is ready for PPP data mode...");
-
- // 发送一个简单的AT命令确认调制解调器状态
+
+ // 发送一个简单的AT命令确认调制解调器状态
ret = ppp_at_send_command("AT", "OK", 3000, &response);
if (ret != PPP_ERR_OK) {
PPP_DEBUG_ERROR("Modem not responding to AT - may already be in data mode");
PPP_DEBUG_INFO("Network registration status: %s", response.response);
}
- // 5. 发送PPP拨号指令 (对应chat文件: OK 'ATD*99***2#' -> CONNECTED)
+ // 5. 发送PPP拨号指令 - 使用Neoway N706A特有的XIIC命令
+ // 根据AT命令手册,应该使用AT+XIIC=1来建立PPP连接,而不是ATD*99***2#
+ #if 1
+ PPP_DEBUG_INFO("Starting PPP connection using Neoway N706A ATD*99***2# command...");
ret = ppp_at_send_command("ATD*99***2#", "CONNECT", 30000, &response);
if (ret != PPP_ERR_OK) {
- PPP_DEBUG_ERROR("PPP dial command failed");
+ PPP_DEBUG_ERROR("PPP connection command (ATD*99***2#) failed");
return ret;
}
- PPP_DEBUG_INFO("PPP dial sequence completed successfully - entering data mode");
-
- // 6.5. 关键修复:确保调制解调器完全进入数据模式
- PPP_DEBUG_INFO("Ensuring modem is fully in PPP data mode...");
-
+ PPP_DEBUG_INFO("PPP connection established successfully with ATD*99***2# command");
+ #else
+ PPP_DEBUG_INFO("Starting PPP connection using Neoway N706A XIIC command...");
+ ret = ppp_at_send_command("AT+XIIC=1", "OK", 30000, &response);
+ if (ret != PPP_ERR_OK) {
+ PPP_DEBUG_ERROR("PPP connection command (AT+XIIC=1) failed");
+ return ret;
+ }
+ PPP_DEBUG_INFO("PPP connection established successfully with XIIC command");
+ #endif
// 等待调制解调器稳定
osal_msleep(1000);
-
// 发送一个空的AT命令来测试是否还在AT模式
// 如果还在AT模式,会有响应;如果在PPP模式,不会有响应
uint8_t test_cmd[] = "AT\r\n";
PPP_DEBUG_INFO("Modem data mode verification completed");
return PPP_ERR_OK;
}
+/**
+ * @brief 发送AT关机指令,支持快速关机和正常关机
+ * @param shutdown_type 关机类型: 0-快速关机, 1-正常流程关机
+ * @return ppp_error_t
+ */
+ppp_error_t ppp_at_poweroff_modem(uint8_t shutdown_type)
+{
+ if (!g_at_ctx.initialized) {
+ return PPP_ERR_INVALID_PARAM;
+ }
+
+ PPP_DEBUG_INFO("Sending AT+NWPWROFF=%d to power off modem", shutdown_type);
+
+ char cmd[32];
+ snprintf(cmd, sizeof(cmd), "AT+NWPWROFF=%d", shutdown_type);
+
+ ppp_at_response_t response;
+ ppp_error_t ret = ppp_at_send_command(cmd, "OK", 10000, &response);
+
+ if (ret == PPP_ERR_OK) {
+ PPP_DEBUG_INFO("Modem power off command sent successfully");
+ } else {
+ PPP_DEBUG_ERROR("Failed to send modem power off command");
+ }
+ ppp_power_off_cat1();
+ return ret;
+}
/**
* @brief 挂断PPP连接
return PPP_ERR_INVALID_PARAM;
}
- PPP_DEBUG_INFO("Hanging up PPP connection");
-
- /* 发送+++切换到命令模式 */
- osal_msleep(1000); // 等待1秒
-
- const char *escape_seq = "+++";
- if (uapi_uart_write(g_at_ctx.uart_bus, (const uint8_t *)escape_seq, 3, 0) != 3) {
- PPP_DEBUG_ERROR("Failed to send escape sequence");
- return PPP_ERR_UART;
- }
-
- osal_msleep(1000); // 等待1秒
+ PPP_DEBUG_INFO("Disconnecting PPP connection using Neoway N706A XIIC command");
- /* 发送ATH挂断命令 */
+ /* 使用N706A特有的XIIC=0命令断开PPP连接 */
ppp_at_response_t response;
- ppp_error_t ret = ppp_at_send_command("ATH", "OK", PPP_AT_CMD_TIMEOUT, &response);
+ ppp_error_t ret = ppp_at_send_command("AT+XIIC=0", "OK", 10000, &response);
if (ret != PPP_ERR_OK) {
- PPP_DEBUG_ERROR("Failed to hangup PPP connection");
- return ret;
+ PPP_DEBUG_ERROR("Failed to disconnect PPP connection using XIIC=0");
+
+ /* 如果XIIC=0失败,尝试传统的挂断方法作为备用 */
+ PPP_DEBUG_WARN("Trying traditional hangup method as fallback...");
+
+ /* 发送+++切换到命令模式 */
+ osal_msleep(1000);
+
+ const char *escape_seq = "+++";
+ if (uapi_uart_write(g_at_ctx.uart_bus, (const uint8_t *)escape_seq, 3, 0) != 3) {
+ PPP_DEBUG_ERROR("Failed to send escape sequence");
+ return PPP_ERR_UART;
+ }
+
+ osal_msleep(1000);
+
+ /* 发送ATH挂断命令 */
+ ret = ppp_at_send_command("ATH", "OK", PPP_AT_CMD_TIMEOUT, &response);
+ if (ret != PPP_ERR_OK) {
+ PPP_DEBUG_ERROR("Traditional hangup also failed");
+ return ret;
+ }
+ PPP_DEBUG_INFO("Traditional hangup successful");
+ } else {
+ PPP_DEBUG_INFO("PPP connection disconnected successfully using XIIC=0");
+
+ // 验证断开状态
+ osal_msleep(500);
+ ret = ppp_at_send_command("AT+XIIC?", "OK", 5000, &response);
+ if (ret == PPP_ERR_OK) {
+ PPP_DEBUG_INFO("PPP disconnection status: %s", response.response);
+ if (strstr(response.response, "+XIIC: 0,") != NULL) {
+ PPP_DEBUG_INFO("PPP disconnection verified - connection closed");
+ }
+ }
}
- PPP_DEBUG_INFO("PPP connection hung up");
+ PPP_DEBUG_INFO("PPP connection hangup completed");
return PPP_ERR_OK;
}
{
(void)data;
PPP_DEBUG_WARN("AT command timeout");
-}
\ No newline at end of file
+}
+
+/**
+ * @brief 解析AT+CESQ响应
+ * 参考N706A AT命令手册: +CESQ: <rxlev>,<ber>,<rscp>,<ecno>,<rsrq>,<rsrp>
+ */
+static ppp_error_t ppp_parse_cesq_response(const char *response, ppp_network_signal_info_t *info)
+{
+ if (!response || !info) {
+ return PPP_ERR_INVALID_PARAM;
+ }
+
+ memset_s(info, sizeof(ppp_network_signal_info_t), 0, sizeof(ppp_network_signal_info_t));
+
+ // 查找+CESQ:开头的行
+ const char *cesq_line = strstr(response, "+CESQ:");
+ if (!cesq_line) {
+ PPP_DEBUG_WARN("No +CESQ: found in response");
+ return PPP_ERR_AT_FAILED;
+ }
+
+ // 跳过"+CESQ:"
+ cesq_line += 6;
+ while (*cesq_line == ' ' || *cesq_line == '\t') cesq_line++;
+
+ // +CESQ: <rxlev>,<ber>,<rscp>,<ecno>,<rsrq>,<rsrp>
+ int rxlev = 99, ber = 99, rscp = 255, ecno = 255, rsrq = 255, rsrp = 255;
+ int parsed = sscanf(cesq_line, "%d,%d,%d,%d,%d,%d", &rxlev, &ber, &rscp, &ecno, &rsrq, &rsrp);
+
+ if (parsed == 6) {
+ info->valid = true;
+ info->rxlev = rxlev;
+ info->ber = ber;
+ info->rscp = rscp;
+ info->ecno = ecno;
+ info->rsrq = rsrq;
+ info->rsrp = rsrp;
+ PPP_DEBUG_INFO("CESQ parsed successfully: rxlev=%d, ber=%d, rscp=%d, ecno=%d, rsrq=%d, rsrp=%d",
+ rxlev, ber, rscp, ecno, rsrq, rsrp);
+ return PPP_ERR_OK;
+ } else {
+ PPP_DEBUG_WARN("Failed to parse CESQ response, parsed: %d", parsed);
+ return PPP_ERR_AT_FAILED;
+ }
+}
+
+/**
+ * @brief 获取网络信号信息 (AT+CESQ)
+ */
+ppp_error_t ppp_at_get_network_signal_info(ppp_network_signal_info_t *info)
+{
+ if (!g_at_ctx.initialized || !info) {
+ return PPP_ERR_INVALID_PARAM;
+ }
+
+ PPP_DEBUG_INFO("Getting network signal information (AT+CESQ)...");
+
+ ppp_at_response_t response;
+ ppp_error_t ret = ppp_at_send_command("AT+CESQ", "OK", 5000, &response);
+
+ if (ret != PPP_ERR_OK) {
+ PPP_DEBUG_ERROR("AT+CESQ command failed: %d", ret);
+ return ret;
+ }
+
+ // 解析响应
+ ret = ppp_parse_cesq_response(response.response, info);
+ if (ret != PPP_ERR_OK) {
+ PPP_DEBUG_ERROR("Failed to parse CESQ response");
+ return ret;
+ }
+
+ // 打印详细信息
+ PPP_DEBUG_INFO("=== Network Signal Information (AT+CESQ) ===");
+ PPP_DEBUG_INFO("rxlev: %d", info->rxlev);
+ PPP_DEBUG_INFO("ber: %d", info->ber);
+ PPP_DEBUG_INFO("rscp: %d", info->rscp);
+ PPP_DEBUG_INFO("ecno: %d", info->ecno);
+ PPP_DEBUG_INFO("rsrq: %d", info->rsrq);
+ PPP_DEBUG_INFO("rsrp: %d", info->rsrp);
+
+ // LTE信号质量评估 - 仅关注RSRQ和RSRP
+ PPP_DEBUG_INFO("=== LTE Signal Quality Analysis ===");
+
+ // RSRQ评估 (0-49有效,255无效)
+ if (info->rsrq == 255) {
+ PPP_DEBUG_INFO("RSRQ: 无法获取LTE信号质量");
+ } else if (info->rsrq >= 0 && info->rsrq <= 49) {
+ // RSRQ转换公式: 实际值(dB) = (rsrq - 94)/10
+ float rsrq_db = (info->rsrq - 94) / 10.0f;
+ PPP_DEBUG_INFO("RSRQ: %d (%.1f dB)", info->rsrq, rsrq_db);
+
+ // RSRQ评估标准 (范围: -19.5dB ~ -3dB,数值越大质量越好)
+ if (rsrq_db >= -6.0) {
+ PPP_DEBUG_INFO("RSRQ评级: 极佳 (信号质量优秀)");
+ } else if (rsrq_db >= -9.0) {
+ PPP_DEBUG_INFO("RSRQ评级: 良好 (信号质量稳定)");
+ } else if (rsrq_db >= -12.0) {
+ PPP_DEBUG_INFO("RSRQ评级: 一般 (信号质量可用)");
+ } else {
+ PPP_DEBUG_INFO("RSRQ评级: 较差 (信号质量不佳)");
+ }
+ } else {
+ PPP_DEBUG_INFO("RSRQ: %d (超出有效范围0-49)", info->rsrq);
+ }
+
+ // RSRP评估 (0-97有效,255无效)
+ if (info->rsrp == 255) {
+ PPP_DEBUG_INFO("RSRP: 无法获取LTE信号强度");
+ } else if (info->rsrp >= 0 && info->rsrp <= 97) {
+ // RSRP转换公式: 实际值(dBm) = rsrp - 140
+ float rsrp_dbm = info->rsrp - 140.0f;
+ PPP_DEBUG_INFO("RSRP: %d (%.0f dBm)", info->rsrp, rsrp_dbm);
+
+ // RSRP评估标准 (范围: -140dBm ~ -43dBm,数值越大信号越强)
+ if (rsrp_dbm >= -80) {
+ PPP_DEBUG_INFO("RSRP评级: 极佳 (信号强度优秀)");
+ } else if (rsrp_dbm >= -90) {
+ PPP_DEBUG_INFO("RSRP评级: 良好 (信号强度稳定)");
+ } else if (rsrp_dbm >= -100) {
+ PPP_DEBUG_INFO("RSRP评级: 一般 (信号强度可用)");
+ } else {
+ PPP_DEBUG_INFO("RSRP评级: 较差 (信号强度不足)");
+ }
+ } else {
+ PPP_DEBUG_INFO("RSRP: %d (超出有效范围0-97)", info->rsrp);
+ }
+
+ // 综合LTE信号质量评估
+ if (info->rsrq != 255 && info->rsrp != 255 &&
+ info->rsrq >= 0 && info->rsrq <= 49 &&
+ info->rsrp >= 0 && info->rsrp <= 97) {
+
+ float rsrq_db = (info->rsrq - 94) / 10.0f;
+ float rsrp_dbm = info->rsrp - 140.0f;
+
+ const char *overall_quality = "未知";
+ if (rsrq_db >= -6.0 && rsrp_dbm >= -80) {
+ overall_quality = "LTE信号极佳 (质量和强度都优秀)";
+ } else if (rsrq_db >= -9.0 && rsrp_dbm >= -90) {
+ overall_quality = "LTE信号良好 (质量和强度都稳定)";
+ } else if (rsrq_db >= -12.0 && rsrp_dbm >= -100) {
+ overall_quality = "LTE信号一般 (质量和强度可用)";
+ } else {
+ overall_quality = "LTE信号较差 (需要改善网络环境)";
+ }
+
+ PPP_DEBUG_INFO("=== 综合评估: %s ===", overall_quality);
+ } else {
+ PPP_DEBUG_INFO("=== 综合评估: LTE参数无效,无法评估 ===");
+ }
+
+ PPP_DEBUG_INFO("=== End Network Signal Information ===");
+
+ return PPP_ERR_OK;
+}
\ No newline at end of file
ppp_lwip_disconnect();
}
+ /* 清理网络接口 */
+ if (g_lwip_ctx.netif) {
+ PPP_DEBUG_INFO("Cleaning up PPP network interface...");
+
+ /* 如果PPP接口是默认接口,清除默认接口设置 */
+ if (netif_default == g_lwip_ctx.netif) {
+ PPP_DEBUG_INFO("Clearing PPP interface as default");
+ netif_set_default(NULL);
+ }
+
+ /* 设置接口为down状态 */
+ if (netif_is_up(g_lwip_ctx.netif)) {
+ PPP_DEBUG_INFO("Setting PPP interface down");
+ netif_set_down(g_lwip_ctx.netif);
+ }
+
+ /* 设置链路为down状态 */
+ if (netif_is_link_up(g_lwip_ctx.netif)) {
+ PPP_DEBUG_INFO("Setting PPP link down");
+ netif_set_link_down(g_lwip_ctx.netif);
+ }
+
+ /* 从lwIP网络接口列表中移除 */
+ PPP_DEBUG_INFO("Removing PPP interface from lwIP interface list");
+ netif_remove(g_lwip_ctx.netif);
+
+ /* 释放网络接口内存 */
+ PPP_DEBUG_INFO("Freeing PPP interface memory");
+ osal_kfree(g_lwip_ctx.netif);
+ g_lwip_ctx.netif = NULL;
+ }
+
/* 删除PPP控制块 */
if (g_lwip_ctx.ppp_pcb) {
+ PPP_DEBUG_INFO("Freeing PPP control block");
ppp_free(g_lwip_ctx.ppp_pcb);
g_lwip_ctx.ppp_pcb = NULL;
}
- /* 释放网络接口 */
- if (g_lwip_ctx.netif) {
- osal_kfree(g_lwip_ctx.netif);
- g_lwip_ctx.netif = NULL;
- }
-
memset_s(&g_lwip_ctx, sizeof(g_lwip_ctx), 0, sizeof(g_lwip_ctx));
- PPP_DEBUG_INFO("PPP lwIP integration deinitialized");
+ PPP_DEBUG_INFO("PPP lwIP integration deinitialized - network interface removed");
#endif
}
S_AGPIO_L23, // pwr_pin
1,
S_AGPIO_L24,//reset_pin
- 0,
- PIN_NONE,//ring_pin
- 0,
+ 1, //电路中 控制gpio拉高,reset才拉低
+ S_MGPIO21,//ring_pin
+ 2,
S_MGPIO22,//wakemodem_pin
1,
#else
}
gpiopin=g_ppp_cat1_ctl_pins.ring_pin;
- if (gpiopin!=PIN_NONE)
+ if (gpiopin != PIN_NONE)
{
uapi_pin_set_mode(gpiopin, (pin_mode_t)HAL_PIO_FUNC_GPIO);
- uapi_gpio_set_dir(gpiopin,GPIO_DIRECTION_INPUT);
- if (g_ppp_cat1_ctl_pins.ring_pin_en_value)
- uapi_gpio_register_isr_func(gpiopin, GPIO_INTERRUPT_RISING_EDGE, ppp_ring_isr_callback );
- else
- uapi_gpio_register_isr_func(gpiopin, GPIO_INTERRUPT_FALLING_EDGE, ppp_ring_isr_callback );
+ uapi_gpio_set_dir(gpiopin, GPIO_DIRECTION_INPUT);
+ switch (g_ppp_cat1_ctl_pins.ring_pin_en_value)
+ {
+ case 0:
+ uapi_gpio_register_isr_func(gpiopin, GPIO_INTERRUPT_FALLING_EDGE, ppp_ring_isr_callback);
+ break;
+ case 1:
+ uapi_gpio_register_isr_func(gpiopin, GPIO_INTERRUPT_RISING_EDGE, ppp_ring_isr_callback);
+ break;
+ case 2:
+ default:
+ uapi_gpio_register_isr_func(gpiopin, GPIO_INTERRUPT_DEDGE, ppp_ring_isr_callback);
+ break;
+ }
}
}
return 0xff;
}
- if (pwron == 0) {
+ if (pwron == 0) { //取消复位
uapi_gpio_set_dir(en_pin, GPIO_DIRECTION_OUTPUT);
- if (en_value) {
+ if (en_value) { //拉高复位,取消复位,应拉低
uapi_gpio_set_val(en_pin, GPIO_LEVEL_LOW);
PPP_DEBUG_PRINT("PPP: Cat1 reset Off! pin %d value low\n", en_pin);
- } else {
+ } else { //拉低复位,取消复位,应拉高
uapi_gpio_set_val(en_pin, GPIO_LEVEL_HIGH);
PPP_DEBUG_PRINT("PPP: Cat1 reset Off! pin %d value high\n", en_pin);
}
- } else {
+ } else { //复位
uapi_gpio_set_dir(en_pin, GPIO_DIRECTION_OUTPUT);
- if (en_value) {
+ if (en_value) { //拉高复位
uapi_gpio_set_val(en_pin, GPIO_LEVEL_HIGH);
PPP_DEBUG_PRINT("PPP: Cat1 reset On! pin %d value high\n", en_pin);
- } else {
+ } else { //拉低复位
uapi_gpio_set_val(en_pin, GPIO_LEVEL_LOW);
PPP_DEBUG_PRINT("PPP: Cat1 reset On! pin %d value low\n", en_pin);
}
}
+ uint8_t value = uapi_gpio_get_output_val(en_pin);
+ PPP_DEBUG_PRINT("PPP: Cat1 reset value %d\n", value);
return 0;
}
#if defined(BOARD_FD230)
ppp_api_cat1_power_on(1);
ppp_api_cat1_reset(0);
-#elif (defined(BOARD_W9) || defined(BOARD_N9) || defined(BOARD_LEINIAO))
+#elif (defined(BOARD_W9) || defined(BOARD_N9) )
+ ppp_api_cat1_power_on(1);
+ ppp_api_cat1_bat_on(1);
+ osal_msleep(900); // 使用OSAL延时函数
+ ppp_api_cat1_power_on(0);
+#elif defined(BOARD_LEINIAO)
+ ppp_api_cat1_reset(0);
ppp_api_cat1_power_on(1);
ppp_api_cat1_bat_on(1);
osal_msleep(900); // 使用OSAL延时函数
#if defined(BOARD_FD230)
ppp_api_cat1_reset(1);
ppp_api_cat1_power_on(0);
-#elif (defined(BOARD_W9) || defined(BOARD_N9) || defined(BOARD_LEINIAO))
+#elif (defined(BOARD_W9) || defined(BOARD_N9) )
+ ppp_api_cat1_power_on(0);
+ ppp_api_cat1_bat_on(0);
+#elif defined(BOARD_LEINIAO)
+ ppp_api_cat1_reset(0);
ppp_api_cat1_power_on(0);
ppp_api_cat1_bat_on(0);
#endif
void ppp_ring_isr_callback(pin_t pin, uintptr_t param)
{
(void)param;
- PPP_DEBUG_PRINT("PPP: Cat1 ring interrupt on pin %d\n", pin);
- // 中断处理逻辑
+
+ gpio_level_t val = uapi_gpio_get_val(pin);
+ if (val == GPIO_LEVEL_HIGH) {
+ PPP_DEBUG_PRINT("PPP: Cat1 ring interrupt on pin %d high \n", pin);
+ ppp_api_wakeup_cat1(true);
+ } else {
+ PPP_DEBUG_PRINT("PPP: Cat1 ring interrupt on pin %d low\n", pin);
+ ppp_api_wakeup_cat1(false);
+ }
+ uapi_gpio_clear_interrupt(pin);
}
/**
}
PPP_DEBUG_INFO("=== PPP Serial Write Start ===");
+ ppp_api_wakeup_cat1(true);
+ osal_msleep(1);
PPP_DEBUG_INFO("Write request: %u bytes in mode %d", length, g_serial_ctx.current_mode);
PPP_DEBUG_INFO("UART Bus: %u", g_serial_ctx.uart_bus);
result == PPP_ERR_OK ? "SUCCESS" : "FAILED", result);
PPP_DEBUG_INFO("Statistics: tx_bytes=%u, tx_errors=%u", g_serial_ctx.tx_bytes, g_serial_ctx.tx_errors);
PPP_DEBUG_INFO("=== PPP Serial Write End ===");
+ ppp_api_wakeup_cat1(false);
return result;
}
--- /dev/null
+/**
+ * @file ppp_stub_functions.c
+ * @brief 桩函数实现,用于解决编译链接时的未定义引用问题
+ *
+ * 这些函数在PPP模块中不会被实际使用,仅用于满足链接器的符号依赖要求
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+/**
+ * @brief HTTP客户端文件下载桩函数
+ * @param url 下载URL
+ * @param file_path 本地文件路径
+ * @param timeout 超时时间
+ * @return 总是返回失败(-1)
+ */
+int httpc_get_file_dns_to_disk(const char *url, const char *file_path, int timeout)
+{
+ (void)url;
+ (void)file_path;
+ (void)timeout;
+
+ // 桩函数 - 不实现实际功能
+ return -1;
+}
+
+/**
+ * @brief AI流式录音发送桩函数
+ * @param data 音频数据
+ * @param len 数据长度
+ * @param session_id 会话ID
+ * @return 总是返回失败(-1)
+ */
+int streamingRecordAndSend_AI(void *data, int len, const char *session_id)
+{
+ (void)data;
+ (void)len;
+ (void)session_id;
+
+ // 桩函数 - 不实现实际功能
+ return -1;
+}
+
+/**
+ * @brief AI消息队列发送桩函数
+ * @param msg_data 消息数据
+ * @param data_len 数据长度
+ * @return 总是返回失败(-1)
+ */
+int send_msg_data_into_Ai_msg_queue(void *msg_data, int data_len)
+{
+ (void)msg_data;
+ (void)data_len;
+
+ // 桩函数 - 不实现实际功能
+ return -1;
+}
+
+/**
+ * @brief 蓝牙设置AI回答字符串桩函数
+ * @param answer_str AI回答字符串
+ * @return 总是返回失败(-1)
+ */
+int ble_set_ai_Answer_str(const char *answer_str)
+{
+ (void)answer_str;
+
+ // 桩函数 - 不实现实际功能
+ return -1;
+}
+
+/**
+ * @brief 蓝牙设置AI问题字符串桩函数
+ * @param question_str AI问题字符串
+ * @return 总是返回失败(-1)
+ */
+int ble_set_ai_Question_str(const char *question_str)
+{
+ (void)question_str;
+
+ // 桩函数 - 不实现实际功能
+ return -1;
+}
+
+/*
+ * 注意:这些桩函数仅用于解决链接问题,不提供实际功能
+ * 如果需要使用相关功能,请实现对应的真实函数
+ */
\ No newline at end of file
#ifdef CUSTOM_ZHIHUI
system_init_uart();//配置uartat
#endif
+
+#ifdef BOARD_LEINIAO
+ // zhihui_ppp_init();
+#else
if ( cm_poweron_cat1_on_bootup_flag() )
{
PRINT("PowerOn Cat1 !\r\n");
PRINT("PowerOff Cat1 !\r\n");
uapi_set4GCapability(false);
}
+#endif
uapi_gei_btmac_and_chipinfo();
uint8_t buildversion[128]={0};