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
形式になっているので、適切な形に解析する。
以上。