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

BLE unter dem Mikroskop (ATTs GATTs...)

BLE unter dem Mikroskop (ATTs und GATTs…)

Teil 1, Überblick

Es ist schon einige Zeit vergangen, seit die erste Spezifikation für Bluetooth 4.0 veröffentlicht wurde. Obwohl das Thema BLE sehr interessant ist, schreckt es viele Entwickler aufgrund seiner Komplexität ab. In meinen vorherigen Artikeln habe ich hauptsächlich die untersten Ebenen, Link Layer und Physical Layer, behandelt. Dies verhinderte, dass ich mich mit so komplexen und verworrenen Konzepten wie dem Attribut-Protokoll (ATT) und dem allgemeinen Attributprofil (GATT) befassen musste. Allerdings gibt es keinen Weg daran vorbei: Ohne Verständnis dieser Konzepte ist die Entwicklung kompatibler Geräte nicht möglich. Heute möchte ich dieses Wissen mit Ihnen teilen. In meinem Artikel werde ich mich auf Tutorial Einsteigerressourcen von Nordic stützen. Also, lassen Sie uns beginnen.

Warum ist alles so kompliziert?

Meiner Meinung nach war sofort klar, dass die Verwaltung von Geräten über Smartphones ein sehr vielversprechendes und langfristiges Thema ist. Daher haben wir beschlossen, es von Anfang an strukturiert und maximal auszubauen. So können Hersteller verschiedener Geräte keine eigenen Protokolle entwickeln, die dann nicht kompatibel sind. Dies führte zu einer gewissen Komplexität. Schon in der ersten Phase haben wir versucht, im BLE-Protokoll alles unterzubringen, was nur möglich war – unabhängig davon, ob es später nützlich sein wird oder nicht. Außerdem haben wir die Möglichkeit vorgesehen, die Liste der Geräte in Zukunft zu erweitern.

Lassen Sie uns einen Blick auf das Bild werfen, das das Protokollschema von BLE zeigt. Es besteht aus mehreren Schichten. Die unterste, die physische Schicht (PHY), ist für den Funkkanal des Gerätes verantwortlich. Die Link-Schicht (LL) enthält die gesamte Byte-Sequenz der gesendeten Nachricht. In früheren Artikeln haben wir uns genau damit beschäftigt. Das Host Controller Interface (HCI) ist das Protokoll für den Austausch zwischen den Schichten oder Chips von BLE, wenn der Controller und das Host auf unterschiedlichen Chips implementiert sind. Für die Paketbildung, die Segmentierung in Frames, die Fehlerkontrolle und das Zusammenfügen von Paketen ist das Logical Link Control and Adaptation Protocol (L2CAP) zuständig. Die Verschlüsselung der Pakete erfolgt durch das Security Manager Protocol (SMP). Das General Access Profile (GAP) ist für den initialen Datenaustausch zwischen den Geräten verantwortlich, um festzustellen, „wer wer ist“. Dazu gehören auch Scanning und Advertising. In diesem Artikel werde ich auf die beiden verbleibenden Teile des Protokolls eingehen – GATT und ATT. GATT ist eine Erweiterung von ATT, weshalb sie eng miteinander verwoben sind.

BLE unter dem Mikroskop (ATTs GATTs...)

Um die Erzählung zu vereinfachen, möchte ich eine Analogie verwenden. 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 repräsentiert ein bestimmtes Thema. Zum Beispiel haben wir Regale mit Science-Fiction, Mathematik und Enzyklopädien. Auf jedem Regal stehen Bücher zu dem angegebenen Thema. In manchen Büchern befinden sich sogar Papiermarkierungen mit Notizen. Darüber hinaus haben wir einen kleinen Papierkatalog aller Bücher. Wenn Sie sich an Schulbibliotheken erinnern — das ist ein schmaler Kasten mit Papierkarten. In dieser Analogie ist das Regal das Profil unseres Geräts. Die Regale sind die Dienste, die Bücher sind die Eigenschaften und der Katalog ist die Attributtabelle. Die Markierungen in den Büchern sind die Deskriptoren, über die ich später noch ausführlicher sprechen werde.

Jeder, der Geräte entwickelt, weiß, dass in vielen Projekten ähnliche Code Fragmente vorhanden sind. Das liegt daran, dass viele Geräte ähnliche Funktionen bieten. Zum Beispiel wird bei Geräten, die mit Akkus betrieben werden, das Problem des Ladevorgangs und der Überwachung des Akkustands gleich sein. Dasselbe gilt für Sensoren. Tatsächlich verfolgt der objektorientierte Programmieransatz „die Möglichkeit, Objekte zu erstellen, die Eigenschaften und Verhaltensweisen in einer eigenständigen Einheit verbinden, die dann mehrfach verwendet werden kann“. Meiner Meinung nach wurde im BLE ein ähnlicher Ansatz verfolgt. Die Gruppe der Bluetooth Special Interest Group (SIG) hat Profile entwickelt. Geräte verschiedener Hersteller, die über dieselben Profile verfügen, sollten problemlos miteinander arbeiten. Die Profile bestehen wiederum aus Diensten, und die Dienste aus Merkmalen, die durch Deskriptoren ergänzt werden. Allgemein könnte das so aussehen:

BLE unter dem Mikroskop (ATTs GATTs...)

Als Beispiel betrachten wir das Profil des Herzfrequenzmonitors (Fitnessarmband). Es besteht aus zwei Diensten und mehreren Eigenschaften. Dadurch wird die Hierarchie des Profils sofort verständlich. Die Eigenschaft des Kontrollpunkts setzt die Gesamtkalorienverbrauchszählung auf null zurück.

1. Der Herzfrequenzdienst umfasst drei Eigenschaften (0x180D):
    a) Obligatorische Eigenschaft der Herzfrequenz (0x2A37)
    b) Optionale Eigenschaft der Körperpositionssensorik (0x2A38)
    c) Bedingte Eigenschaft des Herzfrequenzkontrollpunkts (0x2A39)
2. Der Batteriedienst (0x180F):
    a) Obligatorische Eigenschaft des Batteriestands (0x2A19)

UUID

Um eindeutig auf die Profilelemente (Dienste, Merkmale und Deskriptoren) zugreifen zu können, müssen wir ihnen eine Nummer zuweisen. Hierzu wird das Konzept der Universally Unique ID (UUID) oder des Universellen eindeutigen Identifikators eingeführt. In Klammern jeder Zeile ist genau dieser UUID angegeben. Dabei gibt es eine Besonderheit: Für UUIDs hat man sich für eine Länge von 16 und 128 Bit entschieden. Warum, fragen Sie sich? Im BLE-Protokoll steht die Energieeinsparung im Vordergrund. Daher erscheint die Dimension von 16 Bit durchaus sinnvoll. Wohl kaum werden in naher Zukunft mehr als 65.000 einzigartige Dienste und Merkmale entstehen. Bis jetzt ist alles, was möglich war, bereits gezählt worden (merken Sie sich, woher das kommt — „er hat auch Sie gezählt“ :-)). Nummerierte Elemente Profilelemente, Dienste, Merkmale und Deskriptoren können Sie über die Links einsehen.

Ich denke, jeder erinnert sich an die Geschichte mit den 4 Byte IP-Adressen im Internet. Zunächst dachte man, das reicht aus, aber wir haben es immer noch nicht geschafft, auf 6-Byte-Adressen umzusteigen. Um einen solchen Fehler nicht zu wiederholen und den kreativen Köpfen von Hobbybastlern nicht zu viel Raum zu geben, hat SIG beschlossen, auch 128-Bit UUIDs einzuführen. Das erinnert mich an den nicht lizenzierten Frequenzbereich von 433 MHz, der verschiedenen Erfindern überlassen wurde. In unserem Fall wurde der 128-Bit-Identifikator für Dienste und Merkmale freigegeben. Das bedeutet, dass wir für unsere Dienste und Geräte nahezu jeden beliebigen 128-Bit-Wert verwenden können. Die Wahrscheinlichkeit, einen identischen UUID zu erstellen, neigt gegen null.

In der Tat haben die kurzen 16-Bit UUIDs ihre Erweiterung auf 128-Bit-Werte. In der Spezifikation wird diese Erweiterung als Bluetooth Basis UUID bezeichnet und hat den Wert 00000000-0000-1000-8000-00805F9B34FB. Wenn die 16-Bit UUID eines Attributs beispielsweise den Wert 0x1234 hat, dann wird die entsprechende 128-Bit UUID den Wert 00001234-0000-1000-8000-00805F9B34FB haben. Es wird sogar die entsprechende Formel angegeben:

                                128_bit_value = 16_bit_value * 2^96 + Bluetooth_Base_UUID

Woher diese magische Zahl stammt, ist mir nicht bekannt. Wenn einer der Leser es weiß, möge er es in den Kommentaren schreiben (Der Nutzer mit dem Nickname Sinopteek hat das bereits getan. Siehe Kommentare). Was die Erstellung von 128-Bit UUIDs betrifft, so kann man im Grunde einen speziellen Generatorverwenden, der das für Sie erledigt.

ATTs GATTs…

Nun kommt der spannendste Teil. Ich möchte daran erinnern, dass ATT auf einem Client-Server-Modell basiert. Jetzt betrachten wir die Struktur des Servers. Dieser enthält Informationen wie Sensorwerte, den Zustand des Lichtschalters, Standortdaten usw. Jetzt, da alle «Teilnehmer unserer Parade» nummeriert sind, müssen wir sie im Speicher des Geräts anordnen. Dafür legen wir sie in eine Tabelle, die als Attributtabelle bekannt ist. Merken Sie sich das gut. Das ist das Herzstück von BLE. Genau das werden wir hier weiter betrachten. Jede Zeile nennen wir ein Attribut. Diese Tabelle befindet sich tief im Stack und normalerweise haben wir keinen direkten Zugriff darauf. Wir initialisieren sie und greifen auf sie zu, aber was intern geschieht, bleibt uns hinter sieben Siegeln verborgen.

Betrachten wir das Bild aus den Spezifikationen, jedoch möchte ich zuvor auf die häufige Verwirrung in den Begriffen hinweisen, insbesondere in Bezug auf Deskriptoren. Die Rolle des Deskriptors besteht darin, die Beschreibung einer Eigenschaft zu ergänzen. Wenn es notwendig ist, die Möglichkeiten zu erweitern, werden Deskriptoren verwendet. Sie sind ebenfalls Attribute und werden zusammen mit den Services und Eigenschaften in der Attributtabelle angeordnet. Wir werden diese im zweiten Teil des Artikels ausführlich behandeln. Es kommt jedoch vor, dass Deskriptoren die Zeilennummer in der Attributtabelle bezeichnen. Das sollte man im Hinterkopf behalten. Um keine Verwirrung zu stiften, werden wir für diese Zwecke den Begriff „Attributzeiger“ verwenden.
BLE unter dem Mikroskop (ATTs GATTs...)

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

Wie ist das alles zu verstehen? Ein Attributzeiger ist sozusagen seine Nummer in unserer Tabelle.
Er ermöglicht es dem Kunden, auf das Attribut in Lese- oder Schreibanfragen zu verweisen. Wir können unsere Zeilen (Attribute) von 0x0001 bis 0xFFFF nummerieren. In unserer Assoziation mit einem Bücherregal entspricht dies der Nummer der Karte im Papierkatalog. Ähnlich wie im Bibliothekskatalog sind die Karten in aufsteigender Reihenfolge angeordnet. Die Nummer jeder nachfolgenden Zeile muss größer als die vorherige sein. Wie in einer Bibliothek können manchmal Karten verloren gehen, so können auch in unserer Zeilennummerierung Lücken auftreten. Das ist zulässig. Wichtig ist, dass sie in aufsteigender Reihenfolge fortlaufen.

Der Typ des Attributs bestimmt, was dieses Attribut darstellt. Ähnlich wie in der Programmiersprache C,
wo es boolesche, numerische Variablen und Strings gibt, ist es auch hier. Anhand des Typs des Attributs erfahren wir,
mit was wir es zu tun haben und wie wir weiter mit diesem Attribut arbeiten können. Nachfolgend werden wir einige spezifische Typen von Attributen betrachten. Zum Beispiel die „Service-Deklaration“ (0x2800), die „Charakteristik-Deklaration“ (0x2803) und die „Descriptor-Deklaration“ (0x2902).

Der Wert eines Attributs ist sein tatsächlicher Wert, um es einfach auszudrücken. Ist der Typ des Attributs ein String, könnte der Wert beispielsweise das Motto „Hello World !!!“ sein. Handelt es sich um eine „Serviceerklärung“, so ist der Wert der Service selbst. Manchmal handelt es sich auch um Informationen, wo andere Attribute und deren Eigenschaften zu finden sind.

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

So sieht das aus

Das Konzept von GATT besteht darin, die Attribute in der Attributtabelle in einer sehr spezifischen und logischen Reihenfolge zu gruppieren. Werfen wir einen genaueren Blick auf das nachstehende Profil der Herzfrequenz. Die ganz linke Spalte dieser Tabelle ist nicht verpflichtend. Sie beschreibt lediglich, was diese Zeile (Attribut) darstellt. Alle anderen Spalten sind uns bereits vertraut.

BLE unter dem Mikroskop (ATTs GATTs...)

Am oberen Ende jeder Gruppe haben wir immer das Attribut der Dienstbeschreibung. 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, ohne irgendeine Authentifizierung oder Autorisierung. Über diese Konzepte werden wir später sprechen. Der Wert ist ein weiterer UUID, der definiert, um welchen Dienst es sich handelt. In der Tabelle hat der Wert 0x180D, der von der Bluetooth SIG als Dienst für Herzfrequenz definiert wird.

Nach der Ankündigung des Dienstes folgt die Beschreibung der Eigenschaften. In seiner Form ist es ähnlich wie die Ankündigung des Dienstes. Seine UUID hat immer den Wert 0x2803, und die Berechtigungen sind ebenfalls stets nur lesbar, ohne jegliche Authentifizierung oder Autorisierung. Schauen wir uns das Feld 'Attributwert' an, das einige Daten enthält. Es enthält immer einen Zeiger, eine UUID und eine Menge von Eigenschaften. Diese drei Elemente beschreiben die anschließende Anzeige des Attributwerts. Der Zeiger gibt natürlicherweise die Position der Anzeige des Attributwerts in der Attributtabelle an. Die UUID beschreibt, welche Art von Information oder Wert wir erwarten können. Zum Beispiel den Temperaturwert, den Zustand des Lichtschalters oder einen anderen beliebigen Wert. Und schließlich die Eigenschaften, die beschreiben, wie man mit dem Attributwert interagieren kann.

Hier erwartet uns ein weiteres Hindernis. Es bezieht sich auf die Berechtigungen der Attribute und die Eigenschaften der Merkmale. Lassen Sie uns das Bild der Bitfeld-Eigenschaften aus der Spezifikation betrachten.

BLE unter dem Mikroskop (ATTs GATTs...)

Wie Sie sehen, gibt es hier ebenso Felder, die Lese- und Schreibmöglichkeiten bieten. Sie fragen sich vielleicht, warum wir Lese-/Schreibberechtigungen für die Attribute und Eigenschaften haben.
So sollten die Lesefähigkeit und Schreibfähigkeit für den Wert der Eigenschaft nicht immer gleich sein? Tatsächlich sind die Eigenschaften für den Wert der Eigenschaft lediglich Empfehlungen für den Kunden, die in GATT und Anwendungsschichten verwendet werden. Es sind einfach Hinweise darauf, was der Kunde von dem Attribut der Merkmalsbeschreibung erwarten kann. Lassen Sie uns das genauer betrachten. Welche Arten von Berechtigungen gibt es für das Attribut?

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 von Attributen und den Eigenschaften von Merkmale besteht darin, dass erstere sich auf Server beziehen, während letztere auf Clients zutreffen. Ein Server kann beispielsweise das Lesen des Wertes einer Eigenschaft erlauben, jedoch könnte eine Authentifizierung oder Autorisierung erforderlich sein. Daher erhalten wir bei der Abfrage von Eigenschaftswerten durch den Client die Rückmeldung, dass das Lesen erlaubt ist, jedoch tritt bei einem Leseversuch ein Fehler auf. Daher kann man mit Sicherheit sagen, dass Berechtigungen über den Eigenschaften stehen. Informationen darüber, welche Berechtigungen ein Attribut hat, können wir von der Client-Seite aus nicht abrufen.

Deskriptor

Lassen Sie uns zu unserer Tabelle zurückkehren. Nach der Deklaration eines Eigenschaftswertes sind folgende Attributdeklarationen möglich:
1. Neue Deklaration eines Merkmals (es kann viele Merkmale im Dienst geben)
2. Neue Deklaration eines Dienstes (es kann viele davon in der Tabelle geben)
3. Deklaration des Deskriptors

Wenn es um die Messung der Herzfrequenz geht, wird in unserer Tabelle der Wert der Eigenschaft von einer Beschreibung begleitet. Die Beschreibung ist ein Attribut mit zusätzlichen Informationen zur Eigenschaft. Es gibt mehrere Arten von Beschreibungen. Auf diese werden wir in Teil zwei dieses Artikels ausführlich eingehen. Jetzt betrachten wir nur den Konfigurationsdescriptor der Kundeneigenschaft (Client Characteristic Configuration Descriptor – CCCD). Dieser hat eine UUID von 0x2902. Mit diesem Descriptor hat der Kunde die Möglichkeit, die Anzeige oder Benachrichtigung auf dem Server zu aktivieren. Der Unterschied zwischen beiden ist gering, besteht aber dennoch. Eine Benachrichtigung benötigt keine Bestätigung des Empfangs durch den Kunden. Eine Anzeige hingegen erfordert diese Bestätigung, auch wenn sie auf GATT-Ebene erfolgt und nicht bis zur Anwendungsebene reicht. Warum ist das so, fragen Sie sich? Leider kann ich Ihnen das nicht sagen. Ich kann nur erwähnen, dass die Experten von Nordic empfehlen, die Benachrichtigung zu nutzen. Zumal die Integritätsprüfung des Pakets (mittels CRC) in beiden Fällen erfolgt.

Fazit

Am Ende des Artikels möchte ich Folgendes sagen. Die letzte Tabelle ist etwas verwirrend. Ich habe mich jedoch dafür entschieden, sie wiederzugeben, weil sie in Artikel, auf die ich mich stütze. Im zweiten Teil meines Artikels beabsichtige ich, tiefer in die Spezifikationen von Bluetooth 4.0 einzutauchen. Dort erwarten uns genauere Diagramme und Illustrationen. Im dritten Teil möchte ich ein Protokoll analysieren, das mit dem Programm Wireshark von einem der Geräte erfasst wurde, und die gesamte Theorie, die wir gemeinsam erarbeitet haben, „live“ sehen.

Mitarbeiter der Unternehmensgruppe „Cäsar Satellit“
Wladimir Petscherski

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster