As a team of schoolchildren on the hackathon, NASA performed a reverse-engineering of the fitness bracelet to control the drone
A year ago, I purchased a SONY SmartBand SWR10 fitness tracker. Like most other fitness trackers, the gadget did not play a big role in my life, its main occupation was to lie on my desk. However, this is an interesting electronic device, and when a friend invited me to join his team in the NASA Space Apps hackathon, I decided to use the tracker. We chose the section "Do not break my drone", where it was required to create a solution to control the drone. It was decided to use this tracker to control the drone.
As soon as the hackathon started, I began to search for my bracelet API or developer tools, but nothing was found. Some forum users said that SONY has a proprietary SDK, which is given to developers who have decided to cooperate with the company, but under the terms of the hackathon, only open-source solutions could be used. So I decided it was time to create my own drone management interface. I launched the tracker application, and turned on the “Bluetooth HCI snoop log” feature. This feature allowed you to sniff traffic and save a dump to an SD card. ')
I found a log: ~ adb shell echo $ EXTERNAL_STORAGE / sdcard ~ adb pull /sdcard/btsnoop_hci.log
And opened it in WireShark:
It seems that data transmission was carried out via the Bluetooth Low Energy protocol, or more precisely, via the GATT protocol. This is a two-way data transfer, where the phone acts as a server, the “GATT Server”, and the peripheral devices receive “GATT characteristics”, which can contain any binary data.
I chose the first UUID (00000208–37cb-11e3–8682–0002a5d5c51b), and searched it on Google. I expected to find the usual standardized GATT service, but found something more interesting .
I decided that we discovered someone's Git-repository, created by a man who carried out reverse-engineering of the protocol. And it was partly like this: the project contained several working functions, including connection, response to hand movement, reading battery status and keeping the connection active. But the implementation of the accelerometer was strange. I added accelerometer data to MPAndroidChart , and got this:
Although the slope information was correct, the values ​​were not displayed. After studying the function code, it turned out that the 32-bit single-precision number contained three 10-bit values. This makes sense, since most accelerometers work with 10-bit precision (like most ADC, analog-to-digital converters). Here are the initial data, pay attention to the first two bits:
But parsing the data as three 10-bit values ​​was rather strange, every few degrees of inclination changed the value from 511 to -512, and the offset did not change it (and there were no integer overflow problems here). So I decided that SONY could use some kind of proprietary binary packaging method, or the company uses arithmetic coding and compression.
I tried Protobuf, MsgPack, Thrift, and several parsers, but nothing worked. I had only a day to connect my device to the Wi-Fi drone. Already in despair, I tried the dex-decompilation of the company's application, and after half an hour, this was what happened:
The first half [0, 512] was inverted, so the situation described above arose. I fixed it using normal XOR, and everything worked out. I added the gravity factor, with the result [-1,1] for ± 1 g, and all I had to do next was to use the accelerometer data to control the drone.