Characteristic este unitatea fundamentală de date în Bluetooth Low Energy, prin care Central primește sau scrie informații pe dispozitivul periferic. Fiecare Characteristic aparține unui serviciu GATT specific, are un UUID unic și un set de proprietăți (read, write, notify, indicate) care definesc operațiile posibile. Conform Bluetooth Core Specification 5.4 (2023), Bluetooth SIG a specificat peste 500 de caracteristici standard pentru dispozitive medicale, de fitness și industriale. Dezvoltatorul creează caracteristici personalizate pentru transmiterea oricăror date utilizator — de la citiri ale senzorilor până la comenzi de control al dispozitivului.
Principalele puncte
Characteristic este un atribut al protocolului GATT care conține o valoare (value) și metadate. În arhitectura BLE, datele nu sunt transmise direct între dispozitive, ci prin citirea și scrierea valorilor caracteristicilor serviciului. Dacă serviciul este un folder, atunci Characteristic este un fișier în acel folder.
Fiecare Characteristic constă din trei componente: declarație (declaration), valoare (value) și descriptori (descriptors). Declarația conține UUID-ul caracteristicii și proprietățile sale. Valoarea reprezintă datele propriu-zise transmise între Central și Peripheral. Descriptorii oferă configurație suplimentară.
Conform Bluetooth Core Specification 5.4 (2023), toate schimburile de date în BLE au loc prin operații asupra caracteristicilor. Chiar și profilurile standard, cum ar fi Heart Rate Profile sau Battery Service, sunt construite pe un set de caracteristici cu UUID-uri predefinite. Aceasta asigură compatibilitatea dispozitivelor de la diferiți producători fără configurare prealabilă.
Este important ca dezvoltatorul să înțeleagă: fiecare Characteristic poate suporta diferite combinații de proprietăți. O caracteristică poate fi doar pentru citire, alta — pentru scriere, a treia — pentru notificări. Alegerea corectă a proprietăților determină scenariul de utilizare și consumul de energie al dispozitivului.
Proprietățile (properties) caracteristicii definesc ce operații sunt permise asupra acesteia. Este o mască de octeți, unde fiecare bit activează sau dezactivează o anumită operație. Mai jos sunt enumerate proprietățile principale.
| Proprietate | Bit | Descriere | Utilizare tipică |
|---|---|---|---|
| Read | 0x02 | Central poate citi valoarea curentă | Stare, nivel baterie, configurare |
| Write | 0x08 | Central poate scrie o valoare nouă | Comenzi de control, setări |
| Notify | 0x10 | Peripheral trimite valoarea fără confirmare | Date în flux (puls, temperatură) |
| Indicate | 0x20 | Peripheral trimite valoarea cu confirmare | Date critice (alarme, stări) |
| Write Without Response | 0x04 | Scriere fără așteptarea confirmării de la server | Transmitere de comenzi de mare viteză |
Permisiunile (permissions) reprezintă nivelul de acces la nivelul serverului GATT. Spre deosebire de proprietăți, care sunt declarate în declarația caracteristicii, permisiunile sunt verificate la fiecare operație. Acestea pot include cerințe de criptare și autentificare.
Bluetooth SIG a specificat peste 500 de caracteristici standard care acoperă majoritatea scenariilor comune de utilizare BLE. Utilizarea UUID-urilor standard garantează că orice dispozitiv receptor va interpreta corect datele fără configurare prealabilă.
Iată cele mai frecvent utilizate caracteristici standard:
| UUID | Nume | Tip de date | Serviciu |
|---|---|---|---|
| 0x2A19 | Battery Level | uint8 (0–100%) | Battery Service |
| 0x2A37 | Heart Rate Measurement | uint8 + flags | Heart Rate |
| 0x2A6E | Temperature | int16 (0.01°C) | Environmental Sensing |
| 0x2A6F | Humidity | uint16 (0.01%) | Environmental Sensing |
| 0x2A00 | Device Name | UTF-8 string | Generic Access |
| 0x2A01 | Appearance | uint16 | Generic Access |
Dacă o caracteristică standard existentă acoperă sarcina dumneavoastră — utilizați-o. Aceasta simplifică certificarea Bluetooth și crește compatibilitatea cu ecosistemul. Creați caracteristici personalizate doar pentru date unice care nu există în registrul SIG.
Crearea caracteristicii se realizează pe partea de Peripheral — dispozitivul care furnizează datele. Să analizăm implementarea pe iOS (Swift) și Android (Java).
Core Bluetooth oferă clasa CBMutableCharacteristic pentru crearea unei caracteristici cu specificarea UUID-ului, proprietăților și valorii inițiale.
import CoreBluetooth
let characteristicUUID = CBUUID("2A19") // Caracteristica nivelului bateriei
let characteristic = CBMutableCharacteristic(
type: characteristicUUID,
properties: [.read, .notify],
value: nil,
permissions: [.readable]
)
// Actualizați valoarea la modificare
let batteryData = Data([batteryLevel]) // uint8
peripheralManager.updateValue(
batteryData,
for: characteristic,
onSubscribedCentrals: nil
)
Pe Android, caracteristica se creează prin BluetoothGattCharacteristic cu specificarea UUID-ului, proprietăților și permisiunilor.
import android.bluetooth.*;
UUID charUuid = UUID.fromString("00002A19-0000-1000-8000-00805F9B34FB");
BluetoothGattCharacteristic characteristic =
new BluetoothGattCharacteristic(
charUuid,
BluetoothGattCharacteristic.PROPERTY_READ
| BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_READ
);
// Setați valoarea
characteristic.setValue(batteryLevel, BluetoothGattCharacteristic.FORMAT_UINT8, 0);
gattServer.notifyCharacteristicChanged(device, characteristic, false);
Operațiile asupra Characteristic se împart în trei tipuri: citire (read), scriere (write) și notificări (notify/indicate). Alegerea operației depinde de scenariu: datele la cerere se citesc, comenzile se scriu, datele în flux se abonează prin notificări.
Read — Central trimite o cerere de citire a valorii caracteristicii. Peripheral răspunde cu valoarea curentă. Operația este sincronă și necesită o cerere explicită din ambele părți. Este utilizată pentru date care se schimbă rar: versiunea firmware-ului, numărul de serie, setări.
Write — Central trimite date către Peripheral. Există două moduri: Write with Response (confirmare de la Peripheral) și Write Without Response (fără confirmare). Write with Response garantează livrarea — Peripheral trimite o confirmare după scriere. Write Without Response este mai rapid, dar nu garantează livrarea.
Notify și Indicate — Peripheral inițiază trimiterea datelor către Central. La Notify, datele sunt trimise fără confirmare — dacă Central nu a reușit să primească pachetul, acesta se pierde. La Indicate, Central trimite o confirmare (la nivel PDU), ceea ce garantează livrarea. Indicate este mai lent, dar mai fiabil. Pentru abonarea la notificări, Central scrie valoarea 0x0001 în CCCD (Client Characteristic Configuration Descriptor).
MTU (Maximum Transmission Unit) definește dimensiunea maximă a unui singur pachet de date BLE. În mod implicit, MTU este de 23 de octeți, dintre care 3 octeți sunt ocupați de antet — sarcura utilă (ATT payload) este de 20 de octeți. Acest lucru este suficient pentru majoritatea datelor senzorilor, dar insuficient pentru transmiterea de fișiere sau configurații mari.
Bluetooth Core Specification 5.4 acceptă negocierea MTU (MTU negotiation) — Central și Peripheral pot conveni asupra unei dimensiuni mai mari a pachetului de până la 517 octeți. Procesul arată astfel: Central trimite o cerere MTU Exchange cu propunerea propriului MTU; Peripheral răspunde cu propriul MTU; se utilizează valoarea minimă dintre cele două.
// iOS solicită MTU la conectare
// MTU maxim în iOS este de 185 de octeți
func peripheral(
_ peripheral: CBPeripheral,
didDiscoverServices error: Error?
) {
// Solicitați MTU pentru un periferic specific
peripheral.maximumWriteValueLength(for: .withResponse)
}
Conform Bluetooth SIG (2023), creșterea MTU de la 23 la 185 de octeți reduce costurile de transmisie a datelor cu până la 80% datorită reducerii numărului de pachete. Pentru aplicațiile care transmit citiri cu frecvență înaltă (de exemplu, EKG sau accelerometru), creșterea MTU este critică pentru stabilitatea fluxului.
Întrebări frecvente
Specificația BLE nu limitează numărul de caracteristici dintr-un serviciu. În practică, limitarea este determinată de memoria disponibilă a serverului GATT și de cerințele de performanță. Pentru dispozitivele încorporate, se recomandă nu mai mult de 10–15 caracteristici per serviciu.
Notify trimite date fără confirmare — pachetul poate fi pierdut fără notificarea expeditorului. Indicate necesită confirmare (ACK) la nivel de protocol, ceea ce garantează livrarea. Indicate este mai lent, dar mai fiabil. Pentru date critice (alarme, comenzi) utilizați Indicate.
Da, o caracteristică poate avea o combinație de proprietăți. De exemplu, o caracteristică de setări poate suporta Read (citirea valorii curente) și Write (modificarea setării). Combinați proprietățile în conformitate cu scenariul dumneavoastră de utilizare.
Utilizați negocierea MTU pentru a crește dimensiunea pachetului la 185–517 octeți. Dacă datele sunt încă prea mari — implementați fragmentarea la nivel de aplicație: împărțiți datele în mai multe cereri secvențiale cu controlul integrității.
Dacă sarcina dumneavoastră este acoperită de o caracteristică standard — utilizați UUID din registrul Bluetooth SIG. Aceasta simplifică certificarea și asigură compatibilitatea cu ecosistemul. Creați UUID-uri personalizate doar pentru date unice ale producătorilor terți.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și