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

Bluetooth Low Energy: vous saurez tout

Alexis DUQUE
February 09, 2017

Bluetooth Low Energy: vous saurez tout

Avec l’essor de l’IoT, le Bluetototh Low Energy a fait son apparition en permettant à des objets de communiquer avec votre smartphone : thermomètres, bracelets d’activité, mais aussi piloter votre cafetière préférée. Néanmoins, ce protocole radio reste souvent mystérieux pour les utilisateurs et les développeurs.

Cette présentation démystifiera son fonctionnement, son avenir avec l’arrivée du Bluetooth 5.0 et son implémentation sur les plateformes mobiles. Pour les plus bricoleurs de l'auditoire, nous verrons également comment créer rapidement son propre périphérique BLE en utilisant un kit de développement grand public.

Alexis DUQUE

February 09, 2017
Tweet

More Decks by Alexis DUQUE

Other Decks in Programming

Transcript

  1. Au programme • Comprendre le protocole BLE et ses évolutions

    • Concevoir son périphérique Bluetooth • Développer une application mobile • Éviter les pièges !
  2. Bluetooth 1994 Harald Blåtand 24 MBit/s Portée de 1m à

    100m Standardisé par le Bluetooth SIG
  3. Bluetooth Low Energy 2010 Faible débit et faible conso. ~50

    kbps Portée de 10m à 50m Faible latence (~10ms) et protocole “non connecté” Chip radio presque toujours OFF Très petits paquets : MTU de 20 octets pour 4.0
  4. La couche PHY • Modulation GFSK 1 Mbps • Bande

    passante de 220KHz à 1MHz • RF 2.4 GHz (ISM) découpant en 23->79 canaux • Frequency Hopping (1600 hops/sec) • Time Division Duplex mode • Puissance en Tx 0.1 watt • Distance : 10m à 50m • 7 liens possibles (configuration en étoile)
  5. Advertising Broadcast et non connecté Informations sur le périphérique 31B

    de payload custom 2 types : ADV_DATA et SCAN_RESPONSE
  6. Consommation Très Variables ! En veille : quelques uA Advertising

    : 30 uA => 1 an avec une pile CR2032 Scan : 20 mA Connecté et actif : 750 mA
  7. Bluetooth 4.0 -4.1 (2010 - 2013) 1er version de Bluetooth

    Low Energy version Orienté bas débit, faible latence, basse conso Mise à jour mineurs en 2013 : 4.1 • Support du multi rôle
  8. Bluetooth 4.2 • Support de l’IPv6 et Bluetooth 6LoWPAN •

    Secure pairing: (AES-CCM + ECDH) • Privacy • Réduction de la consommation • Encore + rapide : débit x 2.5 • Data Length Extension: taille des paquets x 10 • Voice-over-BLE
  9. Lockpicking in the IoT, Chaos Communication Congress “75 Percent of

    Bluetooth Smart Locks Can Be Hacked” How to hack a smartlock ? Nulock Keyless Matthew Garrett .... “The password is sent unencrypted” … “There's a command that resets the password to 123456” ...
  10. LE Legacy – Problèmes Mike Ryan (2013) La clé LTK

    est transmise over-the-air La clé TK est vaut O en “Just work” Protection contre le Passive Eyesdropping Protection contre MITM
  11. LE Security Mode 1 Bluetooth 4.0, 4.1 4 modes •

    No Security – No Authentication and No Encryption • Unauthenticated pairing + encryption • Authenticated pairing + encryption • Authenticated LE Secure Connections pairing + encryption
  12. LE Security Mode 2 2 modes • Unauthenticated pairing with

    data signing • Authenticated pairing with data signing
  13. LE Secure Connections – Elliptic Curve Diffie Hellman Échange des

    clés publiques/privées avec le protocole ECDH AES-CMAC pour l’authentification Protection contre le Passive Eyesdropping Protection contre MITM
  14. Plusieurs possibilités Programmer la carte avec les binaires du SDK

    Utiliser la plateforme MBED Utiliser les projets d’exemple du SDK Nordic avec Eclipse, Keil ou IAR Utiliser l’application nRF Connect https://devzone.nordicsemi.com/tutorials/
  15. Android https://developer.android.com/guide/topics/con nectivity/bluetooth-le.html Supportée depuis 4.3 - API 18 -

    Jelly Bean Mode Central uniquement Stable depuis 5.1 - API 21 - Lollipop Mode Périphérique (advertiser) depuis Lollipop
  16. Plugin Cordova iOS, Android, Windows Phone (Presque) tout est faisable

    … backgound mode Ne pas hésiter à mettre la main à la patte https://github.com/randdusing/cordova-plugin-bluetoothle https://github.com/don/cordova-plugin-ble-central Apache 2 MIT
  17. Comparaison Fonctionnement et esprit similaires : NSLog(@"Reading value for characteristic

    %@", interestingCharacteristic); [peripheral readValueForCharacteristic:interestingCharacteristic]; … (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { NSData *data = characteristic.value; // parse the data as needed … } final BluetoothGattCharacteristic characteristic; final BluetoothGatt gatt = mBluetoothGatt; LOG.d(TAG, "Reading value for characteristic " + characteristic); gatt.readCharacteristic(characteristic); … @Override public final void onCharacteristicRead(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final int status) { if (status == BluetoothGatt.GATT_SUCCESS) { // parse the data as needed } } ble.read(device_id, service_uuid, characteristic_uuid, success, failure);
  18. Les étapes Scanner les périphériques à portée Se connecter utilisant

    l'adresse BD ou l’UUID Découvrir les services et caractéristiques disponibles Sauvegarder les handles, pour les réutiliser ! Écrire, lire ou souscrire aux notifications Ne pas oublier de (bien) se déconnecter
  19. Ne pas oublier les permissions Dans le manifest, dont ACCESS_COARSE_LOCATION

    depuis API21 <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  20. Demander les permissions Au runtime et avant de démarrer le

    scan String LOCATION_PERMSISSION = Manifest.permission.ACCESS_COARSE_LOCATION; private void checkForLocationPermissionsAndScan() { if (ContextCompat.checkSelfPermission(this, LOCATION_PERMSISSION) == PackageManager.PERMISSION_GRANTED) { if (!isBleEnabled()) { // REQUEST BLE PERMISSION } else { // START SCAN } } else { ActivityCompat.requestPermissions(this, new String[]{LOCATION_PERMSISSION}, REQUEST_ACCESS_COARSE_LOCATION); } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { // HANDLE RESULT }
  21. Ne pas utiliser auto-connect Le comportement est très variable selon

    les modèles de smartphone public void connect(final BluetoothDevice device) { if (mConnected) return; if (mBluetoothGatt != null) { mBluetoothGatt.close(); mBluetoothGatt = null; } final boolean autoConnect = false; mUserDisconnected = !autoConnect; // We will receive Linkloss events only when the device is connected with autoConnect=true mBluetoothGatt = device.connectGatt(mContext, autoConnect, getGattCallback()); }
  22. Toujours découvrir les services Après s’être connecté correctement @Override public

    final void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) { if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) { // Notify the parent activity/service mConnected = true; mCallbacks.onDeviceConnected(); mHandler.postDelayed(new Runnable() { @Override public void run() { if (gatt.getDevice().getBondState() != BluetoothDevice.BOND_BONDING) { gatt.discoverServices(); } } }, 600); // Add 600ms delay, Nordic Recommendation }
  23. Attendre d’être prêt ! En utilisant la callback onServicesDiscovered @Override

    public void onServicesDiscovered(BluetoothGatt gatt, int status) { super.onServicesDiscovered(gatt, status); bleHandler.obtainMessage(MSG_SERVICES_DISCOVERED, gatt).sendToTarget(); } @Override public boolean handleMessage(Message msg) { switch (msg.what) { case MSG_SERVICES_DISCOVERED: // Discovery successful, fetch services, chars and descs... BluetoothGatt gatt = (BluetoothGatt) msg.obj; commService = gatt.getService(DATA_SERVICE_ID); inputChar = commService.getCharacteristic(INPUT_CHAR_ID); outputChar = commService.getCharacteristic(OUTPUT_CHAR_ID); break; } }
  24. Ecrire 20 bytes maximum ! Sauf pour les devices qui

    supportent requestMtu() // Should always be called on our BLE thread! private void writeDataToChar(byte[] data) { if(data.length > 20) { throw new IllegalArgumentException(); } outputChar.setValue(data); gatt.writeCharacteristic(characteristic); } @Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic c, int status) { if (status == BluetoothGatt.GATT_SUCCESS && c.getUuid().equals(outputChar.getUuid())) { // Write operation successful, proceed with next chunk! } }
  25. Ne pas oublier le champ descriptor Lors de l’activation des

    notifactions private void enableDataNotifications(BluetoothGatt gatt BluetoothGattCharacteristic c) { gatt.setCharacteristicNotification(c, true); } // This is usually needed as well... BluetoothGattDescriptor desc = c.getDescriptor(INPUT_DESC_ID); // Could also be ENABLE_NOTIFICATION_VALUE desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); gatt.writeDescriptor(desc); }
  26. Déconnexion : close() vs disconnect() close() == "unregister app" disconnect()

    == fermer la connection Ne pas hésiter à faire les 2: gatt.disconnect(); gatt.close();
  27. En cas d’erreur Ne pas avoir de se déconnecter, fermer

    la connexion et se connecter de nouveau : les erreur de type GATT_ERROR sont souvent irrécupérables Réinitialiser le BluetoothAdapter
  28. En cas d’erreur Jeter un oeil au code source du

    Framework Logger les appels aux callbacks BluetoothGattCallback et leur paramètres mais ne pas mettre de breakpoint !
  29. Ce que l’on peut faire Scanner des périphériques Démarrer une

    app si un périphérique est détecté Même après redémarrage d’Android Android Beacon Library Google Nearby
  30. Ce que l’on peut faire Scanner des périphériques Se connecter

    à des périphériques Lire/écrite des caractéristiques et recevoir des notifications Mais Il faut obligatoirement filtrer sur 1 service L’interval de scan est augmenté
  31. Bluetooth 5.0 Vitesse de modulation multipliée par 2 • Débit

    5x sup. à 4.0 Augmentation des capacités d’advertising • Payload du Scan Response x7
  32. Bluetooth 5.0 Portée multipliée par 4 : 50m en indoor

    et 200m en outdoor • Puissance Tx doublée • Nouveau codage PHY
  33. nFR5240 ARM Cryptocell-310 • Secure Element • Secure Boot •

    Secure/Authenticated Debugging • AES - Courbes Elliptiques