Characteristic е фундаменталната единица данни в Bluetooth Low Energy, чрез която Central получава или записва информация на периферно устройство. Всяка Characteristic принадлежи към определена GATT услуга, има уникален UUID и набор от свойства (read, write, notify, indicate), които определят възможните операции. Според Bluetooth Core Specification 5.4 (2023), Bluetooth SIG е специфицирал над 500 стандартни характеристики за медицински, фитнес и индустриални устройства. Разработчикът създава персонализирани характеристики за прехвърляне на всякакви потребителски данни — от показания на сензори до команди за управление на устройството.
Основни точки
Characteristic е атрибут на GATT протокола, който съдържа стойност (value) и метаданни. В архитектурата на BLE данните не се прехвърлят директно между устройствата, а чрез четене и запис на стойностите на характеристиките на услугата. Ако услугата е папка, то Characteristic е файл в тази папка.
Всяка Characteristic се състои от три компонента: декларация (declaration), стойност (value) и дескриптори (descriptors). Декларацията съдържа UUID на характеристиката и нейните свойства. Стойността са собствените данни, които се прехвърлят между Central и Peripheral. Дескрипторите предоставят допълнителна конфигурация.
Според Bluetooth Core Specification 5.4 (2023), всички обмени на данни в BLE се извършват чрез операции над характеристиките. Дори стандартните профили, като Heart Rate Profile или Battery Service, са изградени върху набор от характеристики с предварително дефинирани UUID. Това осигурява съвместимост на устройства от различни производители без предварителна конфигурация.
За разработчика е важно да разбере: всяка Characteristic може да поддържа различни комбинации от свойства. Една характеристика може да бъде само за четене, друга — за запис, трета — за уведомления. Правилният избор на свойства определя сценария на използване и консумацията на енергия на устройството.
Свойства (properties) на характеристиката определят какви операции са разрешени върху нея. Това е байтова маска, където всеки бит включва или изключва определена операция. По-долу са изброени основните свойства.
| Свойство | Бит | Описание | Типично приложение |
|---|---|---|---|
| Read | 0x02 | Central може да чете текущата стойност | Статус, ниво на батерията, конфигурация |
| Write | 0x08 | Central може да запише нова стойност | Команди за управление, настройки |
| Notify | 0x10 | Peripheral изпраща стойност без потвърждение | Потокови данни (пулс, температура) |
| Indicate | 0x20 | Peripheral изпраща стойност с потвърждение | Критични данни (аларми, статуси) |
| Write Without Response | 0x04 | Запис без изчакване на потвърждение от сървъра | Бързо предаване на команди |
Разрешения (permissions) са ниво на достъп на ниво GATT сървър. За разлика от свойствата, които се декларират в декларацията на характеристиката, разрешенията се проверяват при всяка операция. Те могат да включват изисквания за криптиране и удостоверяване.
Bluetooth SIG е специфицирал над 500 стандартни характеристики, които покриват повечето често срещани сценарии за използване на BLE. Използването на стандартни UUID гарантира, че всяко приемащо устройство ще интерпретира правилно данните без предварителна конфигурация.
Ето най-често използваните стандартни характеристики:
| UUID | Име | Тип данни | Услуга |
|---|---|---|---|
| 0x2A19 | Battery Level | uint8 (0–100%) | Battery Service |
| 0x2A37 | Heart Rate Measurement | uint8 + флагове | 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 |
Ако съществуваща стандартна характеристика покрива вашата задача — използвайте я. Това опростява сертифицирането Bluetooth и повишава съвместимостта с екосистемата. Създавайте персонализирани характеристики само за уникални данни, които не съществуват в регистъра на SIG.
Създаването на характеристика се извършва от страна на Peripheral — устройството, което предоставя данни. Нека разгледаме имплементацията на iOS (Swift) и Android (Java).
Core Bluetooth предоставя класа CBMutableCharacteristic за създаване на характеристика с посочване на UUID, свойства и начална стойност.
import CoreBluetooth
let characteristicUUID = CBUUID("2A19") // Характеристика на нивото на батерията
let characteristic = CBMutableCharacteristic(
type: characteristicUUID,
properties: [.read, .notify],
value: nil,
permissions: [.readable]
)
// Актуализиране на стойност при промяна
let batteryData = Data([batteryLevel]) // uint8
peripheralManager.updateValue(
batteryData,
for: characteristic,
onSubscribedCentrals: nil
)
На Android характеристиката се създава чрез BluetoothGattCharacteristic с посочване на UUID, свойства и разрешения.
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
);
// Задаване на стойност
characteristic.setValue(batteryLevel, BluetoothGattCharacteristic.FORMAT_UINT8, 0);
gattServer.notifyCharacteristicChanged(device, characteristic, false);
Операциите върху Characteristic се делят на три типа: четене (read), запис (write) и уведомления (notify/indicate). Изборът на операция зависи от сценария: данни при поискване се четат, команди се записват, потокови данни се абонират чрез уведомления.
Read — Central изпраща заявка за четене на стойността на характеристиката. Peripheral отговаря с текущата стойност. Операцията е синхронна и изисква изрична заявка от двете страни. Използва се за данни, които се променят рядко: версия на фърмуера, сериен номер, настройки.
Write — Central изпраща данни към Peripheral. Има два режима: Write with Response (потвърждение от Peripheral) и Write Without Response (без потвърждение). Write with Response гарантира доставка — Peripheral изпраща потвърждение след запис. Write Without Response е по-бърз, но не гарантира доставка.
Notify и Indicate — Peripheral инициира изпращане на данни към Central. При Notify данните се изпращат без потвърждение — ако Central не е успял да получи пакета, той се губи. При Indicate Central изпраща потвърждение (на PDU ниво), което гарантира доставка. Indicate е по-бавен, но по-надежден. За абониране за уведомления, Central записва стойност 0x0001 в CCCD (Client Characteristic Configuration Descriptor).
MTU (Maximum Transmission Unit) определя максималния размер на един BLE пакет данни. По подразбиране MTU е 23 байта, от които 3 байта са заглавна част — полезният товар (ATT payload) е 20 байта. Това е достатъчно за повечето сензорни данни, но недостатъчно за прехвърляне на файлове или големи конфигурации.
Bluetooth Core Specification 5.4 поддържа MTU договаряне (MTU negotiation) — Central и Peripheral могат да се споразумеят за по-голям размер на пакета до 517 байта. Процесът изглежда така: Central изпраща заявка за MTU Exchange с предложение за своя MTU; Peripheral отговаря със своя MTU; използва се по-малката от двете стойности.
// iOS изисква MTU при свързване
// Максималният MTU в iOS е 185 байта
func peripheral(
_ peripheral: CBPeripheral,
didDiscoverServices error: Error?
) {
// Изискване на MTU за конкретно периферно устройство
peripheral.maximumWriteValueLength(for: .withResponse)
}
Според Bluetooth SIG (2023), увеличаването на MTU от 23 на 185 байта намалява разходите за предаване на данни до 80% благодарение на намаляване на броя пакети. За приложения, предаващи показания с висока честота (напр. ЕКГ или акселерометър), увеличаването на MTU е критично за стабилността на потока.
Често задавани въпроси
Спецификацията BLE не ограничава броя на характеристиките в една услуга. На практика ограничението се определя от наличната памет на GATT сървъра и изискванията за производителност. За вградени устройства се препоръчват не повече от 10–15 характеристики на услуга.
Notify изпраща данни без потвърждение — пакетът може да бъде загубен без уведомление на подателя. Indicate изисква потвърждение (ACK) на протоколно ниво, което гарантира доставка. Indicate е по-бавен, но по-надежден. За критични данни (аларми, команди) използвайте Indicate.
Да, характеристика може да има комбинация от свойства. Например характеристика за настройки може да поддържа Read (четене на текущата стойност) и Write (промяна на настройката). Комбинирайте свойства според вашия сценарий на използване.
Използвайте MTU договаряне за увеличаване на размера на пакета до 185–517 байта. Ако данните все още са твърде големи — приложете фрагментиране на ниво приложение: разделете данните на няколко последователни заявки с контрол на целостта.
Ако вашата задача се покрива от стандартна характеристика — използвайте UUID от регистъра на Bluetooth SIG. Това опростява сертифицирането и осигурява съвместимост с екосистемата. Създавайте персонализирани UUID само за уникални данни на производители трети страни.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също