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
// Стандартен 16-битов UUID
let batteryServiceUUID = CBUUID("180F")
// Персонализиран 128-битов UUID
let customServiceUUID = CBUUID("E20A39F4-73F5-4BC4-A12F-17D1AD07A961")
let service = CBMutableService(
type: customServiceUUID,
primary: true
)
// Добавяне на характеристики
service.characteristics = [characteristic]
// Публикуване на услуга чрез peripheralManager
peripheralManager.add(service)
На Android услугата се регистрира чрез BluetoothGattServer и BluetoothGattService. UUID се предава като низ в java.util.UUID.fromString.
import android.bluetooth.*;
// Персонализиран 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
);
// Добавяне на характеристики
service.addCharacteristic(characteristic);
// Регистриране на GATT сървър
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
)
}
// Делегатът получава само устройства Heart Rate Service
func centralManager(
_ central: CBCentralManager,
didDiscover peripheral: CBPeripheral,
advertisementData: [String: Any],
rssi RSSI: NSNumber
) {
// peripheral има само устройства с 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 и собствен набор от характеристики.
При множество услуги е важно да се вземе предвид ограничението на рекламния пакет. BLE рекламният пакет може да съдържа до 31 байта данни. Ако UUID на услугите заемат твърде много място, някои от тях може да не се поберат в рекламния пакет. В този случай се използва scan response — вторият пакет, който се изпраща по заявка на Central.
Според Bluetooth Core Specification 5.4 (2023) максималният брой първични услуги на един GATT сървър не е ограничен от спецификацията, но на практика е ограничен от паметта на устройството и изискванията за производителност. За вградени устройства с 256 KB флаш памет се препоръчват не повече от 5–10 услуги.
Често задавани въпроси
16-битовите UUID са резервирани от Bluetooth SIG за стандартни услуги и заемат 2 байта в рекламния пакет. 128-битовите UUID се използват за персонализирани услуги и заемат 16 байта. Изборът зависи от типа услуга: стандартната функционалност използва 16-битов UUID, уникалната — 128-битов UUID.
Използвайте 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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също