BLE unter dem Mikroskop (ATTs GATTs…)

BLE unter dem Mikroskop (ATTs, GATTs...)

BLE unter dem Mikroskop (ATTs GATTs…)

Teil 1, Überblick

Es ist schon eine ganze Weile her, seit die erste Spezifikation für Bluetooth 4.0 veröffentlicht wurde. Und obwohl das Thema BLE sehr interessant ist, hält es viele Entwickler aufgrund seiner Komplexität immer noch auf Abstand. In meinen früheren Artikeln habe ich hauptsächlich die untersten Ebenen, die Link Layer und Physical Layer, behandelt. Dies ermöglichte es, nicht auf die komplexen und verworrenen Begriffe wie den Attributprotokoll (ATT) und das allgemeine Attributprofil (GATT) einzugehen. Doch man kommt nicht daran vorbei – ohne ihr Verständnis ist die Entwicklung kompatibler Geräte nicht möglich. Heute möchte ich mein Wissen mit Ihnen teilen. In meinem Artikel werde ich mich auf Lehrbuch für Einsteiger von der Seite Nordic stützen. Lassen Sie uns beginnen.

Warum ist alles so kompliziert?

Meiner Meinung nach war von Anfang an klar, dass die Steuerung von Geräten über Smartphones ein sehr zukunftsträchtiges und nachhaltiges Thema ist. Deshalb wurde beschlossen, es sofort umfassend zu strukturieren, damit die Hersteller verschiedener Gadgets keine eigenen Protokolle entwickeln, die später nicht kompatibel sein würden. Daher die Komplexität. Bereits in der ersten Phase wurde versucht, alles Mögliche in das BLE-Protokoll zu integrieren. Und es spielt keine Rolle, ob es später gebraucht wird oder nicht. Außerdem wurde die Möglichkeit vorgesehen, die Liste der Geräte für die Zukunft zu erweitern.

Schauen wir uns das Bild an, auf dem das Schema des BLE-Protokolls dargestellt ist. Es besteht aus mehreren Schichten. Die unterste physische Schicht (PHY) ist für den Funkkanal des Geräts verantwortlich. Link Layer (LL) enthält die gesamte Byte-Sequenz in der übertragenen Nachricht. In früheren Artikeln haben wir uns genau mit ihm beschäftigt. Das Host Controller Interface (HCI) ist das Protokoll für den Austausch zwischen den Schichten oder Chips des BLE, falls Controller und Host auf verschiedenen Chips implementiert sind. Für die Paketerstellung, die Aufteilung in Frames, die Fehlerkontrolle und die Zusammenstellung der Pakete ist das Logical Link Control and Adaptation Protocol (L2CAP) zuständig. Das Security Manager Protocol (SMP) ist für die Verschlüsselung der Pakete verantwortlich. Das allgemeine Zugangsprofil (GAP) ist verantwortlich für den anfänglichen Datenaustausch zwischen Geräten, um „Wer ist wer“ zu bestimmen. Dazu gehören auch das Scanning und das Advertising. In diesem Artikel werde ich mich auf die beiden verbleibenden Teile des Protokolls – GATT und ATT – konzentrieren. GATT ist ein Overlay über ATT, daher sind sie stark miteinander verwoben.

BLE unter dem Mikroskop (ATTs, GATTs...)

Um die Erzählung zu vereinfachen, möchte ich auf eine Analogie eingehen. Ich habe sie irgendwo gehört und möchte sie unterstützen. Stellen Sie sich ein BLE-Gerät als ein Bücherregal mit mehreren Regalen vor. Jedes Regal ist ein separates Thema. Zum Beispiel haben wir Regale mit Science-Fiction, Mathematik, Enzyklopädien. Auf jedem Regal stehen Bücher zu dem angegebenen Thema. Und in einigen Büchern gibt es sogar Papierlegemarken mit Notizen. Darüber hinaus haben wir einen kleinen Papierkatalog aller Bücher. Wenn Sie sich an Schulbibliotheken erinnern – das ist eine schmale Schublade mit Papierkarten. Bei dieser Analogie ist das Regal das Profil unseres Geräts. Die Regale sind die Dienste, die Bücher sind die Merkmale und der Katalog ist die Tabelle der Attribute. Die Legemarken in den Büchern sind die Deskriptoren, über die ich später ebenfalls ausführlicher sprechen werde.

Jeder, der Geräte entwickelt hat, weiß, dass in vielen Projekten ähnliche Codeabschnitte vorhanden sind. Das liegt daran, dass viele Geräte eine ähnliche Funktionalität besitzen. Zum Beispiel, wenn Geräte von Batterien betrieben werden, wird dasselbe Problem mit dem Aufladen und der Kontrolle ihres Niveaus auftreten. Gleiches gilt für Sensoren. Tatsächlich ermöglicht der objektorientierte Ansatz in der Programmierung „die Erstellung von Objekten, die Eigenschaften und Verhaltensweisen zu einer eigenständigen Einheit verbinden, die dann mehrfach verwendet werden kann“. Meiner Meinung nach wurde im BLE ein ähnlicher Ansatz versucht. Die Bluetooth Special Interest Group (SIG) hat Profile entwickelt. Geräte von verschiedenen Herstellern, die dieselben Profile haben, sollten problemlos miteinander funktionieren. Die Profile bestehen wiederum aus Diensten, und die Dienste aus Merkmalen, die durch Deskriptoren ergänzt werden. Im Allgemeinen könnte das so aussehen:

BLE unter dem Mikroskop (ATTs, GATTs...)

Als Beispiel betrachten wir das Schema des Herzfrequenzmonitors (Fitnessarmband). Es besteht aus zwei Diensten und mehreren Merkmalen. Daraus wird sofort die Hierarchie des Profils klar. Das Merkmal der Kontrollpunkt setzt die Gesamtsumme der Kalorienverbrauch auf null zurück.

1. Der Herzfrequenzdienst umfasst drei Merkmale (0x180D):
    a) Obligatorisches Merkmal der Herzfrequenz (0x2A37)
    b) Fakultatives Merkmal der Körperpositionssensor (0x2A38)
    c) Bedingtes Merkmal des Kontrollpunkts der Herzfrequenz (0x2A39)
2. Der Service für die Batteriepflege (0x180F):
    a) Obligatorische Kennzeichnung des Batterieladezustands (0x2A19)

UUID

Um eindeutig auf die Elemente des Profils (Dienste, Merkmale und Deskriptoren) zugreifen zu können, müssen diese einer Nummerierung unterzogen werden. Zu diesem Zweck wird das Konzept der Universally Unique ID (UUID) oder des Universellen eindeutigen Identifikators eingeführt. Die UUID ist in Klammern bei jeder Zeile angegeben. Und hier gibt es eine Besonderheit. Für UUIDs wurde ein Code mit einer Länge von 16 und 128 Bit verwendet. Warum, fragen Sie sich? Im BLE-Protokoll dreht sich alles um Energiesparen. Aus diesem Grund ist eine Dimension von 16 Bit durchaus sinnvoll. Es ist unwahrscheinlich, dass in naher Zukunft mehr als 65 Tausend einzigartige Dienste und Merkmale erstellt werden. Bis jetzt wurde alles, was möglich war, bereits gezählt (erinnern Sie sich an das Sprichwort — „Er hat auch Sie gezählt“ :-)) Nummerierte Elemente profile, Dienste, merkmale und deskriptoren können Sie über die Links einsehen.

Ich denke jedoch, dass sich alle an die Geschichte mit den 4 Byte IP-Adressen im Internet erinnern. Zuerst dachte man, das würde ausreichen, und jetzt können wir einfach nicht auf die 6 Byte Adresse umsteigen. Um diesen Fehler nicht zu wiederholen und den schelmischen Händen von Bastlern keinen Raum zu geben, beschloss der SIG gleich, auch 128-Bit UUIDs einzuführen. Das erinnert mich persönlich an das nicht lizenzierte Frequenzband von 433 MHz, das an verschiedene Bastler aus der Radiokanal-Community verkauft wurde. In unserem Fall wurde der 128-Bit Identifikator für Dienste und Merkmale zum Verkauf angeboten. Das bedeutet, dass wir für unsere Dienste und Geräte praktisch jeden 128-Bit Wert verwenden können. Die Wahrscheinlichkeit, dass zwei identische UUIDs erfunden werden, tendiert gegen Null.

Tatsächlich haben die kurzen 16-Bit UUIDs ihre Erweiterung auf einen 128-Bit Wert. In den Spezifikationen wird diese Erweiterung Bluetooth Base UUID genannt und hat den Wert 00000000-0000-1000-8000-00805F9B34FB. Wenn die 16-Bit UUID des Attributs beispielsweise den Wert 0x1234 hat, dann hat die entsprechende 128-Bit UUID den Wert 00001234-0000-1000-8000-00805F9B34FB. Es wird sogar eine entsprechende Formel angegeben:

                                128_bit_value = 16_bit_value * 2^96 + Bluetooth_Base_UUID

Woher diese magische Zahl stammt, ist mir nicht bekannt. Wenn jemand aus den Lesern es weiß, kann er in den Kommentaren schreiben (Der Benutzer mit dem Nicknamen Sinopteek hat dies bereits getan. Siehe Kommentare). Was das Erstellen von 128-Bit UUIDs betrifft, so kann man im Prinzip einen speziellen Generator, der das für Sie erledigt.

ATTs GATTs…

Tatsächlich beginnt jetzt das Interessanteste. Ich erinnere daran, dass ATT auf einer Client-Server-Beziehung basiert. Jetzt betrachten wir das Gerät des Servers. Es enthält Informationen wie Sensordaten, den Zustand des Lichtschalters, Standortdaten usw. Nun, da alle „Teilnehmer unserer Parade“ nummeriert sind, müssen sie im Speicher des Geräts angeordnet werden. Dazu platzieren wir sie in einer Tabelle, die als Attributtabelle bezeichnet wird. Merkt euch das gut. Das ist das Herzstück von BLE. Genau das werden wir weiter betrachten. Nun werden wir jede Zeile als Attribut bezeichnen. Diese Tabelle befindet sich tief im Stack und normalerweise haben wir keinen direkten Zugriff darauf. Wir initialisieren sie und greifen darauf zu, aber was dort innen passiert, bleibt hinter sieben Siegeln verborgen.

Betrachten wir das Bild aus der Spezifikation, jedoch möchte ich zuvor auf die häufige Verwirrung bei den Begriffen hinweisen, insbesondere bei den Deskriptoren. Die Rolle des Deskriptors besteht darin, die Beschreibung einer Eigenschaft zu ergänzen. Wenn man ihre Möglichkeiten erweitern muss, werden Deskriptoren verwendet. Sie sind ebenfalls Attribute und stehen gleichwertig zu Diensten und Eigenschaften in der Attributtabelle. Wir werden sie im zweiten Teil des Artikels ausführlich behandeln. Manchmal werden jedoch mit Deskriptoren die Zeilennummern in der Attributtabelle bezeichnet. Das sollte man im Hinterkopf behalten. Um Verwirrung zu vermeiden, verwenden wir hierfür den Begriff „Attributanzeiger“.
BLE unter dem Mikroskop (ATTs, GATTs...)

Ein Attribut ist also ein diskretes Wert, das die folgenden Eigenschaften besitzt:
1. Attributanzeiger (Attribute Handle) — das ist der Index der Tabelle, der dem Attribut entspricht
2. Attributtyp (Attribute Type) — das ist die UUID, die seinen Typ beschreibt
3. Attributwert (Attribute Value) — das sind die Daten, die durch den Attributanzeiger indiziert werden
4. Attributberechtigungen (Attribute Permissions) — dies ist der Teil des Attributs, dessen Berechtigungen nicht mit dem Attributprotokoll gelesen oder geschrieben werden können

Wie versteht man das alles? Der Attributanzeiger ist, um es vorsichtig auszudrücken, seine Nummer in unserer Tabelle.
Es ermöglicht dem Kunden, in Lese- oder Schreibanfragen auf ein Attribut zu verweisen. Wir können unsere Zeilen (Attribute) von 0x0001 bis 0xFFFF nummerieren. In unserer Assoziation mit einem Bücherregal ist dies die Kartennummer im Papierkatalog. Ähnlich wie im Bibliothekskatalog sind die Karten in aufsteigender Reihenfolge nummeriert. Die Nummer jeder nachfolgenden Zeile muss größer sein als die vorherige. Wie in der Bibliothek gehen manchmal einige Karten verloren, so dass auch in unserer Nummerierung der Zeilen Lücken auftreten können. Das ist zulässig. Wichtig ist, dass sie aufsteigend sind.

Der Attributtyp bestimmt, was dieses Attribut darstellt. Analog zur Programmiersprache C,
wo es Boolesche Variablen, numerische Variablen und Strings gibt, so gibt es auch hier Unterschiede. Anhand des Attributtyps erfahren wir,
womit wir es zu tun haben und wie wir mit diesem Attribut weiterarbeiten können. Unten werden wir einige spezifische Attributtypen betrachten. Zum Beispiel „Service Declaration“ (0x2800), „Characteristic Declaration“ (0x2803), „Descriptor Declaration“ (0x2902).

Der Attributwert ist genau das, was er bedeutet, entschuldigen Sie die Tautologie. Wenn der Attributtyp ein String ist, kann der Attributwert beispielsweise der Slogan „Hello World !!!“ sein. Wenn der Attributtyp „Service Declaration“ ist, besteht sein Wert im Dienst selbst. Manchmal handelt es sich auch um Informationen darüber, wo andere Attribute und deren Eigenschaften zu finden sind.

Die Berechtigungen der Attribute ermöglichen es dem Server zu verstehen, ob der Zugriff zum Lesen oder Schreiben erlaubt ist.
Bitte beachten Sie, dass diese Berechtigungen nur für den Attributwert gelten, nicht für den Zeiger, den Typ und das Feld der Berechtigungen selbst. Das heißt, wenn das Schreiben eines Attributs erlaubt ist, können wir zum Beispiel die Zeile „Hello World !!!“ in die Zeile „Good morning“ ändern. Aber wir können nicht das Hinzufügen einer neuen Zeile untersagen oder den Attributtyp ändern und die Zeile als „Service Declaration“ kennzeichnen. Wenn der Client auf den Server zugreift, fragt der Client nach seinen Attributen. Dies ermöglicht es dem Client, zu erfahren, was der Server bereitstellen kann. Es ist jedoch nicht notwendig, Werte zu lesen und zu schreiben.

Wie es aussieht

Das Konzept von GATT besteht darin, Attribute in der Attributtabelle in einer sehr spezifischen und logischen Reihenfolge zu gruppieren. Lassen Sie uns das Profil der Herzfrequenz, das unten aufgeführt ist, genauer betrachten. Die ganz linke Spalte dieser Tabelle ist optional. Sie beschreibt nur, was diese Zeile (Attribut) ist. Alle anderen Spalten sind uns bereits bekannt.

BLE unter dem Mikroskop (ATTs, GATTs...)

Immer an oberster Stelle jeder Gruppe haben wir das Attribut zur Dienstdeklaration. Sein Typ ist immer 0x2800, und der Zeiger hängt davon ab, wie viele Attribute bereits in der Tabelle vorhanden sind. Seine Berechtigungen sind stets nur lesbar und erfordern keine Authentifizierung oder Autorisierung. Über diese Konzepte werden wir später sprechen. Der Wert ist ein weiterer UUID, der bestimmt, um welchen Dienst es sich handelt. In der Tabelle hat der Wert 0x180D, der von Bluetooth SIG als Dienst für Herzfrequenzen definiert wird.

Nach der Dienstdeklaration folgt die Charakteristikdeklaration. In der Form ist sie analog zur Dienstdeklaration. Ihr UUID hat immer den Wert 0x2803, und die Berechtigungen sind ebenfalls stets nur lesbar, ohne dass eine Authentifizierung oder Autorisierung erforderlich ist. Lassen Sie uns das Feld Attributwert betrachten, das einige Daten umfasst. Es enthält immer einen Zeiger, UUID und eine Menge von Eigenschaften. Diese drei Elemente beschreiben die nachfolgende Deklaration des Charakteristikwerts. Der Zeiger bezeichnet natürlich den Ort der Deklaration des Charakteristikwerts in der Attributtabelle. Die UUID beschreibt, welche Art von Informationen oder Werten wir erwarten können. Zum Beispiel den Temperaturwert, den Status eines Lichtschalters oder einen anderen beliebigen Wert. Und schließlich die Eigenschaften, die beschreiben, wie man mit dem Charakteristikwert interagieren kann.

Hier wartet auf uns ein weiterer Stolperstein. Er steht im Zusammenhang mit den Berechtigungen der Attribute und den Eigenschaften der Charakteristiken. Lassen Sie uns das Bild der Eigenschaften des Bitfelds aus der Spezifikation betrachten.

BLE unter dem Mikroskop (ATTs, GATTs...)

Wie Sie sehen können, gibt es hier auch Felder, die Lese- und Schreibmöglichkeiten bieten. Sie könnten sich fragen, warum wir Berechtigungen für das Lesen/Schreiben für das Attribut und die Eigenschaften haben.
Lesen/Schreiben für den Wert der Eigenschaft? Sollten diese nicht immer gleich sein? Die Sache ist die, dass die Eigenschaften für den Wert der Eigenschaft tatsächlich nur Empfehlungen für den Kunden sind, die in GATT und Anwendungsschichten verwendet werden. Es sind einfach Hinweise darauf, was der Kunde von der Eigenschaftsdeklaration erwarten kann. Lassen Sie uns das näher betrachten. Welche Arten von Berechtigungen gibt es für die Eigenschaft?

1. Zugriffsberechtigungen:
     — lesen
     — schreiben
     — lesen und schreiben
2. Authentifizierungsberechtigung:
     — Authentifizierung erforderlich
     — Authentifizierung nicht erforderlich
3. Autorisierungsberechtigung:
     — Autorisierung erforderlich
     — Autorisierung nicht erforderlich

Der Hauptunterschied zwischen den Berechtigungen der Attribute und den Eigenschaften der Merkmale besteht darin, dass erstere sich auf Server beziehen, während letztere sich auf Kunden beziehen. Ein Server kann die Leseerlaubnis für den Wert des Merkmals haben, jedoch die Anforderung einer Authentifizierung oder Autorisierung bestehen. Daher werden wir, wenn der Kunde Eigenschaften des Merkmals anfordert, feststellen, dass das Lesen erlaubt ist. Bei dem Versuch, zu lesen, wird jedoch ein Fehler auftreten. Daher kann man mit Fug und Recht von der Priorität der Berechtigungen gegenüber den Eigenschaften sprechen. Das Wissen darüber, welche Berechtigungen das Attribut hat, können wir von der Kundenseite aus nicht erhalten.

Deskriptor

Kommen wir zurück zu unserer Tabelle. Nach der Deklaration des Wertes der Eigenschaft sind folgende Deklarationen der Attribute möglich:
1. Neue Merkmalsdeklaration (es kann viele Merkmale im Dienst geben)
2. Neue Dienstdeklaration (es kann viele davon in der Tabelle geben)
3. Deklaration des Deskriptors

Im Falle der Charakterisierung der Messung der Herzfrequenz wird in unserer Tabelle die Ankündigung des Wertzeichens von der Ankündigung des Deskriptors begleitet. Der Deskriptor ist ein Attribut mit zusätzlichen Informationen zur Charakteristik. Es gibt mehrere Arten von Deskriptoren. Darüber werden wir im zweiten Teil dieses Artikels ausführlich sprechen. Jetzt werden wir uns nur mit dem Deskriptor der Konfiguration der Client-Charakteristika (Client Characteristic Configuration Descriptor – CCCD) befassen. Er hat eine UUID von 0x2902. Mithilfe dieses Deskriptors hat der Client die Möglichkeit, die Anzeige oder Benachrichtigung auf dem Server zu aktivieren. Der Unterschied zwischen ihnen ist gering, aber dennoch vorhanden. Eine Benachrichtigung erfordert keine Bestätigung des Empfangs durch den Client. Eine Anzeige hingegen erfordert dies, auch wenn sie auf GATT-Ebene erfolgt und nicht bis zur Anwendungsebene gelangt. Warum ist das so, fragen Sie? Leider weiß ich das nicht. Ich kann nur sagen, dass die Experten von Nordic empfehlen, die Benachrichtigung zu verwenden. Zudem findet die Überprüfung der Integrität des Pakets (mittels CRC) in beiden Fällen statt.

Fazit

Am Ende des Artikels möchte ich Folgendes sagen. Die letzte Tabelle ist etwas verwirrend. Ich habe jedoch darauf bestanden, da sie in Artikel, auf die ich mich stütze. Im zweiten Teil meines Artikels beabsichtige ich, mich eingehender mit der Spezifikation von BlueTooth 4.0 zu beschäftigen. Dort erwarten uns genauere Diagramme und Zeichnungen. Im dritten Teil möchte ich ein Protokoll analysieren, das mit dem Programm Wireshark von einem der Gadgets erfasst wurde, und die gesamte Theorie, die wir zusammen lernen, „live“ sehen.

Mitarbeiter der Unternehmensgruppe „Cäsar Satellite“
Wladimir Pecherski

Quelle: habr.com

Zuverlässiges Hosting für Websites mit DDoS-Schutz kaufen, VPS VDS Server 🔥 Zuverlässiges Hosting für Websites mit DDoS-Schutz kaufen, VPS VDS Server - ProHoster