{"id":84024,"date":"2020-06-04T19:42:32","date_gmt":"2020-06-04T17:42:32","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/ble-pod-mikroskopom-atty-gatty"},"modified":"2020-06-04T19:42:32","modified_gmt":"2020-06-04T17:42:32","slug":"ble-pod-mikroskopom-atty-gatty","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/ble-pod-mikroskopom-atty-gatty","title":{"rendered":"BLE pod mikroskopem (ATTy GATTy&#8230;)","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"BLE pod mikroskopem (ATT i GATT...)\" src=\"\/wp-content\/uploads\/2020\/06\/d8587bf897b27457b354549b99399bcc.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h2>BLE pod mikroskopem (ATTy GATTy&#8230;)<\/h2>\n<p> <b>Cz\u0119\u015b\u0107 1, przegl\u0105dowa<\/b><\/p>\n<p>Min\u0119\u0142o ju\u017c sporo czasu od momentu, gdy wydano pierwsz\u0105 specyfikacj\u0119 Bluetooth 4.0. I chocia\u017c temat BLE jest bardzo interesuj\u0105cy, wci\u0105\u017c odstrasza wielu programist\u00f3w z powodu swojej z\u0142o\u017cono\u015bci. W moich wcze\u015bniejszych artyku\u0142ach omawia\u0142em g\u0142\u00f3wnie najni\u017cszy poziom Link Layer i Physical Layer. To pozwoli\u0142o unikn\u0105\u0107 tak skomplikowanych i zamotanych poj\u0119\u0107 jak protok\u00f3\u0142 atrybut\u00f3w (ATT) i og\u00f3lny profil atrybut\u00f3w (GATT). Jednak nie ma ucieczki \u2014 nie rozumiej\u0105c ich, nie mo\u017cna opracowa\u0107 kompatybilnych urz\u0105dze\u0144. Dzi\u015b chcia\u0142bym podzieli\u0107 si\u0119 z Wami t\u0105 wiedz\u0105. W swoim artykule b\u0119d\u0119 opiera\u0142 si\u0119 na <noindex><a rel=\"nofollow\" href=\"https:\/\/devzone.nordicsemi.com\/nordic\/short-range-guides\/b\/bluetooth-low-energy\/posts\/ble-characteristics-a-beginners-tutorial\">podr\u0119cznik<\/a><\/noindex> dla pocz\u0105tkuj\u0105cych z witryny Nordic-a. A wi\u0119c, zaczynajmy.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Dlaczego wszystko jest tak skomplikowane?<\/h3>\n<p>\nMoim zdaniem, od pocz\u0105tku by\u0142o jasne, \u017ce zarz\u0105dzanie urz\u0105dzeniami za pomoc\u0105 smartfon\u00f3w to bardzo obiecuj\u0105cy i d\u0142ugoterminowy temat. Dlatego postanowiono go od razu uporz\u0105dkowa\u0107 i z maksymalnym naciskiem. Aby producenci r\u00f3\u017cnych gad\u017cet\u00f3w nie wymy\u015blali swoich protoko\u0142\u00f3w, kt\u00f3re b\u0119d\u0105 p\u00f3\u017aniej niekompatybilne. St\u0105d bierze si\u0119 z\u0142o\u017cono\u015b\u0107. Ju\u017c na pierwszym etapie w protok\u00f3\u0142 BLE pr\u00f3bowano wcisn\u0105\u0107 wszystko, co tylko by\u0142o mo\u017cliwe. I nie wa\u017cne, czy to si\u0119 przyda p\u00f3\u017aniej, czy nie. Co wi\u0119cej, przewidziano mo\u017cliwo\u015b\u0107 rozszerzenia listy urz\u0105dze\u0144 na przysz\u0142o\u015b\u0107.<\/p>\n<p>Sp\u00f3jrzmy na obrazek, na kt\u00f3rym przedstawiona jest schemat protoko\u0142u BLE. Sk\u0142ada si\u0119 on z kilku warstw. Najni\u017csza, warstwa fizyczna (PHY) odpowiada za kana\u0142 radiowy urz\u0105dzenia. Link Layer (LL) zawiera ca\u0142\u0105 sekwencj\u0119 bajt\u00f3w w przesy\u0142anej wiadomo\u015bci. W poprzednich artyku\u0142ach w\u0142a\u015bnie to badali\u015bmy. Host Controller Interface (HCI) \u2013 to protok\u00f3\u0142 wymiany mi\u0119dzy warstwami lub uk\u0142adami BLE, je\u015bli kontroler i host s\u0105 realizowane na r\u00f3\u017cnych chipach. Za formowanie pakiet\u00f3w, dzielenie na ramki, kontrol\u0119 b\u0142\u0119d\u00f3w i zbieranie pakiet\u00f3w odpowiada Logical Link Control and Adaptation Protocol (L2CAP). Za szyfrowanie pakiet\u00f3w odpowiada Security Manager Protocol (SMP). Profil og\u00f3lnego dost\u0119pu (GAP) odpowiada za pocz\u0105tkow\u0105 wymian\u0119 danych mi\u0119dzy urz\u0105dzeniami, aby okre\u015bli\u0107 \u201eKto jest kim\u201d. Do niego odnosz\u0105 si\u0119 r\u00f3wnie\u017c skanowanie i reklamowanie. W tym artykule skupi\u0119 si\u0119 na dw\u00f3ch pozosta\u0142ych cz\u0119\u015bciach protoko\u0142u \u2014 GATT i ATT. GATT jest nadbudow\u0105 nad ATT, dlatego s\u0105 one ze sob\u0105 \u015bci\u015ble powi\u0105zane.<\/p>\n<p><img decoding=\"async\" alt=\"BLE pod mikroskopem (ATT i GATT...)\" src=\"\/wp-content\/uploads\/2020\/06\/8060076152cfe3ae648eca362889e571.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAby upro\u015bci\u0107 narracj\u0119, chcia\u0142bym pos\u0142u\u017cy\u0107 si\u0119 analogi\u0105. Gdzie\u015b o niej s\u0142ysza\u0142em i chcia\u0142bym j\u0105 wspiera\u0107. Wyobra\u017a sobie urz\u0105dzenie BLE jako rega\u0142 z ksi\u0105\u017ckami z kilkoma p\u00f3\u0142kami. Ka\u017cda p\u00f3\u0142ka to osobna tematyka. Na przyk\u0142ad, mamy p\u00f3\u0142ki z fantastyk\u0105, matematyk\u0105, encyklopediami. Na ka\u017cdej p\u00f3\u0142ce stoj\u0105 ksi\u0105\u017cki na dany temat. A w niekt\u00f3rych ksi\u0105\u017ckach s\u0105 nawet papierowe zak\u0142adki z notatkami. Ponadto, mamy niewielki papierowy katalog wszystkich ksi\u0105\u017cek. Je\u015bli pami\u0119tacie szkolne biblioteki \u2014 to by\u0142 w\u0105ski szuflad z papierowymi kartami. W tej analogii rega\u0142 to profil naszego urz\u0105dzenia. P\u00f3\u0142ki to us\u0142ugi, ksi\u0105\u017cki to cechy, a katalog to tabela atrybut\u00f3w. Zak\u0142adki w ksi\u0105\u017ckach to deskryptory, o kt\u00f3rych r\u00f3wnie\u017c opowiem p\u00f3\u017aniej, bardziej szczeg\u00f3\u0142owo.<\/p>\n<p>Wszyscy, kt\u00f3rzy tworzyli urz\u0105dzenia, wiedz\u0105, \u017ce w wielu projektach s\u0105 podobne fragmenty kodu. Chodzi o to, \u017ce wiele urz\u0105dze\u0144 ma zbli\u017con\u0105 funkcjonalno\u015b\u0107. Na przyk\u0142ad, je\u015bli urz\u0105dzenia dzia\u0142aj\u0105 na akumulatorach, to problem \u0142adowania i monitorowania ich poziomu b\u0119dzie taki sam. To samo dotyczy czujnik\u00f3w. Tak naprawd\u0119, podej\u015bcie obiektowe w programowaniu <i>\u201eumo\u017cliwia tworzenie obiekt\u00f3w, kt\u00f3re \u0142\u0105cz\u0105 w\u0142a\u015bciwo\u015bci i zachowania w samodzielny zwi\u0105zek, kt\u00f3ry nast\u0119pnie mo\u017cna wielokrotnie u\u017cywa\u0107\u201d<\/i>. Moim zdaniem w BLE podj\u0119to pr\u00f3b\u0119 podobnego podej\u015bcia. Grupa Bluetooth Special Interest Group (SIG) opracowa\u0142a profile. Urz\u0105dzenia r\u00f3\u017cnych producent\u00f3w, maj\u0105ce te same profile, powinny bez trudu wsp\u00f3\u0142pracowa\u0107 ze sob\u0105. Profile sk\u0142adaj\u0105 si\u0119 z us\u0142ug, a us\u0142ugi z cech, uzupe\u0142nianych deskryptorami. W og\u00f3lnym przypadku mo\u017ce to wygl\u0105da\u0107 tak:<\/p>\n<p><img decoding=\"async\" alt=\"BLE pod mikroskopem (ATT i GATT...)\" src=\"\/wp-content\/uploads\/2020\/06\/34cbbeee142d40e56dff7626ef752d42.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNa przyk\u0142ad, rozwa\u017cmy schemat profilu monitora pracy serca (fitness bracelet). Sk\u0142ada si\u0119 on z dw\u00f3ch us\u0142ug i kilku cech. Od razu wida\u0107 hierarchi\u0119 profilu. Cecha kontrolna zeruje ca\u0142kowity licznik wydatk\u00f3w kalorycznych na zero. <\/p>\n<p>1. Us\u0142uga rytmu serca zawiera trzy cechy (0x180D):<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;a) Obowi\u0105zkowa cecha cz\u0119stotliwo\u015bci skurcz\u00f3w serca (0x2A37)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;b) Opcjonalna cecha po\u0142o\u017cenia czujnika cia\u0142a (0x2A38)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;c) Warunkowa cecha kontrolnej punktu rytmu serca (0x2A39)<br \/>\n2. Us\u0142uga zarz\u0105dzania bateri\u0105 (0x180F):<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;a) Wymagana w\u0142a\u015bciwo\u015b\u0107 poziomu na\u0142adowania baterii (0x2A19)<\/p>\n<h3>UUID<\/h3>\n<p>\nAby mo\u017cna by\u0142o jednoznacznie odnosi\u0107 si\u0119 do element\u00f3w profilu (us\u0142ug, w\u0142a\u015bciwo\u015bci i deskryptor\u00f3w), nale\u017cy je jako\u015b ponumerowa\u0107. W tym celu wprowadza si\u0119 poj\u0119cie Universally Unique ID (UUID) lub Uniwersalnego unikalnego identyfikatora. W nawiasach ka\u017cdej linii w\u0142a\u015bnie wskazano UUID. I tu jest jedna cecha. Dla UUID zdecydowano si\u0119 na zastosowanie kodu o d\u0142ugo\u015bci 16 i 128 bit\u00f3w. Czemu, zapytacie? W protokole BLE wszystko podporz\u0105dkowane jest oszcz\u0119dzaniu energii. Dlatego rozmiar w 16 bitach jest zupe\u0142nie uzasadniony. Ma\u0142o prawdopodobne, aby w najbli\u017cszej przysz\u0142o\u015bci powsta\u0142o wi\u0119cej ni\u017c 65 tys. unikalnych us\u0142ug i w\u0142a\u015bciwo\u015bci. Na ten moment wszystko, co mogli, ju\u017c policzyli (pami\u0119tacie sk\u0105d to \u2014 \u201eon i was policzy\u0142\u201d :-)) Ponumerowane elementy <noindex><a rel=\"nofollow\" href=\"https:\/\/www.bluetooth.com\/specifications\/gatt\/\">profil\u00f3w<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.bluetooth.com\/specifications\/gatt\/services\/\">us\u0142ug<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.bluetooth.com\/specifications\/gatt\/characteristics\/\">w\u0142a\u015bciwo\u015bci<\/a><\/noindex> i <noindex><a rel=\"nofollow\" href=\"https:\/\/www.bluetooth.com\/specifications\/gatt\/descriptors\/\">deskryptor\u00f3w<\/a><\/noindex> mo\u017cecie Pa\u0144stwo zobaczy\u0107 w linkach.<\/p>\n<p>Jednak, my\u015bl\u0119, \u017ce wszyscy pami\u0119taj\u0105 histori\u0119 z 4 bajtami adresu IP w internecie. Najpierw my\u015bleli, \u017ce wystarczy, a teraz nie mog\u0105 przej\u015b\u0107 na 6-bajtowy adres. Aby nie powt\u00f3rzy\u0107 tego b\u0142\u0119du i da\u0107 pole do popisu r\u0119kom majsterkowicz\u00f3w, SIG zdecydowa\u0142o si\u0119 od razu wprowadzi\u0107 r\u00f3wnie\u017c 128-bitowe UUID. To osobi\u015bcie przypomina mi nielegalny zakres 433MHz, kt\u00f3ry zosta\u0142 oddany w r\u0119ce r\u00f3\u017cnych Kuliabin\u00f3w od radia. W naszym przypadku oddano 128-bitowy identyfikator us\u0142ug i w\u0142a\u015bciwo\u015bci. Oznacza to, \u017ce dla naszych us\u0142ug i urz\u0105dze\u0144 mo\u017cemy u\u017cywa\u0107 praktycznie dowolnej warto\u015bci 128-bitowej. I tak nadal prawdopodobie\u0144stwo wymy\u015blenia takiego samego UUID d\u0105\u017cy do zera.<\/p>\n<p>W rzeczywisto\u015bci kr\u00f3tkie 16-bitowe UUID maj\u0105 swoje rozszerzenie do warto\u015bci 128-bitowej. W specyfikacji to rozszerzenie nosi nazw\u0119 Bluetooth Base UUID i ma warto\u015b\u0107 00000000-0000-1000-8000-00805F9B34FB. Je\u015bli na przyk\u0142ad 16-bitowy UUID atrybutu ma warto\u015b\u0107 0x1234, to odpowiadaj\u0105cy mu 128-bitowy UUID ma warto\u015b\u0107 00001234-0000-1000-8000-00805F9B34FB. A nawet podano odpowiedni\u0105 formu\u0142\u0119:<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;128_bit_value = 16_bit_value * 2^96 + Bluetooth_Base_UUID<\/p>\n<p>Sk\u0105d wzi\u0119\u0142a si\u0119 ta magiczna liczba, nie wiem. Je\u015bli kto\u015b z czytelnik\u00f3w wie \u2014 niech napisze w komentarzach (U\u017cytkownik o nicku Sinopteek ju\u017c to zrobi\u0142. Zobacz komentarze). Co do wymy\u015blania 128-bitowych UUID, to w zasadzie mo\u017cna skorzysta\u0107 ze specjalnego <noindex><a rel=\"nofollow\" href=\"https:\/\/www.famkruithof.net\/uuid\/uuidgen\">generatora<\/a><\/noindex>, kt\u00f3ry zrobi to za Ciebie.<\/p>\n<h3>ATT\u044b GATT\u044b\u2026<\/h3>\n<p>\n Zaraz zacznie si\u0119 to, co najciekawsze. Przypomn\u0119, \u017ce ATT oparty jest na relacji klient-serwer. Teraz rozwa\u017camy urz\u0105dzenie serwera. Zawiera ono informacje, takie jak warto\u015bci czujnik\u00f3w, stan prze\u0142\u0105cznika \u015bwiat\u0142a, dane dotycz\u0105ce lokalizacji itd. Teraz, gdy wszyscy \u201euczestnicy naszej parady\u201d s\u0105 ponumerowani, musimy je jako\u015b umie\u015bci\u0107 w pami\u0119ci urz\u0105dzenia. W tym celu umieszczamy je w tabeli, kt\u00f3ra nazywa si\u0119 tabel\u0105 atrybut\u00f3w. Zapami\u0119taj to dobrze. To jest serce BLE. To w\u0142a\u015bnie to b\u0119dziemy analizowa\u0107 dalej. Teraz ka\u017cd\u0105 lini\u0119 b\u0119dziemy nazywa\u0107 atrybutem. Ta tabela znajduje si\u0119 g\u0142\u0119boko w stosie i zazwyczaj nie mamy do niej bezpo\u015bredniego dost\u0119pu. Inicjujemy j\u0105 i do niej si\u0119 odwo\u0142ujemy, ale co dzieje si\u0119 wewn\u0105trz, pozostaje dla nas tajemnic\u0105. <\/p>\n<p>Przyjrzyjmy si\u0119 obrazkowi ze specyfikacji, ale przed tym chcia\u0142bym zwr\u00f3ci\u0107 uwag\u0119 na cz\u0119ste zamieszanie terminologiczne, a konkretnie w odniesieniu do deskryptor\u00f3w. Rola deskryptora polega na uzupe\u0142nieniu opisu charakterystyki. Gdy trzeba rozszerzy\u0107 jego mo\u017cliwo\u015bci, wtedy stosuje si\u0119 deskryptory. S\u0105 r\u00f3wnie\u017c atrybutami i obok us\u0142ug i charakterystyk znajduj\u0105 si\u0119 w tabeli atrybut\u00f3w. Dok\u0142adnie om\u00f3wimy je w drugiej cz\u0119\u015bci artyku\u0142u. Jednak czasami deskryptorami nazywaj\u0105 numer linii w tabeli atrybut\u00f3w. Nale\u017cy to mie\u0107 na uwadze. Aby unikn\u0105\u0107 zamieszania, b\u0119dziemy u\u017cywa\u0107 terminu \u201ewska\u017anik atrybutu\u201d w tym kontek\u015bcie.<br \/>\n<img decoding=\"async\" alt=\"BLE pod mikroskopem (ATT i GATT...)\" src=\"\/wp-content\/uploads\/2020\/06\/6df836477b153c396bdba9068129bb6f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nZatem atrybut \u2014 to dyskretna warto\u015b\u0107, kt\u00f3ra ma nast\u0119puj\u0105ce w\u0142a\u015bciwo\u015bci zwi\u0105zane z ni\u0105:<br \/>\n1. Wska\u017anik atrybutu (Attribute Handle) \u2014 to indeks w tabeli odpowiadaj\u0105cy atrybutowi. <br \/>\n2. Typ atrybutu (Attribute Type) \u2014 to UUID, kt\u00f3ry opisuje jego typ. <br \/>\n3. Warto\u015b\u0107 atrybutu (Attribute Value) \u2014 to dane, indeksowane przez wska\u017anik atrybutu. <br \/>\n4. Uprawnienia atrybut\u00f3w (Attribute Permissions) \u2014 to cz\u0119\u015b\u0107 atrybutu, uprawnie\u0144, kt\u00f3re nie mog\u0105 by\u0107 odczytywane ani zapisywane za pomoc\u0105 protoko\u0142u atrybut\u00f3w<\/p>\n<p>Jak to wszystko rozumie\u0107? Wska\u017anik atrybutu \u2014 to, \u017ce tak powiem, jego numer w naszej tabeli.<br \/>\nUmo\u017cliwia to klientowi odwo\u0142ywanie si\u0119 do atrybutu w zapytaniach odczytu lub zapisu. Mo\u017cemy numerowa\u0107 nasze wiersze (atrybuty) od 0x0001 do 0xFFFF. W naszym skojarzeniu z biblioteczk\u0105 \u2014 to numer karty w papierowym katalogu. Podobnie jak w katalogu biblioteki, karty s\u0105 uporz\u0105dkowane rosn\u0105co wed\u0142ug numeru. Numer ka\u017cdego kolejnego wiersza musi by\u0107 wi\u0119kszy od poprzedniego. Jak w bibliotece, czasami znikaj\u0105 niekt\u00f3re karty, tak i u nas \u2014 w numeracji wierszy mog\u0105 wyst\u0119powa\u0107 luki. Jest to dopuszczalne. Najwa\u017cniejsze, aby by\u0142y uporz\u0105dkowane rosn\u0105co.<\/p>\n<p>Typ atrybutu okre\u015bla, co ten atrybut reprezentuje. Podobnie jak w j\u0119zyku C,<br \/>\ngdzie istniej\u0105 zmienne boolowskie, liczbowe i ci\u0105gi, tak i tutaj. Dzi\u0119ki typowi atrybutu dowiadujemy si\u0119, <br \/>\nz czym mamy do czynienia i jak musimy dalej pracowa\u0107 z tym atrybutem. Poni\u017cej om\u00f3wimy niekt\u00f3re specyficzne typy atrybut\u00f3w. Na przyk\u0142ad \u201edeklaracja us\u0142ugi\u201d (0x2800), \u201edeklaracja cechy\u201d (0x2803), \u201edeklaracja deskryptora\u201d (0x2902).<\/p>\n<p>Warto\u015b\u0107 atrybutu to w\u0142a\u015bciwie jego warto\u015b\u0107, przepraszam za tautologi\u0119. Je\u015bli typ atrybutu to ci\u0105g, to warto\u015bci\u0105 atrybutu mo\u017ce by\u0107 na przyk\u0142ad slogan \u201eHello World !!!\u201d. Je\u015bli typ atrybutu to \u201edeklaracja us\u0142ugi\u201d, to jego warto\u015bci\u0105 jest sama us\u0142uga. A czasami to informacje o tym, gdzie znale\u017a\u0107 inne atrybuty i ich w\u0142a\u015bciwo\u015bci.<\/p>\n<p>Uprawnienia atrybut\u00f3w pozwalaj\u0105 serwerowi zrozumie\u0107, czy dost\u0119p do odczytu lub zapisu jest dozwolony. <br \/>\nZwr\u00f3\u0107 uwag\u0119, \u017ce te uprawnienia stosuj\u0105 si\u0119 tylko do warto\u015bci atrybutu, a nie do wska\u017anika, typu i samego pola uprawnie\u0144. Tzn. je\u015bli zapis atrybutu jest dozwolony, mo\u017cemy na przyk\u0142ad zmieni\u0107 ci\u0105g \u201eHello World !!!\u201d na ci\u0105g \u201eGood morning\u201d. Ale nie mo\u017cemy zabroni\u0107 zapisu nowego wiersza ani zmieni\u0107 typu atrybutu i oznaczy\u0107 ci\u0105g jako \u201edeklaracja us\u0142ugi\u201d. Kiedy klient zwraca si\u0119 do serwera, klient \u017c\u0105da jego atrybut\u00f3w. Umo\u017cliwia to klientowi dowiedzenie si\u0119, co mo\u017ce zaoferowa\u0107 serwer. Chocia\u017c nie jest konieczne odczytywanie i zapisywanie warto\u015bci.<\/p>\n<h3>Jak to wygl\u0105da<\/h3>\n<p>\nKoncepcja GATT polega na zgrupowaniu atrybut\u00f3w w tabeli atrybut\u00f3w w bardzo specyficzny i logiczny spos\u00f3b. Przejrzyjmy dok\u0142adniej profil cz\u0119sto\u015bci akcji serca przedstawiony poni\u017cej. Najlewsza kolumna tej tabeli jest opcjonalna. Opisuje, czym jest ten wiersz (atrybut). Wszystkie pozosta\u0142e kolumny s\u0105 nam ju\u017c znane.<\/p>\n<p><img decoding=\"async\" alt=\"BLE pod mikroskopem (ATT i GATT...)\" src=\"\/wp-content\/uploads\/2020\/06\/110813482dacb0f19cb49e735f4a9e34.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNa g\u00f3rze ka\u017cdej grupy zawsze znajduje si\u0119 atrybut og\u0142oszenia us\u0142ugi. Jego typ zawsze wynosi 0x2800, a wska\u017anik zale\u017cy od liczby atrybut\u00f3w ju\u017c obecnych w tabeli. Jego uprawnienia s\u0105 zawsze dost\u0119pne tylko do odczytu, bez \u017cadnej autoryzacji czy uwierzytelnienia. O tych poj\u0119ciach porozmawiamy p\u00f3\u017aniej. Warto\u015b\u0107 \u2014 to kolejny UUID, kt\u00f3ry okre\u015bla, co to za us\u0142uga. W tabeli warto\u015b\u0107 wynosi 0x180D, co jest zdefiniowane przez Bluetooth SIG jako us\u0142uga cz\u0119sto\u015bci akcji serca. <\/p>\n<p>Po og\u0142oszeniu us\u0142ugi nast\u0119puje og\u0142oszenie cechy. Pod wzgl\u0119dem formy przypomina og\u0142oszenie us\u0142ugi. Jego UUID zawsze wynosi 0x2803, a uprawnienia s\u0105 zawsze dost\u0119pne tylko do odczytu bez \u017cadnej autoryzacji czy uwierzytelnienia. Przyjrzyjmy si\u0119 polu Value Atrybutu, kt\u00f3re zawiera niekt\u00f3re dane. Zawsze zawiera wska\u017anik, UUID i zestaw w\u0142a\u015bciwo\u015bci. Te trzy elementy opisuj\u0105 kolejne og\u0142oszenie warto\u015bci cechy. Wska\u017anik naturalnie oznacza miejsce og\u0142oszenia warto\u015bci cechy w tabeli atrybut\u00f3w. UUID opisuje, jaki typ informacji lub warto\u015bci mo\u017cemy si\u0119 spodziewa\u0107. Na przyk\u0142ad warto\u015b\u0107 temperatury, stan prze\u0142\u0105cznika \u015bwiat\u0142a lub inna dowolna warto\u015b\u0107. I w ko\u0144cu w\u0142a\u015bciwo\u015bci, kt\u00f3re opisuj\u0105, jak mo\u017cna wchodzi\u0107 w interakcj\u0119 z warto\u015bci\u0105 cechy. <\/p>\n<p>Czeka nas tu kolejna pu\u0142apka. Dotyczy to uprawnie\u0144 atrybut\u00f3w i w\u0142a\u015bciwo\u015bci cech. Przyjrzyjmy si\u0119 obrazkowi z w\u0142a\u015bciwo\u015bciami bitowego pola w specyfikacji.<\/p>\n<p><img decoding=\"async\" alt=\"BLE pod mikroskopem (ATT i GATT...)\" src=\"\/wp-content\/uploads\/2020\/06\/7397f7f69e573ae3084cbacdcd318829.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJak wida\u0107, tutaj r\u00f3wnie\u017c znajduj\u0105 si\u0119 pola umo\u017cliwiaj\u0105ce odczyt i zapis. Mo\u017cesz zada\u0107 sobie pytanie, dlaczego mamy uprawnienia do odczytu\/zapisu dla atrybutu i w\u0142a\u015bciwo\u015bci. <br \/>\nCzytanie\/zapisywanie warto\u015bci cechy? Czy nie powinny one zawsze by\u0107 takie same? Rzecz w tym, \u017ce w\u0142a\u015bciwo\u015bci dla warto\u015bci cechy s\u0105 w rzeczywisto\u015bci jedynie zaleceniami dla klienta, stosowanymi w GATT oraz w warstwach aplikacyjnych. To po prostu wskaz\u00f3wki dotycz\u0105ce tego, czego klient mo\u017ce oczekiwa\u0107 od atrybutu og\u0142oszenia cechy. Zajmijmy si\u0119 tym bardziej szczeg\u00f3\u0142owo. Jakie rodzaje uprawnie\u0144 maj\u0105 atrybuty? <\/p>\n<p>1. Uprawnienia dost\u0119pu:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp; \u2014 do odczytu<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp; \u2014 do zapisu<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp; \u2014 do odczytu i zapisu<br \/>\n2. Uprawnienia uwierzytelniania:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp; \u2014 wymagane uwierzytelnienie<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp; \u2014 niewymagane uwierzytelnienie<br \/>\n3. Uprawnienia autoryzacji:<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp; \u2014 wymagana autoryzacja<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp; \u2014 niewymagana autoryzacja<\/p>\n<p>G\u0142\u00f3wna r\u00f3\u017cnica mi\u0119dzy uprawnieniami atrybut\u00f3w a w\u0142a\u015bciwo\u015bciami cech polega na tym, \u017ce pierwsze dotycz\u0105 serwer\u00f3w, a drugie klient\u00f3w. Serwer mo\u017ce mie\u0107 dozwolony odczyt warto\u015bci cechy, ale mo\u017ce tak\u017ce wymaga\u0107 uwierzytelnienia lub autoryzacji. Dlatego, gdy klient prosi o w\u0142a\u015bciwo\u015bci cechy, uzyskuje informacje, \u017ce odczyt jest dozwolony. Jednak gdy spr\u00f3buje dokona\u0107 odczytu, otrzyma b\u0142\u0105d. Mo\u017cna wi\u0119c \u015bmia\u0142o powiedzie\u0107, \u017ce uprawnienia maj\u0105 priorytet nad w\u0142a\u015bciwo\u015bciami. Nie mo\u017cemy jednak z perspektywy klienta zdoby\u0107 informacji o tym, jakie uprawnienia ma dany atrybut.<\/p>\n<h3>Descriptor<\/h3>\n<p>\nWr\u00f3\u0107my do naszej tabeli. Po og\u0142oszeniu warto\u015bci cechy mo\u017cliwe s\u0105 nast\u0119puj\u0105ce og\u0142oszenia atrybut\u00f3w: <br \/>\n1. Nowe og\u0142oszenie cechy (w us\u0142udze mo\u017ce by\u0107 wiele cech)<br \/>\n2. Nowa deklaracja us\u0142ugi (mo\u017ce ich by\u0107 wiele w tabeli)<br \/>\n3. Og\u0142oszenie deskryptora <\/p>\n<p>W przypadku charakterystyki pomiaru t\u0119tna w naszej tabeli og\u0142oszenie warto\u015bci charakterystyki towarzyszy og\u0142oszeniu deskryptora. Deskryptor to atrybut z dodatkowymi informacjami o charakterystyce. Istnieje kilka rodzaj\u00f3w deskryptor\u00f3w. O nich szczeg\u00f3\u0142owo porozmawiamy w drugiej cz\u0119\u015bci tego artyku\u0142u. Teraz skupimy si\u0119 tylko na deskryptorze konfiguracji charakterystyk klienta (Client Characteristic Configuration Descriptor \u2014 CCCD). Ma on UUID r\u00f3wny 0x2902. Dzi\u0119ki temu deskryptorowi klient ma mo\u017cliwo\u015b\u0107 w\u0142\u0105czenia na serwerze wskazania lub powiadomienia. R\u00f3\u017cnica mi\u0119dzy nimi jest niewielka, ale jednak istnieje. Powiadomienie nie wymaga potwierdzenia odbioru ze strony klienta. Wskazanie natomiast to wymaga, chocia\u017c dzieje si\u0119 to na poziomie GATT, nie docieraj\u0105c do poziomu aplikacji. Po co tak, zapytacie? Niestety, nie wiem. Mog\u0119 tylko powiedzie\u0107, \u017ce specjali\u015bci z Nordic-a zalecaj\u0105 u\u017cycie powiadomienia. Tym bardziej, \u017ce sprawdzenie integralno\u015bci pakietu (przy u\u017cyciu CRC) odbywa si\u0119 w obu przypadkach.<\/p>\n<h3>Podsumowanie<\/h3>\n<p>\nNa ko\u0144cu artyku\u0142u chcia\u0142bym powiedzie\u0107 o jednej rzeczy. Ostatnia tabela jest nieco myl\u0105ca. Zatrzyma\u0142em si\u0119 przy niej, poniewa\u017c jest podana w <noindex><a rel=\"nofollow\" href=\"https:\/\/devzone.nordicsemi.com\/nordic\/short-range-guides\/b\/bluetooth-low-energy\/posts\/ble-characteristics-a-beginners-tutorial\">artyku\u0142<\/a><\/noindex>, na kt\u00f3r\u0105 si\u0119 opieram. W drugiej cz\u0119\u015bci mojego artyku\u0142u zamierzam zg\u0142\u0119bi\u0107 specyfikacj\u0119 Bluetooth 4.0. Czekaj\u0105 nas tam dok\u0142adniejsze schematy i rysunki. W trzeciej cz\u0119\u015bci chcia\u0142bym przeanalizowa\u0107 log uzyskany za pomoc\u0105 programu Wireshark z jednego z gad\u017cet\u00f3w i zobaczy\u0107 \u201ena \u017cywo\u201d ca\u0142\u0105 t\u0119 teori\u0119, kt\u00f3r\u0105 wsp\u00f3lnie studiujemy.<\/p>\n<p>Pracownik Grupy Firm <noindex><a rel=\"nofollow\" href=\"https:\/\/www.csat.ru\/\">\"Cezar Satellite\"<\/a><\/noindex><br \/>\nW\u0142odzimierz Piecherski<br \/>\n<br \/>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/505078\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>BLE \u043f\u043e\u0434 \u043c\u0438\u043a\u0440\u043e\u0441\u043a\u043e\u043f\u043e\u043c (ATT\u044b GATT\u044b&#8230;) \u0427\u0430\u0441\u0442\u044c 1, \u043e\u0431\u0437\u043e\u0440\u043d\u0430\u044f \u0423\u0436\u0435 \u043f\u0440\u043e\u0448\u043b\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u0441 \u0442\u0435\u0445 \u043f\u043e\u0440, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b\u0448\u043b\u0430 \u043f\u0435\u0440\u0432\u0430\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043d\u0430 Bluetooth 4.0. \u0418, \u0445\u043e\u0442\u044f \u0442\u0435\u043c\u0430 BLE \u043e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430, \u043e\u043d\u0430 \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0433\u0438\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u0438\u0437-\u0437\u0430 \u0441\u0432\u043e\u0435\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u0412 \u0441\u0432\u043e\u0438\u0445 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u044f \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0441\u0430\u043c\u044b\u0439 \u043d\u0438\u0436\u043d\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c Link Layer \u0438 Physical Layer. [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":84025,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-84024","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"BLE \u043f\u043e\u0434 \u043c\u0438\u043a\u0440\u043e\u0441\u043a\u043e\u043f\u043e\u043c (ATT\u044b GATT\u044b...) \u0427\u0430\u0441\u0442\u044c 1.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/ble-pod-mikroskopom-atty-gatty\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47BLE \u043f\u043e\u0434 \u043c\u0438\u043a\u0440\u043e\u0441\u043a\u043e\u043f\u043e\u043c (ATT\u044b GATT\u044b\u2026) | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"BLE \u043f\u043e\u0434 \u043c\u0438\u043a\u0440\u043e\u0441\u043a\u043e\u043f\u043e\u043c (ATT\u044b GATT\u044b...) \u0427\u0430\u0441\u0442\u044c 1.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/ble-pod-mikroskopom-atty-gatty\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-06-04T17:42:32+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-06-04T17:42:32+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47BLE pod mikroskopem (ATT i GATT\u2026) | ProHoster","description":"BLE pod mikroskopem (ATT i GATT...) Cz\u0119\u015b\u0107 1.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/ble-pod-mikroskopom-atty-gatty","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47BLE \u043f\u043e\u0434 \u043c\u0438\u043a\u0440\u043e\u0441\u043a\u043e\u043f\u043e\u043c (ATT\u044b GATT\u044b\u2026) | ProHoster","og:description":"BLE \u043f\u043e\u0434 \u043c\u0438\u043a\u0440\u043e\u0441\u043a\u043e\u043f\u043e\u043c (ATT\u044b GATT\u044b...) \u0427\u0430\u0441\u0442\u044c 1.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/ble-pod-mikroskopom-atty-gatty","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-06-04T17:42:32+00:00","article:modified_time":"2020-06-04T17:42:32+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"84024","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 15:06:38","updated":"2022-09-28 11:11:59","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/84024","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=84024"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/84024\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/84025"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=84024"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=84024"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=84024"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}