Service UUID — це унікальний 16- або 128-бітний ідентифікатор Bluetooth Low Energy (BLE), який однозначно визначає функціональний сервіс на пристрої. Bluetooth SIG виділив стандартні 16-бітні UUID для поширених сервісів, таких як Battery Service (0x180F), Device Information (0x180A) та Heart Rate (0x180D), що спрощує крос-платформну сумісність. Згідно з Bluetooth Core Specification 5.4 (2023), кастомні сервіси сторонніх розробників зобов'язані використовувати 128-бітні UUID, формат яких гарантує глобальну унікальність без центрального реєстру. Правильне оголошення Service UUID — перший крок до коректної роботи GATT-сервера на периферійному пристрої.
Головне
Service UUID — це ідентифікатор, який призначається GATT-сервісу Bluetooth Low Energy для його однозначного розпізнавання іншими пристроями. В архітектурі BLE кожен сервіс являє собою логічну групу характеристик, об'єднаних спільною функцією. Наприклад, сервіс Battery Service містить характеристику Battery Level, яка передає поточний заряд батареї.
Bluetooth SIG (Special Interest Group) керує реєстром стандартних 16-бітних UUID, які призначаються найпоширенішим сервісам. Це дозволяє пристроям різних виробників розпізнавати сервіси один одного без попереднього налаштування. Фітнес-трекер будь-якого бренду може оголосити Heart Rate Service з UUID 0x180D, і будь-який смартфон зрозуміє, що це сервіс пульсу.
Згідно з Bluetooth Core Specification 5.4 (2023), діапазон 16-бітних UUID (0x0000–0xFFFF) розділено на дві частини: від 0x0001 до 0xFFFE — стандартні сервіси Bluetooth SIG, а 0xFFFF зарезервовано. Якщо розробнику потрібен унікальний сервіс, якого немає в реєстрі SIG, він використовує 128-бітний UUID.
Різниця між стандартним і кастомним UUID не лише в довжині: 16-бітні UUID економлять ефірний час рекламного пакета, оскільки передаються як 2 байти замість 16 байт. Для пристроїв з жорсткими обмеженнями за розміром advertising-пакета (до 31 байта) це критично.
Стандартні 16-бітні UUID покривають основні категорії BLE-пристроїв: медичні датчики, фітнес-трекери, носимий електроніку та аксесуари. Якщо пристрій реалізує стандартну функцію — розробнику рекомендується використовувати відповідний UUID з реєстру Bluetooth SIG для максимальної сумісності.
Ось кілька прикладів стандартних сервісних UUID:
| UUID (hex) | Ім'я сервісу | Призначення |
|---|---|---|
| 0x1800 | Generic Access | Управління доступом, ім'я пристрою, зовнішній вигляд |
| 0x180A | Device Information | Виробник, модель, серійний номер, версія ПЗ |
| 0x180D | Heart Rate | Вимірювання пульсу, локація сенсора, енергія батареї |
| 0x180F | Battery Service | Рівень заряду батареї у відсотках |
| 0x181A | Environmental Sensing | Температура, вологість, тиск, освітленість |
| 0x181C | User Data | Вік, вага, зріст, стать, пульс у спокої |
Кастомні 128-бітні UUID необхідні, коли пристрій надає унікальну функціональність. Наприклад, виробник розумного замка створює власний сервіс Lock Control з UUID виду XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. Такий UUID гарантовано не конфліктуватиме з іншими сервісами, оскільки простір 128-бітних значень практично невичерпний.
128-бітний UUID записується в стандартному форматі UUID RFC 4122: вісім шістнадцяткових символів, дефіс, чотири, дефіс, чотири, дефіс, чотири, дефіс, дванадцять символів. Для BLE використовується версія, де базова частина UUID Bluetooth SIG має фіксовані біти.
Bluetooth SIG визначає базовий UUID: 0000XXXX-0000-1000-8000-00805F9B34FB. Для стандартних 16-бітних сервісів у цю маску підставляється значення UUID: наприклад, 0x180F перетворюється на 0000180F-0000-1000-8000-00805F9B34FB. Кастомні сервіси використовують повністю незалежний UUID, згенерований розробником.
При створенні кастомного UUID можна використовувати будь-який генератор UUID (UUID v4). Випадковий UUID v4 забезпечує 122 біти ентропії, що робить колізії практично неможливими. Не використовуйте модифіковану версію базового UUID Bluetooth SIG для кастомних сервісів — це порушує специфікацію.
Оголошення сервісу з UUID виконується на стороні Peripheral при створенні GATT-сервера. У iOS для цього використовується Core Bluetooth, в Android — android.bluetooth.le. Розглянемо обидва підходи.
У Swift сервіс створюється через CBMutableService із зазначенням UUID, після чого до нього додаються характеристики через 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 advertising-пакет може містити список 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 фільтрація за UUID також підтримується через ScanFilter.Builder. Це ефективний спосіб звузити коло пошуку без підключення до кожного пристрою.
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
);
Один BLE-пристрій може оголошувати кілька сервісів одночасно. Наприклад, фітнес-браслет може містити Battery Service (0x180F), Heart Rate Service (0x180D) і кастомний сервіс для синхронізації даних з хмарою. Кожен сервіс має власний UUID і власний набір характеристик.
При множинних сервісах важливо враховувати обмеження рекламного пакета. Advertising-пакет BLE може містити до 31 байта даних. Якщо UUID сервісів займають занадто багато місця, деякі з них можуть не поміститися в рекламний пакет. У цьому випадку використовується scan response — другий пакет, який надсилається за запитом Central.
Згідно з Bluetooth Core Specification 5.4 (2023), максимальна кількість первинних сервісів на одному GATT-сервері не обмежена специфікацією, але на практиці обмежена пам'яттю пристрою та вимогами до продуктивності. Для вбудованих пристроїв з 256 КБ флеш-пам'яті рекомендується не більше 5–10 сервісів.
Поширені запитання
16-бітні UUID зарезервовані Bluetooth SIG для стандартних сервісів і займають 2 байти в рекламному пакеті. 128-бітні UUID використовуються для кастомних сервісів і займають 16 байт. Вибір залежить від типу сервісу: стандартна функціональність використовує 16-бітний UUID, унікальна — 128-бітний.
Використовуйте UUID v4 — випадковий UUID, який генерується онлайн-інструментами, термінальною командою uuidgen або API вашої мови програмування. Приклад: UUID.fromString(UUID.randomUUID().toString()) в Java або UUID() у Swift.
Ні, реєстрація не потрібна. 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 створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.