回顧上篇
上篇文章講述了藍芽
Mesh
的概念、iOS
要怎麼去開發藍芽Mesh
、以及iOS
在開發藍芽Mesh
中需要做哪些事情?詳細講解了藍芽Mesh
的裝置是如何進行配網的。上篇文章iOS藍芽Mesh開發總結一,本篇文章就開始繼續上篇遺留下來的問題:手機如何給Mesh
網路內的節點傳送訊息。
訊息分類
訊息從使用場景上進行分類可分為以下三類:
- 配置訊息:給已配網的節點設定配置資訊的訊息,如:
節點新增/刪除AppKey、節點裡的Model繫結/解綁AppKey、新增訂閱地址、設定釋出地址、重置節點
這類訊息。 - 通用訊息:由
SIG
定義的藍芽Mesh
通用訊息,如:通用開關狀態訊息,通用亮度訊息等
。配置訊息其實也是通用訊息,只是對應的功能不同,所以這裡進行了區分。 - 自定義訊息:雖然
通用訊息
在第三方庫中已經幫我們實現了,用起來很方便。但是由於功能太過簡單,基本上滿足不了我們的開發需求,這時就只能使用自定義訊息
了。
以上三種型別的訊息的前兩種在nrf
第三方庫中基本上都已經實現,我們只需使用其中的方法去實現需求即可,對於第三方庫的用法這裡不再進行過多的講解,想要用好還是得自己仔細研究研究。
自定義訊息
這裡主要講解自定義訊息相關的內容,但還是要簡單說下通用訊息,經過對比可以瞭解這兩種訊息的區別。
通用訊息:由SIG
定義的功能,訊息的opcode
最多佔2個位元組
(比如:模型繫結AppKey
的opcode
是0X803D
,模型設定釋出地址
的opcode
是0X03
),這裡說明下opcode
是功能的唯一標識
,一個opcode
對應一個功能。
自定義訊息:自定義訊息的opcode
和通用訊息的opcode
不同,自定義訊息的opcode
佔3個位元組
,其中後面兩個位元組
是廠商模型的廠商在SIG註冊的id
,第一個位元組是0xC0
和我們自定義的opcode
與運算計算出的,因此能給我們使用的opcode
只有2的6次方 = 64
個。下面是廠商自定義訊息有關opcode
的程式碼:
public extension VendorMessage {
/// The Op Code as defined by the company.
///
/// There are 64 3-octet opcodes available per company identifier.
/// Op Code is encoded in the 6 least significant
/// bits of the first octet of the message Op Code.
var opCode: UInt8 {
// 3 和 F連在一起釋出時會提示有敏感詞,無法釋出
// 所以16進位制就被我改成了二進位制--> 0b00111111
return UInt8(opCode >> 16) & 0b00111111
}
/// The Company Identifiers are 16-bit values defined by the
/// Bluetooth SIG and are coded into the second and third octets
/// of the 3-octet opcodes
var companyIdentifier: UInt16 {
return UInt16(opCode & 0xFFFF).bigEndian
}
}
複製程式碼
那個nrf第三方庫現在的第二版
提供了自定義訊息
的類定義,如上。但是目前這個SDK中並沒有提供專門用來傳送接收自定義訊息的介面
。也就是說如果要實現自定義訊息的收發功能
,只能自己在這個庫的基礎上使用庫中定義的格式自己實現。可以參考這個庫的demo
中的一個自定義訊息收發功能。
上面已經描述了iOS開發藍芽Mesh需要做哪些東西,需要怎麼做?
----------------------------------分割線-------------------------------------
下面的內容是筆者在開發藍芽Mesh時的一些總結。
藍芽Mesh工作流程
配網流程
1、掃描帶有
1827
服務的藍芽裝置。
2、連線裝置,發現服務,特徵,訂閱讀特徵。
3、呼叫第三方庫中的入網邀請方法邀請裝置入網,等待裝置返回成分資料。 4、呼叫第三方庫中的裝置配網方法完成配網並給節點及元素分配唯一地址。 5、給節點新增AppKey
。
6、給模型繫結指定的AppKey
。
7、執行我們公司自己商議的裝置認證協議
,全部完成後才算真正配網成功。
連線代理節點的流程
1、掃描帶有
1828
服務的藍芽裝置(裝置一旦配網完成後裡面的服務就會發生變化,由1827變成1828,相應的服務下的特徵UUID也會有所變化,但還是一個讀一個寫,這是由藍芽Mesh協議定義的)
。
2、掃描到之後就驗證這個節點是否屬於當前的Mesh
網路,可從代理節點的廣播的資料中進行驗證。
3、驗證通過後連線裝置,發現服務,特徵,訂閱讀特徵。
4、開始定時傳送心跳包,同步節點和手機的時間。
Mesh網路的資料持久化
建立了一個Mesh並給Mesh網路中配幾個節點,那麼這些資訊肯定不能儲存到裝置上,畢竟裝置能儲存的資料並不多,因此只能由我們手機端進行持久化儲存。
在藍芽Mesh的那個第三方庫中有提供資料快取相關的功能,但不滿足我們需要儲存多個網路的需求。因此,只能改第三方庫程式碼了,哈哈哈。
1、最開始是修改了資料快取類,將
Mesh
網路的id
作為儲存路徑,將不同的Mesh
網路的資料儲存在不同的路徑下。
2、後來需要做Mesh
網路的匯入匯出功能,可以和使用者進行繫結,使用者在另一個手機登入賬號,只需要呼叫以下獲取網路列表介面即可獲取Mesh
網路的資料並儲存在這個手機內。
3、因為要保證iOS
和安卓
的Mesh
資訊共享,因此就商議了一套協議用來儲存Mesh
網路的關鍵資料,以此實現了Mesh網路與使用者繫結
,並能夠跨平臺
的需求。
總結起來資料快取這一塊實現起來還是很複雜的,因為要時刻保證Mesh網路的資料同步。
好了,本次iOS藍芽Mesh開發總結到此也就結束了,主要目的是對開發藍芽Mesh中遇到的比較重要的地方的實現思路進行記錄,方便自己以後忘記的時候查詢。同樣也希望可以給正在開發藍芽Mesh的iOS同行提供一些經驗和資料。