このドキュメンテーションは、MicroPython の最新開発ブランチのためのものです。 リリースバージョンでは利用できない機能に言及することがあります。

特定のリリースのドキュメントをお探しの場合は、左側のドロップダウンメニューを使って、 望みのバージョンを選択します。

bluetooth --- 低レベル Bluetooth

このモジュールは、ボード上の Bluetooth コントローラーへのインターフェースを提供します。現在、このモジュールは Bluetooth Low Energy(BLE)をサポートしています。セントラル(Central)、ペリフェラル(Peripheral)、ブロードキャスター(Broadcaster)、オブザーバー(Observer)のロールがありますし、GATT サーバー/クライアントと L2CAP connection-oriented-channel のロールもあります。デバイスは複数のロールで同時に動作できます。ペアリング(とボンディング)をサポートするポートもあります。

このAPIは、低レベルの Bluetooth プロトコルに相当するもので、特定のデバイスタイプなどの高レベルの抽象化のビルディングブロックを提供します。

注釈

ほとんどのアプリケーションでは、上位の aioble ライブラリ の利用を推奨します。

注釈

このモジュールはまだ開発中であり、そのクラス、関数、メソッド、定数は変更される可能性があります。

クラス BLE

コンストラクタ

class bluetooth.BLE

シンゲルトンの BLE オブジェクトを返します。

設定

BLE.active([active, ]/)

オプションでBLE無線のアクティブ状態を変更し、現在の状態を返します。

このクラスの他のメソッドを使用する前には、BLE無線をアクティブにする必要があります。

BLE.config('param', /)
BLE.config(*, param=value, ...)

BLE インターフェイスの設定値を取得または設定します。値を取得するには、パラメーター名を文字列として一度に1つだけ指定します。値を設定する場合には、キーワード構文を使って、一度に1つ以上のパラメーターを設定できます。

現在サポートされている値は次のとおりです:

  • 'mac': 現在利用中のアドレス。これは現在のアドレスモードに依存します。戻り値は (addr_type, addr) のタプルです。

    アドレスタイプ addr_type について詳しくは gatts_write を参照してください。

    これはインターフェイスがアクティブなときにのみ取得できます。

  • 'addr_mode': アドレスモードを設定します。設定できる値には次のものがあります:

    • 0x00 - PUBLIC - デバイス固有の物理アドレスを使います。

    • 0x01 - RANDOM - 電源投入のたびに生成される乱数アドレスを使います。

    • 0x02 - RPA - Resolvable Private Addresses を使います。

    • 0x03 - NRPA - Non-Resolvable Private Addresses を使います。

    既定のアドレスモードは、デバイスが固有の物理アドレスを持っている場合 PUBLIC になり、持っていない場合は RANDOM になります。

  • 'gap_name': サービス 0x1800、キャラクタリスティック(Characteristic) 0x2a00 で利用する GAP デバイス名を取得/設定します。これはいつでも設定でき、何度も変更できます。

  • 'rxbuf': 着信イベントの保存に使用される内部バッファーのサイズをバイト単位で取得/設定します。このバッファは BLE ドライバーー全体に対してグローバルであるため、すべてのキャラクタリスティック(Characteristic)を含むすべてのイベントの着信データを処理します。これを増やすと、バーストな受信データ(スキャン結果など)の処理が改善され、より大きなキャラクタリスティック値を受信できるようになります。

  • 'mtu': ATT MTU 交換で使われる MTU を取得/設定します。結果として得られる MTU は、この MTU とリモートデバイスの MTU の最小値になります。ATT MTU 交換は(リモートデバイスが開始しない限り)自動的には行われず、 gattc_exchange_mtu を使って手動で開始する必要があります。指定された接続の MTU を発見するには _IRQ_MTU_EXCHANGED イベントを使います。

  • 'bond': ペアリング中にボンディングを有効にするかどうかを設定します。有効にすると、ペアリング要求は "bond" フラグを設定し、鍵が両方のデバイスに保存されます。

  • 'mitm': ペアリングに MITM-protection が必要かどうかを設定します。

  • 'io': このデバイスの I/O 機能を設定します

    設定できるオプションは次のとおりです:

    _IO_CAPABILITY_DISPLAY_ONLY = const(0)
    _IO_CAPABILITY_DISPLAY_YESNO = const(1)
    _IO_CAPABILITY_KEYBOARD_ONLY = const(2)
    _IO_CAPABILITY_NO_INPUT_OUTPUT = const(3)
    _IO_CAPABILITY_KEYBOARD_DISPLAY = const(4)
    
  • 'le_secure': "LE Secure" ペアリングが必要かどうかを設定します。既定値は false です(すなわち "Legacy Pairing" になります)。

イベント処理

BLE.irq(handler, /)

BLE スタックからのイベントのコールバックを登録します。 handler に指定するコールバックは二つの引数 event (後述するイベントコードのいずれか)と data (イベント固有の値のタプル)をとります

注記: 不必要な割り当てを防ぐための最適化として、タプルの addr, adv_data, char_data, notify_data, uuid 項目は、bluetooth の内部リングバッファを指す読み取り専用のメモリビューインスタンスです。これらの値は IRQ ハンドラ関数の呼び出し中にのみ有効です。IRQ ハンドラから戻ってきた後でこれらの値にアクセスする必要がある場合には(クラスインスタンスやグローバル変数に保存するなど)、次に示すように bytes(addr) または bluetooth.UUID(uuid) を使ってこれらのデータをコピーする必要があります:

connected_addr = bytes(addr)  # adv_data, char_data, notify_data も同様
matched_uuid = bluetooth.UUID(uuid)

たとえば、スキャン結果の IRQ ハンドラは adv_data を検査してそれが正しいデバイスであるかどうかを判断し、プログラムの他の場所で使えるようにアドレスデータをコピーすることができます。また、IRQ ハンドラの中からデータを出力するには print(bytes(addr)) とすることが必要になります。

すべてのイベントを処理するイベントハンドラーの例を示します:

def bt_irq(event, data):
    if event == _IRQ_CENTRAL_CONNECT:
        # A central has connected to this peripheral.
        conn_handle, addr_type, addr = data
    elif event == _IRQ_CENTRAL_DISCONNECT:
        # A central has disconnected from this peripheral.
        conn_handle, addr_type, addr = data
    elif event == _IRQ_GATTS_WRITE:
        # A client has written to this characteristic or descriptor.
        conn_handle, attr_handle = data
    elif event == _IRQ_GATTS_READ_REQUEST:
        # A client has issued a read. Note: this is only supported on STM32.
        # Return a non-zero integer to deny the read (see below), or zero (or None)
        # to accept the read.
        conn_handle, attr_handle = data
    elif event == _IRQ_SCAN_RESULT:
        # A single scan result.
        addr_type, addr, adv_type, rssi, adv_data = data
    elif event == _IRQ_SCAN_DONE:
        # Scan duration finished or manually stopped.
        pass
    elif event == _IRQ_PERIPHERAL_CONNECT:
        # A successful gap_connect().
        conn_handle, addr_type, addr = data
    elif event == _IRQ_PERIPHERAL_DISCONNECT:
        # Connected peripheral has disconnected.
        conn_handle, addr_type, addr = data
    elif event == _IRQ_GATTC_SERVICE_RESULT:
        # Called for each service found by gattc_discover_services().
        conn_handle, start_handle, end_handle, uuid = data
    elif event == _IRQ_GATTC_SERVICE_DONE:
        # Called once service discovery is complete.
        # Note: Status will be zero on success, implementation-specific value otherwise.
        conn_handle, status = data
    elif event == _IRQ_GATTC_CHARACTERISTIC_RESULT:
        # Called for each characteristic found by gattc_discover_services().
        conn_handle, end_handle, value_handle, properties, uuid = data
    elif event == _IRQ_GATTC_CHARACTERISTIC_DONE:
        # Called once service discovery is complete.
        # Note: Status will be zero on success, implementation-specific value otherwise.
        conn_handle, status = data
    elif event == _IRQ_GATTC_DESCRIPTOR_RESULT:
        # Called for each descriptor found by gattc_discover_descriptors().
        conn_handle, dsc_handle, uuid = data
    elif event == _IRQ_GATTC_DESCRIPTOR_DONE:
        # Called once service discovery is complete.
        # Note: Status will be zero on success, implementation-specific value otherwise.
        conn_handle, status = data
    elif event == _IRQ_GATTC_READ_RESULT:
        # A gattc_read() has completed.
        conn_handle, value_handle, char_data = data
    elif event == _IRQ_GATTC_READ_DONE:
        # A gattc_read() has completed.
        # Note: Status will be zero on success, implementation-specific value otherwise.
        conn_handle, value_handle, status = data
    elif event == _IRQ_GATTC_WRITE_DONE:
        # A gattc_write() has completed.
        # Note: Status will be zero on success, implementation-specific value otherwise.
        conn_handle, value_handle, status = data
    elif event == _IRQ_GATTC_NOTIFY:
        # A server has sent a notify request.
        conn_handle, value_handle, notify_data = data
    elif event == _IRQ_GATTC_INDICATE:
        # A server has sent an indicate request.
        conn_handle, value_handle, notify_data = data
    elif event == _IRQ_GATTS_INDICATE_DONE:
        # A client has acknowledged the indication.
        # Note: Status will be zero on successful acknowledgment, implementation-specific value otherwise.
        conn_handle, value_handle, status = data
    elif event == _IRQ_MTU_EXCHANGED:
        # ATT MTU exchange complete (either initiated by us or the remote device).
        conn_handle, mtu = data
    elif event == _IRQ_L2CAP_ACCEPT:
        # A new channel has been accepted.
        # Return a non-zero integer to reject the connection, or zero (or None) to accept.
        conn_handle, cid, psm, our_mtu, peer_mtu = data
    elif event == _IRQ_L2CAP_CONNECT:
        # A new channel is now connected (either as a result of connecting or accepting).
        conn_handle, cid, psm, our_mtu, peer_mtu = data
    elif event == _IRQ_L2CAP_DISCONNECT:
        # Existing channel has disconnected (status is zero), or a connection attempt failed (non-zero status).
        conn_handle, cid, psm, status = data
    elif event == _IRQ_L2CAP_RECV:
        # New data is available on the channel. Use l2cap_recvinto to read.
        conn_handle, cid = data
    elif event == _IRQ_L2CAP_SEND_READY:
        # A previous l2cap_send that returned False has now completed and the channel is ready to send again.
        # If status is non-zero, then the transmit buffer overflowed and the application should re-send the data.
        conn_handle, cid, status = data
    elif event == _IRQ_CONNECTION_UPDATE:
        # The remote device has updated connection parameters.
        conn_handle, conn_interval, conn_latency, supervision_timeout, status = data
    elif event == _IRQ_ENCRYPTION_UPDATE:
        # The encryption state has changed (likely as a result of pairing or bonding).
        conn_handle, encrypted, authenticated, bonded, key_size = data
    elif event == _IRQ_GET_SECRET:
        # Return a stored secret.
        # If key is None, return the index'th value of this sec_type.
        # Otherwise return the corresponding value for this sec_type and key.
        sec_type, index, key = data
        return value
    elif event == _IRQ_SET_SECRET:
        # Save a secret to the store for this sec_type and key.
        sec_type, key, value = data
        return True
    elif event == _IRQ_PASSKEY_ACTION:
        # Respond to a passkey request during pairing.
        # See gap_passkey() for details.
        # action will be an action that is compatible with the configured "io" config.
        # passkey will be non-zero if action is "numeric comparison".
        conn_handle, action, passkey = data

イベントコードには次のものがあります:

from micropython import const
_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_WRITE = const(3)
_IRQ_GATTS_READ_REQUEST = const(4)
_IRQ_SCAN_RESULT = const(5)
_IRQ_SCAN_DONE = const(6)
_IRQ_PERIPHERAL_CONNECT = const(7)
_IRQ_PERIPHERAL_DISCONNECT = const(8)
_IRQ_GATTC_SERVICE_RESULT = const(9)
_IRQ_GATTC_SERVICE_DONE = const(10)
_IRQ_GATTC_CHARACTERISTIC_RESULT = const(11)
_IRQ_GATTC_CHARACTERISTIC_DONE = const(12)
_IRQ_GATTC_DESCRIPTOR_RESULT = const(13)
_IRQ_GATTC_DESCRIPTOR_DONE = const(14)
_IRQ_GATTC_READ_RESULT = const(15)
_IRQ_GATTC_READ_DONE = const(16)
_IRQ_GATTC_WRITE_DONE = const(17)
_IRQ_GATTC_NOTIFY = const(18)
_IRQ_GATTC_INDICATE = const(19)
_IRQ_GATTS_INDICATE_DONE = const(20)
_IRQ_MTU_EXCHANGED = const(21)
_IRQ_L2CAP_ACCEPT = const(22)
_IRQ_L2CAP_CONNECT = const(23)
_IRQ_L2CAP_DISCONNECT = const(24)
_IRQ_L2CAP_RECV = const(25)
_IRQ_L2CAP_SEND_READY = const(26)
_IRQ_CONNECTION_UPDATE = const(27)
_IRQ_ENCRYPTION_UPDATE = const(28)
_IRQ_GET_SECRET = const(29)
_IRQ_SET_SECRET = const(30)

_IRQ_GATTS_READ_REQUEST イベントで使えるリターンコードは次のとおりです:

_GATTS_NO_ERROR = const(0x00)
_GATTS_ERROR_READ_NOT_PERMITTED = const(0x02)
_GATTS_ERROR_WRITE_NOT_PERMITTED = const(0x03)
_GATTS_ERROR_INSUFFICIENT_AUTHENTICATION = const(0x05)
_GATTS_ERROR_INSUFFICIENT_AUTHORIZATION = const(0x08)
_GATTS_ERROR_INSUFFICIENT_ENCRYPTION = const(0x0f)

_IRQ_PASSKEY_ACTION イベントで使えるアクションは次のとおりです:

_PASSKEY_ACTION_NONE = const(0)
_PASSKEY_ACTION_INPUT = const(2)
_PASSKEY_ACTION_DISPLAY = const(3)
_PASSKEY_ACTION_NUMERIC_COMPARISON = const(4)

ファームウェアのスペースを節約するために、これらの定数は bluetooth モジュールには含まれていません 。上記のリストから必要なものをプログラムに追加してください。

ブロードキャスターロール(アドバタイザー)

BLE.gap_advertise(interval_us, adv_data=None, *, resp_data=None, connectable=True)

指定された間隔(マイクロ秒単位)でアドバタイジング(Advertising)を開始します。この間隔は、625us に最も近いところで切り捨てられます。アドバタイジングを停止するには interval_usNone に設定します。

adv_dataresp_data はバッファプロトコルを実装する任意のタイプにできます(bytes, bytearray, str など)。 adv_data はすべてのブロードキャストに含まれ、 resp_data はアクティブスキャンへの返信として送信されます。

注記: adv_data (または resp_data)が None の場合、前の gap_advertise 呼び出しに渡されたデータが再利用されます。これにより gap_advertise(interval_us) だけで、ブロードキャスターはアドバタイジングを再開できます。アドバタイジングペイロードをクリアするには、空の bytes 、すなわち b'' を渡します。

オブザーバーロール(スキャナー)

BLE.gap_scan(duration_ms, interval_us=1280000, window_us=11250, active=False, /)

指定された期間(ミリ 秒単位)持続するスキャン操作を実行します。

無期限にスキャンするには duration_ms0 に設定します。

スキャンを停止するには duration_msNone に設定します。

オプションでデューティ比(duty cycle)を設定するには interval_uswindow_us を使います。スキャナは全体の duration_ms ミリ秒の間の interval_us マイクロ秒毎に window_us マイクロ秒間実行します。 interval_uswindow_us のデフォルト値はそれぞれ 1.28 と 11.25 です(バックグラウンドスキャン)。

スキャン結果ごとに、_IRQ_SCAN_RESULT イベントが発生します。イベントデータは (addr_type, addr, adv_type, rssi, adv_data) です。

addr_type の値は PUBLIC または RANDOM アドレスであるかを示します:
  • 0x00 - PUBLIC

  • 0x01 - RANDOM (RANDOM, RPA, NRPA のいずれか。どれであるかはアドレス自体にエンコードされています)

"adv_type の値は次の Bluetooth 仕様に対応しています:

  • 0x00 - ADV_IND - 接続/スキャン可能な無向アドバタイジング

  • 0x01 - ADV_DIRECT_IND - 接続可能な有向アドバタイジング

  • 0x02 - ADV_SCAN_IND - スキャン可能な無向アドバタイジング

  • 0x03 - ADV_NONCONN_IND - 接続不可能な無向アドバタイジング

  • 0x04 - SCAN_RSP - スキャン応答

スキャンの応答を結果として受け取りたい場合は、 activeTrue にします。

スキャンが終了すると(終了時間になったか、明示的に停止した場合)、 _IRQ_SCAN_DONE イベントが発生します。

セントラルロール

セントラルデバイスは、オブザーバーロール(gap_scan を参照)を使うか、既知のアドレスで検出したペリフェラルに接続できます。

BLE.gap_connect(addr_type, addr, scan_duration_ms=2000, min_conn_interval_us=None, max_conn_interval_us=None, /)

ペリフェラルに接続します。

アドレスタイプの詳細については gap_scan を参照してください。

未処理の接続試行を早期にキャンセルするには gap_connect(None) を呼び出してください。

接続に成功すると _IRQ_PERIPHERAL_CONNECT イベントが発生します。接続の試行をキャンセルすると _IRQ_PERIPHERAL_DISCONNECT イベントが発生します。

デバイスからのアドバタイジングペイロードを受信するまで scan_duration_ms まで待機します。

接続間隔は min_conn_interval_us および max_conn_interval_us のいずれかまたは両方を使って マイクロ 秒単位で設定できます。それ以外の場合は、通常 30000~50000 マイクロ秒の間でデフォルトの間隔が選択されます。間隔を短くするとスループットが向上しますが消費電力は増加します。

ペリフェラルロール

ペリフェラルデバイスは、接続可能なアドバタイズを送信することが期待されます(gap_advertise)。これは通常、 gatts_register_services を用いて最初に登録されたサービスとキャラクタリスティックを持つ GATT サーバとして動作します。

セントラルが接続すると _IRQ_CENTRAL_CONNECT イベントが発生します。

セントラル&ペリフェラルロール

BLE.gap_disconnect(conn_handle, /)

指定した接続ハンドルを切断します。これは、(ペリフェラルとして動作している)このデバイスに接続したセントラル、または(セントラルとして動作している)このデバイスに以前に接続されていたペリフェラルのいずれかになります。

切断に成功すると _IRQ_PERIPHERAL_DISCONNECT または _IRQ_CENTRAL_DISCONNECT イベントが発生します。

接続ハンドルが接続されていない場合は False を、そうでない場合は True を返します。

GATT サーバー

GATT サーバには登録されたサービスのセットがあります。各サービスにはキャラクタリスティック(Characteristic)が含まれていることがあり、各キャラクタリスティックは値を持ちます。キャラクタリスティックには、それ自体に値を持つディスクリプタを含めることもできます。

これらの値はローカルに保存され、サービス登録中に生成される「値ハンドル(value handle)」によってアクセスされます。また、リモートのクライアントデバイスから読み書きすることもできます。さらに、ペリフェラルは接続ハンドルを介して接続されたクライアントにキャラクタリスティックを「通知(notify)」できます。

セントラルまたはペリフェラルのいずれかのロールを持つデバイスが GATT サーバとして機能することもありますが、ほとんどの場合、ペリフェラルがサーバとして機能するのが一般的です。

キャラクタリスティックとディスクリプタのデフォルト最大サイズは 20 バイトです。クライアントによってそれらに書き込まれたものはすべて、この長さに切り捨てられます。ただし、クライアントから特定のキャラクタリスティックへのより大きな書き込みを許可したくて、ローカル書き込みの最大サイズを大きくするには、登録後に gatts_write を使います。たとえば gatts_write(char_handle, bytes(100)) のようにします。

BLE.gatts_register_services(services_definition, /)

指定したサービスでサーバーを構成し、既存のサービスを置換します。

services_definitionサービス のリストであり、各 サービス は UUID と キャラクタリスティック のリストを含む2項目のタプルです。

キャラクタリスティック は、UUID、 フラグ 値、およびオプションの ディスクリプタ のリストを含む2または3項目のタプルです。

ディスクリプタ は UUID と フラグ 値を含む2項目のタプルです。

フラグ は、後述するフラグのビット論理和の組み合わせです。これらは、キャラクタリスティック(またはディスクリプタ)の振舞いおよびセキュリティとプライバシーの要件の両方を設定します。

戻り値は、タプル(各項目は値ハンドル)のリスト(サービスごとに1項目)です。キャラクタリスティックとディスクリプタのハンドルは、定義された順序で同じタプルにフラット化されます。

次の例では、2つのサービス(心拍数と Nordic UART)を登録します。

HR_UUID = bluetooth.UUID(0x180D)
HR_CHAR = (bluetooth.UUID(0x2A37), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,)
HR_SERVICE = (HR_UUID, (HR_CHAR,),)
UART_UUID = bluetooth.UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E')
UART_TX = (bluetooth.UUID('6E400003-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,)
UART_RX = (bluetooth.UUID('6E400002-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_WRITE,)
UART_SERVICE = (UART_UUID, (UART_TX, UART_RX,),)
SERVICES = (HR_SERVICE, UART_SERVICE,)
( (hr,), (tx, rx,), ) = bt.gatts_register_services(SERVICES)

3項目のハンドル (hr, tx, rx) は gatts_read, gatts_write, gatts_notify, gatts_indicate で使えます。

注記: サービスを登録する前に、アドバタイジングを停止する必要があります。

キャラクタリスティックとディスクリプタで使えるフラグは次のとおりです:

from micropython import const
_FLAG_BROADCAST = const(0x0001)
_FLAG_READ = const(0x0002)
_FLAG_WRITE_NO_RESPONSE = const(0x0004)
_FLAG_WRITE = const(0x0008)
_FLAG_NOTIFY = const(0x0010)
_FLAG_INDICATE = const(0x0020)
_FLAG_AUTHENTICATED_SIGNED_WRITE = const(0x0040)

_FLAG_AUX_WRITE = const(0x0100)
_FLAG_READ_ENCRYPTED = const(0x0200)
_FLAG_READ_AUTHENTICATED = const(0x0400)
_FLAG_READ_AUTHORIZED = const(0x0800)
_FLAG_WRITE_ENCRYPTED = const(0x1000)
_FLAG_WRITE_AUTHENTICATED = const(0x2000)
_FLAG_WRITE_AUTHORIZED = const(0x4000)

先述の IRQ と同様に、必要な定数を Python コードに追加してください。

BLE.gatts_read(value_handle, /)

このハンドルのためのローカル値(gatts_write かリモートクライアントで書き込まれたもの)を読み取ります。

BLE.gatts_write(value_handle, data, send_update=False, /)

このハンドルのローカル値を書き込みます。これは、クライアントによって読み取ることができます。

send_updateTrue の場合、サブスクライブしているクライアントにこの書き込みについて通知されます(またはサブスクライブしている内容と、キャラクタリスティックがサポートしている操作に応じてレスポンスを要求します)

BLE.gatts_notify(conn_handle, value_handle, data=None, /)

接続されているクライアントにノーティフィケーション要求を送信します。

dataNone であれば(デフォルト)、現在のローカル値(gatts_write で設定された値)が送信されます。

dataNone でなければ、その値が通知の一部としてクライアントに送信されます。ローカル値は変更されません。

注記:** 通知は、このキャラクタリスティックに対するクライアントのサブスクリプションステータスに関係なく送信されます。

BLE.gatts_indicate(conn_handle, value_handle, data=None, /)

指示(indication)要求を接続中のクライアントに送信します。

dataNone であれば(デフォルト)、現在のローカル値(gatts_write で設定された値)が送信されます。

dataNone でなければ、その値が指示の一部としてクライアントに送信されます。ローカル値は変更されません。

acknowledgment (あるいはタイムアウトなどの失敗)があった場合、 _IRQ_GATTS_INDICATE_DONE イベントが発生します。

注記:** 指示は、このキャラクタリスティックに対するクライアントのサブスクリプションステータスに関係なく送信されます。

BLE.gatts_set_buffer(value_handle, len, append=False, /)

値の内部バッファサイズをバイト数で設定します。これにより、受信可能な最大の書き込みが制限されます。デフォルトは 20 です。

appendTrue に設定すると、すべてのリモート書き込みが現在の値に置き換えられるのではなく、追加されます。この方法では、最大で len バイトをバッファリングできます。 gatts_read を使用すると、読み取り後に値がクリアされます。この機能は、Nordic UART サービスのようなものを実装するときに役立ちます。

GATT クライアント

GATT クライアントは、リモートの GATT サーバ上のキャラクタリスティックを発見し、読み書きすることができます。

セントラルロールを持つデバイスが GATT クライアントとして動作するのが一般的ですが、接続したセントラルについての情報を発見するためにペリフェラルがクライアントとして動作することも可能です(デバイス情報サービスからデバイス名を読み取るなど)

BLE.gattc_discover_services(conn_handle, uuid=None, /)

サービスについて接続されたサーバーを問い合わせます。

オプションで照会するサービスの uuid を指定できます。

検出された各サービスについて _IRQ_GATTC_SERVICE_RESULT イベントが発生し、検索が完了すると _IRQ_GATTC_SERVICE_DONE になります。

BLE.gattc_discover_characteristics(conn_handle, start_handle, end_handle, uuid=None, /)

指定した範囲のキャラクタリスティックについて接続されたサーバーを問い合わせます。

オプションで照会するキャラクタリスティックの uuid を指定できます。

任意のサービスのキャラクタリスティックを検索するには start_handle=1, end_handle=0xffff とします。

検出された各キャラクタリスティックについて _IRQ_GATTC_CHARACTERISTIC_RESULT イベントが発生し、検索が完了すると _IRQ_GATTC_CHARACTERISTIC_DONE になります。

BLE.gattc_discover_descriptors(conn_handle, start_handle, end_handle, /)

指定した範囲のディスクリプタについて接続されたサーバーを問い合わせます。

検出された各ディスクリプタについて _IRQ_GATTC_DESCRIPTOR_RESULT イベントが発生し、検索が完了すると _IRQ_GATTC_DESCRIPTOR_DONE になります。

BLE.gattc_read(conn_handle, value_handle, /)

指定したキャラクタリスティックあるいはディスクリプタについて接続されたサーバーにリモート読み込みを発行します。

値は有効であれば _IRQ_GATTC_READ_RESULT イベントが発生し、加えて _IRQ_GATTC_READ_DONE が発生します。

BLE.gattc_write(conn_handle, value_handle, data, mode=0, /)

指定したキャラクタリスティックあるいはディスクリプタについて接続されたサーバーにリモート書き込みを発行します。

引数 mode は書き込み動作を指定します。現在サポートされている値は次のとおりです:

  • mode=0 (デフォルト)は応答なしの書き込みです。書き込みはリモートサーバーに送信されますが、確認は返されず、イベントは発生しません。

  • mode=1 は応答付きの書き込みです。リモートサーバーはデータを受信したという応答/承認(acknowledgement)を送信するように要求されます。

リモートサーバーから応答を受信すると _IRQ_GATTC_WRITE_DONE イベントが発生します。

BLE.gattc_exchange_mtu(conn_handle, /)

BLE.config(mtu=value) で設定した優先 MTU を使って、接続されているサーバとの MTU 交換を開始します。

MTU 交換が完了すると _IRQ_MTU_EXCHANGED イベントは発生します。

注記: MTU 交換は通常、セントラルによって開始されます。セントラルロールで BlueKitchen スタックを使う場合、リモートペリフェラルが MTU 交換を開始することはサポートしていません。NimBLE は両方のロールに対応しています。

L2CAP connection-oriented-channels

この機能により、2つの BLE デバイス間でソケットのようなデータ交換が可能になります。デバイスが GAP を介して接続されると、どちらかのデバイスは他方のデバイスが PSM (Protocol/Service Multiplexer)番号でリスン(listen)できます。

注記: これは現在、STM32 および Unix で NimBLE スタックを使用している場合にのみサポートされています(ESP32 ではサポートしていません)。一度に1つの L2CAP チャネルのみがアクティブになることがあります(つまりリスン中は接続できません)。

アクティブな L2CAP チャネルは、確立された接続ハンドルと CID (チャネル ID)によって識別されます。

接続指向のチャネルには、クレジットベースのフロー制御が組み込まれています。デバイスが共有 MTU をネゴシエートする ATT とは異なり、リスン中のデバイスと接続中のデバイスの両方がそれぞれ独立した MTU を設定し、リモートデバイスが l2cap_recvinto で完全に消費される前に送信できる未処理データの最大量を制限します。

BLE.l2cap_listen(psm, mtu, /)

指定の psmmtu に指定のローカル MTU で、L2CAP チャネル要求の着信のためのリスンを開始します。

リモートデバイスが接続を開始すると _IRQ_L2CAP_ACCEPT イベントが発生し、リスン中のサーバに着信接続を(0 以外の整数を返すことで)拒否する機会が与えられます。

接続が受け入れられると _IRQ_L2CAP_CONNECT イベントが発生し、サーバがチャネル ID (CID) とローカルおよびリモートの MTU を取得できるようになります。

注意: 現在のところリスンを停止することはできません。

BLE.l2cap_connect(conn_handle, psm, mtu, /)

mtu に設定したローカル MTU で、指定した psm 上のリスニングピアに接続します。

接続に成功すると _IRQ_L2CAP_CONNECT イベントが発生し、クライアントは CID とローカルおよびリモートの(ピア) MTU を取得できるようになります。

接続に失敗すると _IRQ_L2CAP_DISCONNECT イベントが発生し、ステータスは 0 以外になります。

BLE.l2cap_disconnect(conn_handle, cid, /)

指定した conn_handlecid を持つアクティブな L2CAP チャネルを切断します。

BLE.l2cap_send(conn_handle, cid, buf, /)

conn_handlecid で識別される L2CAP チャネル上で、指定した buf (バッファプロトコルをサポートしている必要あり)を送信します。

指定されたバッファは、リモート(ピア) MTU よりも大きく、ローカル MTU の 2倍以下のサイズにすることはできません。

これはチャネルが「ストール」している場合に False を返します。この状態では _IRQ_L2CAP_SEND_READY イベントを受信するまで(リモートデバイスがより多くのクレジットを付与したとき、通常はデータを受信して処理した後に発生します)、 l2cap_send を再度呼び出してはなりません。

BLE.l2cap_recvinto(conn_handle, cid, buf, /)

指定した conn_handle および cid から、指定した buf (bytearray や memoryview などのバッファプロトコルをサポートしている必要があり)にデータを受信します。

チャネルから読み込んだバイト数を返します。

buf が None の場合、利用可能なバイト数を返します。

注記: _IRQ_L2CAP_RECV イベントを受信した後、アプリケーションは受信バッファにバイト列がなくなるまで(通常はリモート(ピア)の MTU のサイズになるまで)、 l2cap_recvinto を呼び出し続ける必要があります。

受信バッファが空になるまで、リモートデバイスはそれ以上のチャネルクレジットを付与されず、それ以上のデータを送信できなくなります。

ペアリングとボンディング

ペアリングは、シークレット(パスキー認証によるオプションのMITM保護付き)を交換することで、暗号化した接続と認証が可能になります。

ボンディングは、これらのシークレットを不揮発性のストレージに格納するプロセスです。ボンディングされると、デバイスは、格納された ID 解決キー(IRK)に基づいて別のデバイスから解決可能なプライベートアドレス(RPA)を解決できます。ボンディングをサポートするには、アプリケーションは _IRQ_GET_SECRET イベントと _IRQ_SET_SECRET イベントを実装する必要があります。

注記: これは現在のところ、ESP32, STM32, Unix で NimBLE スタックを使う場合にのみサポートされています。

BLE.gap_pair(conn_handle, /)

リモートデバイスとのペアリングを開始します。

これを呼び出す前に io, mitm, le_secure, bond 構成オプションが(config で)設定していることを確認してください。

ペアリングに成功すると _IRQ_ENCRYPTION_UPDATE イベントが発生します。

BLE.gap_passkey(conn_handle, action, passkey, /)

指定した conn_handleaction_IRQ_PASSKEY_ACTION イベントに応答します。

passkey は数値であり、 action に依存します(どのような I/O が設定されているかに依存します)。

  • action_PASSKEY_ACTION_INPUT の場合、アプリケーションはリモートデバイスに表示されているパスキーを入力するようユーザに促します。

  • action_PASSKEY_ACTION_DISPLAY の場合、アプリケーションはランダムな6桁のパ スキーを生成してユーザーに示します。

  • action_PASSKEY_ACTION_NUMERIC_COMPARISON の場合、アプリケーションは _IRQ_PASSKEY_ACTION イベントで提供されたパスキーを表示し、 0 (ペアリングのキャンセル)または 1 (ペアリングの受け入れ)のいずれかで応答すべきです。

クラス UUID

コンストラクタ

class bluetooth.UUID(value, /)

指定した value で UUID インスタンスを作成します。

value は次のいずれかです:

  • 16 ビット整数。たとえば 0x2908

  • 128 ビット UUID 文字列。たとえば '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'