fun with bluetooth

why?

progressive web apps

pwa’s ! are great

but...

bluetooth

bluetooth s k c su

classic bluetooth vs. y d o b y r h e t v o e o t n e o u s l a b e s r e e t a th h control dron es and bluetooth low energy other cool s hit

bluetooth low energy also known as B l Bluetooth Smar t uetooth LE B l u e t o o t h 4 BLE

bluetooth low energy also known as B l Bluetooth Smar t uetooth LE B l u e t o o t h 4 and 5 BLE

10 million bluetooth devices shipping every day

e n o h p e l i b mo

computer

glu r o t i n o m e s o c so d n a h s ' y d o b e m

activity tracker

e r e ph u b y a pl s lb b l u b y a l p

8 b b o i r e h sp

e n o r d i n i parrot m

r e n n i p s t e fidg

the boring theoretical stuff

central peripheral

central

generic attribute profile

generic attribute profile ?

generic attribute profile c e b , t t a g a w p a g ause n e k a t y d a e r l a s

central peripheral client server

§ i device information light e c i v e d r e p s e c i v r e s e l p i t l u m

i device information battery flight control

i device information battery steering control

i device information battery heart rate

i device information battery heart rate

i device information battery heart rate

i device information manufacturer model number serial number hardware revision firmware revision software revision ... s c i t s i r e t c a r a h c e l e p c i i t v l r e s mu r pe

server service characteristic value array of objects object property value

services and characteristics are identified by uuid’s 16 bit or 1 28 bit

i device information 16 bit 128 bit 0x180A 0000180A-0000-1000-8000-00805F9B34FB

battery 16 bit 128 bit 0x180F 0000180F-0000-1000-8000-00805F9B34FB

steering control light still, ever y body does 16 bit 128 bit not recommended any UUID outside of the range xxxxxxxx-0000-1000-8000-00805F9B34FB flight c this

i device information manufacturer model number serial number hardware revision firmware revision software revision ...

i 0x180A 0x2A29 0x2A24 0x2A25 0x2A27 0x2A26 0x2A28 ... b good fo ad for rea r saving dability bandwi , dth

s t r o p p u s c i t s i r e t e c s a e r h a t h f c o each one or more read write write without response notify

every value is an array of bytes s e t y b st n a f no u j , s e p y t a t a d cy

pfew...

s t c a f g n i r o b t u o ab fun with bluetooth

fun with bluetooth

web bluetooth still not t he fun pa r t :( api

connecting to a device

navigator.bluetooth.requestDevice({ filters: [ { namePrefix: 'PLAYBULB' } ], optionalServices: [ 0xff0f ] }) .then(device => device.gatt.connect()) .then(server => server.getPrimaryService(0xff0f)) .then(service => service.getCharacteristic(0xfffc)) t a h w r e s w o r b e h t we tell t n a w e w e c i v e d f o kind .then(characteristic => { return characteristic.writeValue( new Uint8Array([ 0x00, r, g, b ); ])

s t c e l e s r e s u e th al device u t c a the

navigator.bluetooth.requestDevice({ filters: [ { namePrefix: 'PLAYBULB' } ], optionalServices: [ 0xff0f ] }) .then(device => { .... }) .then(device => device.gatt.connect()) .then(server => server.getPrimaryService(0xff0f)) .then(service => service.getCharacteristic(0xfffc)) m o r p 7 1 0 2 o s e r a ises .then(characteristic => { return characteristic.writeValue(

let device = await navigator.bluetooth.requestDevice({ filters: [ { namePrefix: 'PLAYBULB' } ], optionalServices: [ 0xff0f ] }); .then(device => device.gatt.connect()) .then(server => server.getPrimaryService(0xff0f)) .then(service => service.getCharacteristic(0xfffc)) .then(characteristic => { return characteristic.writeValue( new Uint8Array([ 0x00, r, g, b ); ])

let device = await navigator.bluetooth.requestDevice({ filters: [ { namePrefix: 'PLAYBULB' } ], optionalServices: [ 0xff0f ] }); r e v r e s e h t o t t c e n n co let server = await device.gatt.connect()); let service = await server.getPrimaryService(0xff0f)); let characteristic = await service.getCharacteristic(0xfffc)); .then(characteristic => { return characteristic.writeValue( new Uint8Array([ 0x00, r, g, b ); e c i v r e s get the c i t s i r e t c a r a h c ]) get the

writing data

let let let let device = await navigator.bluetooth.requestDevice({ ... }); server = await device.gatt.connect()); service = await server.getPrimaryService(0xff0f)); characteristic = await service.getCharacteristic(0xfffc)); characteristic.writeValue( new Uint8Array([ 0x00, r, g, b ); ]) w s e t y b e m o s ir te

reading data

let let let let device = await navigator.bluetooth.requestDevice({ ... }); server = await device.gatt.connect()); service = await server.getPrimaryService(0xff0f)); characteristic = await service.getCharacteristic(0xfffc)); let value = await characteristic.readValue(); let r = value.getUint8(1); let g = value.getUint8(2); let b = value.getUint8(3); d a re e m so s e t y b

get notified of changes

let let let let device = await navigator.bluetooth.requestDevice({ ... }); server = await device.gatt.connect()); service = await server.getPrimaryService(0xff0f)); characteristic = await service.getCharacteristic(0xfffc)); characteristic.addEventListener( 'characteristicvaluechanged', e => { let r = e.target.value.getUint8(1); let g = e.target.value.getUint8(2); let b = e.target.value.getUint8(3); } ); characteristic.startNotifications(); r e n e t s i l t n e v e add don't forget to star t listen ing

things you need to know: • the webbluetooth api • promises (or async await) • typed arrays d ! h u

custom characteristics. wtf!

writing a value: function(r, g, b) { return new Uint8Array([ 0x00, r, g, b } ]); reading a value: function(buffer) { return { r: buffer.getUint8(1), g: buffer.getUint8(2), b: buffer.getUint8(3) } } fro g n i d a e r d n a o t g writin c i t s i r e t c a r a h c e m a s e h t m

writing a value: function(r, g, b) { return new Uint8Array([ 0x01, g, 0x01, 0x00, 0x01, b, 0x01, r, 0x01, 0x00 ]); } t n e r r u c e h t g n i read e l b i s s o p t o n s i r colo

writing a value: function(r, g, b) { var buffer = new Uint8Array([ 0xaa, 0x0a, 0xfc, 0x3a, 0x86, 0x01, 0x0d, 0x06, 0x01, r, g, b, 0x00, 0x00, (Math.random() * 1000) & 0xff, 0x55, 0x0d ]); for (var i = 1; i < buffer.length - 2; i++) { buffer[15] += buffer[i]; } return buffer; } t n e r r u c e h t g n i read e l b i s s o p t o n s i r colo

writing a value: function(r, g, b, position) { let buffer = new Uint8Array([ 0x07, 0x02, position + 1, r, g, b ]); return buffer; }

writing a value: function(r, g, b, position) { let buffer = new Uint8Array([ 0x58, r, g, b, 0x01, position ]); ...

writing a value: function(r, g, b, position) { let buffer = new Uint8Array([ 0x58, r, g, b, 0x01, position ]); let payload = new Uint8Array(buffer.length + 4); payload[0] = payload.length - 2; payload[1] = payload.length - 2 >>> 8; payload.set(buffer, 2); let checksum = payload.reduce((a, b) => a + b, 0); payload[payload.length - 2] = checksum; payload[payload.length - 1] = checksum >>> 8; let extra = payload.filter(value => {

message[m] = 0x03; message[m + 1] = 0x05; m += 2; } else if (payload[i] === 0x03) { message[m] = 0x03; message[m + 1] = 0x06; m += 2; } else { message[m] = payload[i]; m++; } } message[0] = 0x01; message[message.length - 1] = 0x02; return message; }

adafruit bluetooth sniffer

log all bluetooth packets on your phone o t b d a e g s o l u e d n a nsfer th tra

o t k r a h s a e t r a i d w e e h us k at t o o l

decompiling the apk t ' n do ! e n o y n a l l e t

finally t he fun p ar t demo

warning experimental technology o l g n i t t se s n o i t a t c e p x we

warning wifi interference r e h t r u f n e v e m e h t g n i r e w lo

fun with bluetooth !

questions? @htm l5test