目录
1:BLE SIG Mesh初始化
2:未配网设备的unprovisioned mesh beacon
3:配网数据传输控制
4:天猫精灵PB-ADV配网过程
4.1 provisioning invite与provisioning capabilities
4.2 provisioning start
4.3 provisioning public key exchange
4.4 authentication
4.5 Distribution of provisioning data
4.6 provisioning complete & provisioning fail
5:绑定AppKey过程
6:天猫精灵对AB1611配网问题总结
整理了下思维导图笔记:
关于环境搭建,参考《基于Airoha AB1611的mesh智能灯方案》https://www.wpgholdings.com/news/detail/zhcn/program/project_code_5226
关于BLE SIG Mesh的初始化过程详见《AB16xx_Mesh_Developers_Guide.pdf》
需要本文关注的是两个地方:
<1> BT_MISC_EVENT_INITED蓝牙初始化完毕后,通过mesh_three_tuples_get_uuid获取了阿里发布的三元组数据,并将前16字节数据写入deviceUuid。deviceUuid是每个与天猫精灵配网的设备的唯一标识,其内包括设备MAC地址。
<2>bt_mesh_init调用前对BLE SIG Mesh网络的初始化相关设置。
未配网的设备会向外部广播自身的信息,BLE SIG Mesh支持两种配网方式:PB-GATT与PB-ADV:
<1>PB-GATT是通过BLE与设备直连进行配网的方式,设备为了支持PB-GATT配网会向外广播ADV_IND类型的unprovisioned dev beacon,可以参考我的另一篇博文:
《Telink BLE SIG Mesh GATT 配网功能》https://blog.csdn.net/abc517789065/article/details/95066020
<2>PB-ADV是通过广播包对设备进行配网的方式,天猫精灵采用该种方式对设备配网。设备处于未配网状态下会广播ADV_NONCONN_IND类型的unprovisioned mesh beacon,beacon包含有设备的UUID信息;当用户命令天猫精灵“发现设备”时,天猫精灵会进行一段时间的mesh beacon接收,搜寻周围未配网的设备的UUID。
Airoha AB1611设备未配网时的unprovisioned mesh beacon抓包数据:
<1>本节主要参见《Mesh_v1.0.pdf》 5.3 Generic Provisioning layer
<2>PDU:协议数据单元。对于SIG Mesh配网协议,PDU即是配网协议的基本数据单元,包含三种类型:start PDU、ack PDU、连续传输PDU。
详见《Mesh_v1.0.pdf》5.3.1 Generic Provisioning PDU Types。
<3>配网承载层控制:BLE SIG Mesh配网过程是基于抽象的“link”(PB-GATT方式建立在BLE连接上;PB-ADV方式通过广播包,并非真实的link),其实就是会话的含义。配网时先由配网者(如天猫精灵/手机...)生成随机的linkID,配网者与未配网的设备之间通过link_open & link_ack消息建立配网承载层连接,配网结束通过link_close消息关闭配网承载层连接:
详见《Mesh_v1.0.pdf》5.3.1.4 Provisioning Bearer Control
<4>Airoha AB1611被天猫精灵配网时天猫精灵发送的link_open消息,关键是linkID:
本节内容参考《Mesh_v1.0.pdf》5.4 Provisioning protocol与AB161X SDK代码,思维导图部分:
如本文第3章“配网数据传输控制”所述,当配网者发送link_open消息且被配网的设备回复link_ack时,意味着配网的承载层连接建立。
此时,配网者需要向未配网的设备发出配网邀请provisioning invite,未配网的设备需要回复自身的provisioning capabilities给配网者。
AB1611接收到的天猫精灵provisioning invite与回复的provisioning capabilities:
<1>provisoning invite
provisoning invite |
||
参考文档 |
《Mesh_v1.0.pdf》5.4.1.1 |
|
AB1611 SDK代码 |
bt_mesh_evt_prov_invite_t |
|
关键数据 |
Attention Duration
|
天猫精灵设置attention duration为0(OFF),但是从AB1611 log看,启动一个provision的超时定时器60s |
<2>provisoning capabilities
provisoning capabilities |
||
参考文档 |
《Mesh_v1.0.pdf》5.4.1.2 |
|
AB1611 SDK代码 |
bt_mesh_evt_prov_capabilities_t |
|
关键数据 |
Number of Elements |
<1>当前设备元素数,AB1611返回2个 <2>BLE SIG Mesh每个设备必须有一个主元素,另外还可以有多个附加元素。每个主元素对应配网时唯一的unicast addr,附加元素在主元素的地址上子序列寻址 <3>AB1611 SDK代码返回的2个元素: 主元素,包含Light CTL Server model及其它 附加元素,包含Light CTL Temperature Server model |
Algorithms |
AB1611返回0,FIPS P-256 Elliptic Curve |
|
Public Key Type |
AB1611返回0,密钥OOB数据有效 |
|
Static OOB Type |
AB1611返回1,static OOB信息无效 |
|
Output OOB Size |
AB1611返回0,表示不支持输出OOB |
|
Output OOB Action |
AB1611返回0,Output OOB Action blink;但Output OOB Size为0,该数据无效 |
|
Input OOB Size |
AB1611返回0,表示不支持输入OOB |
|
Input OOB Action |
AB1611返回0,Iutput OOB Action push; 但Input OOB Size为0,该数据无效 |
经过这一步,作为配网者的天猫精灵获取到对AB1611设备配网的初步信息。
当作为配网者的设备获取到未配网设备的provisioning capabilities并决定对此设备进行配网,会向该设备发送provisioning start消息。
AB1611接收到的天猫精灵provisioning start消息数据:
provisoning start |
||
参考文档 |
《Mesh_v1.0.pdf》5.4.1.3 |
|
AB1611 SDK代码 |
bt_mesh_prov_start_t |
|
关键数据 |
Algorithm |
AB1611接收0 采用FIPS P-256 Elliptic Curve算法 |
Public Key |
AB1611接收0 使用No OOB的public key |
|
Authentication Method |
AB1611接收1 认证方式使用static OOB认证 |
|
Authentication Action |
AB1611接收0 注:当Authentication Method == 1 Authentication Action必须设为0 |
|
Authentication Size |
AB1611接收0 注:当Authentication Method == 1 Authentication Size 必须设为0 |
AB1611设备端接收到provisioning start消息后,知道天猫精灵对其进行配网使用的public key不包含OOB,认证使用static OOB数据。这一步决定了接下来配网者天猫精灵与被配网的AB1611设备间的密钥交换流程。
本节主要参考《Mesh_v1.0.pdf》5.4.2.3 exchange public keys
public keys用于FIPS P-256 Elliptic Curve算法加密使用,该算法可以参见《Mesh_v1.0.pdf》5.4.3 Provisioning security;
根据配网是否采用带OOB的public key以及认证的方式,provisioning public exchange的过程是不同的(具体参见《Mesh_v1.0.pdf》5.4.2.3);
如4.2所述,天猫精灵对AB1611设备配网采用的路径是:
① No OOB的public key
② static OOB方式的auth method
与之对应密钥交换时序是,天猫精灵先将自身的public key发给AB1611设备;AB1611设备再将自身的public key发给天猫精灵:
<1> 天猫精灵向AB1611发送己方public key
<2>AB1611向天猫精灵返回己方public key
配网者与被配网设备间的密钥交换都是按照provisioning PDUs的格式多包传输的,可对照《Mesh_v1.0.pdf》5.3.1 Generic Provisioning PDU types。
至此,public key exchange过程完成,天猫精灵与AB1611设备各自拿到对方的public key,将开始认证过程。
与4.3密钥交换流程一样,认证过程根据public key以及认证是否带OOB分为几种时序,具体参考《Mesh_v1.0.pdf》5.4.2.4 Authentication;
No OOB的public key 与 static OOB authentication对应的认证时序是:
简单的说,所谓认证就是配网者与被配网者基于各自的随机数发生器、OOB数据以及配网期间交互过的数据包根据约定的算法生成各自的provisioning confirm数据发给对方;然后将各自用于生成provisioning confirm数据的随机数再发给对方;最后各自校验对方provisioning confirm数据是否正确的过程。
具体的计算方法在《Mesh_v1.0.pdf》5.4.2.4 Authentication里有详细的叙述;AB1611的SDK也做的比较完善,从打印信息上可以完全看到各类变量的计算结果,两者一一对应即可:
从AB1611 SDK 源码的BT_MESH_EVT_PROV_REQUEST_OOB_AUTH_VALUE事件下,可以看出天猫精灵与AB1611配网所使用的static OOB其实就是从阿里发放的三元组获取的:mesh_three_tuples_get_authentication_value。天猫精灵应该需要联网从服务器端拿到某个UUID(如前所述,mesh beacon内附带)对应的static OOB数据。
本节的具体数据计算待有必要再研究,至少从AB1611的打印信息看,足够非官方SDK开发人员判断配网的过程,这点确实MTK还是很专业的。
本节参考《Mesh_v1.0.pdf》5.4.2.5 Distribution of provisioning data。
配网认证完毕,配网者就可向被配网设备下发配网数据;
配网数据的下发是加密的,包括两个部分:provisioning data与 provisioning data MIC,最终在AB1611设备端被解密:
provisoning data |
||
参考文档 |
《Mesh_v1.0.pdf》5.4.2.5 |
|
AB1611 SDK代码 |
bt_mesh_prov_data_t |
|
关键数据 |
Network Key |
网络密钥,具有相同网络密钥的设备才位于同一个网络 |
Key Index |
网络密钥序号 |
|
Flags |
标志位,指示是否网络密钥刷新的阶段、是否IV index正在刷新 |
|
IV Index |
IV index是32位数据,位于相同网络的设备共享相同的IV index,并在网络运作过程中通过secure network beacon更新共享 |
|
Unicast Address |
设备主元素地址,网络内通过该地址寻址设备 |
AB1611端的打印信息:
至此,AB1611设备端已接收到配网者的下发的全部网络信息,基于这些信息,该设备与配网者同在一个BLE SIG Mesh网络,可以互相访问控制。
参考《Mesh_v1.0.pdf》5.4.1.9 & 5.4.1.10有provisioning完毕或者失败的消息,失败消息携带有错误码,可以方便开发人员判断配网失败原因。不过一般情况下,应用开发工程师遇到的问题都不会在这些错误上。
配网成功的设备已成为BLE SIG Mesh网络内的节点。
然而通常实际使用情况下,根据SIG Mesh规范,为了能够使用节点的具体功能,配网成功后还需要为节点的models绑定AppKey:
“BLE SIG Mesh规范规定了两种类型的密钥:NetKey与AppKey。NetKey用于网络层消息认证,AppKey用于传输层应用程序的数据加密。NetKey与AppKey在BLE SIG Mesh网络的节点之间是存在共享的;因此还有另外一种DevKey,每个节点的DevKey可以不同,用于配置端与节点之间的加密。关于BLE SIG Mesh的密钥与加密详见《Mesh_v1.0.pdf》3.8 Mesh security”。
实际使用中,需要将AppKey依次绑定某个节点上需要交互的models。以AB1611 SDK ali_mesh_device这个工程的固件为例,节点上element与model的关系大致是(初步看了下,不一定正确):
从AB1611配网期间的log看,天猫精灵bind了绿色部分的models,也就是说天猫精灵bind成功这些models之后才可以控制AB1611灯的开关、亮度、色温。
PS:按照个人的理解,天猫部分应该还使用了不少vendor model的自定义指令,但是AB1611 SDK上并没有相关的部分。
本文的目的即是为了在实际产品开发过程中遇到配网失败的问题时进行分析,相关问题随着项目进展再进行整理总结。