L’Internet des Objets
7.1 Le Bluetooth basse consommation
Le protocole BLE est très différent du protocole Bluetooth. Avec Bluetooth, il était concevable d’établir un petit réseau. Avec BLE, il est possible d’utiliser les communications point à multipoints, diffusion (Broadcast) et mesh. Un support IPv6 est aussi évoqué.
Les standards (février 2025 sont résumés dans le tableau suivant (source WikiPedia) :
- 1.0
-
Mai 1999 première spécification
- 1.0b
-
Décembre 1999 Interopérabilité entre marques
- 1.1
-
2002
-
• Quelques corrections de bug
-
• Utilisation possible de canaux non chiffrés
-
• Ajout d’un signal qui permet de mesurer la puissance de réception
-
- 1.2
-
2003 Débit pratique supérieur porté à 721 kbit/s et amélioration de la résistance aux interférences
- 2.0
-
2004
-
• Débit pratique supérieur
-
• Rétrocompatibilité
-
• Réduction de la consommation des périphériques et optimisation des transferts
-
- 2.0+EDR
-
2004 Débit maximal théorique porté à 3 Mbit/s (2,1 Mbit/s utiles) avec le mode EDR (Enhanced Data Rate)
- 2.1+EDR
-
2007
-
• Couplage plus simple et plus rapide.
-
• Sécurité renforcée
-
• Ajout d’un mode de connexion par « NFC » (Near Field Communication) qui facilite l’appairage à très courte portée.
-
- 3
-
2009 Débit théorique supérieur porté à 24 Mbit/s en mode haute vitesse « HS/AMP » (Bluetooth v3.0 + Wi-Fi) optionnel et abandonné par la suite
- 4+LE
-
2010
-
• Bluetooth classique : peu de changement
-
• Restitutions musicales stéréophoniques de qualité comparable au CD12.
-
• Bluetooth LE (création) : réduction de la consommation des périphériques (Low Energy)
-
- 4.1
-
2013
-
• Bluetooth classique : peu ou pas de changement
-
• Bluetooth LE : connexion de plusieurs appareils sur un seul accès maître pour la sortie des smartphones LTE
item[4.2] 2014
-
• Bluetooth classique : peu ou pas de changement
-
• Bluetooth LE : réduction de la consommation des protocoles IP sécurisés pour les objets connectés.
-
• Augmentation de la taille utile des paquets (PDU) de 31 à 256 octets, ce qui permet de diminuer significativement les temps de téléchargement.
-
- 5
-
Décembre 2016
-
• Bluetooth classique : réduction des interférences avec d’autres appareils (Slot Availability Mask)13
-
• Bluetooth LE : débit théorique plus élevé (2 Mbit/s PHY), pratique : 1,4 Mbit/s, en option13, portée de 40 m à 350 m et jusqu’à 500 mètres avec certains modules.
-
- 5.1
-
Janvier 2019
-
• Bluetooth classique : angles d’arrivée et de départ, utilisé pour géolocaliser les appareils
-
• Bluetooth LE : possibilité pour un appareil de déterminer la direction du signal Bluetooth (localisation)
-
- 5.2
-
Décembre 2019
-
• Bluetooth classique : peu ou pas de changement
-
• Bluetooth LE : création d’un profil audio (réservé jusque-là au Bluetooth classique) à l’aide du codec LC312
-
- 5.3
-
Juillet 2021
-
• Bluetooth classique : abandon des modes AMP/HS (obsolètes)
-
• Bluetooth LE : améliorations du contrôle des clés de chiffrement et de la sélection des canaux radio
-
- 5.4
-
Février 2023
-
• Bluetooth classique : peu ou pas de changement
-
• Bluetooth LE : améliorations du chiffrement et de la sécurité de transmission
-
- 6.0
-
Août 2024 Bluetooth classique : peu ou pas de changement
Bluetooth LE :
-
• amélioration de la détection des périphériques
-
• Amélioration de la localisation et détection de proximité des appareils LE par sondage bidirectionnel.
-
• Optimisation de la fiabilité, de la latence et des débits.
-
• Flexibilité du délai entre trames (était fixe à 150 µs), pour améliorer le débit (réduction du délai) ou l’efficacité énergétique (augmentation du délai).
-
• Facilitation des connexions et envois par échange d’information sur les couches de liaisons utilisées.
-
Le site d’Adafruit fournit une bonne introduction :
https://learn.adafruit.com/introduction-to-bluetooth-low-energy. Le livre d’Oreilly est bien utile.
[ ?]
Le BLE utilise la bande ISM 2,4GHz. Cette bande est divisée en 40 canaux de 2 MHz. Le débit est de 1 Mb/s (2 Mb/s avec la version 2). Le débit applicatif est de 800 ou 1400 kb/s.
Il y a quatre modes principaux du BLE :
- Non connecté
- Connecté
- Localisation
- Audio
-
Un des comportements classique consiste, pour un objet BLE, consiste à diffuser une annonce que tous peuvent recevoir. L’objet est donc non connecté. Il peut agir comme un serveur et attendre une demande de connexion. En BLE, il s’agit du rôle périphérique. Un autre objet peut agir comme un client et prendre le rôle de central. Le central peut alors se connecter et échanger des données. Ces connexions sont privées, les autres appareils ne peuvent suivre ces échanges. Un périphérique ne peut être connecté qu’à un seul central.
Il est possible aussi d’utiliser le mode sans connexion pour diffuser des données à tous les équipements pouvant utiliser cette information. Les phares (beacons) utilisent un message d’annonce spécifique pour ajouter une information de localisation.
La localisation BLE utilise soit la puissance de réception (RSSI : Received Signal Strength Indicator). La précision avoisine le mètre. Une autre technique utilise plusieurs antennes pour mesurer l’angle d’arrivée du signal.
Depuis peu, il est possible d’utiliser la diffusion Audio avec le BLE.
7.1.1 Les outils Debian pour le BLE
La prochaine version (qui sera / est sortie pendant l’été 2025 propose des outils pour le BLE :
-
python3-bleak client indépendant de la plateforme pour le Bluetooth à basse consommation
-
python3-bluetooth-adapters Enumerate and find Bluetooth Adapters in Python
-
python3-bluetooth-data-tools Python tools for converting bluetooth data and packets
-
python3-bluetooth-sensor-state-data Models for storing and converting Bluetooth Sensor State Data
-
python3-bluez Python 3 wrappers around BlueZ for rapid bluetooth development
-
python3-bthome-ble BLE parser for sensors supporting BTHome format
-
python3-gardena-bluetooth controlling gardena bluetooth enabled watering
-
python3-gattlib Bluetooth LE GATT library for Python 3
-
python3-govee-ble gestion des appareils BLE de Govee
-
python3-home-assistant-bluetooth Home Assistant Bluetooth Models and Helpers
-
python3-meater-python bibliothèque pour interagir avec la sonde de cuisson de Meater
-
python3-uart-devices Python library for managing UART devices on Linux
-
python3-usb-devices Tools for mapping, describing, and resetting USB devices
Nous allons ici en explorer quelques uns :
7.1.1.1 Python Bleak
Bleak est un acronyme pour Bluetooth Low Energy platform Agnostic Klient.
Bleak est un logiciel client au protocole GATT (Generic Attribute Profile), capable de se connecter à des appareils BLE (Bluetooth à basse consommation) agissant comme serveurs GATT. Il est conçu pour fournir une API Python asynchrone et multiplateforme pour se connecter et communiquer avec, par exemple, des capteurs.
Bleak prend en charge la lecture, l’écriture et l’obtention des notifications de serveurs GATT, ainsi qu’une fonction de découverte d’appareils BLE.
7.1.2 Utilisation du BLE
Le BLE peut s’utiliser de plusieurs façons :
-
• diffuser des données ;
-
• échanger les valeurs des caractéristiques avec un central ;
-
• communiquer par une connexion série ;
-
• Rayonner la présence, comme un phare (beacon).
La diffusion des données utilise le mécanisme d’annonce (advertising). Il permet de diffuser la même valeur à plusieurs récepteurs.
Échanger des données plus ou moins structurées entre un périphérique et un unique central. Le central, après une connexion réussie qui exclue les autres centraux potentiels, peut lire ou écrire une valeur de caractéristique.
La connexion série permet d’établir une liaison série. Elle permet d’utiliser l’interpréteur MicroPython par exemple. Cela utilise le mécanisme des caractéristiques.
Le mode balise permet de diffuser une présence avec une notion de distance. Le mode balise diffuse une valeur qui est censée être la puissance de réception (en dBm) à 1m de distance. Le niveau de réception (RSSI : received signal strength indicator) donne une idée de la distance. Nous présentons (6.5.1) une expérimentation sur la réception de balise.
7.1.3 Les annonces BLE
Un objet BLE peut commencer par une phase d’annonce. Cela permet de détecter les objets à proximité et, éventuellement, permettre leur connexion. Ces annonces peuvent aussi être utilisées pour diffuser une données à tous les récepteurs à proximité. Ce cas est d’ailleurs utilisé par les balises BLE.
Annoncer depuis un microcontrôleur
Pour programmer une annonce, il faut avoir défini un message de 31 octets maximum (à moins que cela n’ai changé). Ensuite, il faut récupérer le fichier ble_advertising.py depuis les sources de MicroPython ou depuis le site STM32Python.
Une attaque, la supply chain attack, consiste à proposer une modification d’un fichier sur le site du projet. Cette modification peut permettre de corrompre tous les logiciels ayant téléchargé la version corrompue, c’est pourquoi, il est important de
vérifier le contenu de ce fichier. Debian propose cette vérification pour les paquets de la version stable.
Ensuite, il faut :
-
1. Définir une classe pour gérer les annonces :
class BLE_Adv_Env: # Initialisations def __init__(self, ble): self._ble = ble self._ble.active(True) self._connections = set() self._handler = None # Envoi des trames d'advertising def advertise(self, interval_us=500000, message = None): self._payload = advertising_payload ( name=message, services=None, appearance=_ADV_APPEARANCE_GENERIC_ENVSENSOR) self._ble.gap_advertise(interval_us, adv_data=self._payload, connectable = False) # ===================================================================== -
2. Initialiser le BLE configurer l’annonceur :
ble = bluetooth.BLE() wbdev = BLE_Adv_Env(ble)
-
3. personnaliser l’équipement
mon_nom = "wbkaa" # Voir org.bluetooth.characteristic.gap.appearance.xml _ADV_APPEARANCE_GENERIC_ENVSENSOR = const(5696)
-
4. Entrer dans une boucle qui, définit un message à diffuser. Ce message doit avoir au maximum 21 caractères.
while True: Parametres = "Lisez Zola" wbdev.advertise(message = mon_nom + "|" + Parametres) time.sleep(30)
Réception sur un système GNU/Linux
La réception de l’annonce peut se faire en faisant un scan BLE. Sous GNU/linux, de nombreuses commandes et logiciels sont disponibles. Pour les téléphones utilisant Linux ou un noyau similaire, il faut demander une association avec un nouveau périphérique, ce qui déclenchera le scan.
hcitool lescan LE Scan ... 6C:E8:1A:02:A0:7A (unknown) 02:04:73:9D:2F:5A Lisez Émile Zola !
la figure 7.2 présente la capture de l’annonce obtenue entre le système d’exploitation et le périphérique.
La figure 7.3 présente la même annonce capturée avec un sniffer BLE réalisé à partir de la carte NUCLEO-WB55.
7.1.4 Les balises BLE
Une balise BLE (beacon) est une annonce (advertisement) BLE classique dont les valeurs sont spécifiées par un fabricant de téléphone et qui peut donc imposer la structure de l’annonce.
La balise émet son signal de façon répétée. Le but initial est marketing. En recevant le paquet, un téléphone muni de l’application du magasin peut déclencher des événements, comme afficher les promotions du rayon. Ceci incite l’utilisateur à installer une application non sécurisée sur son téléphone, ce qui affaibli la sécurité de l’utilisateur.
Il existe de nombreuses implémentation de la balise. Des objets sont vendus avec cette unique fonctionnalité. Il est aussi possible de programmer des microcontrôleurs dans ce mode en utilisant l’IDE Arduino ou MicroPython. Bien sûr un système GNU/Linux peut agir comme une balise.
En Gnu/Linux, la commande hcitool permet de mettre en place une balise.
Il faut commencer par définir les paramètres de l’annonce :
=> hcitool -i hci0 cmd 0x08 0x0006 a0 00 a0 00 03 \
00 00 00 00 00 00 00 00 07 00
HCI Command: ogf 0x08, ocf 0x0006, plen 15
A0 00 A0 00 03 00 00 00 00 00 00 00 00 07 00
> HCI Event: 0x0e plen 4
01 06 20 0C
Puis le message de l’annonce :
=> hcitool -i hci0 cmd 0x08 0x0008 1E \
02 01 06 1A FF 4C 00 02 15 \
FB 0B 57 A2 82 28 44 CD 91 3A 94 A1 22 BA 12 06 \
00 1E 00 03 CD 00
< HCI Command: ogf 0x08, ocf 0x0008, plen 32
1E 02 01 06 1A FF 4C 00 02 15 FB 0B 57 A2 82 28 44 CD 91 3A
94 A1 22 BA 12 06 00 1E 00 03 CD 00
> HCI Event: 0x0e plen 4
01 08 20 00
Quelques explications : => hcitool -i hci0 cmd 0x08 0x0008
FB 0B 57 A2 82 28 44 CD 91 3A 94 A1 22 BA 12 06
- -i hci0
-
identification du périphérique BLE ;
- cmd 0x08 0x0008
-
définition de la commande ;
- 1E
-
la longueur du message ;
- 02 01 06 1A FF 4C 00 02 15
-
le préfixe d’advertisment des pommes ;
- FB 0B 57 A2 82 28 44 CD 91 3A 94 A1 22 BA 12 06
-
l’UUID ;
- 001E
-
le majeur (30) ;
- 0003
-
le mineur ;
- CD
-
le RSSI à 1m, il faut le positionner à la main, c’est ce qui permettra d’afficher une distance estimée.
Et enfin activer les annonces ou les supprimer :
=> hcitool -i hci0 cmd 0x08 0x000a 01 < HCI Command: ogf 0x08, ocf 0x000a, plen 1 01 > HCI Event: 0x0e plen 4 02 0A 20 00 => hcitool -i hci0 cmd 0x08 0x000a 00 < HCI Command: ogf 0x08, ocf 0x000a, plen 1 00 > HCI Event: 0x0e plen 4 02 0A 20 00
La figure 7.4 présente le résultat sur l’application Beacon Locator récupérée sur F-Droid.
Pour un Eddystone, il faut utiliser l’annonce suivante :
=> hcitool -i hci0 cmd 0x08 0x0008 1f 02 01
06 03 03 aa fe 17 16 aa fe 00 CD \
32 f2 ac d1 4a 82 8e a1 2c 30 \
AF 1E 03 00 14 17 \
CD 00
< HCI Command: ogf 0x08, ocf 0x0008, plen 32
1F 02 01 06 03 03 AA FE 17 16 AA FE 00 CD 32 F2 AC D1 4A 82
8E A1 2C 30 AF 1E 03 00 14 17 CD 00
> HCI Event: 0x0e plen 4
01 08 20 00
- CD
-
la puissance de transmission
- 32 f2 ac d1 4a 82 8e a1 2c 30
-
l’espace de nommage ;
- AF 1E 03 00 14 17
-
l’instance
Le site http://yencarnacion.github.io/eddystone-url-calculator/ fournit un calculateur qui génère les paramètres de la commande hcitool pour transmettre une URL, si elle est suffisamment courte.
7.1.5 Scannez les annonces BLE
7.1.5.1 Scannez les annonces BLE depuis Debian
Pour scanner les annonces depuis un ordinateur Debian, il y a plusieurs solutions. L’installation de Bluez (Le support Bluetooth pour Linux) fournit le programme interactif bluetoothcl, un outil classique est fournit par le package hcitool.
=> bluetoothctl Agent registered [bluetooth]# scan on Discovery started [CHG] Controller 14:AF:C5:AF:B4:E2 Discovering: yes [NEW] Device 02:04:73:9D:3B:82 Lisez Zola !!!!
Le logiciel hcitool n’est pas interactif, les sous commandes spécifiques au BLE sont préfixées par le :
=> hcitool lescan LE Scan ... 02:04:73:9D:3B:82 Lisez Zola !!!! CF:75:A9:EB:60:EE (unknown)
Le langage Python facilite la programmation :
#! /bin/python3
import asyncio
from bleak import BleakScanner
import asyncio
from bleak import BleakScanner
async def main():
devices = await BleakScanner.discover()
for device in devices:
print(device)
asyncio.run(main())
L’exécution liste les périphériques trouvés :
=> ./scanner.py 02:04:73:9D:3B:82: Lisez Zola !!!! 48:7A:80:09:8C:B7: 48-7A-80-09-8C-B7 10:25:27:36:AF:05: 10-25-27-36-AF-05
7.1.6 Le BLE audio
Le BLE audio est capable de diffuser le flux sonore vers un nombre quelconque de récepteur. Sur le site Bluetooth, il est mentionné la technologie Auracast et propose un nouveau codec plus performant Low Complexity Communications Codec (LC3).
La spécification est décrite(?) dans la figure 7.7.
https://wiki.st.com/stm32mcu/wiki/Connectivity:Introduction_to_Bluetooth_LE_Audio https://wiki.st.com/stm32mcu/wiki/Connectivity:Bluetooth_LE_Audio_-_STM32WBA_Public_Broadcast_Profile https://wiki.st.com/stm32mcu/wiki/Connectivity:Bluetooth_LE_Audio_-_STM32WBA_Telephony_%26_Media_Audio_Profile
https://github.com/siewedu/auracast_assistant https://www.bluetooth.com/wp-content/uploads/2023/03/Developing_Auracast_Receivers-Legacy_Smartphones.pdf
https://google.github.io/bumble/index.html
7.1.7 Bleak : interagissez entre un Linux et un objet BLE
Bleak est un acronyme pour Bluetooth Low Energy platform Agnostic Klient. Il est directement accessible en paquet Debian (python3-bleak). La documentation de Yannick Marietti présente comment interagir avec un Nucleo.
7.1.7.1 Scannez le réseau
La première étape consiste à scanner le réseau pour lister les objets BLE :
#! /usr/bin/python3
import asyncio
from bleak import BleakScanner
async def main():
devices = await BleakScanner.discover()
for d in devices:
print(d)
asyncio.run(main())
À l’exécution, il retourne la liste des objets détectés, avec si possible leur nom :
arno@laurel:~$ ./scanBLE.py 2E:8F:70:E0:A3:28: 2E-8F-70-E0-A3-28 49:E8:FE:F5:3B:9F: 49-E8-FE-F5-3B-9F 41:F0:3D:D7:BD:94: LE-OpenRun Pro 02:02:27:4E:1B:0A: wb01|23.1|42.3|1007 88:92:CC:C3:B5:CA: WH-CH720N
7.1.7.2 Listez les caractéristiques d’un objet
Certains objets BLE peuvent utiliser les caractéritiques BLE pour interagir avec le système d’information. Le programme suivant permet de lister celles d’un objet :
Found 5 service(s):
===============================================
Service: 00001801-0000-1000-8000-00805f9b34fb
Description: Generic Attribute Profile
Handle: 1
Characteristics (1):
...
-----------------------------------------------
Service: 00001800-0000-1000-8000-00805f9b34fb
Description: Generic Access Profile
Handle: 27
Characteristics (2):
---------------------------------------------
UUID: 00002a00-0000-1000-8000-00805f9b34fb
Description: Device Name
Handle: 28
Properties: read
Value (string): LE-Bose QC Headphones
UUID: 00002a01-0000-1000-8000-00805f9b34fb
Description: Appearance
Handle: 30
Properties: read
Value (string): ^@^@
--------------------------
7.1.7.3 écoutez les annonces
Pour écouter les annonces d’un objet, il est possible de s’inspirer du programme suivant :
#! /usr/bin/python
"""
BLE get advertisement from selected device
"""
# =====================================================================
# imports
import asyncio
import sys
import argparse
from bleak import BleakScanner
from bleak.exc import BleakError
from datetime import datetime
import time
# =====================================================================
timeout_seconds = 50
address_to_look_for = 'F1:D9:3B:39:4D:A2'
name_to_look_for = "wb01"
# =====================================================================
async def main():
# Wait for at most 1 second
try:
await asyncio.wait_for((getenv()), timeout=60.0)
except TimeoutError:
print('timeout!')
async def getenv():
stop_event = asyncio.Event()
def callback(device, advertisement_data):
# Looking for: wb in local_name
name = advertisement_data.local_name
if (name != None) :
if (name[0] == "w") and (name[1] == "b"):
print(name)
stop_event.set()
async with BleakScanner(callback,timeout=4) as scanner:
await stop_event.wait()
asyncio.run(main())
Ce programme fonctionne en mode asynchrone. Cela permet de lancer plusieurs tâches simultanément ou de les contrôler.
La tâche principale (main), lance getenv en limitant sa durée d’exécution.
la tâche getnv créé un scanner qui va lancer la routine callback lors de la réception d’une annonce. En filtrant sur l’annonce, on sélectionne une annonce qui correspong à l’annonce attendue et on arrête la tâche, ce qui conduit à la terminaison du programme.






