杰理 SDK 文档中心
首页
首页
  • SDK 概述与快速开始

    • SDK 概览与 AC791N 芯片平台
    • 环境搭建与编译指南
    • 烧录与固件升级
    • 工程结构导览
  • 产品方案应用

    • WiFi 摄像头方案
    • WiFi IPC 可视对讲方案
    • WiFi 故事机方案
    • 扫码枪 HID 方案
    • 开发板示例工程
  • 公共应用组件

    • 语音识别 ASR 引擎
    • LLM 与 AI 语音助手接入
    • 摄像头传感器驱动
    • UI 显示框架与驱动
    • USB 主机与设备栈
    • 文件系统与存储管理
    • 系统服务与外设管理
    • 生产测试与射频工具
  • 蓝牙协议栈

    • 经典蓝牙 BR/EDR
    • BLE 低功耗蓝牙
    • 蓝牙 Mesh 网络
    • 蓝牙扩展协议(RCSP/广播/无线麦克风)
  • WiFi 与网络协议栈

    • WiFi 驱动与网络模式
    • lwIP TCP/IP 协议栈
    • 网络安全与加密库
    • 应用层网络协议
    • 流媒体与音视频传输
    • 云平台接入 SDK
    • P2P 远程访问与设备互联
  • 芯片平台与驱动

    • wl82 平台与硬件加速
    • 外设驱动框架
    • 平台配置与固件打包工具
  • 媒体与音频引擎

    • 音频编解码与音源
    • 音效处理引擎
    • 视频与图像处理
  • 操作系统与运行时

    • 实时操作系统与 POSIX 层
    • C/C++ 运行时库
  • 开发资源与文档

    • 文档与规格书
    • 公共示例工程
    • UI 资源工程与打包
    • SDK 辅助工具与脚本

P2P 远程访问与设备互联

本文档介绍 AC79NN AIoT SDK 中实现 P2P 远程访问与设备互联能力的应用层网络架构:以 wifi_app_task 网络任务为核心,通过 lwIP socket、流媒体服务器(Fenice)、网络服务器(net_server)与配网/静态 IP 机制,支撑设备间点对点互联与远程访问。

Purpose and Scope

本页覆盖以下内容:

  • 网络应用任务模型:wifi_app_task.c 中的 wifi_app_hdl 状态标志与 net_app_init / net_app_uninit 生命周期管理;
  • 局域网互联基础:SoftAP 热点配置(192.168.0.1)、静态 IP 恢复(VM_STA_IPADDR_INDEX)、net_set_lan_info_ext 下发的 LAN 信息;
  • Socket 通信层:基于 lwIP 的 UDP/TCP 收发(sock_recvfrom、sock_api),这是设备发现与 P2P 数据通道的基础;
  • 远程服务面:server_core、net_server 与 streaming_media_server(Fenice)提供的媒体流/命令服务入口;
  • 网络使能与测试模式:CONFIG_NET_ENABLE 等编译开关与 RF/STA/AP 测试模式。

边界说明:仓库源码中未发现独立的第三方 P2P SDK(如 TUTK)或专门的 p2p_*.c 模块;本 SDK 的"P2P 远程访问"由应用层自研 socket + 流媒体服务 + 云/局域网服务器组合实现。配网流程(Airkiss、SmartConfig)、BT 低功耗、音乐业务等属于其他页面范畴,本页仅在与网络互联相关的边界处引用。

Overview

AC79NN 是杰理(Jieli)面向 AIoT 场景的 WiFi SoC SDK。在 apps/wifi_story_machine(WiFi 故事机)与 apps/demo/demo_audio 等应用中,网络能力统一收敛到一个网络应用任务(wifi_app_task)中。该任务负责:

  1. 接入网络:以 STA 模式连接路由器(或 SoftAP 模式供手机配网),超时窗口为 CONNECT_TIMEOUT_SEC 60 秒;
  2. 配置网络栈:通过 net_set_lan_info_ext 下发 IP/网关/掩码,静态 IP 场景从 syscfg(VM_STA_IPADDR_INDEX)恢复上次保存的地址;
  3. 开放服务端口:启动 UDP 监听(用于设备发现/透传测试),并集成 net_server / streaming_media_server(Fenice)提供远程访问入口;
  4. 维持互联状态:以位域标志(net_app_init_flag、request_connect_flag 等)管理初始化与重连状态机,防止重复初始化。

P2P 语义在本 SDK 中体现为"设备主动暴露服务端(socket + 流媒体),对端(App/另一台设备)通过局域网或公网直连/中转访问",而非专门的打洞协议实现。

Architecture

flowchart TD
    subgraph sg_App["应用层 apps/wifi_story_machine"]
        WAT["wifi_app_task.c<br/>网络应用任务"]
        HDL["wifi_app_hdl<br/>位域状态标志"]
        LAN["soft_ap_set_lan_setting_info<br/>wifi_set_lan_setting_info"]
        UDP["UDP 监听<br/>sock_recvfrom"]
    end

    subgraph sg_Srv["远程服务面"]
        NS["net_server<br/>server/net_server.h"]
        SC["server_core<br/>server/server_core.h"]
        FEN["streaming_media_server<br/>fenice_config.h"]
    end

    subgraph sg_Stack["网络协议栈"]
        LWIP["lwIP<br/>sockets / netdb / dns / ip"]
        SOCK["sock_api"]
    end

    subgraph sg_Cfg["配置与持久化"]
        SYSCFG["syscfg<br/>VM_STA_IPADDR_INDEX"]
        EVT["net_event"]
        JSON["json_tokener<br/>协议消息"]
    end

    WAT --> HDL
    WAT --> LAN
    WAT --> UDP
    WAT -->|"初始化/使能"| NS
    NS --> SC
    NS --> FEN
    UDP --> LWIP
    NS --> SOCK
    SOCK --> LWIP
    LAN -->|"net_set_lan_info_ext"| LWIP
    WAT -->|"syscfg_read"| SYSCFG
    NS -->|"事件通知"| EVT
    NS -->|"JSON 编解码"| JSON

架构说明:

  • wifi_app_task 是唯一入口:wifi_on() 后调用 net_app_init() 完成网络栈初始化,退出时调用 net_app_uninit() 释放资源;所有互联行为都挂接在这个任务上。
  • 局域网配置是互联的前提:SoftAP 模式固定为 192.168.0.1 网段,保证手机/App 可稳定发现设备;STA 静态 IP 从 syscfg 恢复,使设备在路由器下的地址可预期,便于对端直连。
  • socket 层承担"互联通道"角色:UDP 用于发现与透传,TCP(经 sock_api)用于命令/流媒体;lwip 提供协议栈。
  • 远程服务面把设备变成"服务器":net_server + streaming_media_server(Fenice)让 App 可远程拉取媒体流/下发命令,这正是"设备互联/远程访问"的产品化形态。
  • 协议与事件解耦:JSON(json_tokener)做消息编解码,net_event 向应用层广播网络事件,syscfg 做持久化。

网络应用任务模型

wifi_app_task.c 顶部定义了一个全局单例句柄 wifi_app_hdl,所有网络状态都压缩在位域标志中。这种设计在资源受限的 SoC 上非常典型:用一个 u32 承载全部状态位,避免为每个标志单独占一个变量,同时让整个状态集合可被原子地读取/清空。

static struct {
    int udp_recv_pid;
    u32 use_static_ipaddr_flag : 1;
    u32 net_app_init_flag : 1;
    u32 request_connect_flag : 1;
    u32 save_ssid_flag : 1;
    u32 mac_addr_succ_flag : 1;
    u32 udp_recv_test_exit_flag : 1;
    u32 rf_test_mode : 3;
    u32 reserved : 23;
} wifi_app_hdl;

#define __this	(&wifi_app_hdl)

Source: wifi_app_task.c

各标志位的职责:

标志位宽度含义
use_static_ipaddr_flag1 bit是否使用静态 IP(对应 CONFIG_STATIC_IPADDR_ENABLE)
net_app_init_flag1 bit网络应用是否已初始化,防止重复初始化
request_connect_flag1 bit是否有连接请求待处理
save_ssid_flag1 bit是否保存过 SSID
mac_addr_succ_flag1 bitMAC 地址获取是否成功(关联 CONFIG_ASSIGN_MACADDR_ENABLE)
udp_recv_test_exit_flag1 bitUDP 接收测试是否退出
rf_test_mode3 bitsRF 测试模式(见下方枚举)

rf_test_mode 的取值来自文件顶部的测试模式枚举,覆盖生产测试与认证场景:

enum {
    RF_TEST_CLOSE = 0,
    WIFI_MP_TEST_MODE,
    WIFI_STA_TEST_MODE,
    WIFI_AP_TEST_MODE,
    BT_DUT_TEST_MODE,
    BT_FCC_TEST_MODE,
    BT_BQB_TEST_MODE,
    RF_MULTI_TEST_MODE,
};

Source: wifi_app_task.c

生命周期:net_app_init / net_app_uninit

任务启动与退出遵循严格的"初始化一次、退出一次"模式。net_app_init 用标志位做幂等保护——即使 wifi_on 被多次调用或事件重复触发,也不会重复初始化网络栈:

static void net_app_init(void)
{
    if (__this->net_app_init_flag) {
        return;
    }
    __this->net_app_init_flag = 1;
}

Source: wifi_app_task.c

对应的启动/停止序列(Grep 证据):

wifi_on();
net_app_init();
// ...
net_app_uninit();

Source: wifi_app_task.c

设计意图:wifi_on() 负责底层射频与协议栈上电,net_app_init() 负责应用层(socket 服务、流媒体服务、事件注册)初始化。两者分离使得网络底层重启(如断线重连)不需要重建应用层服务,而应用层重建(如进入测试模式)也不会触碰射频状态。

局域网互联配置

SoftAP 模式:固定网段保证可发现性

设备以 SoftAP 形态出现时(配网/直连场景),LAN 信息被硬编码为 192.168.0.1 网段。固定网段是 P2P 互联的关键设计:对端(手机 App)连上该热点后无需 DHCP 协商即可使用既定地址访问设备,避免了 IP 漂移导致的发现失败:

static void soft_ap_set_lan_setting_info(void)
{
    struct lan_setting lan_setting_info = {
        .WIRELESS_IP_ADDR0  = 192,
        .WIRELESS_IP_ADDR1  = 168,
        .WIRELESS_IP_ADDR2  = 0,
        .WIRELESS_IP_ADDR3  = 1,
        .WIRELESS_NETMASK0  = 255, .WIRELESS_NETMASK1 = 255,
        .WIRELESS_NETMASK2  = 255, .WIRELESS_NETMASK3 = 0,
        .WIRELESS_GATEWAY0  = 192, .WIRELESS_GATEWAY1 = 168,
        .WIRELESS_GATEWAY2  = 0,   .WIRELESS_GATEWAY3 = 1,
        .SERVER_IPADDR1  = 192, .SERVER_IPADDR2 = 168,
        .SERVER_IPADDR3  = 0,   .SERVER_IPADDR4 = 1,
        .CLIENT_IPADDR1  = 192, .CLIENT_IPADDR2 = 168,
        .CLIENT_IPADDR3  = 0,   .CLIENT_IPADDR4 = 2,
        .SUB_NET_MASK1   = 255, .SUB_NET_MASK2 = 255,
        .SUB_NET_MASK3   = 255, .SUB_NET_MASK4 = 0,
    };
    net_set_lan_info_ext(&lan_setting_info, WIFI_NETIF);
}

Source: wifi_app_task.c

注意 SERVER_IPADDR 与 CLIENT_IPADDR 的区分:设备自身固定为 .0.1(服务器角色),对端设备预留 .0.2(客户端角色)——这直接对应"设备互联"中主从设备的地址规划。

STA 静态 IP:从 syscfg 恢复上次配置

当 CONFIG_STATIC_IPADDR_ENABLE 使能时,设备以 STA 模式接入路由器后使用上次保存的静态地址。sta_ip_info 结构体完整保存了 SSID、IP、网关、掩码、DNS、网关 MAC、本地 MAC 与信道,通过 syscfg_read(VM_STA_IPADDR_INDEX, ...) 从 VM 持久化区读出:

struct sta_ip_info {
    char ssid[33];
    u32 ip;
    u32 gw;
    u32 netmask;
    u32 dns;
    u8 gw_mac[6];
    u8 local_mac[6];
    u8 chanel;
};

static void wifi_set_lan_setting_info(void)
{
    struct sta_ip_info  sta_ip_info;
    syscfg_read(VM_STA_IPADDR_INDEX, (char *) &sta_ip_info, sizeof(struct sta_ip_info));

    struct lan_setting lan_setting_info = {
        .WIRELESS_IP_ADDR0  = (u8)(sta_ip_info.ip >> 0),
        .WIRELESS_IP_ADDR1  = (u8)(sta_ip_info.ip >> 8),
        .WIRELESS_IP_ADDR2  = (u8)(sta_ip_info.ip >> 16),
        .WIRELESS_IP_ADDR3  = (u8)(sta_ip_info.ip >> 24),
        // ... netmask / gateway / dns 同理按字节拆分
    };
}

Source: wifi_app_task.c

设计意图:

  1. 持久化 vs 运行时:网络参数存于 syscfg(VM 区),重启不掉电丢失,保证"上次可用配置"可直接恢复,缩短重连时间;
  2. 字节序处理:u32 的 IP 按字节右移拆分填入 lan_setting,与 SoC 小端序匹配,必须逐字节转换而非直接 memcpy;
  3. 弱函数扩展点:wifi_force_set_lan_setting_info 被声明为 __attribute__((weak)),默认返回 0——产品方可以在不改动 SDK 代码的前提下覆盖它,强制注入自定义 LAN 配置,这是本模块预留的扩展点:
int __attribute__((weak)) wifi_force_set_lan_setting_info(void)
{
    return 0;
}

Source: wifi_app_task.c

Socket 通信层:设备互联的数据通道

设备的"互联"本质是 socket 通信。wifi_app_task.c 的依赖头文件揭示了完整通信栈:lwip/sockets.h(BSD socket API)、lwip/netdb.h(域名解析)、lwip/dns.h(DNS)、lwip/ip.h(IP 层),以及 sock_api/sock_api.h(SDK 封装的异步 socket 接口)。

在 apps/wifi_story_machine/wifi_app_task.c 中,UDP 服务采用典型的"绑定端口 + 循环接收"模式,用 remote_addr(struct sockaddr_in)记录对端地址——保存对端地址是 P2P 回复的前提,收到数据后可按 remote_addr 定向回包:

static u32 sock_rcv_cnt;
struct sockaddr_in remote_addr;
socklen_t len = sizeof(remote_addr);

recv_len = sock_recvfrom(socket_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&remote_addr, &len);

Source: wifi_app_task.c

该 UDP 通道的用途包括:

  • 设备发现:App 广播探测包,设备在固定端口应答自身信息;
  • 透传/调试:udp_recv_pid 字段表明接收逻辑运行在独立线程中,udp_recv_test_exit_flag 控制测试模式的退出,避免接收线程泄漏;
  • 轻量命令:不需建立连接的命令走 UDP,降低开销。

为何使用 UDP 而非只依赖 TCP? 设备发现阶段双方 IP 未知,必须借助 UDP 广播/组播完成"寻址-应答",之后才切换到 TCP 建立可靠通道承载命令与媒体流。这是 P2P 互联的标准两步走策略。

远程服务面:让设备成为"服务器"

设备互联的另一半是服务端能力。头文件依赖表明设备集成了三层远程服务:

服务头文件角色
server_coreserver/server_core.h服务框架核心:任务/事件循环、连接管理
net_serverserver/net_server.h网络服务入口:TCP 监听、命令分发
Fenice 流媒体服务器streaming_media_server/fenice_config.h媒体流服务(RTSP/HTTP),远程拉流
#include "server/server_core.h"
#include "server/net_server.h"
#include "streaming_media_server/fenice_config.h"
#include "event/net_event.h"

Source: wifi_app_task.c

Fenice 集成是"远程访问"落地的关键:设备本地播放/采集的音频流通过 Fenice 暴露为流媒体服务,App 端可像访问普通流媒体服务器一样远程拉流,实现"设备互联"中最常见的场景——远程听音/远程控制。

协议与事件

  • JSON 协议:json_c/json_tokener.h 提供 JSON 解析,设备与对端(App/云)之间的命令消息以 JSON 承载,保证协议可扩展、可调试;
  • 事件通知:event/net_event.h 定义网络事件,net_server 层通过事件机制把"连接建立/断开/数据到达"通知到应用任务,应用无需轮询;
  • 系统服务:system/timer.h 提供定时器(配合 CONNECT_TIMEOUT_SEC 做连接超时管理)。

Core Flow:从开机到远程访问

sequenceDiagram
    participant App as 设备应用
    participant WAT as wifi_app_task
    participant LWIP as lwIP 协议栈
    participant NS as net_server / Fenice
    participant Peer as 对端(App/设备)

    App->>WAT: wifi_on()
    WAT->>WAT: 初始化 wifi_app_hdl 标志
    WAT->>WAT: net_app_init()(幂等保护)
    WAT->>LWIP: net_set_lan_info_ext<br/>(SoftAP 192.168.0.1 / 静态 IP)
    WAT->>NS: 启动 UDP/TCP 服务<br/>+ Fenice 流媒体服务
    NS-->>WAT: net_event 通知就绪
    WAT-->>App: 网络就绪事件
    Peer->>NS: UDP 发现请求
    NS->>Peer: 应答设备信息(remote_addr 定向回包)
    Peer->>NS: TCP 连接 / 命令请求
    NS->>NS: 分发命令(JSON 解析)
    Peer->>NS: RTSP/HTTP 拉流
    NS-->>Peer: 媒体流
    NS-->>WAT: 断开事件 -> 重连/清理

关键步骤解读:

  1. 上电:wifi_on() 使能射频与协议栈,随后 net_app_init() 完成应用层服务注册——标志位保证无论事件如何触发都不会重复初始化;
  2. 地址配置:SoftAP 或静态 IP 场景通过 net_set_lan_info_ext 注入 LAN 信息,设备获得稳定地址;
  3. 服务就绪:UDP(发现)+ TCP(命令)+ Fenice(流媒体)全部挂起,设备成为"可被访问的服务器";
  4. 发现-连接:对端先用 UDP 发现设备(remote_addr 记录来源),再升级为 TCP 可靠通道;
  5. 业务流转:命令走 JSON,媒体走流媒体协议,事件通过 net_event 回灌应用层;
  6. 退出/重连:断线触发事件,任务按 net_app_uninit 清理或按需重连,CONNECT_TIMEOUT_SEC 60 约束连接等待时间。

Configuration Options

以下配置项来自 wifi_app_task.c 源码与编译条件,均需在应用工程(如 app_config.h / 板级配置)中定义:

选项类型默认/取值说明
CONFIG_NET_ENABLE编译宏未定义网络功能总开关;wifi_app_task.c 全部代码包裹在其内
CONNECT_TIMEOUT_SEC宏常量60连接超时窗口(秒),控制 wifi_on 后等待网络的时长
CONFIG_STATIC_IPADDR_ENABLE编译宏未定义使能 STA 静态 IP 恢复(VM_STA_IPADDR_INDEX)
CONFIG_ASSIGN_MACADDR_ENABLE编译宏未定义使能 MAC 地址分配(assign_macaddr.h),关联 mac_addr_succ_flag
CONFIG_WIFIBOX_ENABLE编译宏未定义使能 Wi-Fi Box 客户端(client.h)
VM_STA_IPADDR_INDEXsyscfg 索引由 syscfg_id.h 定义静态 IP 信息在 VM 区的存储索引
use_static_ipaddr_flag位域0运行时标志,指示使用静态 IP 配置路径

编译开关的叠加关系:CONFIG_NET_ENABLE 是总闸;CONFIG_STATIC_IPADDR_ENABLE 决定走 wifi_set_lan_setting_info(读 syscfg)还是 SoftAP 固定配置路径;CONFIG_WIFIBOX_ENABLE 额外引入 Wi-Fi Box 云对接能力(对应 client.h,属于公网远程访问的另一通道)。

Failure Modes、边界与并发

连接超时

CONNECT_TIMEOUT_SEC 60 定义了从发起连接到放弃的最长等待时间。在弱信号或错误 SSID 场景下,任务不会无限阻塞,超时后进入失败处理路径。设计意图:IoT 设备对功耗与响应延迟敏感,必须用硬超时兜底,避免任务挂死导致系统无响应。

重复初始化防护

net_app_init 的 net_app_init_flag 幂等检查直接防御了并发/重入问题:网络事件(如连接成功回调、重连定时器)可能在同一时刻被多次触发,若没有标志位保护,socket 会重复 bind、服务会重复注册,最终导致资源泄漏或 EADDRINUSE。同样地,net_app_uninit 与 net_app_init 配对调用,保证退出路径对称。

测试模式下的状态隔离

rf_test_mode(3 bits)承载 8 种测试模式(MP/STA/AP/BT DUT/FCC/BQB/Multi),切换模式时通过 net_app_uninit 释放网络应用资源,防止 RF 测试期间残留的网络任务干扰测试结果。

边界情况

  • UDP 接收线程:udp_recv_pid 表明接收运行于独立任务;udp_recv_test_exit_flag 用于优雅退出接收循环——若未正确处理,切换测试模式时可能残留阻塞中的 sock_recvfrom;
  • 静态 IP 冲突:从 syscfg 恢复的地址可能与路由器 DHCP 池冲突;sta_ip_info 保存了 gw_mac(网关 MAC),可用于连通性校验;
  • 字节序:u32 IP 必须逐字节拆分填入 lan_setting,直接 memcpy 会导致地址错位。

Extension Points

扩展点机制用途
wifi_force_set_lan_setting_info__attribute__((weak)) 弱函数产品方强制注入自定义 LAN 配置,无需改动 SDK
net_event事件订阅应用层监听连接/断开/数据事件,挂接自定义业务
net_server 命令分发服务注册新增自定义 JSON 命令,扩展远程控制能力
Fenice 配置fenice_config.h定制流媒体端口/协议,适配不同拉流端
sock_api封装 socket复用异步收发能力实现自定义 P2P 通道

Related Links

  • net_server.h(网络服务入口) — 远程命令服务定义
  • server_core.h(服务框架) — 服务任务与连接管理
  • fenice_config.h(流媒体服务器) — 远程媒体流服务配置
  • wifi_app_task.c(网络应用任务) — 本页核心实现文件
  • demo_audio 版 wifi_app_task.c — 同名网络任务在 demo 应用中的变体
  • 配网(Airkiss/SmartConfig)、BT 低功耗、音乐业务等详见对应章节页面
Prev
云平台接入 SDK