Embrace+ Hacking

Yesterday, I received my Embrace+ wristband in the mail. I was (un)lucky enough to be in the first batch of wristbands, and thus got mine before most people who backed the Kickstarter over a year ago.

If you don't know what the Embrace+ is, it is a Silicone wristband; incorporating two RGB LEDs, a vibration motor, a rechargeable battery, and BLE (Bluetooth Low Energy). It is designed to connect to your smartphone, and provide different light patterns and vibration according to different app notifications.

In practice, it is very limited, and very closed off (despite the promise of SDK availability when a stretch goal was hit). The android app they produced is pretty bad, very limited, complicated, and incomplete. I decided to sniff the data between the band and my phone, figure out what each byte does, and start working on my own app, and/or be able to use it on other devices.

This post is my place to keep track of information, and make it public so that anyone else who has one of these may be able to make it more useful for their particular use

Battery Issues

Before we get in to the main chunk of figuring out the packet structure and communications of the Embrace+, I think we should look at a very big issue that is plaguing me, and many, many other users of the Embrace+. I will note, at this point, that my battery will not actually charge. I have tested it on the device itself, as well as on a MAX1555 charging board which is known to work with other LiPoly batteries (current limited to ~40mA. The battery currently puts out ~0.5VDC

Battery life

I measured the idle current draw of the Embrace, connected to my phone, at an average of about ~0.65mA. The battery has a labeled capacity of 20mAh. Some simple math tells us that the battery will last approximately 30.77 hours. That does not even include calculating in the current draw of the LEDs or the Vibration motor. That is far, far shorter than the 10 days (with ~100 notifications per day) that was claimed in the kickstarter page.

Current draw under notification

Next I measured the peak current draw, with the vibration motor running, and both LEDs on white at ~98mA. The battery is a 20mAh LiPoly, which means that is a 4.9C discharge. The only source I have been able to find for the battery states it as 10C discharge, but I was also not able to find an actual datasheet for it.

Charging

A large number of commenters on the kickstarter are complaining about the device not charging, charging extremely slowly, or even losing charge when the charger is connected. Myself included. Symptoms include:

  • Boot loop: The device turning on (green light), connecting (blue light), then immediately disconnecting (red light).
  • Unstable charger: The charge indicator randomly switching between charging (dim red flashing glow), and fully charged (dim green flashing glow), and never staying constant.
  • No indication: The device not displaying any sort of charge indication, or result of charging. Device never gains charge.
  • Combination of any/all of the above
This is a major issue, as the device is designed to be portable, and the battery is not user-replaceable. It is not designed to be disposable, but to be used and re-used. The battery seems to be very low quality, and does not lend itself to this application

Charging connector

The magnetic charging connector/cable has also been a major source of issues. It consists of a ~5" long cable, about 1mm diameter with a USB-A connector on one end, and a small, flat, disk on the other. The top of the disk is glossy plastic, and the bottom is a PCB with a circle in the center, surrounded by a ring. There is a magnet inside of the disk. On the device itself, there are two pieces of metal. One a circle, and on the outside, a ring, each with a small raised bump. There is a piece of ferrous metal inside of the device behind the contacts.

I have had several issues with the charging cable, including:

  • Screws/paperclips/misc ferrous items being attracted to the connector and shorting the contacts together.
  • Shorting the connector while connecting or disconnecting the connector.
  • Large amounts of resistance between the contacts. I've measured up to 400KOhm between contacts.
  • Short cable length. Basically relegates charging to laptop usb ports or usb hubs.
I have discovered, that if I connect the charging cable then set the device down, the connector moves enough to cause a short, which resets my entire USB hub, disconnecting everything attached (including my mouse, keyboard, and backup harddrive). This also happens if I disconnect the cable without pulling straight out.

Packet sniffing

In order to figure out what the app sends to the wristband, I needed to sniff the bluetooth packets between the devices.

I do not have an Ubertooth One, which would have been useful, so I needed to find a way to do it on the phone itself. Thankfully, Android 4.4+ has bluetooth sniffing capability built in, which is super useful.

Bluetooth sniff enable location in android

To enable it, you need to enable the Developer Options in android (tap the build number 7 times in the About Device section of the settings). After that, you can enable bluetooth sniffing, by checking the Bluetooth HCI Snoop Log check box in the Developer Options section.

Once you enable this, all bluetooth data is saved to a log file (On my device, it was located at /storage/sdcard0/Android/data/btsnoop_hci.log). At this point, I opened the Embrace+ app, and sent several combinations of colors and patterns, and wrote down the order I sent them in. After sending a good chunk of packets to the device, I disabled bluetooth sniffing (by clearing the previous box) and used ADB to pull the file to my computer.

adb pull /storage/sdcard0/Android/data/btsnoop_hci.log ./

Viewing the data

Now that we have the data that was sent to the Embrace+, we need to decode it. For this, we use the ever-useful Wireshark. Simply open the btsnoop_hci.log file, and it will decode the data, and present it all in a super easy to read and useful format, allowing us to sort the data.

Wireshark window showing our sniffed data

Now we just need to sift through it all, and figure out what data is being sent. Obviously the phone is sending the data to the wristband, so we are going to sort by the 'Source' column and look for localhost(). Once there, we know the phone is writing the data, so we look under the Info column, and look around for a "Send Write Request" packet. There are plenty.

It appears that the Embrace+ app sends two different packets.

One is a request for the battery information:

0A 1B 00
This is a Read Request (0x0A), for handle 0x001B

The second is the actual notification message:

05 14 8C 0A 14 0A 09 00 09 00
This is the command that basically says "Send the 'Oscillate' pattern, with blue on both sides, and activate the vibration motor". It is written to characteristic 0xFFC4. We will go into the packet breakdown next.

Packet breakdown

The Embrace+ uses a simple command protocol to send data for notifications, it is a total of 10 bytes, and contains:

  • Number of repeats
  • Time amounts to keep light on, and to fade
  • Enable or Disable the vibration motor
  • Four color settings, two for each side of the band

Byte Valid Range Description
1 0x01 - 0xFF Number of times to repeat a pattern
2 0x00 - 0xFF Time to keep color one on, in tens of milliseconds (0x01 = 10ms, 0xFF = 2560ms = 2.56 sec)
3 0x8C, 0x8D, 0x84 Config byte. Controls random color choice, and vibration motor.
Bit breakdown as follows:
  • 0bXXXXXXX1 - |= 0x01 - Setting this bit selects random colors on both sides
  • 0bXXXX1XXX - |= 0x08 - Setting this bit enables the vibration motor

I'm unsure of the rest of the bits, but I know at least 0x84 is the base needed. Start with 0x84 and enable the other bits as needed
4 0x00 - 0xFF Time to fade to color two, in tens of milliseconds
5 0x00 - 0xFF Time to keep color two on, in tens of milliseconds
6 0x00 - 0xFF Time to fade back to color one, in tens of milliseconds
7 0x00 - 0x10, 0x9D Color one value for left side. See color table
8 0x00 - 0x10, 0x9D Color two value for left side. See color table
9 0x00 - 0x10, 0x9D Color one value for right side. See color table
10 0x00 - 0x10, 0x9D Color two value for right side. See color table

Color data

Color Value Preview Color Description
0x00 Off Light off.
0x01 White
0x03 Light pink
0x04 Light Purple
0x05 Purple
0x06 Hot Pink
0x07 Dark Red
0x08 Lighter, Orangish Red
0x09 Yellow
0x0A Light Green
0x0B Green
0x0C Orange
0x0D Light Orange
0x0E Light Blue
0x0F Blue
0x9D Random Randomly selected color

Sending my own data

I'm using an application currently called LightBlue, available for Mac OSX. It allows sending data to Bluetooth Low Energy devices, and reading data from them.