Bluetooth通信(RFCOMM)についてのメモ書き

Bluetoothを使いたい

今作っているアプリの通信をWIFIを使ったものからBluetoothを使ったものにしたいと思い、その際に調べたことのメモ。正しいかは分からない。

事前準備

通信する2台の端末のペアリングを済ませて置く

接続

2台の端末間で接続を確立するには、サーバー側とクライアント側の仕組みを実装する必要がある

Android

以下のドキュメントを参考にした。

developer.android.com

ざっくりと説明すると

サーバー側ではサービス名とUUIDを登録して待ち受ける処理を行う。

クライアント側では接続先端末に対してサーバー側で指定したUUIDを指定して接続処理を行う。

という感じ。

Windows

以下のドキュメントを参考にした

docs.microsoft.com

github.com

Androidではサービス名とUUIDのみでSDP(service discovery protocol)部分を意識せずにサーバー側で待ち受けることができた。しかしWindowsではSDP部分を自分で触る必要がある。

UUID

www.bluetooth.com

ここに予約済みUUIDが分かる資料がある

16-bit UUIDsのAllocation type が「Service Classes and Profiles」のものがここで扱うUUIDのものっぽい。 上記値は省略されていて以下のように

0000XXXX-0000-1000-8000-00805F9B34FB

上記のXXXXの部分に当てはめるとよい

monomonotech.jp

SDPについて

どんなサービスを提供するかの情報を表すデータ

データの形式が決まっており、サンプルのコードでは当然のように作成されていたのでこの部分についてメモを残す。

データについて

データ先頭ではデータ型を示す。

具体的には先頭5ビットを型、末尾3ビットを続くデータ長に関する情報が入る。

以下はサービス名をSDP情報として文字列で提供したい時の情報となる。

// 0x25
const byte SdpServiceNameAttributeType = (4 << 3) | 5;

ざっくり説明すると

文字列型を指す値としての4(0000 0100)の型を示したい場合、先頭5bitを型として扱うため3ビット左シフトする(0010 0000)。

次に文字列型の場合データ長は文字列長を示すがこの場合の数値も決まっており、8ビットの場合は5(0000 0101)となる。

上記の型とデータ長を論理和することで(0010 0101)となり8ビットの文字列データであることを表す値は0x25となる。

型やデータ長の値に関してはBLUETOOTH SPECIFICATION Version 2.1 + EDR [vol 3]のpage125 of 268の3 DATA REPRESENTATIONなどを読むとわかる。

データ型、データ長の次は実際のデータとなりますが特に変わったことはないので省略。

IDについて

SDPを追加する際に必要となるID、これはどうもPDU ID(PROTOCOL DATA UNIT ID)というものらしい?

ざっくりな理解だと、SDPの立ち振る舞いみたいな認識?

0x07までは決まっていてそこから0xFFまでが予約されているのでなにか任意のサービスときはそこに入れたらよい?