Telink BLE SIG Mesh GATT 配網功能

目錄

1:準備工作

1.1:抓包工具

1.2:telink BLE SIG Mesh SDK 

1.3:BLE SIG Mesh Spec

1.4:調試設備

2:配網過程概述

3:設備發現

3.1:unprovisioned beacon

3.2:scan for unprovisioned device beacons

4:設備連接與服務發現

4.1:app發起BLE連接與獲取服務

4.2:設備端BLE連接的處理

4.3:異常情況備忘

5:配網邀請與能力值

5.1:配網邀請provisioning invite

5.2:配網能力值provisioning capabilities

6:配網

7:綁定app key


簡單理一下泰凌微電子BLE SigMesh SDK V2.8.2通過手機對設備節點進行配網的過程,爲今後的開發工作做一個參考的文檔。因爲SDK並不是開源的,因此有些部分可能出現謬誤,歡迎指正;未完成部分等出現問題再看吧,目前實在是太懶得去看了。

配網(provision)功能是將一個未分配的節點加入到Mesh網絡使之成爲某個Mesh網絡節點的功能。根據SIG Mesh spec的定義,配網過程會將Mesh網絡的Network Key,IV Index以及分配給節點的unicast addr傳輸給節點。

1:準備工作

1.1抓包工具

採用韋東山安卓視頻藍牙教程部分推薦的wireshark + nRF sniffer

1.2:telink BLE SIG Mesh SDK 

泰凌微電子BLE SIG Mesh SDK下載地址:http://www.telink-semi.cn/viewtopic.php?f=7&t=100

包含固件SDK與android app sdk,其中有兩個相對重要的參考文檔:

<1>《AN_17090701-C1_Usage and Development Guide for Android APP TelinkSigMesh》

<2>《AN_17120401-C2_Telink SIG Mesh SDK Developer Handbook.pdf》

1.3:BLE SIG Mesh Spec

BLE SIG Mesh協議文檔可以到官方網站下載,這裏主要涉及第5章provisioning下的PB-GATT相關內容

1.4:調試設備

telink 8269 usb dongle + vivo

telink 8269 usb dongle MAC:AB:CD:04:0A:93:89

tlsr8269 usb dongle燒錄BLE SIG Mesh SDK V2.8.2 release的固件

vivo手機通過android app對未配網的usb dongle進行掃描、連接、配網的操作

2:配網過程概述

本節主要參考BLE SIG Mesh Spec V1.0以及telink固件開發手冊以下部分:

整理telink SIG Mesh SDK GATT配網模式流程如下:

3:設備發現

app爲設備進行配網,首先要發現周圍的未配網設備,設備發現主要分爲以下三步:

<1>未配網的設備開機後會一直向外發送unprovisioned beacon(可連接類型)廣播包;

<2>用戶打開APP掃描周圍的未配網設備;

<3>app掃描到設備的unprovisioned beacon,並向該設備發出SCAN_REQ;設備接收到SCAN_REQ後回覆SCAN_RSP;

SCAN_RSP內附帶有必要的自定義信息,可幫助app識別設備。

3.1:unprovisioned beacon

3.1.1:設備端beacon/廣播初始化

設備端上電後在user_init函數內有對設備的廣播進行初始化,主要步驟:

bls_ll_setAdvParam:設置廣播間隔10ms,非定向廣播類型,37,38,39三個信道

blc_ll_setAdvCustomedChannel:自定義廣播使用的信道。SIG Mesh要求同時使用37,38,39三個廣播信道,調試時爲了抓包方便可以修改。

bls_ll_setAdvEnable:使能廣播

rf_set_power_level_index:RF功率設置

3.1.2:設備端beacon數據解析

未配網的設備上電後開始不停向外發送unprovisioned beacon;

unprovisioned beacon是可連接類型廣播包(ADV_IND),且已經被BLE SIG Mesh定義完畢全部字段,對應固件SDK代碼內的結構體類型PB_GATT_ADV_DAT:

未配網的設備通過unprovision beacon向外廣播mesh provisioning GATT service的數據service_data,service_data內包含設備的MAC地址及其它數據。Provisioner(APP)可以通過這些數據唯一地識別到發送該beacon的設備;

unprovision beacon必要時會帶有oob_info;oob_info用於提示provisoner在進行下一步配網動作之前需要收集oob(附帶數據);uuid 0x1827爲16位mesh provisioning GATT service UUID

3.2:scan for unprovisioned device beacons

3.2.1:app掃描unprovisioned beacon

Telink BLE SIG Mesh android APP 對設備是掃描發現一個配網一個的,其掃描與配網相關的代碼實現均在DeviceProvisionActivity方法,本節只關注掃描設備相關:

<1>DeviceProvisionActivity.onCreate監聽ScanEvent.DEVICE_FOUND與SCAN_TIMEOUT事件;

<2>DeviceProvisionActivity.onCreate調用startScan方法啓動設備掃描;

<3>DeviceProvisionActivity.startScan首先生成默認掃描配置參數ScanParameters ,然後將已經配網的設備排除,最後調用MeshService.getInstance().startScan(parameters)啓動Mesh服務掃描藍牙設備;

<4>DeviceProvisionActivity.perfomed內對ScanEvent.DEVICE_FOUND事件進行監聽,將掃描到的設備數據AdvertisingDevice device傳給onDeviceFound處理(進行下一步配網)

<5>至此可知,APP掃描unprovisioned beacon獲得的數據被緩存在了AdvertisingDevice device:

上圖藍色部分與3.1.2設備端unprovisioned beacon數據一致。

3.2.2:app獲取設備信息

AdvertisingDevice內除了unprovisoned beacon還有一包數據,是app接收到設備端的unprovisoned beacon包後發給設備一個SCAN_REQ再由設備在SCAN_RSP返回的。設備端SCAN_RSP的內容在mesh_scan_rsp_t結構體內定義,抓包數據如下:

用戶可以(或者說必須)在這個SCAN_RSP附帶自定義的數據回覆給app,例如用以區分識別廠家設備的信息(不是自家的設備不進行連接)。至此,app已發現並獲取了周圍某個未配網設備的必要信息,下一步將建立與設備的BLE連接。

 

4:設備連接與服務發現

app通過unprovisioned beacon掃描到未配網設備後,在正式配網之前,app需與設備建立BLE連接、掃描設備服務(屬性表)、向設備寫入CCC數據。

4.1:app發起BLE連接與獲取服務

4.1.1:app發起BLE連接

app通過unprovisioned beacon獲取到AdvertisingDevice 數據後會在onDeviceFound內繼續調用直到MeshService.getInstance().startProvision(...);

startProvision調用this.device.connectGatt(...)向設備發起BLE連接請求。配網若出現失敗,手機app的CONNECT_REQ沒有收到回覆是常見原因,因此CONNECT_REQ幾個參數標出備查:

(參考:https://www.cnblogs.com/iini/p/8972635.html)

4.1.2:app獲取設備服務

connectGatt接口的狀態回調是onConnectionStateChange,app根據回調狀態判斷BLE連接建立是否成功;成功連接後app再通過gatt.discoverServices()獲取設備支持的attribute table。抓包工具顯示,master(手機app)遞增attributes handle查詢slave(BLE Mesh設備)支持的attribute table:

(本節參考:https://www.cnblogs.com/hzl6255/p/4141505.html)

 

discoverServices()的結果回調是onServicesDiscovered,onServicesDiscovered內app會向設備端寫入CCC數據,CCC的用途是打開設備端的特徵值nodify功能;見writeCCCForPv。

app使能設備端的數據上報後還需要調用enableNotifications使能app對設備PB_OUT_CHARACTERISTIC_UUID/PROXY_OUT_CHARACTERISTIC_UUID/CHARACTERISTIC_UUID_ONLINE_STATUS的nodify接收;當有數據上報時,onCharacteristicChanged接口被回調:

PB_OUT_CHARACTERISTIC_UUID:配網功能GATT Service數據輸出特徵值

PROXY_OUT_CHARACTERISTIC_UUID:代理功能GATT Service數據輸出特徵值CHARACTERISTIC_UUID_ONLINE_STATUS:Mesh網絡狀態上報功能GATT Service

CHARACTERISTIC_UUID_ONLINE_STATUS相關功能是telink爲了實際產品開發狀態同步問題加的,需要相關版本與宏打開;配網功能與代理功能的GATT services則是必須的,只是根據設備端是否已配網加載不同的屬性表,詳見4.2.2。

app會請求更新BLE傳輸的最大傳輸單元MTU(一個協議數據單元中能夠傳輸的最大數據量),MTU默認最大23個字節,後續配網期間傳輸的數據遠不止此。MTU實際變更的數值會在onMtuChanged回調內返回:

4.2設備端BLE連接的處理

4.2.1:設備端BLE連接狀態回調

<1>設備端代碼app.c app_event_handler下HCI_SUB_EVT_LE_CONNECTION_COMPLETE是app與設備端建立BLE連接時的處理,結構體event_connection_complete_t對應4.1.1 app端發送的連接請求指令CONNECT_REQ參數;

<2>bls_app_registerEventCallback接口用於爲各類BLE連接事件註冊回調函數,SDK代碼暴露出來的回調是mesh_ble_connect_cb/mesh_ble_disconnect_cb/mesh_conn_param_update_req;

<3>需要說明的是在mesh_ble_connect_cb與mesh_conn_param_update_req內有一些處理:手機app與設備端的BLE連接建立後會設置need_conn_update_flag與att_service_discover_tick,兩者共同作用在BLE連接建立的500ms後由設備端發起告知手機更新BLE連接參數bls_l2cap_requestConnParamUpdate(16, 32, 0, 200)。根據telink工程師的解釋:手機處於掃描設備階段與建立BLE連接後進行配網/通訊時宜使用的連接參數不同。建立BLE連接500ms後再更新此參數的原因是需要留給手機app讀取全部attribute table的時間。這就有可能涉及到時序問題:更新參數的請求與配網流程中的指令發生碰撞。不過也可改爲配網完畢再進行參數更新,具體還要視SDK版本迭代情況。

4.2.2:設備端BLE attribute table

如4.1.2節所述app有獲取設備端BLE attribute table(實際上是發現GATT services)的操作,設備端相關代碼在app_attr.c下。user_init時會在my_att_init加載bls_att_setAttributeTable,用戶在此添加自定義的GATT service。設備端SDK默認的GATT服務示意如下:

手機app與設備建立BLE連接時,手機作爲BLE master設備端作爲BLE slave;發現設備端GATT service時,則是手機app作爲GATT client,設備端作爲GATT service。GATT service與client之間通過ATT PDUs進行通訊。GATT client訪問GATT service的characterists值通過READ/WRITE操作;GATT service可以把自己的characterists值通過nodify或者indicate的方式告知client;indicate方式相對於nodify有ack回覆,所以較爲可靠。

GATT client(對應手機app)使能/禁用GATT service (對應設備端)nodify/indicate功能,是通過對characteristic descriptors的Client Characterist Configuration(CCC,對應UUID 0x2902,上圖淺藍色部分)進行寫操作實現的。從設備端代碼pb_gatt_Write與proxy_gatt_Write看,CCC數據若寫入失敗,手機app向設備端寫入的配網數據/控制指令均不會生效。

4.3異常情況備忘

實際開發過程中,對於telink SIG Mesh的GATT配網方式,發現出現失敗情況在主要發生本節所述的設備連接與服務發現階段,這裏稍微羅列下一些出現的異常情況:

<1>如4.1.1所述,手機發送給設備端的CONNECT_REQ沒有響應。對應app端一般是出現BLE disconnect的回調發生。造成的原因各種各樣,處理主要還是app重連。

<2>手機app對一個設備配網完畢後再配下一個,這個時序需要處理好,否則可能出現上一個設備配網的確認信息才處理,當前已連接的又是新的一個設備,誤判新的設備配網情況。

<3>如4.1.2所述,手機app需要獲取設備的attribute table。比較弔詭的是,android與iOS在底層獲取atrribute table的具體順序是不同的,因此對於attribute table何時獲取完畢的判斷條件是不同。當然這個情況是app可以處理的。具體抓包TBD。

<4>從獲取attribute table到使能設備端GATT service的nodify(寫入CCC數據)再到向設備端發送provision invite,三者之間需要滿足一定的時序要求。具體原因與時序要求請請教telink原廠。

以上僅供參考備忘,應該隨着SDK迭代都能fix這些情況。

5:配網邀請與能力值

app向設備端寫入CCC後,再滿足一定的時間間隔後,會向設備端發起provisioning invite,隨即設備端回覆provisioning capabilities數據,這些在SIG Mesh Spec有詳細定義。

5.1配網邀請provisioning invite

provisioning invite根據BLE SIG Mesh Spec 5.4.1.1

app通過startProvisionInvite向設備端發送provisioning invite,實際上就是3個字節的數據:{0x03 0x00 0x00}

5.2配網能力值provisioning capabilities

設備端對於provisioning capabilities的定義是結構體:pro_trans_capa

對應BLE SIG Mesh Spec 5.4.1.2。綠框部分依次是寫入CCC,app發起provisioning invite以及設備返回provisioning capabilities的抓包情況:

 

6:配網

TBD

7:綁定app key

TBD

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章