一般來(lái)說(shuō)和藍(lán)牙外設(shè)硬件交互都會(huì)有簡(jiǎn)單的協(xié)議,一是規(guī)范通信券时,二是對(duì)數(shù)據(jù)加密。
我公司的協(xié)議都是由算法定義的伏伯,算法會(huì)給到一份詳細(xì)的協(xié)議文檔橘洞,上面會(huì)詳細(xì)的寫(xiě)清楚數(shù)據(jù)解析及交互。
協(xié)議結(jié)構(gòu).png
例如:讀取電量功能
讀取電量.png
因?yàn)樯婕暗焦井a(chǎn)品说搅,所以打碼炸枣。
按上面的協(xié)議結(jié)構(gòu)來(lái):
假如幀頭是0x01,功能碼是0x02,校驗(yàn)和是0xxx(具體如何計(jì)算适肠,公司內(nèi)部確定)
APP 發(fā)送給 藍(lán)牙外設(shè)的數(shù)據(jù)(讀取電量指令)應(yīng)為:
0x01 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xxx(校驗(yàn)碼)
藍(lán)牙外設(shè)收到讀取電量指令后霍衫,返回電量數(shù)據(jù)應(yīng)為:
0x01 0x02 0x5A 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xxx(校驗(yàn)碼)
注意,第三個(gè)字節(jié)為電量值侯养,解析代碼:
const u_int8_t *bytes = [data bytes];
NSInteger powerValue = bytes[2];
//得到的 powerValue 即為電量值敦跌,接下來(lái)寫(xiě)個(gè)if判斷就好了
if (powerValue == 120) {
//充電中
}else{
//顯示電量即可
}
我自己做的項(xiàng)目中,CBCentralManager逛揩、CBPeripheral都是有單獨(dú)寫(xiě)了一個(gè)類
單獨(dú)的類.png
WSBLECenterManager:搜索外設(shè)柠傍、連接設(shè)備、自動(dòng)重連等等邏輯辩稽,內(nèi)含:
/**
藍(lán)牙狀態(tài)更新
@param central central
*/
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
}
/**
發(fā)現(xiàn)設(shè)備
@param central central
@param peripheral 外設(shè)
@param advertisementData 廣播
@param RSSI 信號(hào)值
*/
- (void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI{
//找到自己需要的設(shè)備后惧笛,可在此處連接,調(diào)用以下方法
[_myCentralManager connectPeripheral:peripheral options:nil];
}
/**
連接成功
@param central central
@param peripheral 外設(shè)
*/
- (void)centralManager:(CBCentralManager *)central
didConnectPeripheral:(CBPeripheral *)peripheral{
}
/**
連接失敗
@param central central
@param peripheral 外設(shè)
@param error error
*/
- (void)centralManager:(CBCentralManager *)central
didFailToConnectPeripheral:(CBPeripheral *)peripheral
error:(NSError *)error{
}
/**
斷開(kāi)連接
@param central central
@param peripheral 外設(shè)
@param error error
*/
- (void)centralManager:(CBCentralManager *)central
didDisconnectPeripheral:(CBPeripheral *)peripheral
error:(NSError *)error{
}
WSBLESensor:發(fā)送指令逞泄、收取數(shù)據(jù)患整、解析數(shù)據(jù)等等功能
內(nèi)含:
/**
發(fā)現(xiàn)服務(wù)
@param peripheral peripheral
@param error error
*/
-(void)peripheral:(CBPeripheral *)peripheral
didDiscoverServices:(NSError *)error{
}
/**
發(fā)現(xiàn)特征
@param peripheral peripheral
@param service service
@param error error
*/
- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverCharacteristicsForService:(CBService *)service
error:(NSError *)error {
}
/**
收到數(shù)據(jù)
@param peripheral peripheral
@param characteristic characteristic
@param error error
*/
-(void)peripheral:(CBPeripheral *)peripheral
didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error{
}
//發(fā)送數(shù)據(jù)到外設(shè),調(diào)用
[self.peripheral writeValue:data
forCharacteristic:self.writeCharacteristic
type:CBCharacteristicWriteWithResponse];
上面發(fā)送讀取電量指令時(shí)炭懊,如下:
Byte bytes[20];
bytes[0] = (Byte)(1);//幀頭
bytes[1] = (Byte)(2);//讀取電量的功能碼
for (NSInteger i = 2; i < 19; i++) {
bytes[i] = (Byte)(0);
}
bytes[19] = (Byte)(/*校驗(yàn)和*/);
NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];
[self.peripheral writeValue:data
forCharacteristic:self.writeCharacteristic
type:CBCharacteristicWriteWithResponse];
我的設(shè)計(jì)藍(lán)牙設(shè)計(jì)思路:
WSBLECenterManager:
包含CBCentralManager單例對(duì)象: _myCentralManager
設(shè)置代理并级、實(shí)現(xiàn)CBCentralManagerDelegate協(xié)議及其方法拂檩。這樣搜索到的設(shè)備都能在WSBLECenterManager獲取到侮腹,同時(shí)連接成功、連接失敗稻励、斷開(kāi)連接等等也都可以通過(guò) CBCentralManagerDelegate 協(xié)議中的代理方法知曉
如果是需要連接設(shè)備父阻,我的做法是在 WSBLECenterManager 中定義了一個(gè)可變數(shù)組,用于存儲(chǔ)連接上的設(shè)備望抽。
查找到的設(shè)備加矛、連接設(shè)備是否成功、斷開(kāi)設(shè)備的提示等都是通過(guò)block或者代理回調(diào)到viewController中
WSBLESensor:
這是外設(shè)模型煤篙,存儲(chǔ)了廣播數(shù)據(jù)斟览,信號(hào)值等等
CBPeripheralDelegate 協(xié)議中的代理方法都在這個(gè)類中實(shí)現(xiàn)。查找服務(wù)辑奈、查找特征苛茂、收取數(shù)據(jù)、解析數(shù)據(jù)鸠窗、發(fā)送數(shù)據(jù)都在這個(gè)類中實(shí)現(xiàn)
數(shù)據(jù)處理結(jié)果妓羊、數(shù)據(jù)發(fā)送結(jié)果等都是通過(guò)block或者代理回調(diào)到viewController中
以上,即可將CBCentralManager稍计、CBPeripheral拆分開(kāi)來(lái)
其他的就是一些枚舉躁绸、block等定義了,可以單獨(dú)寫(xiě)一個(gè).h文件