Beddit Reverse Engineering

Horacio Gonzalez
InMoodForLife
Published in
7 min readJan 10, 2017

Why Beddit?

Before choosing a sleep tracker for InMoodForLife, we spent some time studying the specifications of the different available trackers. Most of them had similar characteristics: measuring heart rate, respiration and sleep cycles, using bluetooth to upload data to a smartphone application.

What made us choose Beddit? They offered a very developer oriented feature: a GitHub repository allowing to read the raw data directly from the device. Having open source code to read data from the device meant that in a worse case scenario we should be able to hack it and adapt it to our needs.

So based on that reasoning, we ordered our Beddit feeling rather reassured. Little we knew that our assurance was going to be short lived…

There is an app for that

When we received our sleep tracker, the first thing we did what to install the official app and test it.

It is a nice app, well done, doing the job it was designed to do: a consumer sleep tracker allowing users to get some fancy graphs about the quality of their sleep.

But for our intended application, using the tracker data to analyse sleep patterns for children with mood disorders, it was basically useless. The application only showed aggregated data, with no option to allow further analysis, and no way to parameter it for specific use cases… as we could expect for a consumer application.

So we decided to pass to our plan B, the GitHub repository, feeling rather happy for having taken that as choice criteria.

If it seems too good to be true…

Oh, a beautiful repository with Python code to read the raw data from the Beddit sensor, it sounds exactly like what we looked for!

So we cloned the project, we installed the required dependencies and we tried to contact our Beddit… without success.

What happened? Well, the problem was simpler that we thought: the code was for a previous version of Beddit, using Bluetooth RFCOMM protocol, while our Beddit device belonged to the new generation, using Bluetooth BLE, and in order to fix some disconnection problems and improve efficiency, uses ATT protocol instead of RFCOMM.

So the code in the GitHub repository was mostly useless for us, and we began to think we had been a bit over optimistic…

Email a friend…

What was the most logical thing to do next? Well, the device maker was committed enough with open source to release the code for the previous version, so there was a chance that if we contacted them they could give us some pointers of how to deal with the current version.

So we sent a mail to one of their developers, explaining our project, our goals, and asking for some help, documentation or information on how to deal with the current version of the sleep tracker.

The answer was encouraging, but not very helpful. In brief, it said something like “Your project is cool, I like it! But I’m sorry, we have no time right now to give you any help”.

So we arrived to another dead end, and that meant that the only solution we had was to take out the heavy artillery to tackle the problem: it was reverse engineering time!

Reverse engineering the Beddit protocol

When trying to reverse engineer a protocol, a good first step is to listen to the messages exchanged, to try to make sense of them later.

Logging Bluetooth traffic with Android Bluetooth HCI

Having installed the Beddit Android application, we had the perfect vector to capture the exchanges between the sleep tracker and the application: an Android phone with the Developer Options enabled.

One of these options is Enable Bluetooth HCI snoop log. Enabling it activates the capture of Bluetooth HCI (Host Controller Interface) packets, placing them in a file on the device storage (/sdcard/btsnoop_hci.log) for retrieval.

So we disconnected the telephone from all Bluetooth devices, we activated the HCI snoop log and we connected it to the Beddit, leaving it run for a night of sleep, in order to get a full dataset. Then we disconnected the device, deactivated the HCI snoop log and transferred the log file from the telephone to the computer.

Analysing the logs…

The log file is stored in the /sdcard folder. In order to recover it on the computer we use the adb command from the Android developer tools.

  • To identify the file: adb shell ls
  • To transfer it to the computer: adb pull

The log file is like an PCAP file, you can open it directly with Wireshark.

Wireshark

As all the request between the BT controller / host and device are logged, the connection sequence is directly readable on Wireshark.

The exchange begins with a classical whoareyou & whoami sequence, where no sensor data is sent.

After tapping on the Sleep button on the app, a “write command” is sent on the handle 0x000e with the value 01.

The android application receives a series of Handle value notifications with a fixed value payload 8000a6789f78a178b078ad78b778ce78d178e278 but without any information about the protocol.

Well, this is not a serious problem, because if the sensor streams raw data (as we supposed), the remaining messages should be simply the encoded data.

Looking at these messages we see that they all begin with a magic number, 80, followed by a rolling sequence number between 01 and ff. The rest of the datagram have a 4 bytes pattern (78xx at the beginning of the example).

That fours bytes sequence suggested us a left to right Little Endian encoding.

So then we could read the messages and extract values, but it isn’t enough to be able to analyse them. Our next step was to transform them into datapoints in a time series and inject it in a time series database.

However, there is no timestamp in this protocol. In order to inject and manipulate it into a time series database, we needed to compute a timestamp. Looking at the messages timestamp on wireshark, we saw that the sensor has a stable sampling period, with around 7 milliseconds between each measure.

That also allowed us to gauge the volume for a full night: with one measure every 7 milliseconds, we would get some 4.6 millions of datapoints for a full 9 hours night of sleep.

If we were right, Beddit sent a raw read from its force sensor, so with this 4.6 millions of datapoints we could be able to apply some filtering to extract breath rythme and heartrate.

As time series database we choose Warp10, an open source time series database with a full analytics framework and language, as their analytics capabilities made it the best tool for this kind of project.

We used a Groovy script to transform the data into Warp10 GTS input format and injected them with curl into Warp10’s ingress endpoint.

With the data into Warp10, we could use its tools to check if our guesses about Beddit data was correct and the input data looks like a force sensor data.

Extracting and plotting some 1000 values (7 seconds) should be enough to observe something like a respiratory rate and confirm our hypothesis.

We use Warp10’s Quantum tool to visualise the time-series, by using Warpscript for accessing data:

And yes! The graph showed us the characteristic curve of somebody breathing in his sleep. After have seen this curve, the InTheMood4Life team definitely knew that “data love” means…

In the next episode…

In the next episode we will tell you how we analysed the data using Warpscript, and what information we could extract from those analysis. In the meantime, if you have any question, or comment, or suggestions, please tell us!

--

--

Horacio Gonzalez
InMoodForLife

Spaniard lost in Brittany, unconformist coder, dreamer and all-around geek. Google Developer Expert in Web Technologies. Polymer and Web Components fan.