蘋果手機可以作為藍牙外設端,被藍牙中央端來掃描連接交互數據,實現模擬藍牙外設硬件。通過閱讀CoreBluetooth庫,可以找到壹個CBPeripheralManager的類,該類主要的作用就是允許妳來管理發布services,把這些services廣告給其他的設備。如果想詳細了解該類的屬性和方法,建議去看看CoreBluetooth/CBPeripheralManager.h。
下面來模擬壹個簡單的藍牙外設端。
上面中,serviceUUID為給外設配置的服務的UUID,可以有多個,characteristicUUID為給service添加的特征的UUID,也可以有多個,可自定義可讀可寫等等屬性.characteristicValue為characteristic的值,localName和serviceUUIDs分別為鍵CBAdvertisementDataLocalNameKey和CBAdvertisementDataServiceUUIDsKey對應的value。由於作為外設端時發送廣播包,廣播包中提供包含著兩個鍵值對,如果有另外的鍵值對想要發送,例如CBAdvertisementDataServiceDataKey,會出現錯誤。
首先要導入藍牙庫
#import <CoreBluetooth/CoreBluetooth.h>
遵守協議
創建peripheralManager對象
創建了peripheralManager對象後會自動調用回調方法didUpdateState
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
if (peripheral.state != CBPeripheralManagerStatePowerOn) {
return;
}
}
給外設配置服務和特征
- (void)configServiceAndCharacteristicForPeripheral {
CBMutableCharacteristic *writeReadCharacteristic = [[CBMutableCharacteristic alloc] initWithType:characteristicUUID properties:CBCharacteristicPropertyWrite | CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadEncryptionRequired | CBAttributePermissionsWriteEncryptionRequired];
CBMutableService *service = [[CBMutableService alloc] initWithType:serviceUUID primary:YES];
[service setCharacteristics:@[writeReadCharacteristic]];
[self.peripheralManager addService:service];
}
調用上面的方法時,會監聽didAddService:
- (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error {
}
開始廣播
調用上 面方法時,會監聽DidStartAdvertising:
- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error {
}
當中央端連接上了此設備並訂閱了特征時會回調 didSubscribeToCharacteristic:
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic {
[self.peripheralManager updateValue:characteristicValue forCharacteristic:characteristic onSubscribedCentrals:nil];
}
當中央端取消訂閱時會調用didUnsubscribeFromCharacteristic:
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic {
}
當接收到中央端讀的請求時會調用didReceiveReadRequest:
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request {
if (request.characteristic.properties & CBCharacteristicPropertyRead) {
NSData *data = request.characteristic.value;
[request setValue:data];
[self.peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
} else {
[self.peripheralManager respondToRequest:request withResult:CBATTErrorReadNotPermitted];
}
}
當接收到中央端寫的請求時會調用didReceiveWriteRequest:
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray<CBATTRequest *> *)requests {
CBATTRequest *request = requests[0];
if (request.characteristic.properties & CBCharacteristicPropertyWrite) {
CBMutableCharacteristic *c = (CBMutableCharacteristic *)request.characteristic;
c.value = request.value;
[self.peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
} else {
[self.peripheralManager respondToRequest:request withResult:CBATTErrorWriteNotPermitted];
}
}
手機app可以作為壹個藍牙外設端來模擬外設硬件,但廣播包裏的數據只能包含localName和serviceUUID,相對於外設硬件來說還是有壹些不足之處。