BLE onder een microscoop (ATTы GATTы…)

BLE onder een microscoop (ATTы GATTы...)

BLE onder een microscoop (ATTы GATTы…)

Deel 1, overzicht

Er is alweer een hele tijd verstreken sinds de eerste specificatie voor Bluetooth 4.0 uitkwam. En hoewel het BLE-onderwerp erg interessant is, schrikt het nog steeds veel ontwikkelaars af vanwege de complexiteit ervan. In mijn vorige artikelen heb ik vooral gekeken naar het laagste niveau, Linklaag en Fysieke Laag. Hierdoor konden we vermijden dat we onze toevlucht moesten nemen tot complexe en verwarrende concepten als het Attribute Protocol (ATT) en het General Attribute Profile (GATT). Je kunt echter nergens heen, zonder ze te begrijpen is het onmogelijk om compatibele apparaten te ontwikkelen. Vandaag wil ik deze kennis graag met jullie delen. In mijn artikel zal ik erop vertrouwen leerboek voor beginners van de Nordic website. Dus laten we beginnen.

Waarom is alles zo moeilijk?

Naar mijn mening was het meteen duidelijk dat het beheren van apparaten via smartphones een veelbelovend en langdurig onderwerp is. Daarom besloten ze om het onmiddellijk en maximaal te structureren. Zodat fabrikanten van verschillende gadgets niet met eigen protocollen komen, die dan incompatibel zijn. Vandaar de moeilijkheid. Al in de eerste fase probeerden ze al het mogelijke in het BLE-protocol te persen. En het maakt niet uit of het later nuttig zal zijn of niet. Bovendien voorzagen ze in de mogelijkheid om de lijst met apparaten voor de toekomst uit te breiden.

Laten we eens kijken naar de afbeelding waarop het BLE-protocoldiagram is getekend. Het bestaat uit verschillende lagen. De onderste, fysieke laag (PHY) is verantwoordelijk voor het radiokanaal van het apparaat. Link Layer(LL) bevat de volledige reeks bytes in het verzonden bericht. In eerdere artikelen hebben we precies dit onderzocht. Host Controller Interface (HCI) is een uitwisselingsprotocol tussen BLE-lagen of chips als de controller en host op verschillende chips zijn geïmplementeerd. Logical Link Control and Adaptation Protocol (L2CAP) is verantwoordelijk voor pakketvorming, framing, foutcontrole en pakketassemblage. Security Manager Protocol (SMP) is verantwoordelijk voor het coderen van pakketten. Het General Access Profile (GAP) is verantwoordelijk voor de initiële uitwisseling van gegevens tussen apparaten om te bepalen “Wie is wie”. Het omvat ook scannen en adverteren. In dit artikel zal ik me concentreren op de twee resterende delen van het protocol: GATT en ATT. GATT is een bovenbouw van ATT, dus ze zijn nauw met elkaar verweven.

BLE onder een microscoop (ATTы GATTы...)

Om het verhaal te vereenvoudigen, zou ik tot een analogie willen overgaan. Ik heb het ergens gehoord en wil het graag ondersteunen. Beschouw een BLE-apparaat als een boekenkast met meerdere planken. Elke plank heeft een apart thema. We hebben bijvoorbeeld planken met sciencefiction, wiskunde en encyclopedieën. Op elke plank staan ​​boeken met een bepaald onderwerp. En sommige boeken hebben zelfs papieren bladwijzers met aantekeningen. Daarnaast hebben we van alle boeken een kleine papieren catalogus. Weet je nog, schoolbibliotheken zijn een smalle doos met papieren kaarten. Met deze analogie is de kast het profiel van ons apparaat. Planken zijn diensten, boeken zijn kenmerken en de catalogus is een attributentabel. Bladwijzers in boeken zijn descriptoren, waar ik later ook meer in detail op zal ingaan.

Iedereen die apparaten heeft ontwikkeld, weet dat veel projecten vergelijkbare stukjes code bevatten. Feit is dat veel apparaten vergelijkbare functionaliteit hebben. Als apparaten bijvoorbeeld worden gevoed door batterijen, zal het probleem van het opladen en controleren van hun niveau hetzelfde zijn. Hetzelfde geldt voor sensoren. Eigenlijk een objectgeoriënteerde benadering van programmeren “biedt de mogelijkheid om objecten te creëren die eigenschappen en gedrag combineren tot een op zichzelf staande unie die vervolgens opnieuw kan worden gebruikt”. Naar mijn mening heeft BLE een soortgelijke aanpak geprobeerd. Profielen zijn ontwikkeld door de Bluetooth Special Interest Group (SIG). Apparaten van verschillende fabrikanten die dezelfde profielen hebben, zouden zonder problemen met elkaar moeten werken. Profielen bestaan ​​op hun beurt uit diensten en diensten over kenmerken, aangevuld met descriptoren. Over het algemeen zou het er zo uit kunnen zien:

BLE onder een microscoop (ATTы GATTы...)

Kijk bijvoorbeeld eens naar het profieldiagram van een hartslagmeter (fitnessarmband). Het bestaat uit twee diensten en verschillende kenmerken. Hieruit wordt de profielhiërarchie onmiddellijk duidelijk. De controlepuntkarakteristiek zet het totale aantal calorieën terug op nul.

1. De hartslagservice omvat drie kenmerken (0x180D):
    a) Verplichte hartslagkarakteristiek (0x2A37)
    b) Optionele lichaamssensorpositiekarakteristiek (0x2A38)
    c) Conditionele kenmerken van het hartslagcontrolepunt (0x2A39)
2. Onderhoudsservice voor de batterij (0x180F):
    a) Verplichte karakteristiek van het laadniveau van de batterij (0x2A19)

UUID

Om op unieke wijze toegang te krijgen tot profielelementen (diensten, kenmerken en descriptoren), moeten we ze allemaal op de een of andere manier nummeren. Voor dit doel wordt een concept geïntroduceerd zoals Universally Unique ID (UUID) of Universally Unique Identifier. De UUID wordt tussen haakjes van elke regel aangegeven. En er is hier één bijzonderheid. Voor UUID hebben we besloten een code van 16 en 128 bits lang te gebruiken. Waarom vraag je dat? In het BLE-protocol draait alles om energiebesparing. Daarom is de afmeting van 16 bits redelijk redelijk. Het is onwaarschijnlijk dat er in de nabije toekomst meer dan 65 duizend zullen worden gecreëerd. unieke diensten en kenmerken. Op dit moment had alles al geteld kunnen worden (onthoud waar dit vandaan kwam - "hij telde jou ook" :-)) Genummerde elementen profielen, van diensten, kenmerken и beschrijvingen je kunt naar de linkjes kijken.

Ik denk echter dat iedereen zich het verhaal herinnert met 4 bytes aan IP-adressen op internet. In eerste instantie dachten we dat dat genoeg was, maar nu kunnen we nog steeds niet overschakelen naar een adres van 6 bytes. Om deze fout niet te herhalen en de speelse handen van doe-het-zelvers de vrije loop te laten, besloot SIG onmiddellijk 128-bit UUID's te introduceren. Dit doet mij persoonlijk denken aan de niet-gelicentieerde 433 MHz-band, die aan allerlei Kulibins van het radiokanaal werd gegeven. In ons geval werd een 128-bits identificatie van diensten en kenmerken uitbesteed. Dit betekent dat wij voor onze diensten en apparaten vrijwel elke 128-bits waarde kunnen gebruiken. Toch neigt de kans om met dezelfde UUID te komen naar nul.

In feite hebben korte 16-bits UUID's hun uitbreiding tot een 128-bits waarde. In de specificatie heet deze extensie Bluetooth Base UUID en heeft de waarde 00000000-0000-1000-8000-00805F9B34FB. Als het 16-bits attribuut UUID bijvoorbeeld de waarde 0x1234 heeft, dan zal de equivalente 128-bits UUID de waarde 00001234-0000-1000-8000-00805F9B34FB hebben. En zelfs de bijbehorende formule wordt gegeven:

                                128_bit_waarde = 16_bit_waarde * 2^96 + Bluetooth_Base_UUID

Ik weet niet waar dit magische getal vandaan komt. Als een van de lezers het weet, laat hem dan in de reacties schrijven (een gebruiker met de bijnaam Sinopteek heeft dit al gedaan. Zie de reacties). Wat het bedenken van 128-bit UUID's betreft, kun je in principe een special gebruiken generatorwie zal het voor je doen.

ATTy GATTy...

Eigenlijk begint dan de pret. Ik wil u eraan herinneren dat ATT gebaseerd is op een client-serverrelatie. Nu kijken we naar het serverapparaat. Het bevat informatie zoals sensorwaarden, status van de lichtschakelaar, locatiegegevens, etc. Nu alle “deelnemers aan onze parade” zijn genummerd, moeten we ze op de een of andere manier in het geheugen van het apparaat plaatsen. Om dit te doen, plaatsen we ze in een tabel die een attributentabel wordt genoemd. Onthoud dit goed. Dit is het hart van BLE. Dit is wat we verder zullen overwegen. Nu zullen we elke regel een attribuut noemen. Deze tafel bevindt zich diep in de stapel en we hebben er in de regel geen directe toegang toe. We initialiseren het en hebben er toegang toe, maar wat er binnenin gebeurt, is voor ons verborgen achter zeven zegels.

Laten we eens kijken naar de afbeelding uit de specificatie, maar daarvoor zou ik onmiddellijk de aandacht willen vestigen op de vaak voorkomende verwarring in termen, namelijk in descriptoren. De rol van de descriptor is het aanvullen van de beschrijving van het kenmerk. Wanneer het nodig is om de mogelijkheden uit te breiden, worden descriptoren gebruikt. Het zijn ook attributen, en net als diensten en kenmerken bevinden ze zich in de attributentabel. We zullen ze in het tweede deel van het artikel in detail onderzoeken. Soms verwijzen descriptors echter naar het rijnummer in de attributentabel. Dit moet in gedachten worden gehouden. Om verwarring te voorkomen gebruiken we voor deze doeleinden de term ‘attribuutaanwijzer’.
BLE onder een microscoop (ATTы GATTы...)

Een attribuut is dus een discrete waarde waaraan de volgende eigenschappen zijn gekoppeld:
1. Attribuuthandle is de tabelindex die overeenkomt met het attribuut
2. Attribuuttype is een UUID die het type ervan beschrijft
3. Attribuutwaarde zijn de gegevens die zijn geïndexeerd door de attribuutaanwijzer
4. Attribuutmachtigingen zijn het deel van een attribuut, de machtigingen, dat niet kan worden gelezen of geschreven met behulp van het attribuutprotocol

Hoe dit allemaal te begrijpen? De attribuutwijzer is, relatief gezien, het nummer ervan in onze tabel.
Hiermee kan een client naar een attribuut verwijzen in lees- of schrijfverzoeken. We kunnen onze regels (attributen) nummeren van 0x0001 tot 0xFFFF. In onze associatie met de boekenkast is dit het kaartnummer in de papieren catalogus. Op dezelfde manier zijn de kaarten, net als in de bibliotheekcatalogus, gerangschikt in oplopende volgorde van aantal. Het nummer van elke volgende regel moet groter zijn dan de vorige. Net als in de bibliotheek gaan er wel eens kaarten verloren, dus bij ons kunnen er gaten in de regelnummering zitten. Dit is toegestaan. Het belangrijkste is dat ze geleidelijk gaan.

Het attribuuttype bepaalt wat het attribuut vertegenwoordigt. Naar analogie met de C-taal,
waar er booleaanse, numerieke variabelen en strings zijn, dus het is hier. Per attribuuttype herkennen we
waar we mee te maken hebben en hoe we met dit kenmerk kunnen blijven werken. Hieronder zullen we enkele specifieke soorten attributen bekijken. Bijvoorbeeld ‘servicedeclaratie’ (0x2800), ‘karakteristiekdeclaratie’ (0x2803), ‘descriptordeclaratie’ (0x2902).

De waarde van een attribuut is de werkelijke betekenis ervan, vergeef de tautologie. Als het attribuuttype een string is, kan de attribuutwaarde bijvoorbeeld de slogan “Hallo wereld !!!” zijn. Als het attribuuttype een “servicedeclaratie” is, dan is de waarde ervan de service zelf. En soms is dit informatie over waar u andere attributen en hun eigenschappen kunt vinden.

Met kenmerkmachtigingen kan de server begrijpen of lees- of schrijftoegang is toegestaan.
Houd er rekening mee dat deze machtigingen alleen van toepassing zijn op de attribuutwaarde, en niet op het pointer-, type- of machtigingsveld zelf. Die. als attribuutopname is toegestaan, kunnen we bijvoorbeeld de regel "Hallo wereld !!!" wijzigen op de regel “Goedemorgen”. Maar we kunnen het schrijven van een nieuwe regel niet verbieden of het attribuuttype wijzigen en de regel aanduiden als een “servicedeclaratie”. Wanneer een client contact opneemt met een server, vraagt ​​de client om de attributen ervan. Hierdoor weet de client wat de server kan bieden. Hoewel het niet nodig is om de waarden te lezen en te schrijven.

Hoe het eruit ziet

Het concept van GATT is om attributen in een attributentabel te groeperen in een zeer specifieke en logische volgorde. Laten we het onderstaande hartslagprofiel eens nader bekijken. De meest linkse kolom van deze tabel is optioneel. Het beschrijft eenvoudigweg wat deze lijn (attribuut) is. Alle andere columns zijn ons al bekend.

BLE onder een microscoop (ATTы GATTы...)

Bovenaan elke groep hebben we altijd een servicedeclaratieattribuut. Het type is altijd 0x2800 en de aanwijzer is afhankelijk van het aantal attributen dat al in de tabel aanwezig is. De machtigingen zijn altijd alleen-lezen, zonder enige authenticatie of autorisatie. We zullen iets later over deze concepten praten. De waarde is een andere UUID die identificeert wat de service is. In de tabel is de waarde 0x180D, die door Bluetooth SIG is gedefinieerd als een hartslagservice.

Na de aankondiging van de dienst volgt de aankondiging van het kenmerk. Het is qua vorm vergelijkbaar met een dienstverklaring. De UUID is altijd 0x2803 en de machtigingen zijn altijd alleen-lezen zonder enige authenticatie of autorisatie. Laten we eens kijken naar het veld Kenmerkwaarde, dat enkele gegevens bevat. Het bevat altijd een pointer, een UUID en een reeks eigenschappen. Deze drie elementen beschrijven de daaropvolgende verklaring van de karakteristieke waarde. De aanwijzer geeft uiteraard de locatie aan van de karakteristieke waardedeclaratie in de attributentabel. De UUID beschrijft welk type informatie of waarde we kunnen verwachten. Bijvoorbeeld de temperatuurwaarde, de status van de lichtschakelaar of een andere willekeurige waarde. En tenslotte eigenschappen, die beschrijven hoe er met de karakteristieke waarde kan worden gecommuniceerd.

Hier wacht ons nog een valkuil. Het wordt geassocieerd met attribuutrechten en karakteristieke eigenschappen. Laten we eens kijken naar de afbeelding van de bitveldeigenschappen uit de specificatie.

BLE onder een microscoop (ATTы GATTы...)

Zoals u kunt zien, zijn er hier ook velden die lees- en schrijfmogelijkheden bieden. U vraagt ​​zich misschien af ​​waarom we lees-/schrijfrechten hebben voor attribuut en eigenschap
lezen/schrijven voor karakteristieke waarde? Moeten ze niet altijd hetzelfde zijn? Feit is dat de eigenschappen voor de karakteristieke waarde eigenlijk slechts aanbevelingen zijn voor de client die wordt gebruikt in GATT en applicatielagen. Dit zijn eenvoudigweg hints over wat de cliënt zou kunnen verwachten van het karakteristieke declaratieattribuut. Laten we dit in meer detail bekijken. Welke soorten machtigingen heeft een attribuut?

1. Toegangsrechten:
     - lezing
     - dossier
     - lezen en schrijven
2. Authenticatietoestemming:
     - verificatie vereist
     - geen authenticatie vereist
3. Autorisatie toestemming:
     - Autorisatie vereist
     - geen toestemming vereist

Het belangrijkste verschil tussen attribuutresolutie en karakteristieke eigenschappen is dat de eerste van toepassing zijn op servers, en de laatste op clients. De server mag de karakteristieke waarde lezen, maar kan authenticatie of autorisatie vereisen. Wanneer de klant de eigenschappen van het kenmerk opvraagt, krijgen wij dus te horen dat uitlezen is toegestaan. Maar als we proberen te lezen, krijgen we een foutmelding. Daarom kunnen we veilig praten over de prioriteit van machtigingen boven eigendommen. Aan de clientzijde kunnen we geen kennis verkrijgen over welke machtigingen een attribuut heeft.

Beschrijving

Laten we terugkeren naar onze tafel. Na het declareren van de waarde van een kenmerk zijn de volgende attribuutdeclaraties mogelijk:
1. Nieuwe kenmerkenverklaring (een dienst kan veel kenmerken hebben)
2. Nieuwe dienstverklaring (mogelijk staan ​​er veel in de tabel)
3. Een handvat declareren

In het geval van de hartslagmetingskarakteristiek gaat in onze tabel de verklaring van de karakteristieke waarde vergezeld van de verklaring van de descriptor. Een descriptor is een attribuut met aanvullende informatie over een kenmerk. Er zijn verschillende soorten descriptoren. We zullen er in het tweede deel van dit artikel in detail over praten. Voorlopig zullen we alleen ingaan op de Client Characteristic Configuration Descriptor (CCCD). Het heeft een UUID gelijk aan 0x2902. Met behulp van deze descriptor heeft de client de mogelijkheid om indicatie of notificatie op de server mogelijk te maken. Het verschil daartussen is klein, maar nog steeds aanwezig. Voor de melding is geen ontvangstbevestiging van de opdrachtgever vereist. Indicatie vereist dit, hoewel dit op GATT-niveau gebeurt en niet op toepassingsniveau. Waarom zo, vraag je? Helaas, ik weet dit niet. Laat ik zeggen dat Scandinavische experts aanbevelen om meldingen te gebruiken. Bovendien vindt in beide gevallen controle van de integriteit van het pakket (met behulp van CRC) plaats.

Conclusie

Aan het einde van het artikel zou ik dit willen zeggen. De laatste tabel is een beetje verwarrend. Ik heb er echter voor gekozen omdat het gegeven is статье, waar ik op vertrouw. In het tweede deel van mijn artikel ben ik van plan dieper in te gaan op de BlueTooth 4.0-specificatie. Daar wachten ons meer correcte diagrammen en tekeningen. In het derde deel zou ik graag het logboek willen ontleden dat is verkregen met behulp van het Wireshark-programma van een van de gadgets en 'live' alle theorie willen zien die we bestuderen.

Medewerker van de bedrijvengroep "Caesar-satelliet"
Pecherskikh Vladimir

Bron: www.habr.com

Voeg een reactie