
BLE pod mikroskopem (ATTy GATTy…)
Část 1, přehledová
Už uplynulo poměrně dlouhé období od vydání první specifikace Bluetooth 4.0. A i když je téma BLE velmi zajímavé, stále odrazuje mnohé vývojáře kvůli své složitosti. Ve svých předchozích článcích jsem se zaměřoval hlavně na nejnižší úroveň Link Layer a Physical Layer. To umožnilo vyhnout se tak složitým a zamotaným pojmům jako je protokol atributů (ATT) a obecný profil atributů (GATT). Ale není úniku, bez jejich porozumění není možné vyvíjet kompatibilní zařízení. Dnes bych chtěl sdílet s vámi tyto znalosti. Ve svém článku budu vycházet z pro začátečníky z webu Nordic. Tak pojďme začít.
Proč je to všechno tak složité?
Z mého pohledu bylo hned jasné, že управление zařízeními přes smartphony — очень перспективная и долгая тема. Proto se rozhodli ji ihned strukturovat co nejlépe. Aby výrobci různých gadgetů nevymýšleli své protokoly, které by později nebyly kompatibilní. Odtud ta složitost. Už na prvním stupni se do protokolu BLE snažili vtěsnat všechno, co bylo možné. A je jedno, zda to bude později užitečné nebo ne. Kromě toho byla zajištěna možnost rozšíření seznamu zařízení do budoucna.
Podívejme se na obrázek, na kterém je znázorněna schéma protokolu BLE. Skládá se z několika vrstev. Nejnižší, fyzická vrstva (PHY) odpovídá za rádiový kanál zařízení. Link Layer (LL) obsahuje celou sekvenci bajtů v přenášené zprávě. V předchozích článcích jsme se zaměřovali právě na něj. Host Controller Interface (HCI) — je protokol výměny mezi vrstvami nebo čipy BLE, pokud jsou Controller a Host implementovány na různých čipech. Za vytváření paketů, dělení na rámce, kontrolu chyb a sestavování paketů odpovídá Logical Link Control and Adaptation Protocol (L2CAP). Za šifrování paketů odpovídá Security Manager Protocol (SMP). Profil obecného přístupu (GAP) odpovídá za počáteční výměnu dat mezi zařízeními, pro určení „Kdo je kdo“. K tomu patří také skenování a inzerování. V tomto článku se zastavím u dvou zbývajících částí protokolu — GATT a ATT. GATT je nadstavba nad ATT, takže jsou úzce provázány.

Aby zsimplifikować opowieść, chciałbym odwołać się do analogii. Gdzieś to słyszałem i chciałbym ją podtrzymać. Wyobraź sobie urządzenie BLE jako regał na książki z kilkoma półkami. Każda półka to osobna tematyka. Na przykład, mamy półki z fantastyką, matematyką, encyklopediami. Na każdej półce stoją książki o określonej tematyce. W niektórych książkach są nawet papierowe zakładki z notatkami. Ponadto mamy mały papierowy katalog wszystkich książek. Jeśli pamiętasz szkolne biblioteki – to wąska szuflada z papierowymi kartami. W tej analogii regał to profil naszego urządzenia. Półki to usługi, książki to właściwości, a katalog to tabela atrybutów. Zakładki w książkach to deskryptory, o których również opowiem później, bardziej szczegółowo.
Wszystkim, którzy projektowali urządzenia, wiadomo, że w wielu projektach są podobne fragmenty kodu. Chodzi o to, że wiele urządzeń ma podobną funkcjonalność. Na przykład, jeśli urządzenia działają na akumulatorach, problem ładowania i kontroli ich poziomu będzie taki sam. Dotyczy to również czujników. W zasadzie, podejście obiektowe w programowaniu "umożliwia tworzenie obiektów, które łączą właściwości i zachowania w samodzielny związek, który następnie można wielokrotnie wykorzystywać". Moim zdaniem, w BLE podjęto próbę podobnego podejścia. Grupa Bluetooth Special Interest Group (SIG) opracowała profile. Urządzenia od różnych producentów, które mają te same profile, powinny łatwo współpracować. Profile składają się z usług, a usługi z właściwości, uzupełnianych deskryptorami. W ogólnym przypadku może to wyglądać tak:

Na przykład, rozważ schemat profilu monitora rytmu serca (opaska fitness). Składa się z dwóch usług i kilku właściwości. Od razu jest widoczna hierarchia profilu. Właściwość punktu kontrolnego zeruje całkowity bilans wydatków kalorycznych.
1. Usługa rytmu serca zawiera trzy właściwości (0x180D):
a) Obowiązkowa właściwość częstości akcji serca (0x2A37)
b) Opcjonalna właściwość pozycji czujnika ciała (0x2A38)
c) Warunkowa właściwość punktu kontrolnego rytmu serca (0x2A39)
2. Usługa zarządzania baterią (0x180F):
a) Povinná charakteristika úrovně nabití baterie (0x2A19)
UUID
Abychom mohli jednoznačně odkazovat na prvky profilu (služby, charakteristiky a popisy), je potřeba je nějak číslovat. K tomu se zavádí pojem Universally Unique ID (UUID) nebo Univerzální unikátní identifikátor. V závorkách každého řádku je právě uveden UUID. A zde je jedna zvláštnost. Pro UUID se rozhodlo použít kód o délce 16 a 128 bitů. Proč, ptáte se? V protokolu BLE je všechno podřízení úspoře energie. Proto je velikost 16 bitů zcela rozumná. Nejspíš se v blízké budoucnosti nevytvoří více než 65 tisíc unikátních služeb a charakteristik. V tuto chvíli už bylo všechno, co mohlo, spočítáno (pamatujete odkud to je — „on vás taky spočítal“ :-)) Číslované prvky , , a můžete se podívat podle odkazů.
Nicméně si myslím, že si všichni pamatují příběh se 4 bajty IP adresy na internetu. Zpočátku si mysleli, že to stačí, a teď se pořád nemůžeme přejít na 6-bajtovou adresu. Abychom se vyhnuli opakování této chyby a dali prostor šikovným rukám kutilů, SIG se rozhodla ihned zavést také 128-bitové UUID. To mi připomíná nelicencovaný pásmo 433 MHz, které bylo dáno volně různým kutilům z radiokanálu. V našem případě byl dán volně 128-bitový identifikátor služeb a charakteristik. To znamená, že pro naše služby a zařízení můžeme používat prakticky jakoukoli 128-bitovou hodnotu. Pravděpodobnost vymyslet stejný UUID se přitom blíží nule.
Ve skutečnosti mají krátké 16-bitové UUID své rozšíření na 128-bitovou hodnotu. V specifikaci se toto rozšíření nazývá Bluetooth Base UUID a má hodnotu 00000000-0000-1000-8000-00805F9B34FB. Pokud například 16-bitový UUID atributu má hodnotu 0x1234, pak ekvivalentní 128-bitový UUID bude mít hodnotu 00001234-0000-1000-8000-00805F9B34FB. A dokonce je uvedena odpovídající rovnice:
128_bit_value = 16_bit_value * 2^96 + Bluetooth_Base_UUID
Odkud se vzalo toto magické číslo, nevím. Pokud někdo z čtenářů ví — ať napíše do komentářů (Uživatel s přezdívkou Sinopteek to již udělal. Podívejte se na komentáře). Co se týče vymýšlení 128-bitových UUID, je možné využít speciální , který to udělá za vás.
ATT a GATT...
Tady začíná to nejzajímavější. Připomínám, že ATT je založen na klient-server vztahu. Nyní zvažujeme zařízení serveru. Obsahuje informace, jako jsou hodnoty senzorů, stav světelného spínače, údaje o poloze atd. Nyní, když jsou všichni „účastníci našeho průvodu“ očíslováni, je třeba je nějak umístit do paměti zařízení. K tomu je umístíme do tabulky, která se nazývá tabulka atributů. Dobře si to zapamatujte. To je srdce BLE. To bude předmětem našeho dalšího zkoumání. Nyní budeme každému řádku říkat atribut. Tato tabulka je hloubkou zásobníku a zpravidla nemáme přímý přístup k ní. Inicializujeme ji a přistupujeme k ní, ale co se děje uvnitř, je od nás skryto za sedmi zámky.
Podívejme se na obrázek ze specifikace, ale předtím chci okamžitě upozornit na časté zmatení termínů, konkrétně v deskriptorech. Úloha deskriptoru je doplnit popis charakteristiky. Když je třeba rozšířit její možnosti, aplikují se deskriptory. Ty také jsou atributy a spolu se službami a charakteristikami se nacházejí v tabulce atributů. Podrobněji je probereme ve druhé části článku. Nicméně někdy se číslem řádku v tabulce atributů nazývají deskriptory. To je důležité si uvědomit. My pro tyto účely, abychom se nezaměňovali, budeme používat termín „ukazatel atributu“.

Takže atribut je diskrétní hodnota, která má následující vlastnosti související s ním:
1. Ukazatel atributu (Attribute Handle) — to je index tabulky odpovídající atributu.
2. Typ atributu (Attribute Type) — to je UUID, které popisuje jeho typ.
3. Hodnota atributu (Attribute Value) — to jsou data, která se indexují ukazatelem atributu.
4. Oprávnění atributů (Attribute Permissions) — to je část atributu, oprávnění, která nelze přečíst nebo zapsat pomocí protokolu atributů.
Jak to všechno pochopit? Ukazatel atributu je, řekněme, jeho číslo v naší tabulce.
Umožňuje klientovi odkazovat na atributy v požadavcích na čtení nebo zápis. Můžeme číslovat naše řádky (atributy) od 0x0001 do 0xFFFF. V naší asociaci s knihovnou je to číslo karty v papírovém katalogu. Podobně, jako v knihovně, jsou karty uspořádány podle vzrůstajícího čísla. Číslo každého následujícího řádku musí být větší než předchozí. Stejně jako v knihovně, i zde mohou být některé karty ztraceny, a v našem číslování řádků mohou být mezery. To je přijatelné. Hlavní je, aby šly podle vzrůstajícího pořádku.
Typ atributu určuje, co tento atribut představuje. Podobně jako v jazyce C,
kde existují logické, číselné proměnné a řetězce, je to i zde. Podle typu atributu zjistíme,
s čím se zabýváme a jak s tímto atributem dále pracovat. Níže si ukážeme některé specifické typy atributů. Například „servisní deklarace“ (0x2800), „deklarace charakteristiky“ (0x2803), „deklarace deskriptoru“ (0x2902).
Hodnota atributu je jeho skutečná hodnota, omlouvám se za tautologii. Pokud je typ atributu řetězec, může být hodnotou atributu například slogan „Hello World !!!“. Pokud je typ atributu „servisní deklarace“, jeho hodnotou je samotná služba. Někdy to může být informace o tom, kde najít další atributy a jejich vlastnosti.
Oprávnění atributů umožňují serveru pochopit, zda je povolen přístup k čtení nebo zápisu.
Všimněte si, že tato oprávnění se vztahují pouze na hodnotu atributu, nikoli na ukazatel, typ a samotné pole oprávnění. Tedy pokud je povoleno zapisovat atribut, můžeme například změnit řetězec „Hello World !!!“ na řetězec „Dobré ráno“. Ale nemůžeme zakázat zápis nového řádku nebo změnit typ atributu a označit řetězec jako „servisní deklarace“. Při žádosti klienta k serveru klient žádá o jeho atributy. To umožňuje klientovi zjistit, co server může poskytnout. Není však nezbytné číst a zapisovat hodnoty.
Jak to vypadá
Koncept GATT spočívá ve skupinování atributů v tabulce atributů do velmi specifického a logického pořadí. Pojďme se podívat na profil srdeční frekvence uvedený níže. Nejlevější sloupec této tabulky není povinný. Pouze nám popisuje, čím je tento řádek (atribut). Všechny ostatní sloupce už známe.

V horní části každé skupiny máme vždy atribut oznámení služby. Jeho typ je vždy 0x2800 a ukazatel závisí na tom, kolik atributů již v tabulce je. Jeho oprávnění jsou vždy dostupná pouze pro čtení, bez jakékoli verifikace nebo autorizace. O těchto pojmech budeme mluvit později. Hodnota je další UUID, který určuje, co je to za službu. V tabulce má hodnotu 0x180D, což je definováno Bluetooth SIG jako služba srdeční frekvence.
Následuje oznámení o charakteristice. Po formě je podobné oznámení služby. Jeho UUID je vždy 0x2803 a oprávnění jsou rovněž vždy dostupná pouze pro čtení bez jakékoli verifikace nebo autorizace. Podívejme se na pole Hodnota atributu, které obsahuje některá data. Vždy obsahuje ukazatel, UUID a soubor vlastností. Tyto tři prvky popisují následné oznámení hodnoty charakteristiky. Ukazatel přirozeně označuje místo oznámení hodnoty charakteristiky v tabulce atributů. UUID popisuje, jaký typ informace nebo hodnoty můžeme očekávat. Například hodnotu teploty, stav přepínače světla nebo jakoukoli jinou libovolnou hodnotu. A nakonec vlastnosti, které popisují, jak lze interagovat s charakteristickou hodnotou.
Zde nás čeká další úskalí. To souvisí s oprávněními atributů a vlastnostmi charakteristik. Pojďme se podívat na obrázek vlastností bitového pole ze specifikace.

Jak vidíte, zde jsou také pole, která umožňují čtení a zápis. Můžete se ptát, proč máme oprávnění pro čtení/zápis pro atribut a vlastnost.
Čtení/zápis pro hodnotu charakteristiky? Neměly by být vždy stejné? Skutečnost je taková, že vlastnosti pro hodnotu charakteristiky jsou ve skutečnosti pouze doporučení pro klienta, používaná v GATT a aplikačních vrstvách. Jsou to jen náznaky toho, co klient může očekávat od atributu prohlášení o charakteristice. Pojďme se na to podívat podrobněji. Jaké typy oprávnění existují pro atribut?
1. Oprávnění k přístupu:
— čtení
— zápis
— čtení a zápis
2. Oprávnění pro autentizaci:
— autentizace vyžadována
— autentizace není vyžadována
3. Oprávnění pro autorizaci:
— autorizace vyžadována
— autorizace není vyžadována
Hlavní rozdíl mezi oprávněními atributů a vlastnostmi charakteristik spočívá v tom, že první se vztahují na servery, zatímco druhé na klienty. Serveru může být povoleno číst hodnotu charakteristiky, ale může existovat požadavek na autentizaci nebo autorizaci. Proto, když klient požaduje vlastnosti charakteristiky, zjistíme, že čtení je povoleno. Ale při pokusu o čtení dojde k chybě. Proto lze s jistotou říci, že oprávnění mají přednost před vlastnostmi. Znalost oprávnění atributu, kterou máme jako klient, nemůžeme získat.
Deskriptor
Vraťme se k naší tabulce. Po vyhlášení hodnoty charakteristiky mohou následovat následující deklarace atributů:
1. Nové vyhlášení charakteristiky (v službě může být mnoho charakteristik)
2. Nová deklarace služby (v tabulce jich může být mnoho)
3. Vyhlášení deskriptoru
Pokud jde o měření charakteristiky srdeční frekvence, v naší tabulce je hodnota charakteristiky doprovázena oznámením popisovače. Popisovač je atribut s dodatečnými informacemi o charakteristice. Existuje několik typů popisovačů. O těchto se podrobněji podíváme ve druhé části tohoto článku. Nyní se však zaměříme pouze na popisovač konfigurace charakteristik zákazníka (Client Characteristic Configuration Descriptor — CCCD). Ten má UUID 0x2902. Pomocí tohoto popisovače má zákazník možnost aktivovat na serveru indikaci nebo notifikaci. Rozdíl mezi nimi je malý, ale přesto existuje. Notifikace nevyžaduje potvrzení o doručení ze strany zákazníka. Indikace naopak to vyžaduje, i když se uskutečňuje na úrovni GATT, nedochází k přenosu na úroveň aplikace. Proč je to tak, ptáte se? Bohužel, to mi není známo. Mohu jen říci, že odborníci z Nordic doporučují používat notifikaci. Tím spíše, že kontrola integrity paketu (pomocí CRC) se provádí v obou případech.
Závěr
Na závěr článku bych chtěl říci toto. Poslední tabulka je poněkud matoucí. Nicméně jsem se na ní zastavil, protože se uvádí v , na kterou se opírám. Ve druhé části svého článku se chci více ponořit do specifikace Bluetooth 4.0. Tam nás čekají přesnější diagramy a obrázky. Ve třetí části bych chtěl probrat log zachycený pomocí programu Wireshark z jednoho z gadgetů a vidět „naživo“ celou teorii, kterou studujeme.
Zaměstnanec Skupiny firem
Vladimir Pečersky
Zdroj: habr.com
