Fun with Bluetooth @ Amsterdam JSNation

Fun with Bluetooth @ Amsterdam JSNation

Time for the browser to get physical. With WebBluetooth the browser can actually take control of all kinds of physical devices in the real world like lightbulbs, robots and even drones. This talk will teach you the basics that you need to get started.

De023a9aff4c7a5ede3a81e8c76f17b5?s=128

Niels Leenheer

June 01, 2018
Tweet

Transcript

  1. fun with bluetooth

  2. why?

  3. progressive 
 web apps

  4. pwa’s are great !

  5. but...

  6. but...

  7. None
  8. None
  9. bluetooth

  10. bluetooth sucks

  11. classic bluetooth the reason everybody 
 hates bluetooth bluetooth low

    energy vs. control drones and other cool shit
  12. bluetooth low energy also known as BLE Bluetooth LE Bluetooth

    Smart Bluetooth 4
  13. bluetooth low energy also known as BLE Bluetooth LE Bluetooth

    Smart Bluetooth 4 and 5
  14. 10 million 
 bluetooth devices
 shipping every day

  15. mobile phone

  16. computer

  17. glucose monitor somebody's hand

  18. activity tracker

  19. playbulb sphere playbulb

  20. spherio bb-8

  21. parrot mini drone

  22. fidget spinner

  23. the boring theoretical stuff

  24. central peripheral

  25. central

  26. generic attribute profile

  27. generic attribute profile ?

  28. generic attribute profile gatt, because gap was already taken

  29. central peripheral client server

  30. server service characteristic value array of objects object property value

  31. services and characteristics are identified by uuid’s 16 bit or

    128 bit
  32. read write write without response notify each characteristic supports one

    or more of these
  33. every value is an array of bytes no fancy datatypes,

    just bytes
  34. pfew...

  35. None
  36. fun with bluetooth boring facts
 about

  37. fun with bluetooth

  38. web
 bluetooth api still not the fun part :-(

  39. connecting to a device

  40. 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 ]) ); }) we tell the browser what 
 kind of device we want
  41. the user selects the actual device

  42. 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 ]) ); }) get the characteristic get the service connect to the server
  43. writing data

  44. navigator.bluetooth.requestDevice({ ... }) .then(device => device.gatt.connect()) .then(server => server.getPrimaryService(0xff0f)) .then(service

    => service.getCharacteristic(0xfffc)) .then(c => { return c.writeValue( new Uint8Array([ 0x00, r, g, b ]) ); }) write some bytes
  45. reading data

  46. navigator.bluetooth.requestDevice({ ... }) .then(device => device.gatt.connect()) .then(server => server.getPrimaryService(0xff0f)) .then(service

    => service.getCharacteristic(0xfffc)) .then(c => c.readValue()) .then(value => { let r = value.getUint8(1); let g = value.getUint8(2); let b = value.getUint8(3); }) read some bytes
  47. get notified of changes

  48. navigator.bluetooth.requestDevice({ ... }) .then(device => device.gatt.connect()) .then(server => server.getPrimaryService(0xff0f)) .then(service

    => service.getCharacteristic(0xfffc)) .then(c => { c.addEventListener('characteristicvaluechanged', e => { let r = e.target.value.getUint8(1); let g = e.target.value.getUint8(2); let b = e.target.value.getUint8(3); }); c.startNotifications(); }) add event listener don't forget to start listening
  49. custom characteristics. wtf!

  50. insert xkcd comic about standards here

  51. 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) 
 } } writing to and reading
 from the same characteristic
  52. writing a value: function(r, g, b) { return new Uint8Array([

    0x01, g, 0x01, 0x00, 0x01, 
 b, 0x01, r, 0x01, 0x00 
 ]); } reading the current 
 color is not possible
  53. 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; } reading the current 
 color is not possible
  54. writing a value: 
 function(r, g, b, position) { let

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

    buffer = new Uint8Array([ 0x58, r, g, b, 0x01, position ]); ...
  56. 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 => {

  57. 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; }
  58. adafruit
 bluetooth 
 sniffer

  59. decompiling 
 the apk don't tell anyone!

  60. demo finally the fun part

  61. warning experimental technology
 setting low expectations

  62. warning wifi interference
 lowering them even further

  63. None
  64. https:/ /bluetooth.rocks/lightbulb
 https:/ /github.com/BluetoothRocks/Lightbulb change the colour 
 of a

    lightbulb
  65. https:/ /bluetooth.rocks/pixel
 https:/ /github.com/BluetoothRocks/Matrix draw pixel art on 
 a

    led matrix display
  66. https:/ /bluetooth.rocks/racer https:/ /github.com/BluetoothRocks/Racer control a lego racer 
 using

    a gamepad use css animations to 
 define a path
  67. https:/ /bluetooth.rocks/drone
 https:/ /github.com/BluetoothRocks/Drone control a drone 
 from your

    browser
  68. https:/ /bluetooth.rocks/pulse
 https:/ /github.com/BluetoothRocks/Pulse find out your 
 current heartbeat

  69. fun with bluetooth !

  70. questions? @html5test