Wie die Hackathon-Schulkinder der NASA ein Fitness-Armband zur Steuerung einer Drohne rückentwickeln



Vor einem Jahr habe ich einen SONY SmartBand SWR10 Fitness-Tracker gekauft. Wie die meisten anderen Fitness-Tracker spielte das Gerät in meinem Leben keine große Rolle, seine Hauptbeschäftigung lag auf meinem Tisch. Dies ist jedoch ein interessantes elektronisches Gerät, und als mich ein Freund einlud, seinem Team beim NASA Space Apps- Hackathon beizutreten , entschied ich mich für den Tracker. Wir haben den Abschnitt Nicht meine Drohne abstürzen ausgewählt, in dem wir eine Lösung für die Steuerung der Drohne erstellen mussten. Es wurde beschlossen, diesen Tracker zur Steuerung der Drohne zu verwenden.



Sobald der Hackathon begann, suchte ich nach der API meines Armbands oder nach Tools für Entwickler, aber es wurde nichts gefunden. Einige Forumbenutzer gaben an, dass SONY über ein proprietäres SDK verfügt, das Entwicklern zur Verfügung gestellt wird, die sich für eine Zusammenarbeit mit dem Unternehmen entscheiden. Im Rahmen des Hackathons könnten jedoch nur Open-Source-Lösungen verwendet werden. Also entschied ich, dass es Zeit war, meine eigene Drohnensteuerungsschnittstelle zu erstellen. Ich habe die Tracker-Anwendung gestartet und die Funktion „Bluetooth HCI Snoop Log“ aktiviert. Mit dieser Funktion konnten Sie den Datenverkehr abhören und den Speicherauszug auf der SD-Karte speichern.

Ich habe das Protokoll gefunden:
~ adb shell echo $ EXTERNAL_STORAGE
/ sdcard
~ adb pull /sdcard/btsnoop_hci.log


und habe es in WireShark geöffnet:



Es scheint, dass die Datenübertragung unter Verwendung des Bluetooth Low Energy-Protokolls oder genauer über das GATT- Protokoll durchgeführt wurde . Dies ist eine bidirektionale Datenübertragung, bei der das Telefon als Server fungiert, "GATT-Server" und Peripheriegeräte "GATT-Eigenschaften" empfangen, die beliebige Binärdaten enthalten können.

Ich habe die erste UUID (00000208–37cb-11e3–8682–0002a5d5c51b) ausgewählt und bei Google gesucht. Ich hatte erwartet, den üblichen standardisierten GATT-Service zu finden, fand aber etwas interessanteres .

Ich entschied, dass wir jemandes Git-Repository entdeckt haben, das von einer Person erstellt wurde, die das Protokoll rückentwickelt hat. Und dies stimmte teilweise: Das Projekt enthielt mehrere Arbeitsfunktionen, darunter Verbinden, Reagieren auf Handbewegungen, Lesen des Batteriestatus und Aktivieren der Verbindung. Aber die Implementierung des Beschleunigungsmessers war seltsam. Ich habe die Beschleunigungsmesserdaten zu MPAndroidChart hinzugefügt und Folgendes erhalten :



Obwohl die Informationen auf den Steigungen korrekt waren, wurden die Werte nicht angezeigt. Nach dem Studium des Funktionscodes stellte sich heraus, dass die 32-Bit-Zahl mit einfacher Genauigkeit drei 10-Bit-Werte enthielt. Dies ist sinnvoll, da die meisten Beschleunigungsmesser mit einer Genauigkeit von 10 Bit arbeiten (wie die meisten ADCs, Analog-Digital-Wandler). Hier sind die Quelldaten, achten Sie auf die ersten beiden Bits:

acc Daten: 0b00101110 0b10110101 0b10111100 0b10111000
acc Daten: 0b00111010 0b11110001 0b00011101 0b11101011
acc Daten: 0b00111110 0b01110110 0b10100110 0b10011001
acc Daten: 0b00001011 0b11011101 0b10111101 0b00111001


Aber Parsing - Daten als die drei 10-Bit - Werte ziemlich seltsam war, alle paar Grad Neigung verändert Wert 511 -512, und der Offset änderte sich nicht (außerdem gab es hier kein Problem mit ganzzahligen Überläufen). Deshalb habe ich beschlossen, dass SONY eine proprietäre binäre Verpackungsmethode verwendet oder dass das Unternehmen arithmetische Codierung und Komprimierung verwendet.

Ich habe Protobuf, MsgPack, Thrift und mehrere Parser ausprobiert, aber nichts hat funktioniert. Ich hatte nur einen Tag Zeit, um mein Gerät mit dem WLAN der Drohne zu verbinden. Bereits verzweifelt versuchte ich die DEX-Dekompilierung der Unternehmensanwendung und nach einer halben Stunde stellte sich Folgendes heraus:

// Ungefähr
1: iconst_0 512 iconst_1 1023
2: r1 xor iconst_0
3: istore_0
4: iload_0
5: ifneq 8
6: r1 xor iconst_1
7: istore_0


if ((data & 0x200)! = 0) {
data = - ((data ^ 1023) + 1);
}
return (((float) (-data)) * 15.625f) / GRAVITY_FACTOR;


Die erste Hälfte [0, 512] wurde invertiert, und daher trat die oben beschriebene Situation auf. Ich habe es mit normalem XOR behoben und es hat geklappt. Ich fügte den Schwerkraftfaktor hinzu, mit dem Ergebnis [-1,1] für ± 1 g, und alles, was als nächstes getan werden musste, war die Verwendung der Beschleunigungsmesserdaten zur Steuerung der Drohne.

Source: https://habr.com/ru/post/de394095/


All Articles