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

Shuichi Tsutsumi: Practical Core Bluetooth in I...

Realm
June 13, 2016

Shuichi Tsutsumi: Practical Core Bluetooth in IoT & Wearable projects

Presented at AltConf 2016

Realm

June 13, 2016
Tweet

More Decks by Realm

Other Decks in Programming

Transcript

  1. Practical Core Bluetooth in IoT & Wearable projects Shuichi Tsutsumi

    @shu223 iOS Freelancer UIKonf 2016 - Berlin
  2. • Low energy • NOT compatible with Classic BT •

    Uses 2.4 GHz radio frequencies • Marketed by the Bluetooth SIG
  3. • Low energy • NOT compatible with Classic BT •

    Uses 2.4 GHz radio frequencies • Marketed by the Bluetooth SIG • etc…
  4. • Low energy • NOT compatible with Classic BT •

    Uses 2.4 GHz radio frequencies • Marketed by the Bluetooth SIG • etc…
  5. The API ‘Core Bluetooth’ is open for developers • API

    for Classic BT is NOT open. - Requires MFi certification.
  6. BLE is almost the ONLY way to enable iOS apps

    to communicate with external hardware without infrastructure or MFi.
  7. Moff Band Moff App Sensor Data BLE Connection Sensors -

    Gyroscope - Accelerometer Analyze sensor data
  8. Moff Band Moff App Sensor Data BLE Connection Sensors -

    Gyroscope - Accelerometer Analyze sensor data Recognize - Gesture - Posture
  9. Moff Band Moff App Sensor Data BLE Connection Sensors -

    Gyroscope - Accelerometer Analyze sensor data Recognize - Gesture - Posture Play sounds
  10. Scan Step 1. Scan Advertise : Search for nearby BLE

    devices centralManager.scanForPeripheralsWithServices(nil, options: nil)
  11. Scan Step 1. Scan Advertise Discover : Search for nearby

    BLE devices func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber!) { print(“Discovered a BLE device!”) }
  12. Scan Step 1. Scan Advertise Discover : Search for nearby

    BLE devices func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber!) { print(“Discovered a BLE device!”) } Central
  13. Scan Step 1. Scan Advertise Discover : Search for nearby

    BLE devices func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber!) { print(“Discovered a BLE device!”) } Peripheral Central
  14. Moff Service xx Service Step 3. Subscribe: Ready to receive

    data GATT = Generic Attribute Profile
  15. Moff Service xx Service Button Characteristic xx Characteristic Sensor Characteristic

    Step 3. Subscribe: Ready to receive data GATT = Generic Attribute Profile
  16. Moff Service xx Service Button Characteristic xx Characteristic Sensor Characteristic

    Subscribe (Request to be notified) Step 3. Subscribe: Ready to receive data GATT = Generic Attribute Profile
  17. Moff Service xx Service Button Characteristic xx Characteristic Sensor Characteristic

    Subscribe (Request to be notified) Step 3. Subscribe: Ready to receive data GATT = Generic Attribute Profile peripheral.setNotifyValue(true, forCharacteristic: c)
  18. Step 4. Notify Notify subscribers Moff Service Sensor Characteristic xxxx

    Characteristic Update the value func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) { print(“Received sensor data!”) }
  19. Step 4. Notify Notify subscribers Moff Service Sensor Characteristic xxxx

    Characteristic Update the value func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) { print(“Received sensor data!”) }
  20. BLE

  21. → Can be used even in areas with poor coverage!

    Group conversation system with VoIP - Detects the human voice - Cuts out all background noise
  22. GATT to send sensor data Foo Service Sensor Data Characteristic

    UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Bar Service xx Characteristic UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Notify Value: acc x, acc y, acc z, gyro x, gyro y, gyro z (2bytes for each) xx Characteristic
  23. GATT to send sensor data Foo Service Sensor Data Characteristic

    UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Bar Service xx Characteristic UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Notify Value: acc x, acc y, acc z, gyro x, gyro y, gyro z (2bytes for each) xx Characteristic
  24. GATT to send sensor data Foo Service Sensor Data Characteristic

    UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Bar Service xx Characteristic UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Notify Value: acc x, acc y, acc z, gyro x, gyro y, gyro z (2bytes for each) xx Characteristic
  25. GATT to send sensor data Foo Service Sensor Data Characteristic

    UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Bar Service xx Characteristic UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Notify Value: acc x, acc y, acc z, gyro x, gyro y, gyro z (2bytes for each) xx Characteristic
  26. GATT to send sensor data Foo Service Sensor Data Characteristic

    UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Bar Service xx Characteristic UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Notify Value: acc x, acc y, acc z, gyro x, gyro y, gyro z (2bytes for each) xx Characteristic
  27. GATT to send sensor data Foo Service Sensor Data Characteristic

    UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Bar Service xx Characteristic UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Notify Value: acc x, acc y, acc z, gyro x, gyro y, gyro z (2bytes for each) xx Characteristic
  28. GATT to send button interactions Foo Service Button Control Characteristic

    UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Notify Value: 0x01 or 0x00
  29. GATT to send button interactions Foo Service Button Control Characteristic

    UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Notify Value: 0x01 or 0x00
  30. GATT to send button interactions Foo Service Button Control Characteristic

    UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Notify Value: 0x01 or 0x00
  31. GATT to send button interactions Foo Service Button Control Characteristic

    UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Notify Value: 0x01 or 0x00 Button interactions
  32. GATT to send button interactions Foo Service Button Control Characteristic

    UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Notify Value: 0x01 or 0x00 Button interactions
  33. GATT to send button interactions Foo Service Button Control Characteristic

    UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Notify Value: 0x01 or 0x00 Button interactions
  34. GATT to send button interactions Foo Service Button Control Characteristic

    UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Notify Value: 0x01 or 0x00 Button interactions Y1VTIFE Y3FMFBTFE
  35. GATT for remote control Foo Service Remote Control Characteristic UUID:

    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Write Value: Horizontal (-100 ~ 100), Vertical (-100 ~ 100)
  36. GATT for remote control Foo Service Remote Control Characteristic UUID:

    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Write Value: Horizontal (-100 ~ 100), Vertical (-100 ~ 100)
  37. GATT for remote control Foo Service Remote Control Characteristic UUID:

    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Write Value: Horizontal (-100 ~ 100), Vertical (-100 ~ 100) values
  38. GATT for remote control Foo Service Remote Control Characteristic UUID:

    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Write Value: Horizontal (-100 ~ 100), Vertical (-100 ~ 100) values
  39. GATT for remote control Foo Service Remote Control Characteristic UUID:

    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Properties: Write Value: Horizontal (-100 ~ 100), Vertical (-100 ~ 100) values
  40. How to define GATT 1. Create UUID for the service

    & characteristic 2. Define the properties (Read, Notify, Write, etc.) Peripheral → Central: Notify 
 Central → Peripheral: Write 3. Define the value format Usually limited to 20 bytes $ uuidgen CEEA31BC-BEAC-4A78-B7ED-FC96B6254D4C
  41. Background behaviors on iOS • Very limited - Listening to

    music - Getting location data - Downloading data
  42. You would have to always keep the app in the

    foreground, while snowboarding!
  43. What functions can be used in the background? • Scanning

    peripherals • Connecting with peripherals
  44. What functions can be used in the background? • Scanning

    peripherals • Connecting with peripherals • Reading characteristics’ value
  45. What functions can be used in the background? • Scanning

    peripherals • Connecting with peripherals • Reading characteristics’ value • Writing characteristics’ value
  46. What functions can be used in the background? • Scanning

    peripherals • Connecting with peripherals • Reading characteristics’ value • Writing characteristics’ value • Receiving notifications
  47. What functions can be used in the background? • Scanning

    peripherals • Connecting with peripherals • Reading characteristics’ value • Writing characteristics’ value • Receiving notifications Almost all functions can be used even in the background!
  48. Limitations • Longer intervals for scanning • Must explicitly specify

    one or more services to scan • CBCentralManagerOptionShowPowerAlertKey option is ignored
  49. Limitations • Longer intervals for scanning • Must explicitly specify

    one or more services to scan • CBCentralManagerOptionShowPowerAlertKey option is ignored Resources - Core Bluetooth Programming Guide - Core Bluetooth Framework Reference (also in headers)
  50. State Preservation and Restoration The system takes over the BLE

    tasks even after the app is killed. - Preserves the state of the app’s central managers and continues the BLE tasks on their behalf.
  51. State Preservation and Restoration The system takes over the BLE

    tasks even after the app is killed. - Preserves the state of the app’s central managers and continues the BLE tasks on their behalf. - Relaunches the app into the background and calls the corresponding delegate method.
  52. State Preservation and Restoration The system takes over the BLE

    tasks even after the app is killed. - Preserves the state of the app’s central managers and continues the BLE tasks on their behalf. - Relaunches the app into the background and calls the corresponding delegate method. → The app can handle BLE events!
  53. • The app is killed by the system • The

    user pushes the button on the peripheral device
  54. • The app is killed by the system • The

    user pushes the button on the peripheral device • The system receives the notification
  55. • The app is killed by the system • The

    user pushes the button on the peripheral device • The system receives the notification • The app is relaunched in the BG and the delegate method is called.
  56. func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) { print(“Received

    the characteristic data!”) } • The app is killed by the system • The user pushes the button on the peripheral device • The system receives the notification • The app is relaunched in the BG and the delegate method is called.
  57. func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) { print(“Received

    the characteristic data!”) } • The app is killed by the system • The user pushes the button on the peripheral device • The system receives the notification • The app is relaunched in the BG and the delegate method is called. The app can process the button interaction!
  58. Implementation • Add an option when initializing the CBCentralManager object.

    let options = [ CBCentralManagerOptionRestoreIdentifierKey: "somekey" ] centralManager = CBCentralManager( delegate: self, queue: queue, options: options)
  59. Implementation • Implement the delegate method which is called when

    the app is restored. func centralManager(central: CBCentralManager, willRestoreState dict: [String : AnyObject]) { print("Restored") }
  60. Testing the restoration • Kill the app as if it

    was killed by the iOS kill(getpid(), SIGKILL);
  61. Did the HW prototypes exist when develop the apps? Projects

    HW prototypes existed? Moff YES WHILL NO BONX NO SmartDrive YES PLEN2 NO Music for the Deaf NO
  62. Emulator App • Develop another iOS app as the alternative

    to the peripheral device • Use CBPeripheralManager
  63. Emulator App • Develop another iOS app as the alternative

    to the peripheral device • Use CBPeripheralManager • Easier for iOS engineers
  64. =

  65. • Connection dropped • Can’t discover services or characteristics •

    Fail to write • Incorrect characteristic values
  66. • Connection dropped • Can’t discover services or characteristics •

    Fail to write • Incorrect characteristic values • Incorrect behaviors in the background
  67. • Connection dropped • Can’t discover services or characteristics •

    Fail to write • Incorrect characteristic values • Incorrect behaviors in the background • etc…
  68. Identify which side the problem is on Is the problem

    on the central side or on the peripheral side? → Compare with another iOS app like ‘LightBlue’
  69. Can’t find the peripheral • Scanning, but can’t find the

    peripheral device Scan but ‘didDiscover’ method isn’t called
  70. func centralManager( central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String :

    AnyObject], RSSI: NSNumber!) { print(advertisementData) } Filtered by iOS! → Can’t see all of the advertisement data
  71. func centralManager( central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String :

    AnyObject], RSSI: NSNumber!) { print(advertisementData) } Filtered by iOS! e.g. Can’t see the ‘Manufacture Data’ field of iBeacon → Can’t see all of the advertisement data
  72. Videos for review • Show how the app works with

    the peripheral device • Not need to be cool!
  73. Recap • What is Bluetooth Low Energy? • Basics of

    Core Bluetooth with an actual product • Practical Core Bluetooth with specific examples - Defining GATT - Defining background behaviors - Testing without HW prototypes - Troubleshooting - App Review
  74. ଋɿ31mm ද 4 ද 1 iOSʷBLE Core Bluetooth ϓϩάϥ ϛ

    ϯά iOSʷBLE Core Bluetooth ϓ ϩ ά ϥ ϛ ϯ ά అ म Ұ দ ଜ ྱ ԝ ử ஶ అमҰʷদଜྱԝ ʹ ஶ Shuichi TSUTSUMI ʷ Reo MATSUMURA iOSʷBLE Core Bluetooth Programming iOSʷBLE 定価:本体4,000円 (税別) Resources • 500 pages about iOS x BLE • Japanese only
  75. Resources • Getting Started with Bluetooth Low Energy - Covers

    large area of BLE • Core Bluetooth Programming Guide - Good to know the overview of Core Bluetooth • Core Bluetooth Framework Reference - Details of Core Bluetooth • Bluetooth Accessory Design Guidelines for Apple Products - For HW side, but helpful also for iOS engineers to know specs or limitations due to HW side such as connection intervals.
  76. Resources • WWDC 2012 - Session 703 - Core Bluetooth

    101 - Helpful to know about BLE • WWDC 2012 - Session 705 - Advanced Core Bluetooth - Connection interval, Caching, etc… • WWDC 2013 - Session 703 - Core Bluetooth - Retrieving peripherals, State preservation & restoration etc.. - Includes advanced and detailed information • Bluetooth Core Specification by Bluetooth SIG - The official specification / Total 2000 pages…
  77. Thank you! Shuichi Tsutsumi - iOS Freelancer • Twitter: @shu223

    • GitHub: shu223 • Blog: https://medium.com/@shu223/ • Email: [email protected]