Service UUID è un identificatore univoco a 16 o 128 bit del Bluetooth Low Energy (BLE) che definisce inequivocabilmente un servizio funzionale su un dispositivo. Bluetooth SIG ha allocato UUID standard a 16 bit per i servizi comuni come Battery Service (0x180F), Device Information (0x180A) e Heart Rate (0x180D), semplificando la compatibilità multipiattaforma. Secondo la Bluetooth Core Specification 5.4 (2023), i servizi personalizzati di sviluppatori terzi devono utilizzare UUID a 128 bit, il cui formato garantisce l'univocità globale senza un registro centrale. La corretta dichiarazione del Service UUID è il primo passo per il corretto funzionamento del server GATT su un dispositivo periferico.
Punti chiave
Service UUID è un identificatore assegnato a un servizio GATT Bluetooth Low Energy per il suo riconoscimento inequivocabile da parte di altri dispositivi. Nell'architettura BLE, ogni servizio rappresenta un gruppo logico di caratteristiche unite da una funzione comune. Ad esempio, Battery Service contiene la caratteristica Battery Level, che trasmette il livello di carica attuale della batteria.
Bluetooth SIG (Special Interest Group) gestisce il registro degli UUID a 16 bit standard assegnati ai servizi più comuni. Ciò consente a dispositivi di diversi produttori di riconoscere i servizi reciproci senza configurazione preliminare. Un tracker fitness di qualsiasi marca può dichiarare un Heart Rate Service con UUID 0x180D, e qualsiasi smartphone capirà che si tratta di un servizio di frequenza cardiaca.
Secondo la Bluetooth Core Specification 5.4 (2023), l'intervallo degli UUID a 16 bit (0x0000–0xFFFF) è diviso in due parti: da 0x0001 a 0xFFFE sono servizi standard Bluetooth SIG, e 0xFFFF è riservato. Se uno sviluppatore ha bisogno di un servizio unico che non è nel registro SIG, utilizza un UUID a 128 bit.
La differenza tra UUID standard e personalizzati non è solo nella lunghezza: gli UUID a 16 bit risparmiano tempo di trasmissione nel pacchetto pubblicitario, poiché vengono trasmessi come 2 byte invece di 16 byte. Per i dispositivi con rigorose limitazioni sulla dimensione del pacchetto pubblicitario (fino a 31 byte), questo è critico.
Gli UUID standard a 16 bit coprono le principali categorie di dispositivi BLE: sensori medici, tracker fitness, elettronica indossabile e accessori. Se un dispositivo implementa una funzione standard, si raccomanda allo sviluppatore di utilizzare l'UUID corrispondente dal registro Bluetooth SIG per la massima compatibilità.
Ecco alcuni esempi di UUID di servizio standard:
| UUID (hex) | Nome del servizio | Scopo |
|---|---|---|
| 0x1800 | Generic Access | Controllo accessi, nome del dispositivo, aspetto |
| 0x180A | Device Information | Produttore, modello, numero di serie, versione firmware |
| 0x180D | Heart Rate | Misurazione del polso, posizione del sensore, energia batteria |
| 0x180F | Battery Service | Livello di carica della batteria in percentuale |
| 0x181A | Environmental Sensing | Temperatura, umidità, pressione, illuminamento |
| 0x181C | User Data | Età, peso, altezza, sesso, polso a riposo |
Gli UUID personalizzati a 128 bit sono necessari quando un dispositivo fornisce funzionalità uniche. Ad esempio, un produttore di serrature intelligenti crea il proprio servizio Lock Control con un UUID nel formato XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. Tale UUID non entrerà in conflitto con altri servizi, poiché lo spazio dei valori a 128 bit è praticamente inesauribile.
Un UUID a 128 bit viene scritto nel formato standard UUID RFC 4122: otto caratteri esadecimali, trattino, quattro, trattino, quattro, trattino, quattro, trattino, dodici caratteri. Per BLE viene utilizzata una versione in cui la parte base dell'UUID Bluetooth SIG ha bit fissi.
Bluetooth SIG definisce l'UUID base: 0000XXXX-0000-1000-8000-00805F9B34FB. Per i servizi standard a 16 bit, il valore UUID viene sostituito in questa maschera: ad esempio, 0x180F diventa 0000180F-0000-1000-8000-00805F9B34FB. I servizi personalizzati utilizzano un UUID completamente indipendente generato dallo sviluppatore.
Quando si crea un UUID personalizzato, è possibile utilizzare qualsiasi generatore di UUID (UUID v4). Un UUID v4 casuale fornisce 122 bit di entropia, rendendo le collisioni praticamente impossibili. Non utilizzare una versione modificata dell'UUID base Bluetooth SIG per servizi personalizzati — ciò viola la specifica.
La dichiarazione di un servizio con un UUID viene eseguita sul lato Peripheral durante la creazione di un server GATT. In iOS viene utilizzato Core Bluetooth, in Android android.bluetooth.le. Esaminiamo entrambi gli approcci.
In Swift, un servizio viene creato tramite CBMutableService specificando l'UUID, dopodiché vengono aggiunte le caratteristiche tramite 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)
Su Android, il servizio viene registrato tramite BluetoothGattServer e BluetoothGattService. L'UUID viene passato come stringa tramite 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);
La scansione per Service UUID consente al Central di trovare dispositivi che forniscono il servizio necessario senza connettersi a tutti i Peripheral scoperti. Un pacchetto pubblicitario BLE può contenere un elenco di UUID dei servizi, consentendo al Central di filtrare i dispositivi nella fase di scansione.
In iOS, CBCentralManager scansiona i dispositivi con un filtro per UUID del servizio. Ciò riduce il consumo energetico e accelera la scoperta dei dispositivi necessari.
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
}
Su Android, il filtraggio per UUID è supportato anche tramite ScanFilter.Builder. Questo è un modo efficiente per restringere la ricerca senza connettersi a ogni dispositivo.
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
);
Un singolo dispositivo BLE può dichiarare più servizi simultaneamente. Ad esempio, un braccialetto fitness può contenere Battery Service (0x180F), Heart Rate Service (0x180D) e un servizio personalizzato per sincronizzare i dati con il cloud. Ogni servizio ha il proprio UUID e il proprio insieme di caratteristiche.
Con più servizi, è importante considerare la limitazione del pacchetto pubblicitario. Un pacchetto pubblicitario BLE può contenere fino a 31 byte di dati. Se gli UUID dei servizi occupano troppo spazio, alcuni potrebbero non entrare nel pacchetto pubblicitario. In questo caso, viene utilizzata la scan response — un secondo pacchetto inviato su richiesta del Central.
Secondo la Bluetooth Core Specification 5.4 (2023), il numero massimo di servizi primari su un singolo server GATT non è limitato dalla specifica, ma in pratica è limitato dalla memoria del dispositivo e dai requisiti di prestazione. Per i dispositivi embedded con 256 KB di memoria flash, si raccomandano non più di 5–10 servizi.
Domande frequenti
Gli UUID a 16 bit sono riservati da Bluetooth SIG per i servizi standard e occupano 2 byte nel pacchetto pubblicitario. Gli UUID a 128 bit vengono utilizzati per i servizi personalizzati e occupano 16 byte. La scelta dipende dal tipo di servizio: la funzionalità standard utilizza un UUID a 16 bit, la funzionalità unica utilizza un UUID a 128 bit.
Utilizza UUID v4 — un UUID casuale generato da strumenti online, dal comando terminale uuidgen o dall'API del tuo linguaggio di programmazione. Esempio: UUID.fromString(UUID.randomUUID().toString()) in Java o UUID() in Swift.
No, la registrazione non è richiesta. Bluetooth SIG registra solo UUID a 16 bit. Gli UUID personalizzati a 128 bit vengono generati indipendentemente dallo sviluppatore e garantiscono l'univocità grazie al vasto spazio di indirizzi (2^128 combinazioni).
Sì, un servizio GATT standard può contenere un numero illimitato di caratteristiche. Ad esempio, Battery Service può contenere Battery Level (0x2A19) e Battery Power State (0x2A1A). Ogni caratteristica ha il proprio UUID e il proprio insieme di proprietà.
Se gli UUID coincidono, il Central non può distinguere un servizio da un altro senza informazioni aggiuntive. La probabilità di collisione di UUID v4 casuali è trascurabile — circa 5,3 × 10^−37. Utilizza un generatore di UUID casuali, non copiare UUID dagli esempi.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche