bluetooth --- 低レベルBluetooth¶
このモジュールは、オンボードのBluetoothコントローラへのインターフェイスを提供します。Bluetooth Low Energy (BLE) のCentral、Peripheral、Broadcaster、Observerの各ロール、さらにGATTサーバーおよびクライアント、L2CAPのコネクション指向チャネルをサポートします。1つのデバイスが複数のロールで同時に動作することもできます。ペアリングおよびボンディングもサポートされています。
このAPIは低レベルのBluetoothプロトコルに対応することを意図しており、特定のデバイスタイプなど、より高レベルの抽象化のための構成要素を提供します。
Tip
ほとんどのアプリケーションでは、このモジュールをasyncioベースでラップした、より高レベルの aioble ライブラリの利用をおすすめします。aioble --- 非同期 BLE を参照してください。
class BLE¶
- class bluetooth.BLE¶
シングルトンのBLEオブジェクトを返します。
設定
- active(active: bool | None = None, /) bool¶
オプションでBLE無線のアクティブ状態を変更し、現在の状態を返します。
このクラスの他のメソッドを使用する前に、無線をアクティブにしておく必要があります。
- config(param: str, /) Any¶
- config(*, **kwargs: Any) None
BLEインターフェイスの設定値を取得または設定します。値を取得するには、パラメータ名を文字列として引用符で囲み、一度に1つのパラメータのみを問い合わせます。値を設定するにはキーワード構文を使用し、一度に1つ以上のパラメータを設定できます。
現在サポートされている値は次のとおりです。
'mac': 現在のアドレスモードに応じた、使用中の現在のアドレス。(addr_type, addr)のタプルを返します。アドレスタイプの詳細については
gap_scanを参照してください。これはインターフェイスが現在アクティブな場合にのみ問い合わせできます。
'addr_mode': アドレスモードを設定します。値は次のとおりです。値
名前
動作
0x00PUBLIC
コントローラのパブリックアドレスを使用します。
0x01RANDOM
生成された静的アドレスを使用します。
0x02RPA
解決可能なプライベートアドレスを使用します。
0x03NRPA
解決不可能なプライベートアドレスを使用します。
デフォルトでは、インターフェイスは利用可能であればPUBLICアドレスを使用し、そうでなければRANDOMアドレスを使用します。
'gap_name': Generic Accessサービス(UUID0x1800)のDevice Name characteristic(UUID0x2a00)で使用されるGAPデバイス名を取得または設定します。これはいつでも設定でき、複数回変更できます。'rxbuf': 受信イベントを格納するために使用される内部バッファのサイズ(バイト単位)を取得または設定します。このバッファはBLEドライバ全体でグローバルであり、すべてのcharacteristicを含む、すべてのイベントの受信データを扱います。これを増やすことで、バースト的に受信するデータ(スキャン結果など)のより適切な処理や、より大きなcharacteristic値の受信が可能になります。'mtu': ATT MTU交換時に使用されるMTUを取得または設定します。結果として得られるMTUは、この値とリモートデバイスのMTUのうち小さい方になります。ATT MTU交換は(リモートデバイスが開始しない限り)自動的には行われず、gattc_exchange_mtuで手動で開始する必要があります。特定の接続のMTUを知るには_IRQ_MTU_EXCHANGEDイベントを使用してください。'bond': ペアリング時にボンディングを有効にするかどうかを設定します。有効にすると、ペアリング要求に「bond」フラグが設定され、両方のデバイスにキーが保存されます。'mitm': ペアリングにMITM保護が必要かどうかを設定します。'io': このデバイスのI/O能力を設定します。利用可能なオプションは次のとおりです。
定数
値
能力
_IO_CAPABILITY_DISPLAY_ONLY0
表示のみ
_IO_CAPABILITY_DISPLAY_YESNO1
はい/いいえ入力付き表示
_IO_CAPABILITY_KEYBOARD_ONLY2
キーボードのみ
_IO_CAPABILITY_NO_INPUT_OUTPUT3
入力も出力もなし
_IO_CAPABILITY_KEYBOARD_DISPLAY4
キーボードと表示
'le_secure': 「LE Secure」ペアリングが必要かどうかを設定します。デフォルトはfalseです(つまり「Legacy Pairing」を許可します)。
イベント処理
- irq(handler: Callable[[int, Tuple], Any | None], /) None¶
BLEスタックからのイベントに対するコールバックを登録します。handler は2つの引数
event(以下のコードのいずれか)とdata(イベント固有の値のタプル)を受け取ります。注意: 不要なアロケーションを防ぐための最適化として、タプル内の
addr、adv_data、char_data、notify_data、uuidの各エントリは、bluetoothの内部リングバッファを指す読み取り専用のmemoryviewインスタンスであり、IRQハンドラ関数の呼び出し中のみ有効です。プログラムがIRQハンドラから戻った後にこれらの値の1つにアクセスするために保存する必要がある場合(例えばクラスインスタンスやグローバル変数に保存する場合)は、次のようにbytes()またはbluetooth.UUID()を使ってデータのコピーを取る必要があります:connected_addr = bytes(addr) # equivalently: adv_data, char_data, or notify_data matched_uuid = bluetooth.UUID(uuid)
例えば、スキャン結果のIRQハンドラは、それが正しいデバイスかどうかを判断するために
adv_dataを調べ、その場合にのみアドレスデータをコピーしてプログラムの別の場所で使用する、といったことができます。また、IRQハンドラ内からデータを表示するにはprint(bytes(addr))が必要になります。ハンドラは通常、イベントコードによってディスパッチし、イベント固有のペイロードタプルをアンパックします:
def bt_irq(event, data): if event == _IRQ_CENTRAL_CONNECT: conn_handle, addr_type, addr = data ... elif event == _IRQ_SCAN_RESULT: addr_type, addr, adv_type, rssi, adv_data = data ...
すべてのイベントコード、それが配信するペイロード、および簡単な説明を以下に示します。
statusフィールドが言及されているイベントについて、statusは成功時に0、失敗時には実装固有の非ゼロ値になります。定数
値
イベント
ペイロードタプル
_IRQ_CENTRAL_CONNECT1
centralがこのperipheralに接続しました。
(conn_handle, addr_type, addr)_IRQ_CENTRAL_DISCONNECT2
centralがこのperipheralから切断しました。
(conn_handle, addr_type, addr)_IRQ_GATTS_WRITE3
接続中のクライアントがローカルのcharacteristicまたはdescriptorに書き込みました。新しい値を取得するには
gatts_readを使用してください。(conn_handle, attr_handle)_IRQ_GATTS_READ_REQUEST4
接続中のクライアントが読み取りを発行しました。読み取りを拒否するには下表の非ゼロのエラーコードを返し、受け入れるには
0/Noneを返します。(conn_handle, attr_handle)_IRQ_SCAN_RESULT5
アクティブスキャン中に1つのアドバタイズパケットを受信しました。
(addr_type, addr, adv_type, rssi, adv_data)_IRQ_SCAN_DONE6
設定された継続時間が経過したか、
gap_scan(None)が呼び出されたため、現在のスキャンが終了しました。()_IRQ_PERIPHERAL_CONNECT7
以前に発行された
gap_connectが成功しました。(conn_handle, addr_type, addr)_IRQ_PERIPHERAL_DISCONNECT8
接続中のperipheralが切断しました。
(conn_handle, addr_type, addr)_IRQ_GATTC_SERVICE_RESULT9
gattc_discover_servicesによって1つのサービスが見つかりました。(conn_handle, start_handle, end_handle, uuid)_IRQ_GATTC_SERVICE_DONE10
サービス探索が完了しました。
(conn_handle, status)_IRQ_GATTC_CHARACTERISTIC_RESULT11
gattc_discover_characteristicsによって1つのcharacteristicが見つかりました。(conn_handle, end_handle, value_handle, properties, uuid)_IRQ_GATTC_CHARACTERISTIC_DONE12
characteristic探索が完了しました。
(conn_handle, status)_IRQ_GATTC_DESCRIPTOR_RESULT13
gattc_discover_descriptorsによって1つのdescriptorが見つかりました。(conn_handle, dsc_handle, uuid)_IRQ_GATTC_DESCRIPTOR_DONE14
descriptor探索が完了しました。
(conn_handle, status)_IRQ_GATTC_READ_RESULT15
以前に発行された
gattc_readがデータを返しました。(conn_handle, value_handle, char_data)_IRQ_GATTC_READ_DONE16
以前に発行された
gattc_readが完了しました。(conn_handle, value_handle, status)_IRQ_GATTC_WRITE_DONE17
以前に発行された
gattc_writeが確認応答されました。(conn_handle, value_handle, status)_IRQ_GATTC_NOTIFY18
リモートサーバーが(確認応答なしの)通知を送信しました。
(conn_handle, value_handle, notify_data)_IRQ_GATTC_INDICATE19
リモートサーバーが(確認応答ありの)インジケーションを送信しました。
(conn_handle, value_handle, notify_data)_IRQ_GATTS_INDICATE_DONE20
以前に送信されたインジケーションがクライアントによって確認応答されました(またはタイムアウトしました)。
(conn_handle, value_handle, status)_IRQ_MTU_EXCHANGED21
ATT MTU交換が完了しました(どちらかの側によって開始されたもの)。
(conn_handle, mtu)_IRQ_L2CAP_ACCEPT22
リモートデバイスが、このデバイスがリッスンしているPSM上でL2CAP接続を要求しました。拒否するには非ゼロの整数を返し、受け入れるには
0/Noneを返します。(conn_handle, cid, psm, our_mtu, peer_mtu)_IRQ_L2CAP_CONNECT23
受信した要求を受け入れたか、発信した
l2cap_connectを完了したことにより、L2CAPチャネルが確立されました。(conn_handle, cid, psm, our_mtu, peer_mtu)_IRQ_L2CAP_DISCONNECT24
L2CAPチャネルが切断されました。
statusはクリーンな切断の場合は0、発信接続の試行が失敗した場合は非ゼロです。(conn_handle, cid, psm, status)_IRQ_L2CAP_RECV25
L2CAPチャネルにデータが到着しました。読み取るには
l2cap_recvintoを呼び出してください。(conn_handle, cid)_IRQ_L2CAP_SEND_READY26
Falseを返した以前のl2cap_sendの送信が完了し、チャネルが再び使用可能になりました。statusが非ゼロの場合は送信バッファがオーバーフローしたことを意味し、アプリケーションはデータを再送信する必要があります。(conn_handle, cid, status)_IRQ_CONNECTION_UPDATE27
リモートデバイスが接続パラメータ(インターバル、レイテンシ、スーパービジョンタイムアウト)を更新しました。
(conn_handle, conn_interval, conn_latency, supervision_timeout, status)_IRQ_ENCRYPTION_UPDATE28
接続の暗号化状態が変化しました。通常はペアリングまたはボンディングの完了後に発生します。
(conn_handle, encrypted, authenticated, bonded, key_size)_IRQ_GET_SECRET29
スタックが保存済みのボンディングシークレットを要求しています。
keyがNoneの場合はsec_typeのindex番目の保存値を返し、そうでない場合は指定された(sec_type, key)に関連付けられた値を返します。何も保存されていない場合はNoneを返します。(sec_type, index, key)_IRQ_SET_SECRET30
スタックがアプリケーションにボンディングシークレットの永続化を要求しています。保存したら
Trueを返します。(sec_type, key, value)_IRQ_PASSKEY_ACTION31
ペアリングの一環としてパスキーアクションが必要です。
gap_passkeyを使って応答してください。可能なアクションについては下のパスキーアクション表を参照してください。(conn_handle, action, passkey)_IRQ_GATTS_READ_REQUESTイベントで利用可能な戻りコードは次のとおりです。定数
値
意味
_GATTS_NO_ERROR0x00読み取りを受け入れます。
_GATTS_ERROR_READ_NOT_PERMITTED0x02読み取りが許可されていません。
_GATTS_ERROR_WRITE_NOT_PERMITTED0x03書き込みが許可されていません。
_GATTS_ERROR_INSUFFICIENT_AUTHENTICATION0x05クライアントが認証されていません。
_GATTS_ERROR_INSUFFICIENT_AUTHORIZATION0x08クライアントが認可されていません。
_GATTS_ERROR_INSUFFICIENT_ENCRYPTION0x0fリンクが暗号化されていません。
_IRQ_PASSKEY_ACTIONイベントで利用可能なアクションは次のとおりです。定数
値
意味
_PASSKEY_ACTION_NONE0
アクションは不要です。
_PASSKEY_ACTION_INPUT2
リモートデバイスに表示されているパスキーを入力するようユーザーに促します。
_PASSKEY_ACTION_DISPLAY3
リモートデバイスが入力するための6桁のパスキーを表示します。
_PASSKEY_ACTION_NUMERIC_COMPARISON4
パスキーがリモートデバイスに表示されているものと一致することを確認します。
ファームウェアの容量を節約するため、これらの定数は
bluetoothモジュールには含まれていません。上記のリストから必要なものをプログラムに追加してください。
Broadcasterロール(アドバタイザ)
- gap_advertise(interval_us: int | None, adv_data: bytes | None = None, *, resp_data: bytes | None = None, connectable: bool = True) None¶
指定されたインターバル(マイクロ秒単位)でアドバタイズを開始します。このインターバルは最も近い625usに切り下げられます。アドバタイズを停止するには、interval_us を
Noneに設定します。adv_data と resp_data には、バッファプロトコルを実装する任意の型(例:
bytes、bytearray、str)を指定できます。adv_data はすべてのブロードキャストに含まれ、resp_data はアクティブスキャンへの応答として送信されます。注意: adv_data(または resp_data)が
Noneの場合、前回のgap_advertise呼び出しに渡されたデータが再利用されます。これにより、broadcasterはgap_advertise(interval_us)だけでアドバタイズを再開できます。アドバタイズペイロードをクリアするには、空のbytes、つまりb''を渡します。
Observerロール(スキャナ)
- gap_scan(duration_ms: int | None, interval_us: int = 1280000, window_us: int = 11250, active: bool = False, /) None¶
指定された継続時間(ミリ秒単位)のスキャン操作を実行します。
無期限にスキャンするには、duration_ms を
0に設定します。スキャンを停止するには、duration_ms を
Noneに設定します。interval_us と window_us を使用して、オプションでデューティサイクルを設定できます。スキャナは、合計 duration_ms ミリ秒の間、interval_us マイクロ秒ごとに window_us マイクロ秒だけ動作します。デフォルトのインターバルとウィンドウはそれぞれ1.28秒と11.25ミリ秒です(バックグラウンドスキャン)。
各スキャン結果に対して
_IRQ_SCAN_RESULTイベントが発生し、イベントデータ(addr_type, addr, adv_type, rssi, adv_data)が渡されます。addr_typeの値はパブリックアドレスかランダムアドレスかを示します。値
名前
意味
0x00PUBLIC
パブリックデバイスアドレス。
0x01RANDOM
ランダムアドレス(静的、RPA、またはNRPAのいずれか。タイプはアドレス自体にエンコードされています)。
adv_typeの値はBluetooth仕様に対応します。値
名前
意味
0x00ADV_IND
接続可能かつスキャン可能な無指向アドバタイズ。
0x01ADV_DIRECT_IND
接続可能な指向アドバタイズ。
0x02ADV_SCAN_IND
スキャン可能な無指向アドバタイズ。
0x03ADV_NONCONN_IND
接続不可能な無指向アドバタイズ。
0x04SCAN_RSP
スキャン応答。
結果にスキャン応答を含めたい場合は、
activeをTrueに設定できます。スキャンが停止すると(継続時間の終了によるもの、または明示的に停止されたもの)、
_IRQ_SCAN_DONEイベントが発生します。
Centralロール
centralデバイスは、observerロールを使って(
gap_scanを参照)発見したperipheral、または既知のアドレスを持つperipheralに接続できます。- gap_connect(addr_type: int | None, addr: bytes | None = None, scan_duration_ms: int = 2000, min_conn_interval_us: int | None = None, max_conn_interval_us: int | None = None, /) None¶
peripheralに接続します。
アドレスタイプの詳細については
gap_scanを参照してください。未完了の接続試行を早期にキャンセルするには、
gap_connect(None)を呼び出します。成功すると
_IRQ_PERIPHERAL_CONNECTイベントが発生します。接続試行をキャンセルした場合は_IRQ_PERIPHERAL_DISCONNECTイベントが発生します。デバイスは、対象デバイスからアドバタイズペイロードを受信するまで最大 scan_duration_ms 待機します。
接続インターバルは、min_conn_interval_us と max_conn_interval_us のいずれかまたは両方を使ってマイクロ秒単位で設定できます。指定しない場合はデフォルトのインターバルが選択され、通常は30000~50000マイクロ秒の範囲になります。インターバルを短くするとスループットが向上しますが、消費電力が増加します。
Peripheralロール
peripheralデバイスは、接続可能なアドバタイズを送信することが期待されます(
gap_advertiseを参照)。通常はGATTサーバーとして動作し、まずgatts_register_servicesを使ってサービスとcharacteristicを登録します。centralが接続すると、
_IRQ_CENTRAL_CONNECTイベントが発生します。CentralおよびPeripheralロール
- gap_disconnect(conn_handle: int, /) bool¶
指定された接続ハンドルを切断します。これは、(peripheralとして動作している場合)このデバイスに接続したcentral、または(centralとして動作している場合)このデバイスが以前に接続したperipheralのいずれかです。
成功すると
_IRQ_PERIPHERAL_DISCONNECTまたは_IRQ_CENTRAL_DISCONNECTイベントが発生します。接続ハンドルが接続されていなかった場合は
Falseを、そうでない場合はTrueを返します。
GATTサーバー
GATTサーバーは登録されたサービスのセットを持ちます。各サービスはcharacteristicを含むことができ、それぞれが値を持ちます。characteristicはまたdescriptorを含むことができ、それ自体が値を持ちます。
これらの値はローカルに保存され、サービス登録時に生成される「value handle」によってアクセスされます。また、リモートのクライアントデバイスから読み取りや書き込みを行うこともできます。さらに、サーバーは接続ハンドルを介して、接続中のクライアントにcharacteristicを「通知」できます。
centralまたはperipheralのいずれのロールのデバイスもGATTサーバーとして機能できますが、ほとんどの場合、peripheralデバイスがサーバーとして動作することがより一般的です。
characteristicとdescriptorのデフォルトの最大サイズは20バイトです(デフォルトのATT MTUである23バイトから3バイトのATTヘッダを引いたもの。ネゴシエートされたMTUが大きくなっても、それだけではこの制限は上がりません)。クライアントがそれらに書き込んだものは、この長さに切り詰められます。ただし、ローカルでの書き込みは最大サイズを増やすため、特定のcharacteristicへのクライアントからのより大きな書き込みを許可したい場合は、登録後に
gatts_writeを使用してください。例:gatts_write(char_handle, bytes(100))。- gatts_register_services(services_definition: Sequence[Sequence], /) Sequence[Sequence[int]]¶
指定されたサービスでサーバーを設定し、既存のサービスを置き換えます。
services_definition は サービス のリストです。各 サービス は、UUIDと characteristic のリストを含む2要素のタプルです。
各 characteristic は、UUID、flags 値、およびオプションで descriptor のリストを含む2要素または3要素のタプルです。
各 descriptor は、UUIDと flags 値を含む2要素のタプルです。
flags は、以下で定義されるフラグのビット単位ORの組み合わせです。これらはcharacteristic(またはdescriptor)の動作と、セキュリティおよびプライバシーの要件の両方を設定します。
戻り値はタプルのリスト(サービスごとに1要素)で、各要素はvalue handleです。characteristicとdescriptorのハンドルは、定義された順序で同じタプルにフラット化されます。
次の例は2つのサービス(Heart RateとNordic UART)を登録します:
bt = bluetooth.BLE() bt.active(True) # Heart Rate service: one Heart Rate Measurement characteristic. HR_SERVICE = ( bluetooth.UUID(0x180D), ( (bluetooth.UUID(0x2A37), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY), ), ) # Nordic UART service: a TX characteristic the client subscribes # to for notifications, and an RX characteristic it writes to. UART_SERVICE = ( bluetooth.UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E'), ( (bluetooth.UUID('6E400003-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY), (bluetooth.UUID('6E400002-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_WRITE), ), ) ((hr,), (tx, rx)) = bt.gatts_register_services( (HR_SERVICE, UART_SERVICE), )
3つのvalue handle(
hr、tx、rx)は、gatts_read、gatts_write、gatts_notify、gatts_indicateで使用できます。注意: サービスを登録する前に、アドバタイズを停止する必要があります。
characteristicとdescriptorで利用可能なフラグは次のとおりです。
定数
値
意味
_FLAG_BROADCAST0x0001characteristicはブロードキャストできます。
_FLAG_READ0x0002クライアントは値を読み取れます。
_FLAG_WRITE_NO_RESPONSE0x0004クライアントは応答を期待せずに書き込めます。
_FLAG_WRITE0x0008クライアントは確認応答ありで書き込めます。
_FLAG_NOTIFY0x0010サーバーは通知(確認応答なし)を送信できます。
_FLAG_INDICATE0x0020サーバーはインジケーション(確認応答あり)を送信できます。
_FLAG_AUTHENTICATED_SIGNED_WRITE0x0040クライアントは署名付き書き込みを発行できます。
_FLAG_AUX_WRITE0x0100拡張プロパティ: キュー付き/信頼性のある書き込みが許可されます。
_FLAG_READ_ENCRYPTED0x0200読み取りには暗号化されたリンクが必要です。
_FLAG_READ_AUTHENTICATED0x0400読み取りには認証された(MITM保護された)リンクが必要です。
_FLAG_READ_AUTHORIZED0x0800読み取りにはアプリケーションレベルの認可が必要です。
_FLAG_WRITE_ENCRYPTED0x1000書き込みには暗号化されたリンクが必要です。
_FLAG_WRITE_AUTHENTICATED0x2000書き込みには認証された(MITM保護された)リンクが必要です。
_FLAG_WRITE_AUTHORIZED0x4000書き込みにはアプリケーションレベルの認可が必要です。
上記のイベント定数と同様に、これらのフラグも
bluetoothモジュールでは提供されていません。必要なものをプログラムにコピーしてください。
- gatts_read(value_handle: int, /) bytes¶
このハンドルのローカル値(
gatts_writeによって、またはリモートクライアントによって書き込まれたもの)を読み取ります。
- gatts_write(value_handle: int, data: bytes, send_update: bool = False, /) None¶
このハンドルのローカル値を書き込みます。これはクライアントから読み取ることができます。
send_update が
Trueの場合、サブスクライブしているクライアントは、この書き込みについて通知(またはインジケーション。クライアントが何にサブスクライブしているか、およびcharacteristicがどの操作をサポートしているかによる)を受け取ります。
- gatts_notify(conn_handle: int, value_handle: int, data: bytes | None = None, /) None¶
接続中のクライアントに通知要求を送信します。
data が
None(デフォルト)の場合、現在のローカル値(gatts_writeで設定されたもの)が送信されます。そうでない場合、data が
Noneでなければ、その値が通知の一部としてクライアントに送信されます。ローカル値は変更されません。注意: 通知は、このcharacteristicに対するクライアントのサブスクリプション状態に関係なく送信されます。
- gatts_indicate(conn_handle: int, value_handle: int, data: bytes | None = None, /) None¶
接続中のクライアントにインジケーション要求を送信します。
data が
None(デフォルト)の場合、現在のローカル値(gatts_writeで設定されたもの)が送信されます。そうでない場合、data が
Noneでなければ、その値がインジケーションの一部としてクライアントに送信されます。ローカル値は変更されません。確認応答時(または失敗時、例: タイムアウト)に、
_IRQ_GATTS_INDICATE_DONEイベントが発生します。注意: インジケーションは、このcharacteristicに対するクライアントのサブスクリプション状態に関係なく送信されます。
- gatts_set_buffer(value_handle: int, len: int, append: bool = False, /) None¶
値の内部バッファサイズをバイト単位で設定します。これにより、受信可能な書き込みの最大サイズが制限されます。デフォルトは20バイトです(デフォルトのATT MTUである23から3バイトのATTヘッダを引いたもの)。
append を
Trueに設定すると、すべてのリモート書き込みが、現在の値を置き換えるのではなく追記するようになります。この方法で最大 len バイトまでバッファできます。gatts_readを使用すると、読み取り後に値がクリアされます。この機能は、Nordic UART Serviceのようなものを実装する際に役立ちます。
GATTクライアント
GATTクライアントは、リモートのGATTサーバー上のcharacteristicを発見し、読み取り/書き込みできます。
centralロールのデバイスがGATTクライアントとして動作するのがより一般的ですが、接続してきたcentralに関する情報を発見するために(例えばdevice informationサービスからデバイス名を読み取るために)、peripheralがクライアントとして動作することも可能です。
- gattc_discover_services(conn_handle: int, uuid: UUID | None = None, /) None¶
接続中のサーバーにそのサービスを問い合わせます。
オプションでサービス uuid を指定して、そのサービスのみを問い合わせることができます。
発見された各サービスに対して
_IRQ_GATTC_SERVICE_RESULTイベントが発生し、完了時に_IRQ_GATTC_SERVICE_DONEが続きます。
- gattc_discover_characteristics(conn_handle: int, start_handle: int, end_handle: int, uuid: UUID | None = None, /) None¶
接続中のサーバーに、指定された範囲内のcharacteristicを問い合わせます。
オプションでcharacteristic uuid を指定して、そのcharacteristicのみを問い合わせることができます。
start_handle=1とend_handle=0xffffを渡すと、GATTのアトリビュートハンドルの全範囲をカバーするため、この組み合わせは実質的にリモートデバイス上のすべてのサービスを検索します。発見された各characteristicに対して
_IRQ_GATTC_CHARACTERISTIC_RESULTイベントが発生し、完了時に_IRQ_GATTC_CHARACTERISTIC_DONEが続きます。
- gattc_discover_descriptors(conn_handle: int, start_handle: int, end_handle: int, /) None¶
接続中のサーバーに、指定された範囲内のdescriptorを問い合わせます。
発見された各descriptorに対して
_IRQ_GATTC_DESCRIPTOR_RESULTイベントが発生し、完了時に_IRQ_GATTC_DESCRIPTOR_DONEが続きます。
- gattc_read(conn_handle: int, value_handle: int, /) None¶
接続中のサーバーに、指定されたcharacteristicまたはdescriptorハンドルに対するリモート読み取りを発行します。
値が利用可能になると
_IRQ_GATTC_READ_RESULTイベントが発生し、完了時に_IRQ_GATTC_READ_DONEが続きます。
- gattc_write(conn_handle: int, value_handle: int, data: bytes, mode: int = 0, /) None¶
接続中のサーバーに、指定されたcharacteristicまたはdescriptorハンドルに対するリモート書き込みを発行します。
引数 mode は書き込みの動作を指定します。現在サポートされている値は次のとおりです。
mode=0(デフォルト)は応答なし書き込みです。書き込みはリモートサーバーに送信されますが、確認は返されず、イベントも発生しません。mode=1は応答あり書き込みです。リモートサーバーに対して、データを受信したことを示す応答/確認応答を送信するよう要求します。
リモートサーバーから応答を受信すると、
_IRQ_GATTC_WRITE_DONEイベントが発生します。
- gattc_exchange_mtu(conn_handle: int, /) None¶
BLE.config(mtu=value)で設定された希望MTUを使用して、接続中のサーバーとMTU交換を開始します。MTU交換が完了すると
_IRQ_MTU_EXCHANGEDイベントが発生します。MTU交換は通常centralによって開始されますが、NimBLEは両方のロールをサポートします。
L2CAPコネクション指向チャネル
この機能により、2つのBLEデバイス間でソケットのようなデータ交換が可能になります。デバイスがGAP経由で接続されると、どちらのデバイスも数値のPSM(Protocol/Service Multiplexer)上で相手の接続をリッスンできます。
一度にアクティブにできるL2CAPチャネルは1つだけです(つまり、リッスン中に接続することはできません)。
アクティブなL2CAPチャネルは、それが確立された接続ハンドルとCID(チャネルID)によって識別されます。
コネクション指向チャネルには、クレジットベースのフロー制御が組み込まれています。デバイスが共有MTUをネゴシエートするATTとは異なり、リッスン側と接続側のデバイスはそれぞれ独立したMTUを設定します。これは、
l2cap_recvintoで完全に消費される前に、リモートデバイスが送信できる未処理データの最大量を制限します。- l2cap_listen(psm: int, mtu: int, /) None¶
指定された psm 上で、ローカルMTUを mtu に設定して、L2CAPチャネル要求の受信をリッスンし始めます。
リモートデバイスが接続を開始すると
_IRQ_L2CAP_ACCEPTイベントが発生し、リッスン中のサーバーは(非ゼロの整数を返すことで)受信接続を拒否する機会が与えられます。接続が受け入れられると
_IRQ_L2CAP_CONNECTイベントが発生し、サーバーはチャネルID(CID)およびローカルとリモートのMTUを取得できます。注意: 現在のところ、リッスンを停止することはできません。
- l2cap_connect(conn_handle: int, psm: int, mtu: int, /) None¶
指定された psm 上で、ローカルMTUを mtu に設定して、リッスン中のピアに接続します。
接続に成功すると
_IRQ_L2CAP_CONNECTイベントが発生し、クライアントはCIDおよびローカルとリモート(ピア)のMTUを取得できます。接続に失敗すると、非ゼロのステータスを伴う
_IRQ_L2CAP_DISCONNECTイベントが発生します。
- l2cap_disconnect(conn_handle: int, cid: int, /) None¶
指定された conn_handle と cid を持つアクティブなL2CAPチャネルを切断します。
- l2cap_send(conn_handle: int, cid: int, buf: bytes, /) bool¶
conn_handle と cid で識別されるL2CAPチャネル上で、指定された buf(バッファプロトコルをサポートする必要があります)を送信します。
バッファは両方の制限を満たす必要があります。リモート(ピア)のMTUを超えてはならず、かつローカルMTUの2倍を超えてもなりません。
チャネルが「ストール」した場合は
Falseを返します。これは、_IRQ_L2CAP_SEND_READYイベントを受信するまでl2cap_sendを再度呼び出してはならないことを意味します(このイベントは、リモートデバイスがより多くのクレジットを付与したとき、通常はデータを受信して処理した後に発生します)。
- l2cap_recvinto(conn_handle: int, cid: int, buf: Any | None, /) int¶
指定された conn_handle と cid から、提供された buf(バッファプロトコルをサポートする必要があります。例: bytearrayまたはmemoryview)にデータを受信します。
チャネルから読み取ったバイト数を返します。
buf が
Noneの場合、利用可能なバイト数を返します。注意:
_IRQ_L2CAP_RECVイベントを受信した後、アプリケーションは受信バッファに利用可能なバイトがなくなるまで(通常はリモート(ピア)のMTUのサイズまで)l2cap_recvintoを呼び出し続ける必要があります。受信バッファが空になるまで、リモートデバイスにはそれ以上のチャネルクレジットが付与されず、これ以上データを送信できなくなります。
ペアリングとボンディング
ペアリングにより、シークレットの交換を通じて接続を暗号化し認証できます(パスキー認証によるオプションのMITM保護付き)。
ボンディングは、それらのシークレットを不揮発性ストレージに保存するプロセスです。ボンディングされると、デバイスは保存された identity resolving key(IRK)に基づいて、別のデバイスからの解決可能なプライベートアドレス(RPA)を解決できます。ボンディングをサポートするには、アプリケーションが
_IRQ_GET_SECRETおよび_IRQ_SET_SECRETイベントを実装する必要があります。- gap_pair(conn_handle: int, /) None¶
リモートデバイスとのペアリングを開始します。
これを呼び出す前に、
io、mitm、le_secure、bondの各設定オプションが(configを介して)設定されていることを確認してください。ペアリングに成功すると
_IRQ_ENCRYPTION_UPDATEイベントが発生します。
- gap_passkey(conn_handle: int, action: int, passkey: int, /) None¶
指定された conn_handle と action に対する
_IRQ_PASSKEY_ACTIONイベントに応答します。passkey の意味は action に依存します(さらにそれは設定されたI/O能力に依存します)。アクション
必要な passkey 応答
_PASSKEY_ACTION_INPUTユーザーがリモートデバイスから読み取るパスキー。
_PASSKEY_ACTION_DISPLAYユーザーに表示される、ローカルで生成された6桁のランダムなパスキー。
_PASSKEY_ACTION_NUMERIC_COMPARISON_IRQ_PASSKEY_ACTIONイベントで表示されたパスキーを受け入れるには1、ペアリングをキャンセルするには0。
class UUID¶
- class bluetooth.UUID(value: int | bytes | str, /)¶
指定された
valueでUUIDインスタンスを作成します。Bluetoothは3つのUUID幅を使用し、UUIDはそのいずれも受け付けます。UUID幅
受け付けられる
valueの型例
16ビット
intまたは2バイトのバッファ(リトルエンディアン)UUID(0x2908)またはUUID(b'\x08\x29')32ビット
4バイトのバッファ(リトルエンディアン)
UUID(b'\x08\x29\x00\x00')128ビット
16バイトのバッファまたはハイフン区切りの文字列
UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E')16ビットおよび32ビットのUUIDは通常SIGによって割り当てられた識別子です(Bluetooth assigned numbers を参照)。128ビットのUUIDは通常ベンダー定義です。