11.6. Služby a charakteristiky

Jakmile GAP dostane dvě zařízení do otevřeného spojení, vrstva nad ním – Generic Attribute Profile, GATT – musí bajtům proudícím tímto spojením dát význam. Volba BLE je zde neobvyklá. Zatímco TCP poskytuje surový proud bajtů a ponechává na aplikaci, aby si vymyslela vlastní rámcování, GATT poskytuje malou databázi klíč/hodnota, kterou jedna strana hostuje a druhá z ní čte, zapisuje do ní nebo se k ní přihlašuje k odběru.

Tato databáze je to, čím návrháři aplikací stráví nad BLE většinu času. Co kamera publikuje do telefonu, co sleduje na vzdáleném senzoru, jak Bluetooth klávesnice sděluje svému hostiteli, která klávesa byla stisknuta – to všechno jsou hodnoty charakteristik v nějaké GATT databázi.

11.6.1. Dvě osy rolí, ne jedna

Častý zdroj nejasností: peripheral / central a server / client jsou dvě nezávislé osy, nikoli synonyma.

  • Peripheral a central jsou role GAP, nastavené při navázání spojení. Peripheral inzeruje a je k němu navázáno spojení; central skenuje a spojení iniciuje. To je dáno v okamžiku, kdy spojení vznikne, a nemění se.

  • Server a client jsou role GATT, nastavené pro každou operaci s charakteristikou. Server hostuje charakteristiku; client z ní čte, zapisuje do ní nebo se k ní přihlašuje k odběru.

Tyto dvě osy jsou specifikací oddělené. Peripheral je obvykle server (pás na měření srdečního tepu publikuje své údaje) a central je obvykle client (telefon je čte), ale BLE umožňuje libovolnou kombinaci – peripheral může objevit charakteristiku na centralu, ke kterému se právě připojil, nebo jediné spojení může hostovat služby na obou stranách najednou.

Většina kamerových aplikací se drží konvenčního párování (peripheral + server, nebo central + client), takže zbytek této části s nimi zachází jako s jednou osou, když je popisován konvenční případ. Když na rozdílu záleží, jsou oba pojmy uvedeny výslovně.

11.6.2. Uvnitř databáze

GATT databáze je strom. Listy nesou skutečné bajty. Větve seskupují související listy do lidsky srozumitelných jednotek.

Strom s vrcholovým uzlem označeným "GATT database". Pod ním tři uzly Service označené "Generic Access (0x1800)", "Battery (0x180F)" a "Environmental Sensing (0x181A)". Každá Service má podřízené uzly Characteristic; služba Battery má "Battery Level (0x2A19)" s podřízeným deskriptorem "CCCD". Služba Environmental Sensing má "Temperature (0x2A6E)" a "Humidity (0x2A6F)".

GATT databáze. Služby seskupují charakteristiky; charakteristiky nesou bajty aplikace; deskriptory nesou metadata o charakteristice.

Existují tři druhy uzlů:

  • Služba je logická skupina souvisejících hodnot. Bluetooth SIG publikuje standardní definice služeb pro běžné případy použití – Battery Service pro úroveň nabití baterie, Environmental Sensing pro teplotu / vlhkost / tlak, Heart Rate pro monitory srdečního tepu – takže obecná aplikace v telefonu dokáže rozpoznat službu, kterou nikdy předtím neviděla. Aplikace si také může definovat vlastní služby pro věci, které SIG nestandardizoval.

  • Charakteristika je jedna pojmenovaná hodnota uvnitř služby. Služba Battery má jedinou charakteristiku – Battery Level, jednobajtové procento. Environmental Sensing má samostatné charakteristiky pro teplotu, vlhkost, tlak a tak dále. Charakteristika je jednotkou operací GATT – charakteristiku čtete, charakteristiku zapisujete, k charakteristice se přihlašujete k odběru.

  • Deskriptor jsou metadata připojená k charakteristice. Některé deskriptory jsou standardizované – Client Characteristic Configuration Descriptor (CCCD) je ten nejznámější, protože zápis do něj je způsob, jakým client sděluje serveru „posílej mi notifikace o této charakteristice“. Jiné jsou definované uživatelem a nesou věci jako formát prezentace nebo rozšířené vlastnosti.

GATT server (typicky peripheral) deklaruje svou databázi jednou při startu a databáze se za běhu nemění. GATT client (typicky central) objevuje, co je v databázi, po připojení – prochází strom, čte UUID služeb, které najde, a poté charakteristiky uvnitř každé z nich.

11.6.3. UUID

Každá služba, charakteristika a deskriptor má UUID (Universally Unique IDentifier), které identifikuje, o jaký druh věci jde. UUID se vyskytují ve třech šířkách:

  • 16bitové. Vyhrazeno pro standardy definované Bluetooth SIG. Battery Service je 0x180F. Battery Level (charakteristika) je 0x2A19. Úplný seznam je publikován na stránce přidělených čísel Bluetooth SIG na adrese https://www.bluetooth.com/specifications/assigned-numbers/.

  • 32bitové. Zřídka používaný střední stupeň.

  • 128bitové. To, co používají všichni ostatní – dodavatel nebo aplikace jej vygeneruje náhodně a použije pro svou vlastní službu nebo charakteristiku. Sem patří kamery definující vlastní protokol.

Třída bluetooth.UUID přijímá kteroukoli ze tří šířek:

import bluetooth

BATTERY_SERVICE = bluetooth.UUID(0x180F)
CUSTOM_SERVICE = bluetooth.UUID("12345678-1234-5678-9abc-def012345678")

16bitové UUID se zakóduje do malé inzertní zprávy, což je jeden z důvodů, proč jsou standardní služby výhodnější, pokud nějaká existuje – pás na měření srdečního tepu, který inzeruje 0x180D (Heart Rate), stojí dva bajty; vlastní UUID stojí šestnáct. Pro aplikace, které nepotřebují standardní interoperabilitu, je správnou odpovědí vygenerované 128bitové UUID.

11.6.4. Co vám služby standardizované SIG přinášejí

Argument pro použití standardní služby je přímočarý: stávající aplikace už s ní umějí komunikovat. Zařízení, které inzeruje službu Heart Rate (0x180D) a poskytuje charakteristiku Heart Rate Measurement (0x2A37), funguje s každou fitness aplikací na planetě, aniž by kdokoli psal nový kód. Zařízení, které stejná data znovu implementuje s vlastními UUID, potřebuje vlastní doprovodnou aplikaci a vlastní dokument protokolu.

Standardy mají svou cenu. Rozložení bajtů uvnitř každé charakteristiky je specifikováno – SIG rozhodl, že Heart Rate Measurement je jednobajtové pole příznaků následované buď 8bitovou, nebo 16bitovou hodnotou srdečního tepu, volitelně následované intervaly R-R – a zařízení odpovídající standardu musí tato rozložení dodržovat. Vlastní služby tímto omezením netrpí.

Pragmatická odpověď pro kamery: použijte standardní službu, pokud nějaká existuje pro druh dat, která máte (Battery Service, Environmental Sensing), a definujte vlastní službu se 128bitovým UUID pro cokoli specifického pro vaši aplikaci.

11.6.5. Objekty na straně serveru a na straně clienta

Pro stejné koncepční stavební bloky (služba, charakteristika, deskriptor) každá GATT knihovna poskytuje dvě paralelní sady objektů: