杰理 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 辅助工具与脚本

蓝牙 Mesh 网络

AC79 AIoT SDK 基于 SIG Bluetooth Mesh(低功耗蓝牙网状网络)协议栈,为设备提供多对多组网通信能力。本文档介绍该协议栈在 SDK 中的整体架构、节点角色、配网(Provisioning)流程、核心 API、参数配置与故障处理机制,覆盖从应用层到预编译协议栈库(lib_sig_mesh.a)的完整链路。

目的与范围

本文档面向需要基于 AC79 平台开发蓝牙 Mesh 应用的工程师,内容涵盖:

  • Mesh 协议栈在 SDK 中的代码组织与模块划分(API 头文件、应用配置、预编译库);
  • 节点角色:Provisioner、Node、LPN(低功耗节点)、Friend(好友节点)及其参数语义;
  • 配网(Provisioning)与消息收发的核心流程;
  • 公共 API、地址模型、错误码与 buffer 工具函数;
  • 可配置参数(广播间隔、超时、缓冲等)及默认值;
  • 故障模式、并发/资源约束与扩展方式。

以下主题属于兄弟页面,不在本文展开:经典蓝牙(BR/EDR)与音频、普通 BLE GATT 外设/主机应用、Wi-Fi 协议栈。与本文相关的详细 API 用法可参考 include_lib/utils/btmesh/api/ 下各模块头文件。

概述

蓝牙 Mesh(SIG Mesh)是一种基于 BLE 广播与扫描机制的组网协议:节点间通过 ADV(不可连接广播)转发消息,支持中继(Relay)、代理(Proxy)、低功耗(LPN)与好友(Friend)等特性,从而在无中心路由器的条件下构建大规模设备网络。

在 AC79 SDK 中,Mesh 协议栈以预编译静态库 + 公开头文件 + 应用参数配置三种形态交付:

形态位置作用
预编译库cpu/wl82/liba/lib_sig_mesh.a协议栈核心实现(网络层、传输层、加密、模型框架)
公开 API 头include_lib/utils/btmesh/api/*.h应用可见的接口定义与类型
内部模块头include_lib/utils/btmesh/*.h协议栈内部数据结构说明
应用参数配置apps/common/ble/mesh/mesh_config_common.c广播、配网、LPN/Friend、beacon 等运行参数
链接/内存布局cpu/wl82/sdk_ld_sdram.c、sdk_ld_sfc.cMesh 代码段、RAM 占用统计与库版本符号

协议栈代码通过 #pragma 段指令映射到专用的 .ble_mesh_* 链接段(见 sig_mesh_api.c),便于在链接脚本中统计 Mesh 功能的 RAM/Flash 占用,并支持按需裁剪。

架构

下图展示了 Mesh 子系统从应用到控制器的分层结构,以及配置与 API 的依赖关系(节点与连接均取自实际源码中的模块/文件):

flowchart TD
    subgraph sg_App["应用层 (apps)"]
        App["应用代码 (业务 task / app_main)"]
    end

    subgraph sg_Config["配置层"]
        CfgCommon["mesh_config_common.c<br/>广播/配网/LPN/Friend 参数"]
        CfgModel["CONFIG_MESH_MODEL<br/>SIG_MESH_PROVISIONER / NODE"]
    end

    subgraph sg_API["API 层 (include_lib/utils/btmesh/api)"]
        SigApi["sig_mesh_api.h / .c"]
        MainApi["mesh_main.h<br/>Provisioning & Profile API"]
        AccessApi["access.h 模型访问"]
        CfgApi["cfg_cli.h / cfg_srv.h"]
        HealthApi["health_cli.h / health_srv.h"]
        ProxyApi["proxy.h"]
        CdbApi["cdb.h 配置数据库"]
    end

    subgraph sg_Stack["Mesh 协议栈 (lib_sig_mesh.a)"]
        Net["mesh_net.h 网络层"]
        Trans["mesh_transport.h 传输层"]
        Crypto["mesh_crypto.h 加密"]
        Settings["mesh_settings.h 持久化"]
    end

    subgraph sg_BT["蓝牙控制器 (wl82)"]
        HCI["HCI / 链路层"]
    end

    App -->|"调用"| SigApi
    App -->|"编译期选择"| CfgModel
    CfgModel --> CfgCommon
    CfgCommon -->|"参数生效"| SigApi
    SigApi --> MainApi
    SigApi --> AccessApi
    SigApi --> CfgApi
    SigApi --> HealthApi
    SigApi --> ProxyApi
    SigApi --> CdbApi
    MainApi --> Net
    Net --> Trans
    Trans --> Crypto
    Settings -->|"读写配置"| Net
    Net -->|"ADV / 扫描 / GATT"| HCI

各层职责说明:

  • 应用层:业务代码通过 sig_mesh_api.h 聚合暴露的接口完成节点初始化、模型注册与消息收发;不直接触碰协议栈内部结构。
  • 配置层:mesh_config_common.c 以全局常量(多数为 _WEAK_ 弱符号)形式定义运行参数,应用可覆盖;CONFIG_MESH_MODEL 决定设备编译为 Provisioner 还是普通 Node,并影响默认广播参数。
  • API 层:sig_mesh_api.h 是总入口,聚合了 access、mesh_main、proxy、cfg_cli/srv、health_cli/srv、cdb 等子模块头文件;sig_mesh_api.c 提供对 net_buf_simple 的 buffer 封装与 OpCode 构造工具。
  • 协议栈层:网络层(mesh_net)、传输层(mesh_transport)、加密(mesh_crypto)与设置持久化(mesh_settings)被编译进 lib_sig_mesh.a,应用只通过 API 头文件交互。
  • 控制器层:最终通过 wl82 蓝牙控制器以 ADV/扫描/连接方式承载 Mesh 广播与 GATT Proxy 通道。

协议栈模块与节点角色

API 聚合与子模块

sig_mesh_api.h 作为唯一公共入口,按 #include 聚合以下子模块(见 sig_mesh_api.h):

头文件职责
api/basic_depend.h基础类型与依赖定义
api/mesh_config.hMesh 编译期配置开关
kernel/atomic_h.h原子操作
api/access.h元素(Element)、模型(Model)注册与消息分发
api/mesh_main.hProvisioning 与 Profile 主 API
api/proxy.hGATT Proxy 服务(手机 App 通过 GATT 接入 Mesh)
api/cfg_cli.h / api/cfg_srv.h配置客户端 / 服务端模型(Composition Data、AppKey 等)
api/health_cli.h / api/health_srv.h健康检测模型(Health)
api/cdb.h配置数据库(Provisioner 侧记录节点信息)

这种"单一入口聚合头 + 预编译库"的设计让应用只需包含一个头文件即可获得全部 Mesh 能力,同时把协议栈内部符号隔离在 lib_sig_mesh.a 中,减少应用编译耦合。

节点角色与编译期选择

SDK 通过 CONFIG_MESH_MODEL 宏区分设备角色,并在 mesh_config_common.c 中为不同角色提供不同的默认广播参数(见 mesh_config_common.c):

#if (CONFIG_MESH_MODEL == SIG_MESH_PROVISIONER)
const u16 config_bt_mesh_node_msg_adv_interval = ADV_SCAN_UNIT(15); // unit: ms
const u16 config_bt_mesh_node_msg_adv_duration = 60; // 40unit: ms
const u8 config_bt_mesh_is_provisioner = 1;
#else
const u16 config_bt_mesh_node_msg_adv_interval = ADV_SCAN_UNIT(10); // unit: ms
const u16 config_bt_mesh_node_msg_adv_duration = 100; // unit: ms
const u8 config_bt_mesh_is_provisioner = 0;
#endif

Source: mesh_config_common.c

  • Provisioner(配网器):负责发现未配网设备并为其分配单播地址、下发 NetKey/AppKey。其节点消息广播间隔更大(15ms vs 10ms),以让出更多射频时间用于配网流程。
  • Node(节点):被配网器纳入网络的普通设备,仅作为消息收发与中继实体。

此外协议栈还支持两种资源受限特性,相关参数在 mesh_config_common.c 中集中定义:

  • LPN(Low Power Node,低功耗节点):通过降低扫描占空比省电,依赖 Friend 缓存消息。参数包括 config_bt_mesh_lpn_* 系列(自动超时、重试、扫描延迟、Poll 超时、接收延迟、RSSI/接收窗口因子、最小队列长度)。
  • Friend(好友节点):为 LPN 代收并缓存消息。参数包括 config_bt_mesh_friend_* 系列(可服务 LPN 数量、接收窗口、订阅列表大小、消息队列大小)。

LPN 与 Friend 通过 Friend Request/Offer/Update 等 PDU 建立关系,config_bt_mesh_lpn_powerup_add_sub_list 控制节点上电后是否自动把订阅地址加入列表,config_bt_mesh_lpn_auto_timeout 控制 LPN 自动进入低功耗模式的延时(0 表示不自动进入)。

配网 Bearer 与 OOB 能力

mesh_main.h 定义了配网使用的两种承载方式与输入/输出 OOB 能力(见 mesh_main.h):

typedef enum {
    BT_MESH_PROV_ADV   = BIT(0),
    BT_MESH_PROV_GATT  = BIT(1),
} bt_mesh_prov_bearer_t;

typedef enum {
    BT_MESH_NO_OUTPUT       = 0,
    BT_MESH_BLINK           = BIT(0),
    BT_MESH_BEEP            = BIT(1),
    BT_MESH_VIBRATE         = BIT(2),
    BT_MESH_DISPLAY_NUMBER  = BIT(3),
    BT_MESH_DISPLAY_STRING  = BIT(4),
} bt_mesh_output_action_t;

Source: mesh_main.h

  • BT_MESH_PROV_ADV:基于不可连接广播的配网(PB-ADV),适合设备间直连配网;
  • BT_MESH_PROV_GATT:基于 GATT 连接的配网(PB-GATT),适合手机 App 通过 Proxy 协议配网。

struct bt_mesh_prov 聚合了设备配网时的身份信息(uuid、uri、OOB 信息)以及输出/输入能力回调(output_number、output_string、输入回调等),应用通过实现这些回调完成人机交互确认。

核心流程

配网与配置流程

sequenceDiagram
    participant P as Provisioner
    participant N as 未配网节点
    participant S as Mesh 协议栈 (lib_sig_mesh.a)
    participant C as 蓝牙控制器

    Note over N,C: 未配网设备广播 Unprovisioned Device Beacon<br/>(config_bt_mesh_unprov_beacon_interval)
    N->>C: 周期广播未配网信标
    C-->>P: 扫描发现设备 (UUID)
    Note over P,N: PB-ADV / PB-GATT 配网协议
    P->>N: Invite (attention duration)
    N-->>P: Capabilities
    P->>N: Start (OOB 选择)
    N-->>P: Public Key (ECDH)
    P->>N: Provisioning Data (NetKey, IV Index, 单播地址)
    Note over P,N: 失败超时由 config_bt_mesh_prov_protocol_timeout 控制<br/>重传由 config_bt_mesh_prov_retransmit_timeout 控制
    N-->>P: Complete

    Note over P,N: 配置阶段 (Config Client 模型)
    P->>N: Config Composition Data Get
    N-->>P: 元素与模型清单
    P->>N: AppKey Add / Model App Bind
    N-->>P: Success

    Note over P,N: 应用消息 (Access → Transport → Network)
    P->>S: 发送应用消息 (OpCode + payload)
    S->>S: mesh_crypto 加密 + mesh_transport 分片
    S->>C: 广播或经 GATT Proxy 发送
    C-->>N: 中继至目标地址 (单播/组播/虚拟)

配网过程的每个阶段都依赖 mesh_config_common.c 中的定时参数:PB-ADV 广播间隔/时长(config_bt_mesh_pb_adv_interval/duration)、配网 PDU 重传超时(config_bt_mesh_prov_retransmit_timeout)、事务超时(config_bt_mesh_prov_transaction_timeout)、链路关闭超时(config_bt_mesh_prov_link_close_timeout)与协议总超时(config_bt_mesh_prov_protocol_timeout),保证配网过程对射频占用与丢包具有容错能力。

消息发送路径

应用消息从 Access 层出发,经传输层分片/重组与网络层加密,最终由控制器广播。sig_mesh_api.c 中的 buffer 工具负责按大小端序组装网络 PDU(见下文"使用示例")。消息可发往三种目标地址,由 sig_mesh_api.h 的地址宏判定:

#define BT_MESH_ADDR_IS_UNICAST(addr) ((addr) && (addr) < 0x8000)
#define BT_MESH_ADDR_IS_GROUP(addr) ((addr) >= 0xc000 && (addr) <= 0xff00)
#define BT_MESH_ADDR_IS_VIRTUAL(addr) ((addr) >= 0x8000 && (addr) < 0xc000)

Source: sig_mesh_api.h

单播(Unicast)定向到单个元素,组播(Group)面向同一订阅组,虚拟(Virtual)基于 128 位标签地址,为多供应商模型提供更灵活的寻址空间。

配置参数详解

以下参数均定义于 mesh_config_common.c,除标注 _WEAK_ 的符号外均为强定义。ADV_SCAN_UNIT(_ms) 将毫秒换算为广播单元(1 单元 = 0.625ms,即 (_ms) * 8 / 5)。

节点消息广播

参数类型默认值说明
config_bt_mesh_node_msg_adv_intervalu16Provisioner: ADV_SCAN_UNIT(15);Node: ADV_SCAN_UNIT(10)节点发送消息时的广播间隔
config_bt_mesh_node_msg_adv_durationu16Provisioner: 60;Node: 100消息广播持续时长(单元)
config_bt_mesh_is_provisioneru81 / 0(随角色)当前设备是否为配网器

Proxy 广播

参数类型默认值说明
config_bt_mesh_proxy_unprovision_adv_intervalu16ADV_SCAN_UNIT(30)未配网状态下的 Proxy 可连接广播间隔
config_bt_mesh_proxy_pre_node_adv_intervalu16Provisioner: ADV_SCAN_UNIT(300);Node: ADV_SCAN_UNIT(10)入网前(pre-node)广播间隔
config_bt_mesh_proxy_node_adv_intervalu16ADV_SCAN_UNIT(300)(_WEAK_)入网后节点 Proxy 广播间隔,应用可覆盖

LPN(低功耗节点)

参数类型默认值说明
config_bt_mesh_lpn_auto_timeoutu80自动进入低功耗模式的延时(秒),0 表示不自动进入
config_bt_mesh_lpn_retry_timeoutu810Friend 请求重试超时(秒)
config_bt_mesh_lpn_scan_latencyint10扫描延迟(毫秒)
config_bt_mesh_lpn_init_poll_timeoutu32300初始 Poll 超时(单位 100ms)
config_bt_mesh_lpn_powerup_add_sub_listu81上电后是否自动添加订阅列表
config_bt_mesh_lpn_recv_delayu8100接收延迟(毫秒,对应 3.6.5.3 Friend Request)
config_bt_mesh_lpn_poll_timeoutu32200正常 Poll 超时(单位 100ms)
config_bt_mesh_lpn_rssi_factoru80RSSI 因子
config_bt_mesh_lpn_recv_win_factoru80接收窗口因子
config_bt_mesh_lpn_min_queue_sizeu81Friend 最小队列长度要求

Friend(好友节点)

参数类型默认值说明
config_bt_mesh_friend_lpn_countu81可服务的 LPN 数量
config_bt_mesh_friend_recv_winu8250Friend 接收窗口(对应 3.6.5.4 Friend Offer)
config_bt_mesh_friend_sub_list_sizeu82订阅列表大小
config_bt_mesh_friend_queue_sizeu82消息队列大小

广播缓冲与配网、Beacon

参数类型默认值说明
config_bt_mesh_adv_buf_countu820(_WEAK_)广播缓存个数,编译期强制 >= 3,否则 #error
config_bt_mesh_pb_adv_intervalu16ADV_SCAN_UNIT(15)PB-ADV 配网广播间隔
config_bt_mesh_pb_adv_durationu1660PB-ADV 广播时长
config_bt_mesh_prov_retransmit_timeoutu32300配网 PDU 重传超时(毫秒)
config_bt_mesh_prov_transaction_timeoutu814配网事务超时(秒)
config_bt_mesh_prov_link_close_timeoutu83配网链路关闭超时(秒)
config_bt_mesh_prov_protocol_timeoutu815配网协议总超时(秒)
config_bt_mesh_unprov_beacon_intervalu32200未配网信标广播间隔(毫秒)
config_bt_mesh_secure_beacon_intervalu1610安全信标广播间隔(秒)

MESH_ADV_BUFFER_COUNT 的编译期检查(#error " MESH_ADV_BUFFER_COUNT must >= 3 ")体现了设计约束:Mesh 依赖广播承载,至少需要 3 个缓存槽位支撑"当前广播 + 排队广播 + 扫描响应"的最小工作集,防止广播饥饿。

使用示例

示例一:按角色配置广播参数

下面的代码展示 SDK 如何根据设备角色(Provisioner / Node)在编译期选择不同的广播参数——这是应用无需改动业务代码即可适配两种角色的关键机制:

#if (CONFIG_MESH_MODEL == SIG_MESH_PROVISIONER)
const u16 config_bt_mesh_node_msg_adv_interval = ADV_SCAN_UNIT(15); // unit: ms
const u16 config_bt_mesh_node_msg_adv_duration = 60; // 40unit: ms
const u8 config_bt_mesh_is_provisioner = 1;
#else
const u16 config_bt_mesh_node_msg_adv_interval = ADV_SCAN_UNIT(10); // unit: ms
const u16 config_bt_mesh_node_msg_adv_duration = 100; // unit: ms
const u8 config_bt_mesh_is_provisioner = 0;
#endif

Source: mesh_config_common.c

示例二:地址类型判定宏

Mesh 应用在收发消息前需要判断目标地址类型,SDK 提供如下位域宏(单播 < 0x8000,虚拟 0x8000~0xBFFF,组播 0xC000~0xFEFF,保留 0xFF00~0xFFFB):

#define BT_MESH_ADDR_IS_UNICAST(addr) ((addr) && (addr) < 0x8000)
#define BT_MESH_ADDR_IS_GROUP(addr) ((addr) >= 0xc000 && (addr) <= 0xff00)
#define BT_MESH_ADDR_IS_VIRTUAL(addr) ((addr) >= 0x8000 && (addr) < 0xc000)
#define BT_MESH_ADDR_IS_RFU(addr) ((addr) >= 0xff00 && (addr) <= 0xfffb)

Source: sig_mesh_api.h

示例三:OpCode 头部构造

协议栈发送消息时需按 SIG 规范将 OpCode 编码为 1/2/3 字节(字节序与 OpCode 长度相关),buffer_head_init 封装了该逻辑:

u32 buffer_head_init(u32 opcode)
{
    if (opcode < 0x100) {
        /* 1-byte OpCode */
        return opcode;
    }

    if (opcode < 0x10000) {
        /* 2-byte OpCode */
        return sys_cpu_to_be16(opcode);
    }

    /* 3-byte OpCode */
    u8 b0 = (opcode >> 16) & 0xff;
    ...
}

Source: sig_mesh_api.c

该函数体现了 Mesh 协议对 OpCode 的分层设计:0x00~0xFF 使用 1 字节 OpCode,0x0100~0xFFFF 使用 2 字节(网络序),更大的厂商自定义 OpCode 使用 3 字节(含 Company ID),以此在短报文(广播信道资源紧张)与地址空间扩展之间取得平衡。

示例四:配网能力枚举

应用通过 struct bt_mesh_prov 声明设备配网能力,其中输出动作枚举如下:

typedef enum {
    BT_MESH_NO_OUTPUT       = 0,
    BT_MESH_BLINK           = BIT(0),
    BT_MESH_BEEP            = BIT(1),
    BT_MESH_VIBRATE         = BIT(2),
    BT_MESH_DISPLAY_NUMBER  = BIT(3),
    BT_MESH_DISPLAY_STRING  = BIT(4),
} bt_mesh_output_action_t;

Source: mesh_main.h

OOB(带外)能力使用位掩码组合,配网器与设备据此协商认证方式(数字/字符串输出、按键/输入等),确保配网过程的安全性。

示例五:buffer 工具封装

sig_mesh_api.c 将 Zephyr 风格 net_buf_simple 的读写操作封装为面向 Mesh 报文的工具函数,统一处理大小端:

u8 *buffer_add_u8_at_tail(void *buf, u8 val)
{
    return net_buf_simple_add_u8((struct net_buf_simple *)buf, val);
}

void buffer_add_le16_at_tail(void *buf, u16 val)
{
    net_buf_simple_add_le16((struct net_buf_simple *)buf, val);
}

void buffer_add_be32_at_tail(void *buf, u32 val)
{
    net_buf_simple_add_be32((struct net_buf_simple *)buf, val);
}

Source: sig_mesh_api.c

Mesh 协议字段混用小端(地址、计数器)与大端(OpCode、部分控制字段),这些封装让上层组装报文时无需关心具体字节序。

API 参考

地址判定宏(sig_mesh_api.h)

宏参数返回值语义
BT_MESH_ADDR_IS_UNICAST(addr)u16 地址布尔单播地址(addr != 0 && addr < 0x8000)
BT_MESH_ADDR_IS_GROUP(addr)u16 地址布尔组播地址(0xC000~0xFF00)
BT_MESH_ADDR_IS_VIRTUAL(addr)u16 地址布尔虚拟地址哈希(0x8000~0xBFFF)
BT_MESH_ADDR_IS_RFU(addr)u16 地址布尔保留地址(0xFF00~0xFFFB)

buffer 工具函数(sig_mesh_api.c)

函数语义
u8 *buffer_add_u8_at_tail(void *buf, u8 val)尾部追加 1 字节
void buffer_add_le16_at_tail(void *buf, u16 val)尾部追加小端 2 字节
void buffer_add_be16_at_tail(void *buf, u16 val)尾部追加大端 2 字节
void buffer_add_le32_at_tail(void *buf, u32 val)尾部追加小端 4 字节
void buffer_add_be32_at_tail(void *buf, u32 val)尾部追加大端 4 字节
u8 buffer_pull_u8_from_head(void *buf)头部取出 1 字节
u16 buffer_pull_le16_from_head(void *buf)头部取出小端 2 字节
u16 buffer_pull_be16_from_head(void *buf)头部取出大端 2 字节
u32 buffer_pull_le32_from_head(void *buf)头部取出小端 4 字节
u32 buffer_pull_be32_from_head(void *buf)头部取出大端 4 字节
void *buffer_memcpy(void *buf, const void *mem, u32 len)尾部追加原始内存块
void *buffer_memset(struct net_buf_simple *buf, u8 val, u32 len)尾部追加填充字节
u32 buffer_head_init(u32 opcode)将 OpCode 编码为 1/2/3 字节网络序头部

错误码约定(sig_mesh_api.h)

协议栈复用类 POSIX 错误码,Mesh 特有扩展包括:

错误码值语义
ENOTSUP35不支持的操作/特性
EMSGSIZE36消息过长(超过传输层可承载尺寸)
ENOBUFS55无可用缓冲区(如广播缓存耗尽)
ENOTCONN57未建立连接(如 Proxy 未连接)
ETIMEDOUT60操作超时(如配网事务超时)
EALREADY69操作已在进行(如重复发起配网)
ECANCELED72操作被取消
EBADMSG77报文格式非法

Provisioning 枚举(mesh_main.h)

  • bt_mesh_output_action_t:设备可执行输出动作(闪烁/蜂鸣/振动/显示数字/显示字符串),BT_MESH_NO_OUTPUT 表示无输出能力;
  • bt_mesh_input_action_t:设备可接受输入动作(按压/旋转/输入数字/输入字符串),BT_MESH_NO_INPUT 表示无输入能力;
  • bt_mesh_prov_bearer_t:配网承载(BT_MESH_PROV_ADV / BT_MESH_PROV_GATT,可组合);
  • bt_mesh_prov_oob_info_t:OOB 信息来源描述(URI、二维码、NFC、设备内外标签等),用于配网流程的安全提示;
  • struct bt_mesh_prov:配网属性与回调集合,包含 uuid、uri、oob_info、static_val、输出/输入能力与 output_number 等回调。

故障模式、边界情况与并发

广播缓存耗尽(ENOBUFS)

Mesh 消息依赖广播承载,config_bt_mesh_adv_buf_count(默认 20,弱符号可覆盖)是并发消息的硬上限。当多模型同时发送消息或中继负载突增时,缓存耗尽将返回 ENOBUFS(错误码 55)。设计上:

  • 编译期强制 MESH_ADV_BUFFER_COUNT >= 3,低于 3 直接 #error,杜绝"广播饥饿";
  • 运行时通过增大广播间隔(如 Provisioner 使用 15ms 而非 Node 的 10ms)让出射频时间,降低缓存竞争概率;
  • 应用侧应避免在短时间窗口内突发大量消息,必要时按业务优先级排队。

配网超时与重传

配网协议对丢包敏感,SDK 用四层超时保障流程收敛:

  1. config_bt_mesh_prov_retransmit_timeout(300ms)——同一 PDU 的重传间隔;
  2. config_bt_mesh_prov_transaction_timeout(14s)——单事务(如 Invite→Capabilities)最大等待;
  3. config_bt_mesh_prov_link_close_timeout(3s)——链路关闭确认等待;
  4. config_bt_mesh_prov_protocol_timeout(15s)——整个配网协议的最长时限。

超时后协议栈以 ETIMEDOUT 通知应用,应用可重新触发配网。并发配网(多个未配网设备同时入网)受 EALREADY 保护:同一时刻仅允许一个配网事务。

地址边界

地址宏对 addr = 0 的处理(BT_MESH_ADDR_IS_UNICAST 要求 addr 非零)防止将"未分配地址"误判为合法单播地址;BT_MESH_ADDR_IS_RFU 覆盖 0xFF00~0xFFFB 保留段,避免把保留地址当作组播使用。

并发与资源占用

协议栈以专用链接段(.ble_mesh_* / .ble_mesh_joint_*)承载代码与数据,在 sdk_ld_sdram.c / sdk_ld_sfc.c 中统计 BTSTACK_LE_HOST_MESH_RAM_TOTAL(Data+BSS)与 BTSTACK_LE_HOST_MESH_FLASH_TOTAL(Code),并导出 lib_btmesh_version 符号用于版本核验。这意味着:

  • Mesh 功能的 RAM/Flash 占用是静态可预算的,利于在资源受限的 wl82 平台规划内存;
  • 打开 MESH_RAM_AND_CODE_MAP_DETAIL 可将 Mesh 代码/数据进一步拆分为独立段(joint 段),便于按模块裁剪。

性能与运维注意事项

  • 广播间隔权衡:较小的 config_bt_mesh_node_msg_adv_interval 提升消息时延表现,但增加射频占用与缓存竞争;Provisioner 默认 15ms、Node 默认 10ms 的差异即是对"配网占用"与"普通通信"不同场景的折中。
  • LPN 省电:config_bt_mesh_lpn_scan_latency 与 config_bt_mesh_lpn_poll_timeout 决定 LPN 的休眠深度,直接关系电池寿命;同时必须与 Friend 的 config_bt_mesh_friend_recv_win、config_bt_mesh_friend_queue_size 匹配,否则消息会因窗口/队列不足而丢失。
  • Proxy 广播:入网后 Proxy 节点默认以 300ms 间隔广播可连接事件(config_bt_mesh_proxy_node_adv_interval 为弱符号,可覆盖),该参数影响手机 App 发现节点的速度与功耗。
  • 日志分级:MESH_HCI、MESH_GATT 两组日志 tag 均以 CONFIG_DEBUG_LIB 控制(默认关闭),生产构建可整体关闭以减小代码体积与日志开销。

扩展点

  1. 弱符号参数覆盖:config_bt_mesh_adv_buf_count、config_bt_mesh_proxy_node_adv_interval 声明为 _WEAK_,应用可重新定义同名强符号覆盖默认值,无需改动 SDK 源码。
  2. 角色编译开关:CONFIG_MESH_MODEL(SIG_MESH_PROVISIONER / 其他)在编译期决定设备角色及相应默认参数。
  3. 配网回调:struct bt_mesh_prov 的 output_number / output_string / 输入回调允许应用接入自定义的人机交互(LED、蜂鸣器、屏幕、按键矩阵)。
  4. 模型框架:access.h 提供的元素/模型注册机制支持应用自定义模型(含 3 字节厂商 OpCode),配合 BT_MESH_ADDR_IS_VIRTUAL 虚拟地址可实现多供应商互操作。
  5. 内存布局:MESH_RAM_AND_CODE_MAP_DETAIL 开启后可对 Mesh 各模块做更细粒度的段映射,为资源裁剪提供入口。

相关链接

  • sig_mesh_api.h(公共 API 总入口)
  • sig_mesh_api.c(buffer 工具实现)
  • mesh_main.h(Provisioning & Profile API)
  • mesh_config_common.c(Mesh 运行参数配置)
  • sdk_ld_sdram.c(Mesh 内存/Flash 统计与库版本)
  • 兄弟页面:经典蓝牙与音频(4.1)、BLE GATT(4.2)、Wi-Fi 联网(4.4)
Prev
BLE 低功耗蓝牙
Next
蓝牙扩展协议(RCSP/广播/无线麦克风)