11.5. Connexions

Une fois qu’un central choisit un périphérique dans le flux d’annonces et lui envoie une requête de connexion, les deux parties quittent le mode d’annonce / de balayage pour entrer dans une connexion. La radio planifie désormais son activité sur les canaux de données de la couche de liaison, en sautant de manière pseudo-aléatoire entre eux selon la séquence convenue au moment de la connexion. Tout ce qui se situe au-dessus de la couche de liaison – GATT, sécurité, L2CAP – s’exécute par-dessus la connexion établie ici.

11.5.1. L’événement de connexion

Deux appareils dans une connexion BLE ne diffusent pas en continu. Ils conviennent d’un intervalle de connexion et, à chaque intervalle, les deux parties réveillent la radio, échangent tous les paquets en attente, accusent réception de ce qu’elles ont reçu, puis se rendorment. Chacun de ces échanges est appelé un événement de connexion.

Une chronologie avec le central sur la piste supérieure et le périphérique sur la piste inférieure. À chaque limite d'intervalle de connexion, les deux pistes affichent une brève impulsion étiquetée « TX/RX ». L'écart entre les impulsions est étiqueté « intervalle de connexion » ; la durée de chaque impulsion est l'« événement de connexion ». Le périphérique a quelques événements ignorés étiquetés « latence du périphérique : le périphérique peut sauter s'il est inactif ».

La radio de chaque côté n’est active que pendant les brefs événements de connexion, tout le reste étant en veille. Le périphérique peut sauter des événements en vertu de la latence du périphérique.

Les valeurs qui régissent cela sont négociées au moment de la connexion et la couche de liaison les fait respecter. Elles sont visibles par l’application à la fois comme paramètres côté requête et comme valeurs résultantes rapportées en retour.

  • Intervalle de connexion. De 7,5 ms à 4 s, par pas de 1,25 ms. Le central choisit la valeur demandée par le périphérique, sauf si la requête est déraisonnable. Des intervalles plus courts fournissent les données avec une latence plus faible au prix d’une activité radio accrue ; des intervalles plus longs économisent l’énergie mais ralentissent chaque aller-retour.

  • Latence du périphérique. Un entier N non négatif. Le périphérique est autorisé à sauter jusqu’à N événements de connexion lorsqu’il n’a rien à envoyer, se rendormant au lieu de réveiller la radio pour un échange vide. Utile pour des capteurs qui se réveillent une fois par seconde pour rapporter, mais qui souhaitent un intervalle de connexion réactif faible pour le rare message immédiat.

  • Délai de supervision. De 100 ms à 32 s. Si l’une des parties n’entend rien de l’autre pendant ce laps de temps, la liaison est déclarée perdue et les deux parties retournent en mode d’annonce / de balayage. Le délai doit être plus long que connection_interval * (1 + peripheral_latency) – la couche de liaison rejette les valeurs qui ne respectent pas cette condition.

aioble.Device.connect() prend min_conn_interval_us et max_conn_interval_us afin que le central puisse demander une plage particulière ; la valeur effective retenue par la radio peut être relue via la configuration de la couche de liaison une fois la connexion établie.

11.5.2. Ce que « central » et « périphérique » signifient au sein d’une connexion

Les rôles définis au moment de l’annonce restent inchangés après l’établissement de la connexion :

  • Le central pilote la temporisation – il détient le côté maître de la séquence de saut et des événements de connexion.

  • Le périphérique est réactif. Il peut demander une modification des paramètres de connexion (un intervalle plus lent pour économiser l’énergie, par exemple), mais c’est le central qui décide de l’accepter ou non.

Les rôles sont indépendants de celui qui héberge la base de données GATT, ce qui constitue un axe distinct. Par convention, le périphérique est aussi le serveur GATT et le central le client GATT, mais BLE permet à l’une ou l’autre partie d’héberger les services GATT. Les caméras suivent presque toujours la convention : périphérique + serveur pour les applications « la caméra publie des données », central + client pour les applications « la caméra lit depuis un capteur ».

11.5.3. L’unité de transmission maximale (MTU)

La couche de liaison transporte par défaut des paquets courts – 27 octets de charge utile, dont seulement 23 sont disponibles pour GATT. C’est suffisant pour une petite mesure ou une commande brève, mais minuscule comparé à tout ce qui dépasse quelques octets. Les deux parties peuvent négocier cette valeur à la hausse, jusqu’à la limite prise en charge par le micrologiciel de la radio (typiquement quelques centaines d’octets sur les contrôleurs modernes).

L’API aioble pilote la négociation via aioble.DeviceConnection.exchange_mtu() et le résultat devient disponible sur l’attribut mtu. Des MTU plus grandes signifient moins d’allers-retours pour toute valeur dépassant ~20 octets, au prix d’un léger surcoût en mémoire tampon.

11.5.4. Durée de vie

Une connexion dure jusqu’à l’un des événements suivants :

  • l’une ou l’autre partie appelle disconnect(),

  • le délai de supervision se déclenche (hors de portée, radio éteinte, pair planté), ou

  • une défaillance explicite de la couche de liaison (incompatibilité de chiffrement, rejet d’appairage).

Lorsque la connexion tombe, chaque opération GATT en file d’attente ou en cours sur celle-ci lève aioble.DeviceDisconnectedError, et tous les blocs async with connection dans lesquels se trouve l’application se terminent proprement. Un périphérique répond généralement en retournant à aioble.advertise() et en attendant le central suivant ; un central répond soit en balayant à nouveau, soit en remontant la déconnexion à l’application.

Cette durée de vie est l’une des raisons pour lesquelles aioble est utile. Une API BLE synchrone devrait exposer des fonctions de rappel de déconnexion et des masques d’événements ; la version asyncio transforme les déconnexions en exceptions à l’intérieur de la coroutine qui attendait l’opération, ce pour quoi le nettoyage de async with est conçu.