BlinkUp Protocol Reversing
Written 2018-04-06
Tags:Toymail Modem WiFi ElectricImp
ElectricImp's BlinkUp protocol is an optical modulation protocol designed for low-speed data transfer using mobile phone displays or LEDs as transmitters. Since the transmitter runs on my phone, we can begin to reverse engineer the protocol strictly from the smali assembly extracted from the APK file.
To start, smali/com/electricimp/blinkup/BlinkupPacket.java's createFromIntent() shows there are currently four different packet types sent over BlinkUp, with (packet type numbers used):
- wifi(1,5,6) - takes enrollment token(5), siteid(5), ssid(1), wpa2psk password(6)
- wps(3,5) - takes enrollment token(5), siteid(5), pin(3)
- fwUpgrade(4) - upgrades firmware over BlinkUp?
- clear(7) - sets up clear wifi?
Packet Bitstream Structure
Type | Bytes | Value |
Preamble | 8 | 0b10101010 |
Size | 1 | various |
Data | N | various |
Checksum | 2 | CRC-16 |
Packet Header
The packet header is quite simple, a preamble of 8 times the byte 85. In binary, this creates an alternating pattern of ones and zeros. Usually, in modem design, a preamble such as this allows the receiver to notice that data is incoming, and to synchronize its receive clock with the transmitted clock. Next, the header byte 42(0b00101010) comes. At this point, the CRC accumulator is zeroed out. Finally, the packet length is appended, updating the CRC.Packet Payload
This varies with the packet type, but starts with a 1 byte indication of the packet type, followed by a UTF8 string ending with a NULL terminator. For packets without a string argument, the payload is simply the packet type byte followed directly by a NULL terminator. Multiple strings can be encoded in a simple integer-to-string dictionary by appending more packet type, string pairs. Perhaps packet type is not the best descriptor, perhaps string type?CRC
Luckily, the implementation uses a CRC table. This means we can take the lazy path to fingerprinting it by searching github for the strings of numbers we find in the CRC table until we find an identical table in somebody else's source code. In this case, the CRC is a CRC-16, The poly is 0x8005 (x^16 + x^15 + x^2 + 1)
Encoding options
No protocol would be complete without a bunch of random cruft tacked on over time as the details of whatever mobile phone you used change.Baud Rate
There are options for encoding the bitstream at both half and two thirds speeds, I suspect to deal with faster and faster mobile phone displays.Binary vs Trinary Encoding
In the simple case, bits are encoded with a black screen meaning zero, and a white screen meaning one.
But another option is the ability to encode in tri-level flashes. In this case, bit 0 is presented as black followed by grey, and bit 1 is presented as black followed by white.