返回首页

BLE Mesh 蓝牙网格网络学习笔记

本笔记学习 Zephyr 的 BLE Mesh 协议栈,实现蓝牙网格网络通信。


示例路径

zephyr/samples/bluetooth/mesh/
nrf/samples/bluetooth/mesh/

核心概念

BLE Mesh 架构

┌─────────────────────────────────────┐
│          Application Layer          │  (应用层)
├─────────────────────────────────────┤
│       Foundation Models             │  (基础模型)
├─────────────────────────────────────┤
│          Access Layer               │  (访问层)
├─────────────────────────────────────┤
│        Transport Layer              │  (传输层)
├─────────────────────────────────────┤
│          Network Layer              │  (网络层)
├─────────────────────────────────────┤
│          Bearers (ADV/GATT)         │  (承载层)
└─────────────────────────────────────┘

关键概念

概念说明
Node网格节点
Element元素(一个节点可有多个元素)
Model模型(定义节点功能)
Provisioning配网(设备加入网络)
Address地址(单播、组播、虚拟)

核心 API

头文件

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/mesh.h>

模型操作码定义

#define OP_ONOFF_GET       BT_MESH_MODEL_OP_2(0x82, 0x01)
#define OP_ONOFF_SET       BT_MESH_MODEL_OP_2(0x82, 0x02)
#define OP_ONOFF_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x03)
#define OP_ONOFF_STATUS    BT_MESH_MODEL_OP_2(0x82, 0x04)

模型操作处理函数

static int gen_onoff_get(const struct bt_mesh_model *model,
                         struct bt_mesh_msg_ctx *ctx,
                         struct net_buf_simple *buf);

static int gen_onoff_set(const struct bt_mesh_model *model,
                         struct bt_mesh_msg_ctx *ctx,
                         struct net_buf_simple *buf);

static const struct bt_mesh_model_op gen_onoff_srv_op[] = {
    { OP_ONOFF_GET,       BT_MESH_LEN_EXACT(0), gen_onoff_get },
    { OP_ONOFF_SET,       BT_MESH_LEN_MIN(2),   gen_onoff_set },
    BT_MESH_MODEL_OP_END,
};

模型定义

OnOff Server 模型

static const struct bt_mesh_model models[] = {
    BT_MESH_MODEL_CFG_SRV,                    // 配置服务器
    BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),  // 健康服务器
    BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, 
                  gen_onoff_srv_op, NULL, NULL),  // OnOff 服务器
};

OnOff Client 模型

static const struct bt_mesh_model models[] = {
    BT_MESH_MODEL_CFG_SRV,
    BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
    BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_CLI, 
                  gen_onoff_cli_op, NULL, NULL),  // OnOff 客户端
};

元素定义

static const struct bt_mesh_elem elements[] = {
    BT_MESH_ELEM(0, models, BT_MESH_MODEL_NONE),
};

static const struct bt_mesh_comp comp = {
    .cid = BT_COMP_ID_LF,
    .elem = elements,
    .elem_count = ARRAY_SIZE(elements),
};

配网 (Provisioning)

配网回调

static void prov_complete(uint16_t net_idx, uint16_t addr)
{
    printk("Provisioning complete\n");
}

static void prov_reset(void)
{
    bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
}

static const struct bt_mesh_prov prov = {
    .uuid = dev_uuid,
    .output_size = 4,
    .output_actions = BT_MESH_DISPLAY_NUMBER,
    .output_numeric = output_numeric,
    .complete = prov_complete,
    .reset = prov_reset,
};

自配网 (测试用)

// 注意:生产环境应由 Provisioner 配网
uint16_t addr = 0x0001;
uint8_t net_key[16] = {...};
uint8_t dev_key[16] = {...};

bt_mesh_provision(net_key, 0, 0, 0, addr, dev_key);

发送消息

OnOff Set 消息

static int gen_onoff_send(bool val)
{
    struct bt_mesh_msg_ctx ctx = {
        .app_idx = models[3].keys[0],
        .addr = BT_MESH_ADDR_ALL_NODES,  // 广播给所有节点
        .send_ttl = BT_MESH_TTL_DEFAULT,
    };
    static uint8_t tid;

    BT_MESH_MODEL_BUF_DEFINE(buf, OP_ONOFF_SET_UNACK, 2);
    bt_mesh_model_msg_init(&buf, OP_ONOFF_SET_UNACK);
    net_buf_simple_add_u8(&buf, val);
    net_buf_simple_add_u8(&buf, tid++);

    return bt_mesh_model_send(&models[3], &ctx, &buf, NULL, NULL);
}

接收消息

状态消息处理

static int gen_onoff_status(const struct bt_mesh_model *model,
                            struct bt_mesh_msg_ctx *ctx,
                            struct net_buf_simple *buf)
{
    uint8_t present = net_buf_simple_pull_u8(buf);

    if (buf->len) {
        uint8_t target = net_buf_simple_pull_u8(buf);
        int32_t remaining_time = model_time_decode(net_buf_simple_pull_u8(buf));
        
        printk("Status: %s -> %s (%d ms)\n", 
               onoff_str[present], onoff_str[target], remaining_time);
    } else {
        printk("Status: %s\n", onoff_str[present]);
    }

    return 0;
}

初始化

int main(void)
{
    int err;

    // 初始化蓝牙
    err = bt_enable(bt_ready);
    if (err) {
        printk("Bluetooth init failed\n");
        return 0;
    }

    return 0;
}

static void bt_ready(int err)
{
    if (err) {
        printk("Bluetooth init failed\n");
        return;
    }

    // 初始化 Mesh
    err = bt_mesh_init(&prov, &comp);
    if (err) {
        printk("Mesh init failed\n");
        return;
    }

    // 加载设置
    if (IS_ENABLED(CONFIG_SETTINGS)) {
        settings_load();
    }

    // 启用配网
    bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);

    printk("Mesh initialized\n");
}

配置选项

# prj.conf
CONFIG_BT=y
CONFIG_BT_MESH=y
CONFIG_BT_MESH_LOW_POWER=y
CONFIG_BT_MESH_FRIEND=y
CONFIG_BT_MESH_PROVISIONER=y
CONFIG_BT_MESH_PB_ADV=y
CONFIG_BT_MESH_PB_GATT=y
CONFIG_SETTINGS=y

nRF54L15 Mesh 特性

特性支持
Node
Friend Node
Low Power Node
Provisioner

应用场景

  1. 智能家居: 灯光控制、传感器网络
  2. 工业物联网: 设备监控、资产管理
  3. 商业照明: 大规模灯光控制
  4. 楼宇自动化: 环境监测、能源管理

注意事项

  1. 网络密钥: 安全存储网络密钥
  2. 地址分配: 合理规划节点地址
  3. TTL 设置: 控制消息跳数
  4. 重传机制: Mesh 自动重传,注意去重

*小白 🤖 - 2026-03-16*