Service UUIDは、Bluetooth Low Energy(BLE)の一意の16ビットまたは128ビットの識別子であり、デバイス上の機能サービスを明確に定義します。Bluetooth SIGは、Battery Service(0x180F)、Device Information(0x180A)、Heart Rate(0x180D)などの一般的なサービスに標準の16ビットUUIDを割り当てており、クロスプラットフォームの互換性を簡素化しています。Bluetooth Core Specification 5.4(2023)によると、サードパーティ開発者のカスタムサービスは128ビットUUIDを使用する必要があり、その形式は中央レジストリなしでグローバルな一意性を保証します。Service UUIDの正しい宣言は、周辺デバイス上のGATTサーバーの正しい動作への第一歩です。
重要なポイント
Service UUIDは、Bluetooth Low Energy GATTサービスに割り当てられる識別子で、他のデバイスによる明確な認識を可能にします。BLEアーキテクチャでは、各サービスは共通の機能によって結びつけられた特性の論理的なグループを表します。例えば、Battery ServiceにはBattery Level特性が含まれ、現在のバッテリー残量を送信します。
Bluetooth SIG(Special Interest Group)は、最も一般的なサービスに割り当てられた標準の16ビットUUIDのレジストリを管理しています。これにより、異なるメーカーのデバイスが事前設定なしでお互いのサービスを認識できます。どのブランドのフィットネストラッカーでもUUID 0x180DでHeart Rate Serviceを宣言でき、どんなスマートフォンでもそれが心拍数サービスであると理解できます。
Bluetooth Core Specification 5.4(2023)によると、16ビットUUIDの範囲(0x0000–0xFFFF)は2つの部分に分かれています:0x0001から0xFFFEはBluetooth SIGの標準サービスで、0xFFFFは予約されています。開発者がSIGレジストリにない一意のサービスを必要とする場合、128ビットUUIDを使用します。
標準UUIDとカスタムUUIDの違いは長さだけではありません。16ビットUUIDはアドバタイズメントパケットのエアタイムを節約します。16バイトではなく2バイトとして送信されるためです。アドバタイズメントパケットサイズに厳しい制限(最大31バイト)があるデバイスにとって、これは重要です。
標準の16ビットUUIDは、BLEデバイスの主要カテゴリ(医療用センサー、フィットネストラッカー、ウェアラブル電子機器、アクセサリ)をカバーしています。デバイスが標準機能を実装する場合、開発者は最大の互換性を得るためにBluetooth SIGレジストリの対応するUUIDを使用することを推奨します。
標準サービスのUUIDの例をいくつか示します:
| UUID(hex) | サービス名 | 目的 |
|---|---|---|
| 0x1800 | Generic Access | アクセス制御、デバイス名、外観 |
| 0x180A | Device Information | メーカー、モデル、シリアル番号、ファームウェアバージョン |
| 0x180D | Heart Rate | 心拍数測定、センサー位置、バッテリー電力 |
| 0x180F | Battery Service | バッテリー充電レベル(パーセント) |
| 0x181A | Environmental Sensing | 温度、湿度、気圧、照度 |
| 0x181C | User Data | 年齢、体重、身長、性別、安静時心拍数 |
カスタムの128ビットUUIDは、デバイスが一意の機能を提供する場合に必要です。例えば、スマートロックメーカーはXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX形式のUUIDを持つ独自のLock Controlサービスを作成します。このようなUUIDは他のサービスと競合しないことが保証されています。128ビットの値空間は実質的に無限だからです。
128ビットUUIDは、標準のUUID RFC 4122形式で記述されます:8つの16進文字、ハイフン、4つ、ハイフン、4つ、ハイフン、4つ、ハイフン、12文字。BLEでは、Bluetooth SIG UUIDのベース部分に固定ビットを持つバージョンが使用されます。
Bluetooth SIGはベースUUIDを定義しています:0000XXXX-0000-1000-8000-00805F9B34FB。標準の16ビットサービスの場合、UUID値がこのマスクに代入されます。例えば、0x180Fは0000180F-0000-1000-8000-00805F9B34FBになります。カスタムサービスは、開発者が生成した完全に独立したUUIDを使用します。
カスタムUUIDを作成する際は、任意のUUIDジェネレーター(UUID v4)を使用できます。ランダムなUUID v4は122ビットのエントロピーを提供し、衝突を実質的に不可能にします。カスタムサービスにベースBluetooth SIG UUIDの修正版を使用しないでください — 仕様に違反します。
UUIDを使用したサービスの宣言は、GATTサーバー作成時にPeripheral側で行われます。iOSではCore Bluetooth、Androidではandroid.bluetooth.leが使用されます。両方のアプローチを見てみましょう。
Swiftでは、UUIDを指定してCBMutableServiceを介してサービスを作成し、その後CBMutableCharacteristicを介して特性を追加します。
import CoreBluetooth
// Standard 16-bit UUID
let batteryServiceUUID = CBUUID("180F")
// Custom 128-bit UUID
let customServiceUUID = CBUUID("E20A39F4-73F5-4BC4-A12F-17D1AD07A961")
let service = CBMutableService(
type: customServiceUUID,
primary: true
)
// Add characteristics
service.characteristics = [characteristic]
// Publish service via peripheralManager
peripheralManager.add(service)
Androidでは、サービスはBluetoothGattServerとBluetoothGattServiceを介して登録されます。UUIDはjava.util.UUID.fromStringを介して文字列として渡されます。
import android.bluetooth.*;
// Custom service UUID
private static final UUID CUSTOM_SERVICE_UUID =
UUID.fromString("E20A39F4-73F5-4BC4-A12F-17D1AD07A961");
BluetoothGattService service = new BluetoothGattService(
CUSTOM_SERVICE_UUID,
BluetoothGattService.SERVICE_TYPE_PRIMARY
);
// Add characteristics
service.addCharacteristic(characteristic);
// Register on GATT server
gattServer.addService(service);
Service UUIDによるスキャンを使用すると、Centralは発見されたすべてのPeripheralに接続することなく、必要なサービスを提供するデバイスを見つけることができます。BLEアドバタイズメントパケットにはサービスのUUIDのリストを含めることができ、Centralはスキャン段階でデバイスをフィルタリングできます。
iOSでは、CBCentralManagerがサービスのUUIDでフィルタリングしてデバイスをスキャンします。これにより消費電力が削減され、必要なデバイスの発見が高速化されます。
import CoreBluetooth
let centralManager = CBCentralManager()
func scanForHeartRateMonitor() {
let services: [CBUUID] = [
CBUUID("180D") // Heart Rate Service
]
centralManager.scanForPeripherals(
withServices: services,
options: nil
)
}
// Delegate receives only Heart Rate Service devices
func centralManager(
_ central: CBCentralManager,
didDiscover peripheral: CBPeripheral,
advertisementData: [String: Any],
rssi RSSI: NSNumber
) {
// peripheral has only devices with UUID 0x180D
}
Androidでは、ScanFilter.Builderを介してUUIDによるフィルタリングもサポートされています。これは各デバイスに接続せずに検索範囲を絞り込む効率的な方法です。
import android.bluetooth.le.*;
ScanFilter filter = new ScanFilter.Builder()
.setServiceUuid(
new ParcelUuid(
UUID.fromString("0000180D-0000-1000-8000-00805F9B34FB")
)
)
.build();
BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner();
scanner.startScan(
Collections.singletonList(filter),
scanSettings,
scanCallback
);
1台のBLEデバイスは、複数のサービスを同時に宣言できます。例えば、フィットネスブレスレットにはBattery Service(0x180F)、Heart Rate Service(0x180D)、およびクラウドとのデータ同期用のカスタムサービスを含めることができます。各サービスには独自のUUIDと独自の特性セットがあります。
複数のサービスがある場合、アドバタイズメントパケットの制限を考慮することが重要です。BLEアドバタイズメントパケットには最大31バイトのデータを含めることができます。サービスのUUIDがスペースを取りすぎると、一部がアドバタイズメントパケットに収まらない可能性があります。この場合、スキャンレスポンスが使用されます — Centralの要求に応じて送信される2番目のパケットです。
Bluetooth Core Specification 5.4(2023)によると、1つのGATTサーバー上のプライマリサービスの最大数は仕様で制限されていませんが、実際にはデバイスのメモリとパフォーマンス要件によって制限されます。256 KBのフラッシュメモリを搭載した組込みデバイスの場合、5〜10個以下のサービスが推奨されます。
よくある質問
16ビットUUIDはBluetooth SIGによって標準サービス用に予約されており、アドバタイズメントパケットで2バイトを占有します。128ビットUUIDはカスタムサービスに使用され、16バイトを占有します。選択はサービスの種類によって異なります:標準機能は16ビットUUIDを使用し、一意の機能は128ビットUUIDを使用します。
UUID v4を使用してください — オンラインツール、ターミナルコマンドuuidgen、またはプログラミング言語のAPIによって生成されるランダムなUUIDです。例:JavaのUUID.fromString(UUID.randomUUID().toString())またはSwiftのUUID()。
いいえ、登録は必要ありません。Bluetooth SIGは16ビットUUIDのみを登録します。カスタム128ビットUUIDは開発者が独立して生成し、広大なアドレス空間(2^128の組み合わせ)によって一意性を保証します。
はい、標準のGATTサービスには無制限の数の特性を含めることができます。例えば、Battery ServiceにはBattery Level(0x2A19)とBattery Power State(0x2A1A)を含めることができます。各特性には独自のUUIDとプロパティのセットがあります。
UUIDが一致した場合、Centralは追加情報なしではサービスを区別できません。ランダムなUUID v4の衝突確率はごくわずかで、約5.3 × 10^−37です。ランダムUUIDジェネレーターを使用し、例からUUIDをコピーしないでください。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。