Helen Sherwood-Taylor

PyCon UK

September 2016

Taking control of your bluetooth devices

Bluetooth Low Energy

  • BLE
  • BTLE
  • "Bluetooth Smart"

aka:

Part of Bluetooth 4.0

BLE Features

  • Simple protocols
  • Low bandwidth
  • Short range
  • Low power
  • Widely used

WHY?

  • Fun
  • Control
  • Endless possibilities!
  • But... where's my API?

ATT

Attribute Protocol

  • Handle (e.g. 0x12)
  • UUID (e.g. f000ffad-0451-4000-b000-000000000000)
  • Properties / Permissions (e.g. 0x02)
  • Value

Attributes

GATT

Generic Attribute PROFILE

  • Builds on attributes
  • Services / characteristics hierarchy
  • All contribute to device profile

STANDARD UUIDs

  • Defined by Bluetooth Special Interest Group (SIG)

  • Based on Bluetooth Base UUID
  •  xxxxxxxx-0000-1000-8000-00805F9B34FB
    
  • Refer to with first 32 bits
  • Can be looked up in spec

  • e.g. heart rate, wind speed, latitude

VENDOR UUIDs

  • Refer to with full 128 bits

  • Chosen by the vendor

  • What do they mean?

Ingredients

Hardware

  • Bluetooth lightbulb
  • Controlling device (Android phone)

Analysis

  • File transfer (adb?)
  • Wireshark

Control

  • Linux box
  • BlueZ
  • bluepy

The App

HCITOOL

$ hcitool lescan
LE Scan ...
88:C2:55:08:CB:77 (unknown)
88:C2:55:08:CB:77 icolorlive
  • Advertising / scanning
  • 48 bit address
  • May require sudo

GATTTOOL

[   ][88:C2:55:08:CB:77][LE]> connect
[CON][88:C2:55:08:CB:77][LE]> characteristics
[CON][88:C2:55:08:CB:77][LE]> 
handle: 0x0002, char properties: 0x02, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0006, char properties: 0x0a, char value handle: 0x0007, uuid: 00002a02-0000-1000-8000-00805f9b34fb
...
handle: 0x0024, char properties: 0x0a, char value handle: 0x0025, uuid: f000ffa3-0451-4000-b000-000000000000
handle: 0x0027, char properties: 0x0a, char value handle: 0x0028, uuid: f000ffa4-0451-4000-b000-000000000000
handle: 0x002a, char properties: 0x0a, char value handle: 0x002b, uuid: f000ffa6-0451-4000-b000-000000000000
...

That's 3 t's!

GATTTOOL

[CON][88:C2:55:08:CB:77][LE]> char-read-hnd 0x3
[CON][88:C2:55:08:CB:77][LE]> 
Characteristic value/descriptor: 69 63 6f 6c 6f 72 6c 69 76 65 

That's 3 t's!

Read characteristic by UUID

[CON][88:C2:55:08:CB:77][LE]> char-read-uuid 0x2a00
[CON][88:C2:55:08:CB:77][LE]> 
handle: 0x0003 	 value: 69 63 6f 6c 6f 72 6c 69 76 65 
[CON][88:C2:55:08:CB:77][LE]> char-read-uuid f000ffa3-0451-4000-b000-000000000000
[CON][88:C2:55:08:CB:77][LE]> 
handle: 0x0025 	 value: 4f 43

Read characteristic by handle

Read by vendor-defined UUID

Log capture

Android Developer Options

  • Toggle
  • Do stuff in app
  • Download log
  • Repeat

WIRESHARK

Filter:

btl2cap.cid == 0x0004

Gatttool

[CON][88:C2:55:08:CB:77][LE]> char-write-cmd 0x28 ff0000
[CON][88:C2:55:08:CB:77][LE]> char-write-cmd 0x28 ffff00
[CON][88:C2:55:08:CB:77][LE]> char-write-cmd 0x28 ff00ff

PYTHON

from time import sleep
from bluepy.btle import Peripheral, ADDR_TYPE_PUBLIC

GREEN = '006600'
BLUE = '000066'
PURPLE = '660066'

addr = sys.argv[1]


def disco(sequence):
    for code in sequence:
        conn.writeCharacteristic(0x28, bytearray.fromhex(code))
        sleep(1.0)

conn = Peripheral(addr, ADDR_TYPE_PUBLIC)
disco((GREEN, BLUE, PURPLE) * 3)
conn.disconnect()

FURTHER reading

Resources

links

Thank you!

twitter: @helenst

github: @helenst

http://helen.st/