Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources

This commit is contained in:
2026-07-06 11:30:13 +08:00
commit e76462eeb7
3451 changed files with 1415300 additions and 0 deletions

314
project/events.c Normal file
View File

@@ -0,0 +1,314 @@
/**
* @file events.c
* @brief 系统事件处理模块 —— WiFi / 网络 / LTE 事件分发与处理
*
* 本文件是 TXW82x FPV SDK 的核心事件处理单元,主要包含:
* - sys_event_hdl() : 全局系统事件处理分发函数(任务上下文,可执行耗时操作)
* - sys_event_hdl_dhcp() : DHCP 客户端生命周期管理WiFi 连接后启动 DHCPDHCP 完成后记录 IP
* - sys_event_hdl_lte() : LTE/4G 网卡与 WiFi 之间的网络切换逻辑
* - sys_wifi_event_cb() : WiFi 协议栈事件回调(在协议栈任务/中断上下文中执行,禁止耗时操作)
* - sys_wifi_event_hdl_default() : 更新 sys_status 结构体中的 WiFi 状态信息
*/
#include "sys_config.h" // 系统总配置头文件,包含各功能模块的宏开关
#include "basic_include.h" // 基础头文件集合os_printf、os_memcpy 等基础 API
#include "lib/net/skmonitor/skmonitor.h" // socket 监控库,用于网络连接状态监控
#include "lib/net/dhcpd/dhcpd.h" // DHCP 服务器端库(本文件未直接使用,但头文件引用保留以备扩展)
#include "lib/net/uhttpd/uhttpd.h" // 超轻量 HTTP 服务器库(本文件未直接使用,保留以备扩展)
#include "lib/umac/ieee80211.h" // IEEE 802.11 协议定义WiFi 事件枚举、模式宏等)
#include "lib/net/utils.h" // 网络工具函数(如 lwip_netif_set_dhcp2 等)
#include "lwip/err.h" // LwIP 错误码定义
#include "lwip/sockets.h" // LwIP BSD socket 兼容层
#include "lwip/netdb.h" // LwIP 网络数据库函数gethostbyname 等)
#include "lwip/sys.h" // LwIP 系统抽象层(线程、信号量等)
#include "lwip/ip_addr.h" // LwIP IP 地址操作宏IPSTR、IP2STR_N 等)
#include "lwip/tcpip.h" // LwIP TCP/IP 协议栈核心接口
#include "lwip/dns.h" // LwIP DNS 解析接口dns_getserver 等)
#include "netif/ethernetif.h" // 以太网网络接口驱动层
#include "lwip/apps/netbiosns.h" // LwIP NetBIOS 名称服务(本文件未直接使用,保留以备扩展)
#include "lwip/dns.h" // LwIP DNS 头文件(重复包含,无副作用,保留原始代码不变)
#include "syscfg.h" // 系统配置持久化存储接口syscfg_save 等)
#include "lib/bluetooth/uble/ble_demo.h" // BLE 蓝牙低功耗演示模块(用于蓝牙配网功能)
#include "sysevt_usb/sysevt_usb.h" // USB 主机事件处理(视频 USB 设备相关)
/**
* @brief WiFi 配对模块的事件处理函数(外部定义)
* 处理 WiFi 配对pair相关的协议栈事件
*/
extern int32 sys_wifi_event_hdl_wifi_pair(uint8 ifidx, uint16 evt, uint32 param1, uint32 param2);
/**
* @brief 配对指示灯模块的事件处理函数(外部定义)
* 根据 WiFi 配对状态控制 LED 指示灯
*/
extern int32 sys_wifi_event_hdl_pairled(uint8 ifidx, uint16 evt, uint32 param1, uint32 param2);
/**
* @brief 配对指示灯模块的事件处理函数(重复声明,保留原始代码不变)
*/
extern int32 sys_wifi_event_hdl_pairled(uint8 ifidx, uint16 evt, uint32 param1, uint32 param2);
/**
* @brief 对讲机模块的事件处理函数(外部定义)
* 处理 WiFi 对讲机walkie-talkie相关的协议栈事件
*/
extern int32 sys_wifi_event_hdl_walkietalkie(uint8 ifidx, uint16 evt, uint32 param1, uint32 param2);
/**
* @brief WiFi 配对的系统事件处理函数(外部定义)
* 在 sys_event_hdl() 任务上下文中处理配对相关逻辑(可执行耗时操作)
*/
extern void sys_event_hdl_wifi_pair(uint32 event_id, uint32 data, uint32 priv);
/**
* @brief 对讲机模块的系统事件处理函数(外部定义)
* 在 sys_event_hdl() 任务上下文中处理对讲机相关逻辑(可执行耗时操作)
*/
extern void sys_event_hdl_walkie_talkie(uint32 event_id, uint32 data, uint32 priv);
/**
* @brief 处理 DHCP 相关系统事件WiFi 连接后启动 DHCP 客户端DHCP 完成后保存 IP 信息)
*
* 该函数由 sys_event_hdl() 调用,运行在系统事件任务上下文中,可以执行耗时操作。
* 主要处理两个事件:
* 1. WiFi 连接成功 → 启动 DHCP 客户端获取 IP 地址
* 2. DHCP 客户端完成 → 将获取到的 IP/掩码/网关/DNS 保存到 sys_status
*
* @param event_id 系统事件 ID由 SYS_EVENT(模块, 子事件) 宏组合而成
* @param data 事件附带的数据(本函数未使用)
* @param priv 事件附带的私有数据(本函数未使用)
*/
//更新 sys_status 信息 // Update sys_status information
static void sys_event_hdl_dhcp(uint32 event_id, uint32 data, uint32 priv)
{
switch (event_id) {
/* WiFi 连接成功事件 */
case SYS_EVENT(SYS_EVENT_WIFI, SYSEVT_WIFI_CONNECTTED):
/* 如果配置中启用了 DHCP 客户端,则启动 DHCP 流程获取 IP 地址 */
if (sys_cfgs.dhcpc_en) {
sys_status.dhcpc_done = 0; // 清零 DHCP 完成标志,表示正在进行 DHCP
lwip_netif_set_dhcp2("w0", 1); // 在 "w0"WiFi 接口)上启动 LwIP DHCP 客户端
os_printf(KERN_NOTICE"wifi connected, start dhcp client ...\r\n"); // 打印日志WiFi 已连接,启动 DHCP
}
/* 如果当前工作在 STAStation 站点)模式,则保存当前连接的 AP 信息到持久化配置 */
if(sys_cfgs.wifi_mode == WIFI_MODE_STA) {
ieee80211_conf_get_ssid(sys_cfgs.wifi_mode, sys_cfgs.ssid); // 获取当前连接的 SSID 并存入配置
ieee80211_conf_get_psk(sys_cfgs.wifi_mode, sys_cfgs.psk); // 获取当前连接的 PSK 密码并存入配置
sys_cfgs.key_mgmt = ieee80211_conf_get_keymgmt(sys_cfgs.wifi_mode); // 获取当前密钥管理方式WPA/WPA2/Open
syscfg_save(); // 将配置持久化保存到 Flash下次开机自动连接
}
break;
/* DHCP 客户端完成事件(成功获取到 IP 地址) */
case SYS_EVENT(SYS_EVENT_NETWORK, SYSEVT_LWIP_DHCPC_DONE): {
struct netif *nif = netif_find("w0"); // 通过名称 "w0" 查找 WiFi 网络接口的 netif 结构体
sys_status.dhcpc_done = 1; // 标记 DHCP 过程已完成
sys_status.dhcpc_result.ipaddr = nif->ip_addr.addr; // 保存 DHCP 分配的 IP 地址
sys_status.dhcpc_result.netmask = nif->netmask.addr; // 保存 DHCP 分配的子网掩码
sys_status.dhcpc_result.svrip = 0; // DHCP 服务器 IP 未使用,置零保留
sys_status.dhcpc_result.router = nif->gw.addr; // 保存 DHCP 分配的默认网关地址
sys_status.dhcpc_result.dns1 = (dns_getserver(0))->addr; // 保存主 DNS 服务器地址索引0
sys_status.dhcpc_result.dns2 = (dns_getserver(1))->addr; // 保存备用 DNS 服务器地址索引1
os_printf(KERN_NOTICE"dhcp done, ip:"IPSTR", mask:"IPSTR", gw:"IPSTR"\r\n", // 打印获取到的 IP 信息
IP2STR_N(nif->ip_addr.addr), IP2STR_N(nif->netmask.addr), IP2STR_N(nif->gw.addr));
}
break;
}
}
/**
* @brief 处理 LTE/4G 网卡与 WiFi 之间的网络切换事件
*
* 当系统同时具备 WiFi 和 LTE通过 USB RNDIS 网卡)两种网络通路时,
* 本函数实现优先级切换策略WiFi 优先WiFi 断开时回退到 LTE。
*
* 切换逻辑:
* - LTE 连接且 WiFi 未连接 → 使用 LTE 作为默认网口,启动 LTE 上的 DHCP
* - WiFi 连接成功 → 关闭 LTE 网口,切换默认网口为 WiFiWiFi 优先)
* - WiFi 断开 → 重新启用 LTE 网口,回退到 LTE 网络
*
* @param event_id 系统事件 ID
* @param data 事件附带的数据(本函数未使用)
* @param priv 事件附带的私有数据(本函数未使用)
*/
void sys_event_hdl_lte(uint32 event_id, uint32 data, uint32 priv)
{
#if defined(RT_USBH_WIRELESS_RNDIS) && !defined(STATIC_RNDIS_NETDEV)
// 只在启用了RNDIS功能且是动态申请网口时才需要事件进行切换
// Only when RNDIS feature is enabled and netdev is dynamically allocated, event-based switching is needed
switch (event_id) {
/* LTE 网卡连接事件USB RNDIS 网卡已就绪) */
case SYS_EVENT(SYS_EVENT_LTE, SYSEVT_LTE_CONNECTED):
os_printf("lte connected\r\n"); // 打印日志LTE 已连接
if (sys_status.wifi_connected == 0) { // 如果 WiFi 当前未连接,则使用 LTE 作为默认网络
lwip_netif_set_default2("l0"); // 将 "l0"LTE 网口)设置为 LwIP 默认路由接口
lwip_netif_set_dhcp2("l0", 1); // 在 LTE 网口上启动 DHCP 客户端获取 IP
os_printf("start dhcp client on l0 ...\r\n"); // 打印日志:在 LTE 接口启动 DHCP
}
break;
/* WiFi 连接成功事件 —— WiFi 优先级高于 LTE关闭 LTE 网口 */
case SYS_EVENT(SYS_EVENT_WIFI, SYSEVT_WIFI_CONNECTTED):
lwip_netif_updown2("l0", 0); // 关闭 "l0"LTE 网口参数0表示 down
lwip_netif_set_default2("w0"); // 将 "w0"WiFi 网口)设为默认路由接口
os_printf("wifi connected, down lte netif ...\r\n"); // 打印日志WiFi 已连接,关闭 LTE
break;
/* WiFi 断开事件 —— 回退到 LTE 网络 */
case SYS_EVENT(SYS_EVENT_WIFI, SYSEVT_WIFI_DISCONNECT):
lwip_netif_updown2("l0", 1); // 重新启用 "l0"LTE 网口参数1表示 up
lwip_netif_set_default2("l0"); // 将默认路由切回 LTE 网口
os_printf("wifi disconnected, up lte netif ...\r\n"); // 打印日志WiFi 已断开,启用 LTE
break;
}
#endif
}
/**
* @brief 全局系统事件处理分发函数(系统事件任务上下文入口)
*
* 该函数是系统事件处理的核心分发器,由系统事件任务循环调用。
* 它依次调用各功能模块的事件处理函数,实现事件的广播式分发。
*
* 重要特性:
* - 运行在独立的系统事件任务上下文中,可以执行耗时操作(如 DHCP、Flash 读写)
* - 返回 SYSEVT_CONTINUE 表示事件继续传递给后续处理函数(不截断事件)
* - 简单功能可直接在此函数中调用处理 API复杂功能建议通过 sys_event_take() 注册独立处理函数
*
* @param event_id 系统事件 ID由 SYS_EVENT(模块, 子事件) 宏组合而成
* @param data 事件附带的数据
* @param priv 事件附带的私有数据
* @return sysevt_hdl_res 返回 SYSEVT_CONTINUE 表示事件继续传递
*/
sysevt_hdl_res sys_event_hdl(uint32 event_id, uint32 data, uint32 priv)
{
#if SYS_WIFI_PAIR
sys_event_hdl_wifi_pair(event_id, data, priv); // WiFi 配对功能的事件处理
#endif
#ifdef SYS_APP_WALKIE_TALKIE
sys_event_hdl_walkie_talkie(event_id, data, priv); // 对讲机功能的事件处理
#endif
/*
* 继续添加其他模块的处理函数 ...
* Continue adding other module handlers ...
* 一些小功能的事件处理没必要使用 sys_event_take在此添加API调用即可。
* Small features can simply add API calls here without using sys_event_take.
* 复杂功能的事件处理,可以使用 sys_event_take API 注册事件处理函数。
* Complex features can use sys_event_take API to register event handlers.
* 使用 sys_event_take 注册每次会消耗16byte heap memory
* Each sys_event_take registration consumes 16 bytes of heap memory
*/
#if SYS_APP_BLENC
sys_event_ble_netconfig(event_id, data, priv); // BLE 蓝牙配网功能的事件处理
#endif
sys_event_hdl_dhcp(event_id, data, priv); // DHCP 客户端生命周期管理
sys_event_hdl_lte(event_id, data, priv); // LTE/WiFi 网络切换处理
system_event_usbh_video_hdl(event_id, data, priv); // USB 主机视频设备事件处理
return SYSEVT_CONTINUE; // 返回"继续传递",不截断事件,让后续处理函数也能收到该事件
}
/**
* @brief WiFi 协议栈事件默认处理函数 —— 更新 sys_status 结构体中的 WiFi 状态
*
* 该函数在 sys_wifi_event_cb() 中被调用,负责将 WiFi 协议栈上报的事件
* 转换为 sys_status 结构体中的状态字段更新,供应用层查询当前 WiFi 状态。
*
* @param ifidx WiFi 接口索引0=w0, 1=w1
* @param evt WiFi 协议栈事件类型IEEE80211_EVENT_xxx
* @param param1 事件参数1具体含义取决于事件类型
* @param param2 事件参数2具体含义取决于事件类型
* @return int32 固定返回 0
*/
//更新 sys_status 信息 // Update sys_status information
static int32 sys_wifi_event_hdl_default(uint8 ifidx, uint16 evt, uint32 param1, uint32 param2)
{
switch (evt) {
/* WiFi 连接成功事件 */
case IEEE80211_EVENT_CONNECTED:
sys_status.wifi_connected = 1; // 标记 WiFi 已连接
sys_status.wifi_status_code = 0; // 连接状态码清零0 = 成功)
sys_status.channel = ieee80211_conf_get_channel(WIFI_MODE_STA); // 获取当前工作信道号
os_memcpy(sys_status.bssid, param1, 6); // 拷贝 AP 的 MAC 地址BSSID6字节到状态结构体
break;
/* RSSI接收信号强度指示更新事件 */
case IEEE80211_EVENT_RSSI:
sys_status.rssi = (int8)param1; // 将最新的 RSSI 值有符号8位单位 dBm保存到状态
break;
/* EVM误差向量幅度更新事件反映信号调制质量 */
case IEEE80211_EVENT_EVM:
sys_status.evm = (int8)param1; // 将最新的 EVM 值保存到状态,值越小信号质量越好
break;
/* WiFi 连接失败事件 */
case IEEE80211_EVENT_CONNECT_FAIL:
sys_status.wifi_connected = 0; // 标记 WiFi 未连接
sys_status.wifi_status_code = param2; // 保存失败原因状态码,用于诊断连接失败原因
break;
/* WiFi 断开连接事件 */
case IEEE80211_EVENT_DISCONNECTED:
sys_status.wifi_connected = 0; // 标记 WiFi 未连接
sys_status.wifi_reason_code = param2; // 保存断开原因码(如 beacon 超时、AP 主动断开等)
break;
/* WiFi 接口使能(启用)事件 */
case IEEE80211_EVENT_INTERFACE_ENABLE:
sys_status.wifi_mode = param1; // 记录当前 WiFi 工作模式STA/AP/MONITOR 等)
break;
/* 信道切换事件(可能由 DFS 雷达检测触发,或手动切换信道) */
case IEEE80211_EVENT_CHANNEL_CHANGE:
sys_status.channel = param2; // 更新当前工作信道号到状态结构体
sys_cfgs.channel = param2; // 同步更新配置中的信道号(可能是 DFS 信道切换)
break;
default:
break; // 未处理的事件类型,忽略
}
return 0; // 返回 0表示处理完成
}
/**
* @brief WiFi 协议栈事件回调函数 —— 在协议栈任务上下文中执行的入口
*
* 该函数由 WiFi 协议栈在事件发生时直接调用,运行在协议栈任务(或中断)上下文中。
*
* 【重要约束】由于运行在协议栈任务上下文:
* - 禁止执行耗时操作(如 DHCP 流程、Flash 读写、长循环等)
* - 只能做轻量级操作(更新状态变量、设置标志位、发送信号量等)
* - 需要执行耗时逻辑时,应通过 sys_event_post() 将事件转发到 sys_event_hdl() 处理
*
* 各子处理函数的返回值通过位或(|=)合并,用于向协议栈返回处理结果。
*
* @param ifidx WiFi 接口索引0=w0, 1=w1
* @param evt WiFi 协议栈事件类型IEEE80211_EVENT_xxx
* @param param1 事件参数1如 BSSID 指针、RSSI 值等)
* @param param2 事件参数2如原因码、状态码等
* @return int32 各子处理函数返回值的位或结果
*/
//WiFi协议栈的事件回调函数 // WiFi protocol stack event callback function
// 该callback是在WiFi协议栈的Task中执行因此该callback中不能执行耗时的代码
// This callback executes in the WiFi protocol stack Task, so time-consuming code is not allowed
// 耗时的代码逻辑可以使用sys_event_hdl来执行
// Time-consuming logic should be dispatched to sys_event_hdl for execution
int32 sys_wifi_event_cb(uint8 ifidx, uint16 evt, uint32 param1, uint32 param2)
{
int32 ret = 0; // 初始化返回值为 0后续通过位或累加各子处理函数的结果
#if SYS_WIFI_PAIR
ret |= sys_wifi_event_hdl_wifi_pair(ifidx, evt, param1, param2); // WiFi 配对功能处理
#endif
#if SYS_WIFI_PAIRLED
ret |= sys_wifi_event_hdl_pairled(ifidx, evt, param1, param2); // 配对指示灯功能处理
#endif
#ifdef SYS_APP_WALKIE_TALKIE
ret |= sys_wifi_event_hdl_walkietalkie(ifidx, evt, param1, param2); // 对讲机功能处理
#endif
/*
* 继续添加其他模块的处理函数 ...
* Continue adding other module handlers ...
*/
ret |= sys_wifi_event_hdl_default(ifidx, evt, param1, param2); // 默认处理:更新 sys_status 状态
return ret; // 返回合并后的处理结果
}