11.5. З’єднання¶
Щойно центральний пристрій вибирає периферійний зі стріму оголошень і надсилає йому запит на з’єднання, обидва пристрої виходять з режиму оголошення / сканування і переходять у стан з’єднання. Радіомодуль тепер планує свою активність на каналах даних канального рівня, псевдовипадково перестрибуючи між ними відповідно до послідовності, узгодженої під час встановлення з’єднання. Все, що знаходиться вище канального рівня – GATT, безпека, L2CAP – працює поверх з’єднання, встановленого тут.
11.5.1. Подія з’єднання¶
Два пристрої у BLE-з’єднанні не ведуть безперервну передачу. Вони домовляються про інтервал з’єднання, і на кожному інтервалі обидва пристрої вмикають радіомодуль, обмінюються всіма пакетами, що стоять у черзі, підтверджують отримане і знову переходять у сплячий режим. Кожен такий обмін називається подією з’єднання.
Радіомодуль на кожному пристрої активний лише під час коротких подій з’єднання, все інше перебуває в сплячому режимі. Периферійний пристрій може пропускати події завдяки периферійній затримці.¶
Числа, що керують цим, погоджуються під час встановлення з’єднання і забезпечуються канальним рівнем. Вони доступні для застосунку як через керуючі елементи на стороні запиту, так і через результуючі значення, що повідомляються у відповідь.
Інтервал з’єднання. Від 7,5 мс до 4 с, кроками по 1,25 мс. Центральний пристрій вибирає значення, яке запитує периферійний, якщо запит не є необґрунтованим. Короткші інтервали передають дані з меншою затримкою, але за рахунок більшої активності радіомодуля; довші економлять енергію, але роблять кожну пересилку повільнішою.
Периферійна затримка. Невід’ємне ціле число N. Периферійному пристрою дозволено пропустити до N подій з’єднання, не маючи нічого для відправлення, засипаючи замість того, щоб вмикати радіомодуль для пустого обміну. Корисно для датчиків, що прокидаються раз на секунду, але бажають мати низький чутливий інтервал з’єднання для рідкісних негайних повідомлень.
Тайм-аут нагляду. Від 100 мс до 32 с. Якщо будь-який пристрій нічого не чує від іншого протягом цього часу, канал вважається втраченим і обидва пристрої повертаються до оголошення / сканування. Тайм-аут має бути довшим за
connection_interval * (1 + peripheral_latency)– канальний рівень відхиляє значення, що порушують цю умову.
aioble.Device.connect() приймає min_conn_interval_us і max_conn_interval_us, щоб центральний пристрій міг запросити певний діапазон; фактичне значення, на якому зупинився радіомодуль, можна зчитати через конфігурацію канального рівня після встановлення з’єднання.
11.5.2. Що означають «центральний» і «периферійний» всередині з’єднання¶
Ролі, встановлені під час оголошення, зберігаються після встановлення з’єднання:
Центральний пристрій керує тактуванням – він є ведучим у послідовності перестрибування і подіях з’єднання.
Периферійний пристрій є реактивним. Він може запросити зміну параметрів з’єднання (наприклад, довший інтервал для економії енергії), але центральний вирішує, чи прийняти зміни.
Ролі не залежать від того, хто розміщує базу даних GATT – це окремий вимір. За угодою периферійний пристрій є також GATT сервером, а центральний – GATT клієнтом, але BLE дозволяє будь-якій стороні розміщувати сервіси GATT. Камери майже завжди дотримуються цієї угоди: периферійний + сервер для застосунків «камера публікує дані», центральний + клієнт для застосунків «камера зчитує дані з датчика».
11.5.3. Максимальний розмір блоку передачі (MTU)¶
Канальний рівень переносить пакети, які за замовчуванням є короткими – 27 байтів корисного навантаження, з яких лише 23 доступні для GATT. Цього достатньо для невеликого значення або короткої команди, але надто мало для будь-чого багатобайтового. Обидві сторони можуть підвищити це значення шляхом переговорів, до ліміту, який підтримує мікропрограма радіомодуля (зазвичай кілька сотень байтів на сучасних контролерах).
API aioble керує переговорами через aioble.DeviceConnection.exchange_mtu(), і результат стає доступним через атрибут mtu. Більший MTU означає менше раундів для будь-якого значення більше ~20 байтів, за невеликою ціною у вигляді буферної пам’яті.
11.5.4. Час життя¶
З’єднання існує до одного з таких моментів:
будь-яка зі сторін викликає
disconnect(),спрацьовує тайм-аут нагляду (поза зоною дії, радіомодуль вимкнено, збій однорангового пристрою), або
явний збій канального рівня (невідповідність шифрування, відхилення сполучення).
Коли з’єднання розривається, кожна операція GATT, що стоїть у черзі або виконується в ньому, викликає aioble.DeviceDisconnectedError, а будь-які блоки async with connection, в яких перебуває застосунок, завершуються коректно. Периферійний пристрій зазвичай реагує поверненням до aioble.advertise() і очікуванням наступного центрального; центральний реагує або повторним скануванням, або передачею події відключення до застосунку.
Час життя є однією з причин корисності aioble. Синхронний BLE API мав би надавати зворотні виклики відключення та маски подій; версія на asyncio перетворює відключення на виключення всередині сопрограми, що очікувала на операцію, а саме для такого очищення в async with і призначений цей механізм.