Introduction
iOS同士でBLE通信をする際のサンプルコードがあったが、その発火順番とその意味がよくわからなかったので、自分の理解を高めるためにもメモとして記すことにした。
用語の定義
Central
- 接続する側
- Advertiseを受けたあとに接続をし、あとはよしなにしてくれる
Peripheral
- 接続される側。
- Advertiseをする側。
ServiceUUID
- 簡単にいうと、サービスの識別子のUUID
- 複数のCharacteristicsUUDを持つことができる
CharacteristicUUID
- Slack(ServiceUUID)に対するチャンネル(CharacteristicUUID)みたいなもの
- 具体的な通信内容を含む。
具体的な手順
設定
- Peripheralサイド
-
CBPeripheralManagerを継承 -
peripheralManagerを初期化 -
peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager)が発火するので、peripheral.stateが.poweredOnの時にperipheralManagerにserviceUUID
とcharacteristicUUIDをセットする。
-
- Centralサイド
-
CBCentralManagerとCBPeripheralManagerを継承 -
centralManagerを初期化 -
centralManagerDidUpdateState(_ central: CBCentralManager)が発火するので、central.stateが.poweredOnの時にscanForPeripherals(withServices serviceUUIDs: [CBUUID]?, options: [String : Any]? = nil)を使い、advertiseを受信する。
-
発火順番
Peripheral アドバタイズの開始
- 設定が終わると
peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?)が発火する。 - エラーがない場合、
PeripheralManager.startAdvertising(_ advertisementData: [String : Any]?)を呼び周囲にアドバタイズを開始する
Central 対象ServiceUUIDがあるか調べる
- advertiserを受けると、
centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber)
が発火する。 - その後、
CBPeripheral.discoverServices(_ serviceUUIDs: [CBUUID]?)を呼び、Central側が探しているサービスがあるのかどうかを調べる
Central 対象CharacteristicUUIDがあるか調べる
- 対象
ServiceUUIDがアドバタイズされていた場合、CBPeripheralDelegate.peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?)が発火する。 -
service内に狙っているcharacteristicUUIDがあるのかを調べるために、CBPeripheral.discoverCharacteristics(_ characteristicUUIDs: [CBUUID]?, for service: CBService)を呼ぶ。
Central Characteristicからデータを読み取るリクエストを飛ばす
- 対象characteristicがあった場合
peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?)が発火する。 -
CBPeripheral.readValue(for characteristic: CBCharacteristic)を用いてデータの読み取りをリクエストする。
Peripheral レスポンスするデータを作成し、Centralに渡す
- リクエストを受けると
peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)requestが発火する。 -
request.valueのデータを変えて、CBPeripheralManager.respond(to request: CBATTRequest, withResult result: CBATTError.Code)でデータを送り返す
Central データを読み取る
- データが送られてくると、
peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?)が発火する。 -
characteristic.valueがData形式になっているので、適切な形に解析する。
以上。