BLE - notpike/ChemionHacking GitHub Wiki

GATT Server Info

GATT services where enumerated using evilsocket's bleah tool.

@ Scanning for 5s [-128 dBm of sensitivity] ...

┌ c7:46:5b:26:83:d5 (-38 dBm) ───────────────────────────────────────────┐
│ Vendor                 │ ?                                             │
│ Allows Connections     │ ✓                                             │
│ Address Type           │ random                                        │
│ Complete 128b Services │ '6e400001-b5a3-f393-e0a9-e50e24dcca9e'        │
│ Complete Local Name    │ CHEMION-83:D5                    │
│ Flags                  │ LE General Discoverable, BR/EDR Not Supported │
└────────────────────────┴───────────────────────────────────────────────┘

@ Connecting to c7:46:5b:26:83:d5 ... connected.
@ Enumerating all the things ...

┌──────────────┬───────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────┬─────────────────────────────────────────────────────────────────────┐
│ Handles      │ Service > Characteristics                                                             │ Properties               │ Data                                                                │
├──────────────┼───────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────┼─────────────────────────────────────────────────────────────────────┤
│ 0001 -> 0007 │ Generic Access ( 00001800-0000-1000-8000-00805f9b34fb )                               │                          │                                                                     │
│ 0003         │   Device Name ( 00002a00-0000-1000-8000-00805f9b34fb )                                │ READ WRITE               │ 'CHEMION-83:D5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' │
│ 0005         │   Appearance ( 00002a01-0000-1000-8000-00805f9b34fb )                                 │ READ                     │ '4\x12'                                                             │
│ 0007         │   Peripheral Preferred Connection Parameters ( 00002a04-0000-1000-8000-00805f9b34fb ) │ READ                     │ Connection Interval: 8 -> 40                                        │
│              │                                                                                       │                          │ Slave Latency: 0                                                    │
│              │                                                                                       │                          │ Connection Supervision Timeout Multiplier: 400                      │
│              │                                                                                       │                          │                                                                     │
│ 0008 -> 000b │ Generic Attribute ( 00001801-0000-1000-8000-00805f9b34fb )                            │                          │                                                                     │
│ 000a         │   Service Changed ( 00002a05-0000-1000-8000-00805f9b34fb )                            │ INDICATE                 │                                                                     │
│              │                                                                                       │                          │                                                                     │
│ 000c -> ffff │ 6e400001-b5a3-f393-e0a9-e50e24dcca9e                                                  │                          │                                                                     │
│ 000e         │   6e400003-b5a3-f393-e0a9-e50e24dcca9e                                                │ NOTIFY                   │                                                                     │
│ 0011         │   6e400002-b5a3-f393-e0a9-e50e24dcca9e                                                │ WRITE NO RESPONSE WRITE  │                                                                     │
│              │                                                                                       │                          │                                                                     │
└──────────────┴───────────────────────────────────────────────────────────────────────────────────────┴──────────────────────────┴─────────────────────────────────────────────────────────────────────┘
  • Uses Nordic UART Emulation over BLE
  • Server UART RX is 0x011
  • Server ACK's are sent threw 0x00e

UART Message Structure

The LED matrix is 24 x 9 - 6 for a total of 210 LEDs. The 6 LEDs that where removed for the nose are still represented in the message strucutre however their values are always \x0.

0 | X X X X X X X X X X X X X X X X X X X X X X X X
1 | X X X X X X X X X X X X X X X X X X X X X X X X 
2 | X X X X X X X X X X X X X X X X X X X X X X X X 
3 | X X X X X X X X X X X X X X X X X X X X X X X X 
4 | X X X X X X X X X X X X X X X X X X X X X X X X 
5 | X X X X X X X X X X X X X X X X X X X X X X X X 
6 | X X X X X X X X X X X X X X X X X X X X X X X X 
7 | X X X X X X X X X X X     X X X X X X X X X X X 
8 | X X X X X X X X X X         X X X X X X X X X X 
  |________________________________________________ 
    0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N

Using Wireshark and HCI Snoop on an Android we figured out that each message is broken into four individual BLE packets. Combining the UART values from these packets while turning on and off the individual LEDS here's how we believe the Messages are structured. Below is an example of the message being sent to turn on LED 0x0 at an 100% *duty cycle.

       *START*                				    *LED*			         *CHECK SUM*   *End*  
FA 03 00 39 01 00 06 	0|  C     0     0     0     0     0     0     0     0     0     0     0
			1|  0     0     0     0     0     0     0     0     0     0     0     0
			2|  0     0     0     0     0     0     0     0     0     0     0     0
			3|  0     0     0     0     0     0     0     0     0     0     0     0
			4|  0     0     0     0     0     0     0     0     0     0     0     0
			5|  0     0     0     0     0     0     0     0     0     0     0     0
			6|  0     0     0     0     0     0     0     0     0     0     0     0
			7|  0     0     0     0     0     0     0     0     0     0     0     0
			8|  0     0     0     0     0     0     0     0     0     0     0     0      C7        55 a9  
			 |______________________________________________________________________
	    		   0 1   2 3   4 5   6 7   8 9   A B   C D   E F   G H   I J   K L   M N
  • Each UART Packet is 20 bytes
  • Every message starts with \xFA030039010006
  • Every message ends with \x55A9
  • Every message is 64 Bytes
  • Nordic UART is big endian while the rest of the BLE packet is little endian
  • Phone app sends a complete map of the LED matrix every time there's an update
  • Animations are actively streamed to the Glasses

Each row makes up for 6 Bytes of data for a total of 54 Bytes for the LED matrix. Every Crumb (Half a Nibble or 2 bits) after START controls 1 LED along the X axis and it's value controls the duty cycle. High Crumbs (ex \b1100) control the Even LEDs along the X axis and the Low Crumbs (ex \b0011) control the Odd positions. Below are the Crumb values used for the LED *duty cycles.

*DUTY CYCLE HIGH CRUMB LOW CRUMB
100% \xC \b1100 \x3 \b0011
50% \x8 \b1000 \x2 \b0010
25% \x4 \b0100 \x1 \b0001
0% \x0 \b0000 \x0 \b0000

Because the message format described above uses Bytes and Nibbles, here are some examples of different Nibble values for when you have the 2 Crumbs added together.

LEDS BIN VALUES HEX VALUES
0x0 100%ON + 1x0 100%ON \b1100 + \b0011 = \b1111 \xC + \x3 = \xF
0x0 100%ON + 1x0 50%ON \b1100 + \b0010 = \b1110 \xC + \x2 = \xE
0x0 25%ON + 1x0 25%ON \b0100 + \b0001 = \b0101 \x4 + \x1 = \x5
0x0 25%ON + 1x0 50%ON \b0100 + \b0010 = \b0110 \x4 + \x2 = \x6
0x0 0%OFF + 1x0 100%ON \b0000 + \b0011 = \b0011 \x0 + \x3 = \x3

*Note: The percentages of each duty cycle are assumed.

UART Message Structure (Check Sum)

The method for finding the check sum comes from the LED matrix portion of the message (Bytes 8 threw 61). This value is calculated by taking 0x07 then XORing each Byte on top of the last from the LED matrix. Below is an example of this function and can be found at /src/msg_checksum.c.

uint8_t checkSum(uint8_t *in) {
    uint8_t checkSum = 0x07;       // Check Sum Magic Number

    int i;
    for (i = 7; i <= 61; i ++) {   // Check Sum for 54Byte LED Matrix
        checkSum ^= in[i];         // Each Byte is XORed ontop of the last
    }
    return checkSum;
}

Save Event

The Glasses has the capability to store 5 CREATIONS. Below are the UART values being passed for this event.

== To Save for slot one == 
Packet1 Value: fa0100030100050455a9
Packet2 Value: fa010004010014011455a9
Packet3 Value: fa010004010014011455a9

- LED Matrix Values
Packet4 Value: fa01003b01000d010a00000000000000003c3c00
Packet5 Value: 0000003c3c000000000000000000000003000000
Packet6 Value: 03c00f00000000c00c000000003ff00000000000
Packet7 Value: 000000cb55a9

Packet8 Value: fa01000301000c0d55a9