Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

Niels Leenheer

June 01, 2018
Tweet

More Decks by Niels Leenheer

Other Decks in Programming

Transcript

  1. fun with
    bluetooth

    View Slide

  2. why?

    View Slide

  3. progressive 

    web apps

    View Slide

  4. pwa’s
    are great
    !

    View Slide

  5. but...

    View Slide

  6. but...

    View Slide

  7. View Slide

  8. View Slide

  9. bluetooth

    View Slide

  10. bluetooth
    sucks

    View Slide

  11. classic bluetooth
    the reason everybody 

    hates bluetooth
    bluetooth low energy
    vs.
    control drones and other cool shit

    View Slide

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

    View Slide

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

    View Slide

  14. 10 million 

    bluetooth devices

    shipping every day

    View Slide

  15. mobile phone

    View Slide

  16. computer

    View Slide

  17. glucose monitor
    somebody's hand

    View Slide

  18. activity tracker

    View Slide

  19. playbulb sphere
    playbulb

    View Slide

  20. spherio bb-8

    View Slide

  21. parrot mini drone

    View Slide

  22. fidget spinner

    View Slide

  23. the boring theoretical stuff

    View Slide

  24. central peripheral

    View Slide

  25. central

    View Slide

  26. generic attribute profile

    View Slide

  27. generic attribute profile ?

    View Slide

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

    View Slide

  29. central peripheral
    client server

    View Slide

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

    View Slide

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

    View Slide

  32. read
    write
    write without response
    notify
    each characteristic supports
    one or more of these

    View Slide

  33. every value is an array of bytes
    no fancy datatypes, just bytes

    View Slide

  34. pfew...

    View Slide

  35. View Slide

  36. fun with
    bluetooth
    boring facts

    about

    View Slide

  37. fun with
    bluetooth

    View Slide

  38. web

    bluetooth
    api
    still not the fun part
    :-(

    View Slide

  39. connecting to a device

    View Slide

  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

    View Slide

  41. the user selects
    the actual device

    View Slide

  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

    View Slide

  43. writing data

    View Slide

  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

    View Slide

  45. reading data

    View Slide

  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

    View Slide

  47. get notified of changes

    View Slide

  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

    View Slide

  49. custom
    characteristics.
    wtf!

    View Slide

  50. insert xkcd comic about standards here

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  54. writing a value:

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

    View Slide

  55. writing a value:

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

    View Slide

  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 => {


    View Slide

  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;
    }

    View Slide

  58. adafruit

    bluetooth 

    sniffer

    View Slide

  59. decompiling 

    the apk
    don't tell anyone!

    View Slide

  60. demo
    finally the fun part

    View Slide

  61. warning
    experimental technology

    setting low expectations

    View Slide

  62. warning
    wifi interference

    lowering them even further

    View Slide

  63. View Slide

  64. https:/
    /bluetooth.rocks/lightbulb

    https:/
    /github.com/BluetoothRocks/Lightbulb
    change the colour 

    of a lightbulb

    View Slide

  65. https:/
    /bluetooth.rocks/pixel

    https:/
    /github.com/BluetoothRocks/Matrix
    draw pixel art on 

    a led matrix display

    View Slide

  66. https:/
    /bluetooth.rocks/racer
    https:/
    /github.com/BluetoothRocks/Racer
    control a lego racer 

    using a gamepad
    use css animations to 

    define a path

    View Slide

  67. https:/
    /bluetooth.rocks/drone

    https:/
    /github.com/BluetoothRocks/Drone
    control a drone 

    from your browser

    View Slide

  68. https:/
    /bluetooth.rocks/pulse

    https:/
    /github.com/BluetoothRocks/Pulse
    find out your 

    current heartbeat

    View Slide

  69. fun with
    bluetooth
    !

    View Slide

  70. questions?
    @html5test

    View Slide