bluetooth — низькорівневий Bluetooth¶
Цей модуль надає інтерфейс до вбудованого контролера Bluetooth. Він підтримує Bluetooth Low Energy (BLE) у ролях Central, Peripheral, Broadcaster та Observer, а також сервер та клієнт GATT і канали L2CAP з орієнтацією на з’єднання. Пристрій може одночасно виконувати кілька ролей. Підтримуються також сполучення та зв’язування.
Цей API призначений для відповідності низькорівневому протоколу Bluetooth і надання будівельних блоків для абстракцій вищого рівня, наприклад типів пристроїв.
Порада
Для більшості застосунків надайте перевагу бібліотеці aioble вищого рівня, яка надає обгортку на основі asyncio навколо цього модуля. Дивіться aioble — Async BLE.
клас BLE¶
- class bluetooth.BLE¶
Повертає одноекземплярний об’єкт BLE.
Налаштування
- active(active: bool | None = None, /) bool¶
За потреби змінює активний стан радіомодуля BLE і повертає поточний стан.
Радіомодуль необхідно активувати перед використанням будь-яких інших методів цього класу.
- config(param: str, /) Any¶
- config(*, **kwargs: Any) None
Отримує або встановлює конфігураційні значення інтерфейсу BLE. Щоб отримати значення, назву параметра слід передати як рядок, і запитується лише один параметр за раз. Для встановлення значень використовується синтаксис ключових слів, і за один раз можна встановити один або кілька параметрів.
Наразі підтримуються такі значення:
'mac': Поточна адреса, що використовується, залежно від поточного режиму адресації. Повертає кортеж(addr_type, addr).Дивіться
gap_scanдля отримання відомостей про тип адреси.Запит до цього поля можна здійснювати лише тоді, коли інтерфейс активний.
'addr_mode': Встановлює режим адресації. Значення:Значення
Назва
Поведінка
0x00PUBLIC
Використовувати публічну адресу контролера.
0x01RANDOM
Використовувати згенеровану статичну адресу.
0x02RPA
Використовувати приватні адреси, що можна розпізнати.
0x03NRPA
Використовувати приватні адреси, які не можна розпізнати.
За замовчуванням інтерфейс використовуватиме адресу PUBLIC, якщо вона доступна, інакше використовуватиметься адреса RANDOM.
'gap_name': Отримати/встановити назву пристрою GAP, яка використовується сервісом Generic Access (UUID0x1800), характеристика Device Name (UUID0x2a00). Може бути встановлена будь-коли та змінена кілька разів.'rxbuf': Отримати/встановити розмір у байтах внутрішнього буфера, що використовується для зберігання вхідних подій. Цей буфер є глобальним для всього драйвера BLE і тому обробляє вхідні дані для всіх подій, включаючи всі характеристики. Збільшення цього значення дозволяє краще обробляти пакетні вхідні дані (наприклад результати сканування) і отримувати більші значення характеристик.'mtu': Отримати/встановити MTU, що буде використовуватися під час обміну ATT MTU. Отриманий MTU буде мінімальним із цього значення та MTU віддаленого пристрою. Обмін ATT MTU не відбуватиметься автоматично (якщо тільки його не ініціює віддалений пристрій) і має бути ініційований вручну за допомогоюgattc_exchange_mtu. Використовуйте подію_IRQ_MTU_EXCHANGEDдля визначення MTU для певного з’єднання.'bond': Встановлює, чи буде зв’язування увімкнено під час сполучення. Коли увімкнено, запити на сполучення встановлюватимуть прапор «bond» і ключі будуть збережені обома пристроями.'mitm': Встановлює, чи потрібен захист від MITM для сполучення.'io': Встановлює можливості вводу/виводу цього пристрою.Доступні параметри:
Константа
Значення
Можливість
_IO_CAPABILITY_DISPLAY_ONLY0
Тільки відображення
_IO_CAPABILITY_DISPLAY_YESNO1
Відображення із введенням так/ні
_IO_CAPABILITY_KEYBOARD_ONLY2
Тільки клавіатура
_IO_CAPABILITY_NO_INPUT_OUTPUT3
Без вводу та виводу
_IO_CAPABILITY_KEYBOARD_DISPLAY4
Клавіатура та відображення
'le_secure': Встановлює, чи потрібне сполучення «LE Secure». За замовчуванням false (тобто дозволяється «Legacy Pairing»).
Обробка подій
- irq(handler: Callable[[int, Tuple], Any | None], /) None¶
Реєструє зворотний виклик для подій зі стека BLE. handler приймає два аргументи:
event(один із кодів нижче) іdata(кортеж значень, специфічних для події).Примітка: Як оптимізація для уникнення зайвих виділень пам’яті, записи
addr,adv_data,char_data,notify_dataтаuuidу кортежах є екземплярами memoryview лише для читання, що вказують на внутрішній кільцевий буферbluetoothі дійсні лише під час виклику функції обробника IRQ. Якщо ваша програма потребує збереження одного з цих значень для доступу після повернення обробника IRQ (наприклад зберігаючи його в екземплярі класу або глобальній змінній), необхідно зробити копію даних, використовуючиbytes()абоbluetooth.UUID(), ось так:connected_addr = bytes(addr) # equivalently: adv_data, char_data, or notify_data matched_uuid = bluetooth.UUID(uuid)
Наприклад, обробник IRQ для результату сканування може перевірити
adv_data, щоб визначити, чи це правильний пристрій, і лише тоді скопіювати дані адреси для використання в іншому місці програми. Для виведення даних з обробника IRQ знадобитьсяprint(bytes(addr)).Обробник зазвичай здійснює диспетчеризацію за кодом події і розпакування кортежу корисного навантаження, специфічного для події:
def bt_irq(event, data): if event == _IRQ_CENTRAL_CONNECT: conn_handle, addr_type, addr = data ... elif event == _IRQ_SCAN_RESULT: addr_type, addr, adv_type, rssi, adv_data = data ...
Нижче наведені всі коди подій, корисне навантаження, що вони передають, і короткий опис. Для подій, де згадується поле
status,statusдорівнює0при успіху та непорожньому значенню, специфічному для реалізації, при невдачі.Константа
Значення
Подія
Кортеж корисного навантаження
_IRQ_CENTRAL_CONNECT1
Центральний пристрій підключився до цього периферійного пристрою.
(conn_handle, addr_type, addr)_IRQ_CENTRAL_DISCONNECT2
Центральний пристрій відключився від цього периферійного пристрою.
(conn_handle, addr_type, addr)_IRQ_GATTS_WRITE3
Підключений клієнт записав значення до локальної характеристики або дескриптора. Використовуйте
gatts_readдля отримання нового значення.(conn_handle, attr_handle)_IRQ_GATTS_READ_REQUEST4
Підключений клієнт здійснив запит на читання. Поверніть ненульовий код помилки з таблиці нижче, щоб відхилити читання, або
0/None, щоб прийняти його.(conn_handle, attr_handle)_IRQ_SCAN_RESULT5
Під час активного сканування було отримано один рекламний пакет.
(addr_type, addr, adv_type, rssi, adv_data)_IRQ_SCAN_DONE6
Поточне сканування завершено: або сплив налаштований час, або було викликано
gap_scan(None).()_IRQ_PERIPHERAL_CONNECT7
Раніше виданий
gap_connectзавершився успішно.(conn_handle, addr_type, addr)_IRQ_PERIPHERAL_DISCONNECT8
Підключений периферійний пристрій відключився.
(conn_handle, addr_type, addr)_IRQ_GATTC_SERVICE_RESULT9
Один сервіс було знайдено за допомогою
gattc_discover_services.(conn_handle, start_handle, end_handle, uuid)_IRQ_GATTC_SERVICE_DONE10
Виявлення сервісів завершено.
(conn_handle, status)_IRQ_GATTC_CHARACTERISTIC_RESULT11
Одну характеристику було знайдено за допомогою
gattc_discover_characteristics.(conn_handle, end_handle, value_handle, properties, uuid)_IRQ_GATTC_CHARACTERISTIC_DONE12
Виявлення характеристик завершено.
(conn_handle, status)_IRQ_GATTC_DESCRIPTOR_RESULT13
Один дескриптор було знайдено за допомогою
gattc_discover_descriptors.(conn_handle, dsc_handle, uuid)_IRQ_GATTC_DESCRIPTOR_DONE14
Виявлення дескрипторів завершено.
(conn_handle, status)_IRQ_GATTC_READ_RESULT15
Раніше виданий
gattc_readповернув дані.(conn_handle, value_handle, char_data)_IRQ_GATTC_READ_DONE16
Раніше виданий
gattc_readзавершено.(conn_handle, value_handle, status)_IRQ_GATTC_WRITE_DONE17
Раніше виданий
gattc_writeбуло підтверджено.(conn_handle, value_handle, status)_IRQ_GATTC_NOTIFY18
Віддалений сервер надіслав (непідтверджене) сповіщення.
(conn_handle, value_handle, notify_data)_IRQ_GATTC_INDICATE19
Віддалений сервер надіслав (підтверджену) індикацію.
(conn_handle, value_handle, notify_data)_IRQ_GATTS_INDICATE_DONE20
Раніше надіслана індикація була підтверджена клієнтом (або закінчився час очікування).
(conn_handle, value_handle, status)_IRQ_MTU_EXCHANGED21
Обмін ATT MTU завершено (ініційований будь-якою зі сторін).
(conn_handle, mtu)_IRQ_L2CAP_ACCEPT22
Віддалений пристрій запросив L2CAP-з’єднання на PSM, який прослуховує цей пристрій. Поверніть ненульове ціле число, щоб відхилити, або
0/None, щоб прийняти.(conn_handle, cid, psm, our_mtu, peer_mtu)_IRQ_L2CAP_CONNECT23
Канал L2CAP тепер встановлено: або шляхом прийняття вхідного запиту, або завершенням вихідного
l2cap_connect.(conn_handle, cid, psm, our_mtu, peer_mtu)_IRQ_L2CAP_DISCONNECT24
Канал L2CAP було відключено.
statusдорівнює0при чистому відключенні, або ненульовий, якщо вихідна спроба з’єднання не вдалася.(conn_handle, cid, psm, status)_IRQ_L2CAP_RECV25
На канал L2CAP надійшли дані. Викличте
l2cap_recvintoдля їх читання.(conn_handle, cid)_IRQ_L2CAP_SEND_READY26
Попередній
l2cap_send, що повернувFalse, завершив передачу і канал готовий знову. Ненульовийstatusозначає, що буфер передачі переповнився і застосунок повинен повторно надіслати дані.(conn_handle, cid, status)_IRQ_CONNECTION_UPDATE27
Віддалений пристрій оновив параметри з’єднання (інтервал, затримка, час нагляду).
(conn_handle, conn_interval, conn_latency, supervision_timeout, status)_IRQ_ENCRYPTION_UPDATE28
Стан шифрування з’єднання змінився, зазвичай після завершення сполучення або зв’язування.
(conn_handle, encrypted, authenticated, bonded, key_size)_IRQ_GET_SECRET29
Стек запитує збережений секрет зв’язування. Якщо
keyдорівнюєNone, повертаєтьсяindex-е збережене значенняsec_type; інакше повертається значення, пов’язане з(sec_type, key). ПовернітьNone, якщо нічого не збережено.(sec_type, index, key)_IRQ_SET_SECRET30
Стек просить застосунок зберегти секрет зв’язування. Поверніть
Trueпісля збереження.(sec_type, key, value)_IRQ_PASSKEY_ACTION31
Під час сполучення потрібна дія з паролем. Відповідайте за допомогою
gap_passkey; дивіться таблицю дій з паролем нижче для можливих дій.(conn_handle, action, passkey)Для події
_IRQ_GATTS_READ_REQUESTдоступні такі коди повернення:Константа
Значення
Значення
_GATTS_NO_ERROR0x00Прийняти читання.
_GATTS_ERROR_READ_NOT_PERMITTED0x02Читання не дозволено.
_GATTS_ERROR_WRITE_NOT_PERMITTED0x03Запис не дозволено.
_GATTS_ERROR_INSUFFICIENT_AUTHENTICATION0x05Клієнт не автентифікований.
_GATTS_ERROR_INSUFFICIENT_AUTHORIZATION0x08Клієнт не авторизований.
_GATTS_ERROR_INSUFFICIENT_ENCRYPTION0x0fКанал не зашифровано.
Для події
_IRQ_PASSKEY_ACTIONдоступні такі дії:Константа
Значення
Значення
_PASSKEY_ACTION_NONE0
Жодної дії не потрібно.
_PASSKEY_ACTION_INPUT2
Запропонувати користувачу ввести пароль, показаний на віддаленому пристрої.
_PASSKEY_ACTION_DISPLAY3
Відобразити 6-значний пароль для введення на віддаленому пристрої.
_PASSKEY_ACTION_NUMERIC_COMPARISON4
Підтвердити, що пароль збігається з показаним на віддаленому пристрої.
З метою економії місця у мікропрограмі ці константи не включені до модуля
bluetooth. Додайте потрібні вам константи зі списків вище до своєї програми.
Роль Broadcaster (Advertiser)
- gap_advertise(interval_us: int | None, adv_data: bytes | None = None, *, resp_data: bytes | None = None, connectable: bool = True) None¶
Розпочинає рекламування з вказаним інтервалом (у мікросекундах). Цей інтервал буде округлено вниз до найближчих 625 мкс. Щоб зупинити рекламування, встановіть interval_us на
None.adv_data і resp_data можуть бути будь-якого типу, що реалізує буферний протокол (наприклад
bytes,bytearray,str). adv_data включається у всі широкомовні передачі, а resp_data надсилається у відповідь на активне сканування.Примітка: якщо adv_data (або resp_data) дорівнює
None, тоді будуть повторно використані дані, передані в попередньому викликуgap_advertise. Це дозволяє broadcaster’у відновити рекламування за допомогою лишеgap_advertise(interval_us). Щоб очистити рекламне навантаження, передайте порожнійbytes, тобтоb''.
Роль Observer (Scanner)
- gap_scan(duration_ms: int | None, interval_us: int = 1280000, window_us: int = 11250, active: bool = False, /) None¶
Запускає операцію сканування тривалістю вказаного часу (у мілісекундах).
Для нескінченного сканування встановіть duration_ms на
0.Щоб зупинити сканування, встановіть duration_ms на
None.Використовуйте interval_us і window_us для необов’язкового налаштування робочого циклу. Сканер працюватиме протягом window_us мікросекунд кожні interval_us мікросекунд загальною тривалістю duration_ms мілісекунд. Інтервал і вікно за замовчуванням становлять 1,28 секунди і 11,25 мілісекунди відповідно (фонове сканування).
Для кожного результату сканування буде викликана подія
_IRQ_SCAN_RESULTз даними події(addr_type, addr, adv_type, rssi, adv_data).Значення
addr_typeвказують на публічні або випадкові адреси:Значення
Назва
Значення
0x00PUBLIC
Публічна адреса пристрою.
0x01RANDOM
Випадкова адреса (статична, RPA або NRPA; тип закодовано в самій адресі).
Значення
adv_typeвідповідають специфікації Bluetooth:Значення
Назва
Значення
0x00ADV_IND
Спрямоване рекламування з можливістю підключення та сканування.
0x01ADV_DIRECT_IND
Спрямоване рекламування з можливістю підключення.
0x02ADV_SCAN_IND
Неспрямоване рекламування з можливістю сканування.
0x03ADV_NONCONN_IND
Неспрямоване рекламування без можливості підключення.
0x04SCAN_RSP
Відповідь на сканування.
activeможе бути встановлено наTrue, якщо ви хочете отримувати відповіді на сканування у результатах.Коли сканування зупинено (або після закінчення тривалості, або при явній зупинці), буде викликана подія
_IRQ_SCAN_DONE.
Роль Central
Центральний пристрій може підключатися до периферійних пристроїв, які він виявив за допомогою ролі Observer (дивіться
gap_scan) або із відомою адресою.- gap_connect(addr_type: int | None, addr: bytes | None = None, scan_duration_ms: int = 2000, min_conn_interval_us: int | None = None, max_conn_interval_us: int | None = None, /) None¶
Підключитися до периферійного пристрою.
Дивіться
gap_scanдля отримання відомостей про типи адрес.Щоб скасувати незавершену спробу підключення раніше, викличте
gap_connect(None).У разі успіху буде викликана подія
_IRQ_PERIPHERAL_CONNECT. При скасуванні спроби підключення буде викликана подія_IRQ_PERIPHERAL_DISCONNECT.Пристрій очікуватиме до scan_duration_ms мілісекунд для отримання рекламного пакету від пристрою.
Інтервал з’єднання можна налаштувати в мікросекундах за допомогою одного або обох параметрів min_conn_interval_us і max_conn_interval_us. Інакше буде обрано інтервал за замовчуванням, зазвичай від 30000 до 50000 мікросекунд. Коротший інтервал збільшить пропускну здатність за рахунок споживання енергії.
Роль Peripheral
Від периферійного пристрою очікується надсилання рекламних пакетів з можливістю підключення (дивіться
gap_advertise). Зазвичай він діє як сервер GATT, попередньо зареєструвавши сервіси та характеристики за допомогоюgatts_register_services.Коли центральний пристрій підключається, буде викликана подія
_IRQ_CENTRAL_CONNECT.Ролі Central і Peripheral
- gap_disconnect(conn_handle: int, /) bool¶
Відключити вказаний дескриптор з’єднання. Це може бути як центральний пристрій, що підключився до цього пристрою (якщо він діє як периферійний), так і периферійний пристрій, до якого цей пристрій підключався раніше (якщо він діє як центральний).
У разі успіху буде викликана подія
_IRQ_PERIPHERAL_DISCONNECTабо_IRQ_CENTRAL_DISCONNECT.Повертає
False, якщо дескриптор з’єднання не був підключений, іTrueв іншому випадку.
GATT Server
GATT server має набір зареєстрованих сервісів. Кожен сервіс може містити характеристики, кожна з яких має значення. Характеристики також можуть містити дескриптори, які самі мають значення.
Ці значення зберігаються локально та доступні за їх «value handle», що генерується під час реєстрації сервісу. Вони також можуть бути прочитані або записані віддаленим клієнтським пристроєм. Крім того, сервер може «сповіщати» характеристику підключеному клієнту через дескриптор з’єднання.
Пристрій у ролі центрального або периферійного може функціонувати як GATT server, однак у більшості випадків периферійний пристрій виступатиме сервером.
Характеристики та дескриптори мають максимальний розмір за замовчуванням 20 байт (стандартний ATT MTU 23 байти мінус 3-байтовий заголовок ATT; більший узгоджений MTU сам по собі не підвищує цей ліміт). Все, що клієнт записує до них, буде усічено до цієї довжини. Однак будь-який локальний запис збільшить максимальний розмір, тому якщо ви хочете дозволити більші записи від клієнта до певної характеристики, використовуйте
gatts_writeпісля реєстрації. Наприклад:gatts_write(char_handle, bytes(100)).- gatts_register_services(services_definition: Sequence[Sequence], /) Sequence[Sequence[int]]¶
Налаштовує сервер із вказаними сервісами, замінюючи будь-які існуючі сервіси.
services_definition — це список сервісів, де кожен сервіс є кортежем із двох елементів, що містить UUID і список характеристик.
Кожна характеристика — це кортеж із двох або трьох елементів, що містить UUID, значення flags і, за потреби, список дескрипторів.
Кожен дескриптор — це кортеж із двох елементів, що містить UUID і значення flags.
flags — це побітова комбінація OR прапорів, визначених нижче. Вони встановлюють як поведінку характеристики (або дескриптора), так і вимоги до безпеки та конфіденційності.
Значення, що повертається, — це список (по одному елементу на сервіс) кортежів (кожен елемент є value handle). Дескриптори характеристик і їх handle’и об’єднані в один кортеж у порядку їх визначення.
Наступний приклад реєструє два сервіси (Heart Rate і Nordic UART):
bt = bluetooth.BLE() bt.active(True) # Heart Rate service: one Heart Rate Measurement characteristic. HR_SERVICE = ( bluetooth.UUID(0x180D), ( (bluetooth.UUID(0x2A37), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY), ), ) # Nordic UART service: a TX characteristic the client subscribes # to for notifications, and an RX characteristic it writes to. UART_SERVICE = ( bluetooth.UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E'), ( (bluetooth.UUID('6E400003-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY), (bluetooth.UUID('6E400002-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_WRITE), ), ) ((hr,), (tx, rx)) = bt.gatts_register_services( (HR_SERVICE, UART_SERVICE), )
Три value handle (
hr,tx,rx) можна використовувати зgatts_read,gatts_write,gatts_notifyтаgatts_indicate.Примітка: Рекламування має бути зупинено перед реєстрацією сервісів.
Доступні прапори для характеристик і дескрипторів:
Константа
Значення
Значення
_FLAG_BROADCAST0x0001Характеристика може транслюватися широкомовно.
_FLAG_READ0x0002Клієнт може читати значення.
_FLAG_WRITE_NO_RESPONSE0x0004Клієнт може записувати без очікування відповіді.
_FLAG_WRITE0x0008Клієнт може записувати з підтвердженою відповіддю.
_FLAG_NOTIFY0x0010Сервер може надсилати сповіщення (непідтверджені).
_FLAG_INDICATE0x0020Сервер може надсилати індикації (підтверджені).
_FLAG_AUTHENTICATED_SIGNED_WRITE0x0040Клієнт може здійснювати підписані записи.
_FLAG_AUX_WRITE0x0100Розширені властивості: дозволені записи в чергу/надійні записи.
_FLAG_READ_ENCRYPTED0x0200Для читання потрібне зашифроване з’єднання.
_FLAG_READ_AUTHENTICATED0x0400Для читання потрібне автентифіковане (захищене від MITM) з’єднання.
_FLAG_READ_AUTHORIZED0x0800Для читання потрібна авторизація на рівні застосунку.
_FLAG_WRITE_ENCRYPTED0x1000Для запису потрібне зашифроване з’єднання.
_FLAG_WRITE_AUTHENTICATED0x2000Для запису потрібне автентифіковане (захищене від MITM) з’єднання.
_FLAG_WRITE_AUTHORIZED0x4000Для запису потрібна авторизація на рівні застосунку.
Як і константи подій вище, ці прапори не надаються модулем
bluetooth; скопіюйте потрібні до своєї програми.
- gatts_read(value_handle: int, /) bytes¶
Читає локальне значення для цього handle (яке було записано
gatts_writeабо віддаленим клієнтом).
- gatts_write(value_handle: int, data: bytes, send_update: bool = False, /) None¶
Записує локальне значення для цього handle, яке може бути прочитане клієнтом.
Якщо send_update дорівнює
True, то підписані клієнти будуть сповіщені (або отримають індикацію, залежно від того, на що вони підписані та які операції підтримує характеристика) про цей запис.
- gatts_notify(conn_handle: int, value_handle: int, data: bytes | None = None, /) None¶
Надсилає запит сповіщення підключеному клієнту.
Якщо data дорівнює
None(за замовчуванням), буде надіслано поточне локальне значення (встановлене за допомогоюgatts_write).Інакше, якщо data не дорівнює
None, це значення надсилається клієнту як частина сповіщення. Локальне значення не змінюватиметься.Примітка: Сповіщення буде надіслано незалежно від статусу підписки клієнта на цю характеристику.
- gatts_indicate(conn_handle: int, value_handle: int, data: bytes | None = None, /) None¶
Надсилає запит індикації підключеному клієнту.
Якщо data дорівнює
None(за замовчуванням), буде надіслано поточне локальне значення (встановлене за допомогоюgatts_write).Інакше, якщо data не дорівнює
None, це значення надсилається клієнту як частина індикації. Локальне значення не змінюватиметься.Після підтвердження (або невдачі, наприклад тайм-аут) буде викликана подія
_IRQ_GATTS_INDICATE_DONE.Примітка: Індикація буде надіслана незалежно від статусу підписки клієнта на цю характеристику.
- gatts_set_buffer(value_handle: int, len: int, append: bool = False, /) None¶
Встановлює розмір внутрішнього буфера для значення в байтах. Це обмежить максимально можливий запис, який може бути отриманий. За замовчуванням 20 байт (стандартний ATT MTU 23 мінус 3-байтовий заголовок ATT).
Встановлення append на
Trueпризведе до того, що всі віддалені записи будуть додаватися до, а не замінювати поточне значення. Таким чином може буферизуватися щонайбільше len байт. При використанніgatts_readзначення буде очищено після читання. Ця функція корисна при реалізації чогось подібного до Nordic UART Service.
GATT Client
GATT client може виявляти та читати/записувати характеристики на віддаленому GATT server.
Пристрій у ролі центрального частіше діє як GATT client, однак периферійний пристрій також може виступати клієнтом для виявлення інформації про центральний пристрій, що підключився до нього (наприклад для читання назви пристрою зі служби інформації про пристрій).
- gattc_discover_services(conn_handle: int, uuid: UUID | None = None, /) None¶
Запит до підключеного сервера про його сервіси.
За потреби вкажіть uuid сервісу для запиту лише цього сервісу.
Для кожного виявленого сервісу буде викликана подія
_IRQ_GATTC_SERVICE_RESULT, після якої після завершення викликається_IRQ_GATTC_SERVICE_DONE.
- gattc_discover_characteristics(conn_handle: int, start_handle: int, end_handle: int, uuid: UUID | None = None, /) None¶
Запит до підключеного сервера про характеристики у вказаному діапазоні.
За потреби вкажіть uuid характеристики для запиту лише цієї характеристики.
Передача
start_handle=1іend_handle=0xffffохоплює весь діапазон GATT attribute-handle, тому ця комбінація фактично здійснює пошук по всіх сервісах на віддаленому пристрої.Для кожної виявленої характеристики буде викликана подія
_IRQ_GATTC_CHARACTERISTIC_RESULT, після якої після завершення викликається_IRQ_GATTC_CHARACTERISTIC_DONE.
- gattc_discover_descriptors(conn_handle: int, start_handle: int, end_handle: int, /) None¶
Запит до підключеного сервера про дескриптори у вказаному діапазоні.
Для кожного виявленого дескриптора буде викликана подія
_IRQ_GATTC_DESCRIPTOR_RESULT, після якої після завершення викликається_IRQ_GATTC_DESCRIPTOR_DONE.
- gattc_read(conn_handle: int, value_handle: int, /) None¶
Видає віддалений запит на читання до підключеного сервера для вказаного дескриптора характеристики або дескриптора.
Коли значення стане доступним, буде викликана подія
_IRQ_GATTC_READ_RESULT, після якої після завершення викликається_IRQ_GATTC_READ_DONE.
- gattc_write(conn_handle: int, value_handle: int, data: bytes, mode: int = 0, /) None¶
Видає віддалений запит на запис до підключеного сервера для вказаного дескриптора характеристики або дескриптора.
Аргумент mode визначає поведінку запису; наразі підтримуються такі значення:
mode=0(за замовчуванням) — це запис без відповіді: запис буде надіслано на віддалений сервер, але підтвердження не буде повернуто і жодна подія не буде викликана.mode=1— це запис з відповіддю: від віддаленого сервера запитується надсилання відповіді/підтвердження отримання даних.
Якщо відповідь отримана від віддаленого сервера, буде викликана подія
_IRQ_GATTC_WRITE_DONE.
- gattc_exchange_mtu(conn_handle: int, /) None¶
Ініціювати обмін MTU з підключеним сервером, використовуючи бажаний MTU, встановлений за допомогою
BLE.config(mtu=value).Подія
_IRQ_MTU_EXCHANGEDбуде викликана після завершення обміну MTU.Обмін MTU зазвичай ініціюється центральним пристроєм; NimBLE підтримує обидві ролі.
Канали L2CAP з орієнтацією на з’єднання
Ця функція дозволяє обмін даними в стилі сокетів між двома BLE-пристроями. Після підключення пристроїв через GAP будь-який пристрій може прослуховувати, чи намагається інший підключитися на числовому PSM (Protocol/Service Multiplexer).
Одночасно може бути активний лише один L2CAP канал (тобто не можна підключатися під час прослуховування).
Активні канали L2CAP ідентифікуються дескриптором з’єднання, на якому вони були встановлені, та CID (ідентифікатор каналу).
Канали з орієнтацією на з’єднання мають вбудований керування потоком на основі кредитів. На відміну від ATT, де пристрої узгоджують спільний MTU, пристрій, що прослуховує, та пристрій, що підключається, кожен встановлюють незалежний MTU, який обмежує максимальну кількість необроблених даних, що може надіслати віддалений пристрій до їх повного споживання в
l2cap_recvinto.- l2cap_listen(psm: int, mtu: int, /) None¶
Починає прослуховування вхідних запитів L2CAP каналу на вказаному psm із локальним MTU, встановленим на mtu.
Коли віддалений пристрій ініціює з’єднання, буде викликана подія
_IRQ_L2CAP_ACCEPT, яка дає можливість сервісу, що прослуховує, відхилити вхідне з’єднання (повернувши ненульове ціле число).Після прийняття з’єднання буде викликана подія
_IRQ_L2CAP_CONNECT, дозволяючи серверу отримати ідентифікатор каналу (CID) та локальний і віддалений MTU.Примітка: Наразі неможливо зупинити прослуховування.
- l2cap_connect(conn_handle: int, psm: int, mtu: int, /) None¶
Підключитися до пристрою, що прослуховує на вказаному psm, із локальним MTU, встановленим на mtu.
При успішному з’єднанні буде викликана подія
_IRQ_L2CAP_CONNECT, дозволяючи клієнту отримати CID та локальний і віддалений (peer) MTU.Невдала спроба з’єднання ініціює подію
_IRQ_L2CAP_DISCONNECTз ненульовим статусом.
- l2cap_disconnect(conn_handle: int, cid: int, /) None¶
Відключити активний канал L2CAP із вказаним conn_handle і cid.
- l2cap_send(conn_handle: int, cid: int, buf: bytes, /) bool¶
Надіслати вказаний buf (що має підтримувати буферний протокол) по каналу L2CAP, ідентифікованому conn_handle і cid.
Буфер повинен задовольняти обидва обмеження: він не повинен перевищувати MTU віддаленого (peer) пристрою і не повинен перевищувати подвійний локальний MTU.
Це поверне
False, якщо канал зараз «заблокований», що означає, щоl2cap_sendне можна викликати знову, поки не буде отримана подія_IRQ_L2CAP_SEND_READY(яка відбудеться, коли віддалений пристрій надасть більше кредитів, зазвичай після отримання та обробки даних).
- l2cap_recvinto(conn_handle: int, cid: int, buf: Any | None, /) int¶
Прийняти дані з вказаного conn_handle і cid у наданий buf (що має підтримувати буферний протокол, наприклад bytearray або memoryview).
Повертає кількість байт, прочитаних із каналу.
Якщо buf дорівнює
None, повертає кількість доступних байт.Примітка: Після отримання події
_IRQ_L2CAP_RECVзастосунок повинен продовжувати викликатиl2cap_recvintoдо тих пір, поки у буфері прийому не залишиться жодного байта (зазвичай до розміру MTU віддаленого (peer) пристрою).Поки буфер прийому не порожній, віддаленому пристрою не будуть надані додаткові кредити каналу і він не зможе надіслати більше даних.
Сполучення та зв’язування
Сполучення дозволяє шифрувати та автентифікувати з’єднання за допомогою обміну секретами (з необов’язковим захистом від MITM за допомогою автентифікації паролем).
Зв’язування — це процес збереження цих секретів у незмінному сховищі. При зв’язуванні пристрій може розпізнати приватну адресу, що можна розпізнати (RPA), іншого пристрою на основі збереженого ключа розпізнавання ідентичності (IRK). Для підтримки зв’язування застосунок повинен реалізувати події
_IRQ_GET_SECRETі_IRQ_SET_SECRET.- gap_pair(conn_handle: int, /) None¶
Ініціювати сполучення з віддаленим пристроєм.
Перед викликом переконайтеся, що параметри конфігурації
io,mitm,le_secureтаbondвстановлені (черезconfig).При успішному сполученні буде викликана подія
_IRQ_ENCRYPTION_UPDATE.
- gap_passkey(conn_handle: int, action: int, passkey: int, /) None¶
Відповісти на подію
_IRQ_PASSKEY_ACTIONдля вказаних conn_handle і action. Значення passkey залежить від action (що, своєю чергою, залежить від налаштованих можливостей вводу/виводу):Дія
Потрібна відповідь passkey
_PASSKEY_ACTION_INPUTПароль, який користувач зчитує з віддаленого пристрою.
_PASSKEY_ACTION_DISPLAYЛокально згенерований випадковий 6-значний пароль, показаний користувачу.
_PASSKEY_ACTION_NUMERIC_COMPARISON1для прийняття пароля, показаного в події_IRQ_PASSKEY_ACTION, або0для скасування сполучення.
клас UUID¶
- class bluetooth.UUID(value: int | bytes | str, /)¶
Створює екземпляр UUID із вказаним
value. Bluetooth використовує три ширини UUID;UUIDприймає будь-яку з них:Ширина UUID
Допустимі типи
valueПриклад
16-бітний
intабо 2-байтовий буфер (little-endian)UUID(0x2908)абоUUID(b'\x08\x29')32-бітний
4-байтовий буфер (little-endian)
UUID(b'\x08\x29\x00\x00')128-бітний
16-байтовий буфер або рядок з дефісами
UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E')16- та 32-бітні UUID є зазвичай ідентифікаторами, виділеними SIG (дивіться Bluetooth assigned numbers); 128-бітні UUID зазвичай визначаються виробниками.