蓝牙 mesh 已经发布有一段时间了,但是不管是芯片厂商还是技术博客大多都停留在文字和概念上,目前Nordic 的mesh SDK还在开发迭代中,相对应的APP 还在Beta版中。 AliOS 有支持 mesh, 不过相关文档太旧了。所以就有了这篇文章。 目标是让刚开始涉及到 mesh 的开发者(大多数迷失在众多mesh 标准文档中)一个感性的认知。
既然是mesh, 那就应该可以实现 n:m
,并且可以实现跳转、转发来增加通信距离。我们先采用最简单的灯控制来感性认知下。最终要实现 1个设备控制2个设备和中继的效果。
1 安装 BlueZ 5.50
1.1 安装系统
Ubuntu 18.04 & Dell G7 笔记本
1.2 更新系统
sudo apt update
sudo apt upgrade
1.3 安装依赖
sudo apt-get install -y git bc libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev autoconf
1.4 安装 json-c
cd ~
wget https://s3.amazonaws.com/json-c_releases/releases/json-c-0.13.tar.gz
tar -xvf json-c-0.13.tar.gz
cd json-c-0.13/
./configure --prefix=/usr --disable-static && make
sudo make install
1.5 安装 ell
cd ~
wget https://mirrors.edge.kernel.org/pub/linux/libs/ell/ell-0.6.tar.xz
tar -xvf ell-0.6.tar.xz
cd ell-0.6/
sudo ./configure --prefix=/usr
sudo make
sudo make install
1.6 安装 Bluez 5.50
cd ~
wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.50.tar.xz
tar -xvf bluez-5.50.tar.xz
cd bluez-5.50/
./configure --enable-mesh --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc --localstatedir=/var
make
sudo make install
1.7 运行 meshctl
在刚才安装的源文件夹 bluez-5.50/mesh
中运行 meshctl
2 准备蓝牙设备
准备至少两块 nRF52832 DK 或者 nR52840 DK 。如果要使用relay中继功能,至少需要3块。
使用 zephyr 1.13 中默认的 onoff-app 工程,直接编译并下载。
3 使用 meshctl 进行 provision
3.1 进入 meshctl 命令
# gaoxiang @ xgx in ~ [15:42:25]
$ cd Desktop/bluez-5.50/mesh
# gaoxiang @ xgx in ~/Desktop/bluez-5.50/mesh [15:42:43]
$ meshctl
[meshctl]#
3.2 使用 help 查看命令
[meshctl]# help
Menu main:
Available commands:
-------------------
config Configuration Model Submenu
onoff On/Off Model Submenu
list List available controllers
show [ctrl] Controller information
select <ctrl> Select default controller
security [0(low)/1(medium)/2(high)] Display or change provision security level
info [dev] Device information
connect [net_idx] [dst] Connect to mesh network or node on network
discover-unprovisioned <on/off> Look for devices to provision
provision <uuid> Initiate provisioning
power <on/off> Set controller power
disconnect [dev] Disconnect device
mesh-info Mesh networkinfo (provisioner)
local-info Local mesh node info
menu <name> Select submenu
version Display version
quit Quit program
exit Quit program
help Display help about this program
export Print evironment variables
[meshctl]#
3.3 发现 unprovisioned 设备
[meshctl]# discover-unprovisioned on
SetDiscoveryFilter success
Discovery started
Adapter property changed
[CHG] Controller 94:B8:6D:F3:16:59 Discovering: yes
Mesh Provisioning Service (00001827-0000-1000-8000-00805f9b34fb)
Device UUID: c768a43cf4ea00000000000000000000
OOB: 0000
[NEW] Device EA:F4:3C:A4:68:C7 Zephyr
3.4 Provision 设备
3.4.1 Provision
运行命令,把上面显示的UUID复制过来
[meshctl]# provision c768a43cf4ea00000000000000000000
3.4.2 输入OOB
如果找到一个新的 unprovisioned 设备, 会出现下面结果。
[meshctl]# provision c768a43cf4ea00000000000000000000
Trying to connect Device EA:F4:3C:A4:68:C7 Zephyr
Adapter property changed
[CHG] Controller 94:B8:6D:F3:16:59 Discovering: no
Connection successful
Services resolved yes
Found matching char: path /org/bluez/hci0/dev_EA_F4_3C_A4_68_C7/service000a/char000b, uuid 00002adb-0000-1000-8000-00805f9b34fb
Found matching char: path /org/bluez/hci0/dev_EA_F4_3C_A4_68_C7/service000a/char000d, uuid 00002adc-0000-1000-8000-00805f9b34fb
Start notification on /org/bluez/hci0/dev_EA_F4_3C_A4_68_C7/service000a/char000d
Characteristic property changed /org/bluez/hci0/dev_EA_F4_3C_A4_68_C7/service000a/char000d
AcquireNotify success: fd 7 MTU 69
Notify for Mesh Provisioning Out Data started
Open-Node: 0x55c2b32446d0
Open-Prov: 0x55c2b3241f00
Open-Prov: proxy 0x55c2b32477d0
Initiated provisioning
Characteristic property changed /org/bluez/hci0/dev_EA_F4_3C_A4_68_C7/service000a/char000b
AcquireWrite success: fd 8 MTU 69
GATT-TX: 03 00 10
GATT-RX: 03 01 04 00 01 00 00 06 00 18 00 00 00
Got provisioning data (12 bytes)
01 04 00 01 00 00 06 00 18 00 00 00
GATT-TX: 03 02 00 00 02 04 06
GATT-TX: 03 03 e8 70 ad 45 e6 84 b2 9f 7f b4 84 bd c8 d3
GATT-TX: 66 80 fa f1 c1 1d f3 6c 92 d2 d5 97 f4 18 a5 40
GATT-TX: c2 fe 79 ee 12 3b fb 13 bf 09 ec 9b 22 32 06 94
GATT-TX: 70 26 40 1b 73 c0 69 49 f4 e3 cf c2 fe 39 93 c5
GATT-TX: 13 29
GATT-RX: 03 03 46 c3 e6 63 4a db d6 a3 f2 60 79 05 ef 87
GATT-RX: ed 3f 24 d0 61 dc 4a 02 cb 73 fa e8 3e b8 cf b0
GATT-RX: df 31 27 93 8b dd fb 5b 4e b4 bd 74 0b 6b 46 fa
GATT-RX: 73 b3 4f 97 45 ff a8 02 a6 d9 6e da e7 1f 93 43
GATT-RX: d8 da
Got provisioning data (65 bytes)
03 46 c3 e6 63 4a db d6 a3 f2 60 79 05 ef 87 ed
3f 24 d0 61 dc 4a 02 cb 73 fa e8 3e b8 cf b0 df
31 27 93 8b dd fb 5b 4e b4 bd 74 0b 6b 46 fa 73
b3 4f 97 45 ff a8 02 a6 d9 6e da e7 1f 93 43 d8
da
Request ASCII key (max characters 6)
[mesh] Enter key (ascii string): BSMCYY #串口会显示该字符串。如果是nrf mesh APP,会是数字
3.4.3 成功信息
配对成功,会显示 node 的数据。
- Relaly
- Proxy
- Friend
- Lpn Low power node
一个设备 node 有4个 Elements,使用 Element Index 来识别。
每个 Elements 有4个 Models,使用 Model Index 来识别。
Composition data for node 0100 {
"cid":"05f1",
"pid":"0000",
"vid":"0000",
"crpl":"000a",
"features":{
"relay":true,
"proxy":true,
"friend":false,
"lpn":false
},
"elements":[
{
"elementIndex":0,
"location":"0000",
"models":[
"0000",
"0001",
"0002",
"1000",
"1001"
]
},
{
"elementIndex":1,
"location":"0000",
"models":[
"1000",
"1001"
]
},
{
"elementIndex":2,
"location":"0000",
"models":[
"1000",
"1001"
]
},
{
"elementIndex":3,
"location":"0000",
"models":[
"1000",
"1001"
]
}
]
}
使用 mesh-info
可以查看所有已经配置过node的信息。
[Zephyr-Node-0100]# mesh-info
"elements":[
{
"elementIndex":0,
"unicastAddress":"0100"
},
{
"elementIndex":1,
"unicastAddress":"0101"
},
{
"elementIndex":2,
"unicastAddress":"0102"
},
{
"elementIndex":3,
"unicastAddress":"0103"
}
]
3.4.4 配置
3.4.4.1 进入配置子菜单
[Zephyr-Node-0100]# menu config
3.4.4.2 选择 node
选择需要配置node。使用target <unicast>
。 可以通过 mesh-info
查询 unicast
。例如现在需要配置当前node 中第一个Element,它的 unicast
就是 0100
。
[Zephyr-Node-0100]# target 0100
Configuring node 0100
3.4.4.3 绑定 APP Key
bind <ele_idx> <app_idx> <mod_id> [cid]
Model 1000 对应 LED , Model 1001 对应 Key 。
[config: Target = 0100]# bind 0 1 1000
GATT-TX: 00 d1 86 0f ab c6 5b 90 da e8 8b f1 93 9f de a5
GATT-TX: f9 51 b4 cf 58 af 0b 12 97 5f 54
GATT-RX: 00 d1 fc 76 63 3c 00 91 a1 ee c5 4a 3b 40 d3 64
GATT-RX: 8d a7 5c b0 fc a5 de fa 42 cf 20 6b
Node 0100 Model App status Success
Element Addr 0100
Model Id 1000
AppIdx 001
3.4.4.4 配置 Subscribe
sub-add <ele_addr> <sub_addr> <model id>
。配置LED 0(model id: 1000)
订阅 C000
地址的消息。
[config: Target = 0100]# sub-add 0100 c000 1000
GATT-TX: 00 d1 a4 2c 01 48 f5 ef 5d fe bb d4 0f 6b b4 40
GATT-TX: 00 c9 05 5a b6 b8 b4 7a f8 92 48
GATT-RX: 00 d1 e7 9b 15 c8 cd 4a 7f d4 0a 3d 2d 87 5f ea
GATT-RX: c7 af 25 7c 8f 53 bf e8 fe 7a ce 84
Node 0100 Subscription status Success
Element Addr 0100
Model Id 1000
Subscr Addr c000
3.4.4.5 绑定 APP Key
[config: Target = 0100]# bind 0 1 1001
GATT-TX: 00 d1 df c5 26 45 69 eb d7 a1 18 0c c7 44 43 a1
GATT-TX: 44 2c 7d 8b 3a c2 46 95 8f 87 54
GATT-RX: 00 d1 75 a6 eb 48 e4 ca f9 06 ec 5d bf ac da 10
GATT-RX: 64 af 2c 6c 77 07 7f d0 ce 2e 9d 16
Node 0100 Model App status Success
Element Addr 0100
Model Id 1001
AppIdx 001
3.4.4.6 配置 Publish
pub-set <ele_addr> <pub_addr> <app_idx> <per (step|res)> <re-xmt (cnt|per)> <mod id> [cid]
配置 按键 0 (model id: 1001)
发布按键消息到 C000
地址上。
到此已经基本配置完成,可以一次短按来点亮LED 0,连续两次短按可以关闭LED 0。
[config: Target = 0100]# pub-set 0100 c000 1 0 0 1001
GATT-TX: 00 d1 f4 1c f7 c6 2e 22 44 a5 3a 19 12 75 0a b2
GATT-TX: fe 8e 19 3c 38 5c c5 48 65 ef 3f 4f c7 82
GATT-TX: 00 d1 8e da 6e 62 14 3d f8 de 3b 7a 4e 79 a3 2b
GATT-TX: 08 70 72 bd cc 98
GATT-RX: 00 d1 13 f2 45 cd 4c 26 14 e1 44 4a 57 15 5f 13
GATT-RX: 6c c7 f9 f8 cb bc 96 81 7c
GATT-RX: 00 d1 58 ea b8 c7 65 4c 74 99 f1 03 c8 5c 6b 65
GATT-RX: de 7c 89 21 ea c4 ba ed af 8a 04 75 0f fa
GATT-RX: 00 d1 34 11 1e 8b 0c d9 74 24 8e 93 d8 37 22 e5
GATT-RX: b8 7a bb e1 a2 a4 37 6c
Node 0100 Publication status Success
Element Addr 0100
Model Id 1001
Pub Addr c000
Period 0 ms
Rexmit count 0
Rexmit steps 0
GATT-TX: 00 d1 4a 05 51 fa b3 3c d0 5e 03 72 5e 83 e1 73
GATT-TX: a2 c2 01 17 0b fd 88 4b ca
3.4.4.7 配置 Relay 角色
默认配置没有开启 Relay
角色, 在隔墙后,可能无法正确控制设备。通过 relay-set <relay> <rexmt count> <rexmt steps>
可以将部分设备设置成relay。
[config: Target = 0100]# relay-set 1 5 1
GATT-TX: 00 d1 4e af cd 8a 79 69 cf 60 1a 66 60 4e 83 41
GATT-TX: 06 ee b0 70 cb e8 c6
GATT-RX: 00 d1 14 ff 8a fa 97 a5 98 3d 90 9f 6d aa fd ec
GATT-RX: 63 4d 91 8d 2c 7a 7b
Node 0100 Relay state 0x01 count 5 steps 1
3.5 再配置2个设备
按照上面的步骤,继续配置两个设备。