11.6. Szolgáltatások és karakterisztikák¶
Miután a GAP két eszközt nyitott kapcsolatba hozott, a felette lévő rétegnek – a Generic Attribute Profile-nak, azaz GATT-nak – értelmet kell adnia a kapcsolaton átfolyó bájtoknak. A BLE itteni választása szokatlan. Míg a TCP egy nyers bájtfolyamot tár fel, és az alkalmazásra hagyja, hogy kitalálja a saját keretezését, a GATT egy kicsi kulcs/érték adatbázist tár fel, amelyet az egyik oldal gazdaként szolgáltat, a másik pedig olvas, ír vagy feliratkozik rá.
Az alkalmazástervezők BLE-vel töltött idejük nagy részét ezzel az adatbázissal töltik gondolkodva. Amit a kamera közzétesz egy telefonnak, amit egy távoli érzékelőn figyel, ahogyan egy Bluetooth-billentyűzet jelzi a gazdájának, melyik billentyűt nyomták le – mind karakterisztika-értékek valamely GATT-adatbázisban valahol.
11.6.1. Két szereptengely, nem egy¶
Gyakori zavarforrás: a peripheral / central és a server / client két független tengely, nem szinonimák.
A peripheral és a central GAP-szerepek, amelyeket a kapcsolat felépítésekor állítanak be. A peripheral hirdet és csatlakoznak hozzá; a central keres és kezdeményezi a kapcsolatot. Ez a kapcsolat létrejöttének pillanatában eldől, és nem változik.
A server és a client GATT-szerepek, amelyeket karakterisztika-műveletenként állítanak be. A server gazdája a karakterisztikának; a client olvassa, írja vagy feliratkozik rá.
A két tengelyt a specifikáció szétválasztja. Egy peripheral általában a server (egy pulzusmérő öv közzéteszi a méréseit), egy central pedig általában a client (egy telefon olvassa azokat), de a BLE bármilyen kombinációt megenged – egy peripheral felderíthet egy karakterisztikát azon a centralon, amelyhez épp csatlakozott, vagy egyetlen kapcsolat egyszerre szolgáltathat szolgáltatásokat mindkét oldalon.
A legtöbb kameraalkalmazás a hagyományos párosítást követi (peripheral + server, vagy central + client), ezért ennek a szakasznak a többi része egyetlen tengelyként kezeli őket, amikor a hagyományos esetet írja le. Amikor a megkülönböztetés számít, mindkét kifejezést kifejezetten kiírjuk.
11.6.2. Az adatbázis belseje¶
A GATT-adatbázis egy fa. A levelek hordozzák a tényleges bájtokat. Az ágak emberi szempontból értelmes egységekbe csoportosítják a kapcsolódó leveleket.
Egy GATT-adatbázis. A szolgáltatások csoportosítják a karakterisztikákat; a karakterisztikák hordozzák az alkalmazás bájtjait; a leírók metaadatokat hordoznak a karakterisztikáról.¶
Háromféle csomópont létezik:
A szolgáltatás kapcsolódó értékek logikai csoportja. A Bluetooth SIG szabványos szolgáltatásdefiníciókat tesz közzé gyakori használati esetekhez – Battery Service az akkumulátorszinthez, Environmental Sensing a hőmérséklethez / páratartalomhoz / nyomáshoz, Heart Rate a pulzusmérőkhöz –, így egy általános alkalmazás egy telefonon felismerhet egy olyan szolgáltatást, amelyet még soha nem látott. Egy alkalmazás szabadon definiálhat saját szolgáltatásokat is olyasmihez, amit a SIG nem szabványosított.
A karakterisztika egy szolgáltatáson belüli egyetlen elnevezett érték. A Battery szolgáltatásnak egyetlen karakterisztikája van – a Battery Level, egy egybájtos százalékérték. Az Environmental Sensingnek külön karakterisztikái vannak a hőmérséklethez, páratartalomhoz, nyomáshoz és így tovább. A karakterisztika a GATT-műveletek egysége – karakterisztikát olvasol, karakterisztikát írsz, karakterisztikára iratkozol fel.
A leíró egy karakterisztikához csatolt metaadat. Néhány leíró szabványosított – a Client Characteristic Configuration Descriptor (CCCD) a legismertebb, mert a rá írással mondja meg a client a servernek, hogy „küldj nekem értesítéseket erről a karakterisztikáról”. Mások felhasználó által definiáltak, és olyasmiket hordoznak, mint a megjelenítési formátum vagy a kiterjesztett tulajdonságok.
Egy GATT-server (jellemzően a peripheral) induláskor egyszer deklarálja az adatbázisát, és az adatbázis futás közben nem változik. Egy GATT-client (jellemzően a central) a csatlakozás után felderíti, mi van az adatbázisban – bejárja a fát, beolvassa a megtalált szolgáltatások UUID-jeit, majd az egyes szolgáltatásokon belüli karakterisztikákat.
11.6.3. UUID-k¶
Minden szolgáltatásnak, karakterisztikának és leírónak van egy UUID-je (Universally Unique IDentifier), amely azonosítja, milyen fajta dolog. Az UUID-k három szélességben léteznek:
16 bites. A Bluetooth SIG által definiált szabványok számára fenntartva. A Battery Service
0x180F. A Battery Level (egy karakterisztika)0x2A19. A teljes lista a Bluetooth SIG kiosztott-számok oldalán található közzétéve a https://www.bluetooth.com/specifications/assigned-numbers/ címen.32 bites. Ritkán használt középút.
128 bites. Amit mindenki más használ – egy gyártó vagy alkalmazás véletlenszerűen generál egyet, és ezt használja az egyedi szolgáltatásához vagy karakterisztikájához. A saját protokolljukat definiáló kamerák ide tartoznak.
A bluetooth.UUID osztály mindhárom szélességet elfogadja:
import bluetooth
BATTERY_SERVICE = bluetooth.UUID(0x180F)
CUSTOM_SERVICE = bluetooth.UUID("12345678-1234-5678-9abc-def012345678")
Egy 16 bites UUID kis hirdetési hasznos terhelésbe kódolódik, ami az egyik oka annak, hogy a szabványos szolgáltatások előnyösebbek, ha létezik ilyen – egy pulzusmérő öv, amely a 0x180D (Heart Rate) értéket hirdeti, két bájtba kerül; egy egyedi UUID tizenhatba. Olyan alkalmazásokhoz, amelyeknek nincs szükségük szabványos együttműködésre, a generált 128 bites UUID a helyes válasz.
11.6.4. Mit nyersz a SIG által szabványosított szolgáltatásokkal¶
A szabványos szolgáltatás használata melletti érv egyszerű: a meglévő alkalmazások már tudják, hogyan kommunikáljanak vele. Egy eszköz, amely a Heart Rate szolgáltatást (0x180D) hirdeti, és feltárja a Heart Rate Measurement karakterisztikát (0x2A37), a bolygó minden fitneszalkalmazásával működik anélkül, hogy bárkinek új kódot kellene írnia. Egy eszköz, amely ugyanazokat az adatokat egyedi UUID-kkel valósítja meg újra, saját kísérőalkalmazást és saját protokolldokumentumot igényel.
A szabványoknak ára van. Az egyes karakterisztikákon belüli bájtelrendezések specifikáltak – a SIG úgy döntött, hogy a Heart Rate Measurement egy egybájtos flag mező, amelyet vagy egy 8 bites, vagy egy 16 bites pulzusérték követ, opcionálisan R-R intervallumokkal kiegészítve –, és egy szabványkövető eszköznek követnie kell ezeket az elrendezéseket. Az egyedi szolgáltatások mentesek ettől a megkötéstől.
A pragmatikus válasz kamerákhoz: használj szabványos szolgáltatást, ha létezik ilyen az általad birtokolt adatfajtához (Battery Service, Environmental Sensing), és definiálj egy egyedit 128 bites UUID-vel bármihez, ami az alkalmazásodra specifikus.
11.6.5. Server-oldali és client-oldali objektumok¶
Ugyanazokhoz a fogalmi építőelemekhez (szolgáltatás, karakterisztika, leíró) minden GATT-könyvtár két párhuzamos objektumkészletet tár fel:
Server-oldali objektumok – amit a peripheral deklarál, hogy szolgáltat. Az
aioble-ben:aioble.Service,aioble.Characteristic,aioble.Descriptor. Ezek a hirdetés megkezdése előtt jönnek létre, és azaioble.register_services()segítségével regisztrálják őket.Client-oldali objektumok – amit a central a társon felfedez a csatlakozás után. Az
aioble-ben:aioble.ClientService,aioble.ClientCharacteristic,aioble.ClientDescriptor. Ezeket a csatlakozás után aaioble.DeviceConnection.service()/services()segítségével járják be.