bluetooth — niskopoziomowa obsługa Bluetooth¶
Ten moduł zapewnia interfejs do wbudowanego kontrolera Bluetooth. Obsługuje Bluetooth Low Energy (BLE) w rolach Central, Peripheral, Broadcaster i Observer, a także serwer i klient GATT oraz kanały L2CAP zorientowane na połączenie. Urządzenie może jednocześnie działać w wielu rolach. Obsługiwane są również parowanie i wiązanie (bonding).
To API ma odzwierciedlać niskopoziomowy protokół Bluetooth i dostarczać elementów składowych dla abstrakcji wyższego poziomu, takich jak konkretne typy urządzeń.
Wskazówka
W przypadku większości zastosowań preferuj bibliotekę wyższego poziomu aioble, która zapewnia opartą na asyncio nakładkę na ten moduł. Zobacz aioble — Asynchroniczne BLE.
class BLE¶
- class bluetooth.BLE¶
Zwraca singletonowy obiekt BLE.
Konfiguracja
- active(active: bool | None = None, /) bool¶
Opcjonalnie zmienia stan aktywności radia BLE i zwraca jego bieżący stan.
Radio musi zostać aktywowane przed użyciem jakichkolwiek innych metod tej klasy.
- config(param: str, /) Any¶
- config(*, **kwargs: Any) None
Pobiera lub ustawia wartości konfiguracyjne interfejsu BLE. Aby pobrać wartość, nazwa parametru powinna zostać podana jako łańcuch znaków w cudzysłowie i w danej chwili odpytywany jest tylko jeden parametr. Aby ustawić wartości, użyj składni z argumentami nazwanymi; jednocześnie można ustawić jeden lub więcej parametrów.
Obecnie obsługiwane są następujące wartości:
'mac': Bieżący adres w użyciu, zależny od aktualnego trybu adresowania. Zwraca krotkę(addr_type, addr).Szczegóły dotyczące typu adresu znajdziesz w
gap_scan.Można to odpytać tylko wtedy, gdy interfejs jest aktualnie aktywny.
'addr_mode': Ustawia tryb adresowania. Dostępne wartości to:Wartość
Nazwa
Zachowanie
0x00PUBLIC
Użyj publicznego adresu kontrolera.
0x01RANDOM
Użyj wygenerowanego adresu statycznego.
0x02RPA
Użyj rozwiązywalnych adresów prywatnych.
0x03NRPA
Użyj nierozwiązywalnych adresów prywatnych.
Domyślnie interfejs będzie używał adresu PUBLIC, jeśli jest dostępny, w przeciwnym razie użyje adresu RANDOM.
'gap_name': Pobiera/ustawia nazwę urządzenia GAP używaną przez usługę Generic Access (UUID0x1800), charakterystykę Device Name (UUID0x2a00). Można ją ustawić w dowolnym momencie i zmieniać wielokrotnie.'rxbuf': Pobiera/ustawia rozmiar w bajtach wewnętrznego bufora używanego do przechowywania przychodzących zdarzeń. Bufor ten jest globalny dla całego sterownika BLE i dlatego obsługuje dane przychodzące dla wszystkich zdarzeń, w tym wszystkich charakterystyk. Zwiększenie go pozwala lepiej obsługiwać gwałtowne napływy danych przychodzących (na przykład wyniki skanowania) oraz umożliwia odbieranie większych wartości charakterystyk.'mtu': Pobiera/ustawia MTU, które będzie używane podczas wymiany ATT MTU. Wynikowe MTU będzie minimum z tej wartości i MTU urządzenia zdalnego. Wymiana ATT MTU nie nastąpi automatycznie (chyba że zainicjuje ją urządzenie zdalne) i musi zostać ręcznie zainicjowana za pomocągattc_exchange_mtu. Użyj zdarzenia_IRQ_MTU_EXCHANGED, aby poznać MTU dla danego połączenia.'bond': Ustawia, czy wiązanie będzie włączone podczas parowania. Po włączeniu żądania parowania ustawią flagę „bond”, a klucze będą przechowywane przez oba urządzenia.'mitm': Ustawia, czy do parowania wymagana jest ochrona MITM.'io': Ustawia możliwości wejścia/wyjścia tego urządzenia.Dostępne opcje to:
Stała
Wartość
Możliwość
_IO_CAPABILITY_DISPLAY_ONLY0
Tylko wyświetlanie
_IO_CAPABILITY_DISPLAY_YESNO1
Wyświetlanie z wejściem tak/nie
_IO_CAPABILITY_KEYBOARD_ONLY2
Tylko klawiatura
_IO_CAPABILITY_NO_INPUT_OUTPUT3
Brak wejścia ani wyjścia
_IO_CAPABILITY_KEYBOARD_DISPLAY4
Klawiatura i wyświetlacz
'le_secure': Ustawia, czy wymagane jest parowanie „LE Secure”. Domyślnie jest to false (tzn. zezwala na „Legacy Pairing”).
Obsługa zdarzeń
- irq(handler: Callable[[int, Tuple], Any | None], /) None¶
Rejestruje wywołanie zwrotne dla zdarzeń ze stosu BLE. handler przyjmuje dwa argumenty:
event(który będzie jednym z poniższych kodów) orazdata(który jest krotką wartości specyficzną dla zdarzenia).Uwaga: W ramach optymalizacji zapobiegającej niepotrzebnym alokacjom wpisy
addr,adv_data,char_data,notify_dataorazuuidw krotkach są instancjami memoryview tylko do odczytu wskazującymi na wewnętrzny bufor pierścieniowy modułubluetoothi są ważne tylko podczas wywołania funkcji obsługi IRQ. Jeśli program musi zapisać jedną z tych wartości, aby uzyskać do niej dostęp po powrocie z funkcji obsługi IRQ (np. zapisując ją w instancji klasy lub zmiennej globalnej), musi wykonać kopię danych, używającbytes()lubbluetooth.UUID(), w ten sposób:connected_addr = bytes(addr) # equivalently: adv_data, char_data, or notify_data matched_uuid = bluetooth.UUID(uuid)
Na przykład funkcja obsługi IRQ dla wyniku skanowania mogłaby sprawdzić
adv_data, aby zdecydować, czy jest to właściwe urządzenie, i dopiero wtedy skopiować dane adresowe do użycia w innym miejscu programu. Aby wydrukować dane wewnątrz funkcji obsługi IRQ, potrzebne będzieprint(bytes(addr)).Funkcja obsługi zazwyczaj rozdziela działanie na podstawie kodu zdarzenia i rozpakowuje krotkę ładunku specyficzną dla zdarzenia:
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 ...
Każdy kod zdarzenia, dostarczany przez nie ładunek oraz krótki opis wymieniono poniżej. W przypadku zdarzeń, w których wspomniane jest pole
status,statusma wartość0w razie powodzenia i specyficzną dla implementacji wartość niezerową w razie niepowodzenia.Stała
Wartość
Zdarzenie
Krotka ładunku
_IRQ_CENTRAL_CONNECT1
Urządzenie central połączyło się z tym urządzeniem peripheral.
(conn_handle, addr_type, addr)_IRQ_CENTRAL_DISCONNECT2
Urządzenie central rozłączyło się z tym urządzeniem peripheral.
(conn_handle, addr_type, addr)_IRQ_GATTS_WRITE3
Połączony klient zapisał wartość do lokalnej charakterystyki lub deskryptora. Użyj
gatts_read, aby pobrać nową wartość.(conn_handle, attr_handle)_IRQ_GATTS_READ_REQUEST4
Połączony klient wysłał żądanie odczytu. Zwróć niezerowy kod błędu z poniższej tabeli, aby odmówić odczytu, lub
0/None, aby go zaakceptować.(conn_handle, attr_handle)_IRQ_SCAN_RESULT5
Podczas aktywnego skanowania odebrano pojedynczy pakiet rozgłoszeniowy.
(addr_type, addr, adv_type, rssi, adv_data)_IRQ_SCAN_DONE6
Bieżące skanowanie zakończyło się, albo z powodu upłynięcia skonfigurowanego czasu trwania, albo dlatego, że wywołano
gap_scan(None).()_IRQ_PERIPHERAL_CONNECT7
Wcześniej wysłane
gap_connectpowiodło się.(conn_handle, addr_type, addr)_IRQ_PERIPHERAL_DISCONNECT8
Połączone urządzenie peripheral rozłączyło się.
(conn_handle, addr_type, addr)_IRQ_GATTC_SERVICE_RESULT9
Metoda
gattc_discover_servicesznalazła jedną usługę.(conn_handle, start_handle, end_handle, uuid)_IRQ_GATTC_SERVICE_DONE10
Wykrywanie usług zostało zakończone.
(conn_handle, status)_IRQ_GATTC_CHARACTERISTIC_RESULT11
Metoda
gattc_discover_characteristicsznalazła jedną charakterystykę.(conn_handle, end_handle, value_handle, properties, uuid)_IRQ_GATTC_CHARACTERISTIC_DONE12
Wykrywanie charakterystyk zostało zakończone.
(conn_handle, status)_IRQ_GATTC_DESCRIPTOR_RESULT13
Metoda
gattc_discover_descriptorsznalazła jeden deskryptor.(conn_handle, dsc_handle, uuid)_IRQ_GATTC_DESCRIPTOR_DONE14
Wykrywanie deskryptorów zostało zakończone.
(conn_handle, status)_IRQ_GATTC_READ_RESULT15
Wcześniej wysłane
gattc_readzwróciło dane.(conn_handle, value_handle, char_data)_IRQ_GATTC_READ_DONE16
Wcześniej wysłane
gattc_readzostało zakończone.(conn_handle, value_handle, status)_IRQ_GATTC_WRITE_DONE17
Wcześniej wysłane
gattc_writezostało potwierdzone.(conn_handle, value_handle, status)_IRQ_GATTC_NOTIFY18
Zdalny serwer wysłał (niepotwierdzone) powiadomienie.
(conn_handle, value_handle, notify_data)_IRQ_GATTC_INDICATE19
Zdalny serwer wysłał (potwierdzone) wskazanie.
(conn_handle, value_handle, notify_data)_IRQ_GATTS_INDICATE_DONE20
Wcześniej wysłane wskazanie zostało potwierdzone przez klienta (lub upłynął jego limit czasu).
(conn_handle, value_handle, status)_IRQ_MTU_EXCHANGED21
Wymiana ATT MTU została zakończona (zainicjowana przez którąkolwiek ze stron).
(conn_handle, mtu)_IRQ_L2CAP_ACCEPT22
Urządzenie zdalne zażądało połączenia L2CAP na PSM, na którym to urządzenie nasłuchuje. Zwróć niezerową liczbę całkowitą, aby odrzucić, lub
0/None, aby zaakceptować.(conn_handle, cid, psm, our_mtu, peer_mtu)_IRQ_L2CAP_CONNECT23
Kanał L2CAP został teraz ustanowiony, albo przez zaakceptowanie przychodzącego żądania, albo przez zakończenie wychodzącego
l2cap_connect.(conn_handle, cid, psm, our_mtu, peer_mtu)_IRQ_L2CAP_DISCONNECT24
Kanał L2CAP został rozłączony.
statusma wartość0w przypadku czystego rozłączenia lub wartość niezerową, jeśli próba połączenia wychodzącego nie powiodła się.(conn_handle, cid, psm, status)_IRQ_L2CAP_RECV25
Na kanale L2CAP nadeszły dane. Wywołaj
l2cap_recvinto, aby je odczytać.(conn_handle, cid)_IRQ_L2CAP_SEND_READY26
Wcześniejsze
l2cap_send, które zwróciłoFalse, opróżniło się i kanał jest ponownie gotowy. Niezerowystatusoznacza, że bufor nadawczy się przepełnił i aplikacja musi ponownie wysłać dane.(conn_handle, cid, status)_IRQ_CONNECTION_UPDATE27
Urządzenie zdalne zaktualizowało parametry połączenia (interwał, latency, supervision timeout).
(conn_handle, conn_interval, conn_latency, supervision_timeout, status)_IRQ_ENCRYPTION_UPDATE28
Stan szyfrowania połączenia uległ zmianie, zazwyczaj po zakończeniu parowania lub wiązania.
(conn_handle, encrypted, authenticated, bonded, key_size)_IRQ_GET_SECRET29
Stos żąda przechowywanego sekretu wiązania. Jeśli
keyma wartośćNone, zwróćindex-tą przechowywaną wartość typusec_type; w przeciwnym razie zwróć wartość powiązaną z podanym(sec_type, key). ZwróćNone, jeśli nic nie jest przechowywane.(sec_type, index, key)_IRQ_SET_SECRET30
Stos prosi aplikację o trwałe zapisanie sekretu wiązania. Zwróć
Truepo zapisaniu.(sec_type, key, value)_IRQ_PASSKEY_ACTION31
W ramach parowania wymagana jest akcja związana z passkey. Odpowiedz, używając
gap_passkey; możliwe akcje znajdziesz w poniższej tabeli akcji passkey.(conn_handle, action, passkey)Dla zdarzenia
_IRQ_GATTS_READ_REQUESTdostępne kody zwrotne to:Stała
Wartość
Znaczenie
_GATTS_NO_ERROR0x00Zaakceptuj odczyt.
_GATTS_ERROR_READ_NOT_PERMITTED0x02Odczyt niedozwolony.
_GATTS_ERROR_WRITE_NOT_PERMITTED0x03Zapis niedozwolony.
_GATTS_ERROR_INSUFFICIENT_AUTHENTICATION0x05Klient nie jest uwierzytelniony.
_GATTS_ERROR_INSUFFICIENT_AUTHORIZATION0x08Klient nie jest autoryzowany.
_GATTS_ERROR_INSUFFICIENT_ENCRYPTION0x0fŁącze nie jest szyfrowane.
Dla zdarzenia
_IRQ_PASSKEY_ACTIONdostępne akcje to:Stała
Wartość
Znaczenie
_PASSKEY_ACTION_NONE0
Nie jest wymagana żadna akcja.
_PASSKEY_ACTION_INPUT2
Poproś użytkownika o wprowadzenie passkey wyświetlonego na urządzeniu zdalnym.
_PASSKEY_ACTION_DISPLAY3
Wyświetl 6-cyfrowy passkey, który ma zostać wprowadzony na urządzeniu zdalnym.
_PASSKEY_ACTION_NUMERIC_COMPARISON4
Potwierdź, że passkey jest zgodny z tym wyświetlonym na urządzeniu zdalnym.
Aby zaoszczędzić miejsce w oprogramowaniu układowym, te stałe nie są dołączone do modułu
bluetooth. Dodaj do swojego programu te z powyższych list, których potrzebujesz.
Rola Broadcaster (Advertiser)
- gap_advertise(interval_us: int | None, adv_data: bytes | None = None, *, resp_data: bytes | None = None, connectable: bool = True) None¶
Rozpoczyna rozgłaszanie w określonym interwale (w mikrosekundach). Interwał ten zostanie zaokrąglony w dół do najbliższych 625us. Aby zatrzymać rozgłaszanie, ustaw interval_us na
None.adv_data i resp_data mogą być dowolnym typem implementującym protokół buforowy (np.
bytes,bytearray,str). adv_data jest zawarte we wszystkich rozgłoszeniach, a resp_data jest wysyłane w odpowiedzi na aktywne skanowanie.Uwaga: jeśli adv_data (lub resp_data) ma wartość
None, to ponownie użyte zostaną dane przekazane w poprzednim wywołaniugap_advertise. Pozwala to rozgłaszaczowi wznowić rozgłaszanie za pomocą samegogap_advertise(interval_us). Aby wyczyścić ładunek rozgłoszeniowy, przekaż pustybytes, tzn.b''.
Rola Observer (Scanner)
- gap_scan(duration_ms: int | None, interval_us: int = 1280000, window_us: int = 11250, active: bool = False, /) None¶
Uruchamia operację skanowania trwającą przez określony czas (w milisekundach).
Aby skanować w nieskończoność, ustaw duration_ms na
0.Aby zatrzymać skanowanie, ustaw duration_ms na
None.Użyj interval_us i window_us, aby opcjonalnie skonfigurować cykl pracy. Skaner będzie działał przez window_us mikrosekund co interval_us mikrosekund przez łącznie duration_ms milisekund. Domyślny interwał i okno wynoszą odpowiednio 1,28 sekundy oraz 11,25 milisekundy (skanowanie w tle).
Dla każdego wyniku skanowania zgłaszane będzie zdarzenie
_IRQ_SCAN_RESULTz danymi zdarzenia(addr_type, addr, adv_type, rssi, adv_data).Wartości
addr_typewskazują adresy publiczne lub losowe:Wartość
Nazwa
Znaczenie
0x00PUBLIC
Publiczny adres urządzenia.
0x01RANDOM
Adres losowy (statyczny, RPA lub NRPA; typ jest zakodowany w samym adresie).
Wartości
adv_typeodpowiadają specyfikacji Bluetooth:Wartość
Nazwa
Znaczenie
0x00ADV_IND
Rozgłaszanie bezkierunkowe, umożliwiające połączenie i skanowanie.
0x01ADV_DIRECT_IND
Rozgłaszanie kierunkowe, umożliwiające połączenie.
0x02ADV_SCAN_IND
Rozgłaszanie bezkierunkowe, umożliwiające skanowanie.
0x03ADV_NONCONN_IND
Rozgłaszanie bezkierunkowe, nieumożliwiające połączenia.
0x04SCAN_RSP
Odpowiedź na skanowanie.
activemożna ustawić naTrue, jeśli chcesz otrzymywać odpowiedzi na skanowanie w wynikach.Gdy skanowanie zostanie zatrzymane (z powodu upłynięcia czasu trwania lub jawnego zatrzymania), zgłoszone zostanie zdarzenie
_IRQ_SCAN_DONE.
Rola Central
Urządzenie central może łączyć się z urządzeniami peripheral, które wykryło, korzystając z roli observer (zobacz
gap_scan), lub o znanym adresie.- 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¶
Łączy się z urządzeniem peripheral.
Szczegóły dotyczące typów adresów znajdziesz w
gap_scan.Aby wcześnie anulować trwającą próbę połączenia, wywołaj
gap_connect(None).W razie powodzenia zgłoszone zostanie zdarzenie
_IRQ_PERIPHERAL_CONNECT. W przypadku anulowania próby połączenia zgłoszone zostanie zdarzenie_IRQ_PERIPHERAL_DISCONNECT.Urządzenie będzie czekać maksymalnie scan_duration_ms na odebranie ładunku rozgłoszeniowego od urządzenia.
Interwał połączenia można skonfigurować w mikrosekundach, używając jednego lub obu parametrów min_conn_interval_us i max_conn_interval_us. W przeciwnym razie zostanie wybrany domyślny interwał, zazwyczaj między 30000 a 50000 mikrosekund. Krótszy interwał zwiększy przepustowość kosztem zużycia energii.
Rola Peripheral
Oczekuje się, że urządzenie peripheral będzie wysyłać rozgłoszenia umożliwiające połączenie (zobacz
gap_advertise). Zazwyczaj będzie ono działać jako serwer GATT, po wcześniejszym zarejestrowaniu usług i charakterystyk za pomocągatts_register_services.Gdy urządzenie central się połączy, zgłoszone zostanie zdarzenie
_IRQ_CENTRAL_CONNECT.Role Central i Peripheral
- gap_disconnect(conn_handle: int, /) bool¶
Rozłącza określony uchwyt połączenia. Może to być albo urządzenie central, które połączyło się z tym urządzeniem (jeśli działa ono jako peripheral), albo urządzenie peripheral, z którym to urządzenie wcześniej się połączyło (jeśli działa ono jako central).
W razie powodzenia zgłoszone zostanie zdarzenie
_IRQ_PERIPHERAL_DISCONNECTlub_IRQ_CENTRAL_DISCONNECT.Zwraca
False, jeśli uchwyt połączenia nie był połączony, aTruew przeciwnym razie.
Serwer GATT
Serwer GATT ma zestaw zarejestrowanych usług. Każda usługa może zawierać charakterystyki, z których każda ma wartość. Charakterystyki mogą również zawierać deskryptory, które same mają wartości.
Wartości te są przechowywane lokalnie i są dostępne przez ich „value handle”, który jest generowany podczas rejestracji usługi. Mogą być również odczytywane lub zapisywane przez zdalne urządzenie klienckie. Dodatkowo serwer może „powiadomić” o charakterystyce połączonego klienta za pomocą uchwytu połączenia.
Urządzenie w roli central lub peripheral może funkcjonować jako serwer GATT, jednak w większości przypadków częściej to urządzenie peripheral będzie działać jako serwer.
Charakterystyki i deskryptory mają domyślny maksymalny rozmiar 20 bajtów (domyślne ATT MTU wynoszące 23 bajty minus 3-bajtowy nagłówek ATT; większe wynegocjowane MTU samo w sobie nie podnosi tego limitu). Wszystko, co klient do nich zapisze, zostanie obcięte do tej długości. Jednak każdy lokalny zapis zwiększy maksymalny rozmiar, więc jeśli chcesz zezwolić na większe zapisy od klienta do danej charakterystyki, użyj
gatts_writepo rejestracji. Np.gatts_write(char_handle, bytes(100)).- gatts_register_services(services_definition: Sequence[Sequence], /) Sequence[Sequence[int]]¶
Konfiguruje serwer z określonymi usługami, zastępując wszelkie istniejące usługi.
services_definition jest listą usług, gdzie każda usługa jest dwuelementową krotką zawierającą UUID oraz listę charakterystyk.
Każda charakterystyka jest dwu- lub trzyelementową krotką zawierającą UUID, wartość flags oraz opcjonalnie listę deskryptorów.
Każdy deskryptor jest dwuelementową krotką zawierającą UUID oraz wartość flags.
flags są kombinacją bitową OR flag zdefiniowanych poniżej. Ustawiają one zarówno zachowanie charakterystyki (lub deskryptora), jak i wymagania dotyczące bezpieczeństwa i prywatności.
Wartością zwracaną jest lista (po jednym elemencie na usługę) krotek (każdy element jest uchwytem wartości). Uchwyty charakterystyk i deskryptorów są spłaszczone do tej samej krotki, w kolejności, w jakiej zostały zdefiniowane.
Poniższy przykład rejestruje dwie usługi (Heart Rate oraz 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), )
Trzy uchwyty wartości (
hr,tx,rx) mogą być używane zgatts_read,gatts_write,gatts_notifyorazgatts_indicate.Uwaga: Rozgłaszanie musi zostać zatrzymane przed zarejestrowaniem usług.
Dostępne flagi dla charakterystyk i deskryptorów to:
Stała
Wartość
Znaczenie
_FLAG_BROADCAST0x0001Charakterystyka może być rozgłaszana.
_FLAG_READ0x0002Klient może odczytać wartość.
_FLAG_WRITE_NO_RESPONSE0x0004Klient może zapisywać bez oczekiwania na odpowiedź.
_FLAG_WRITE0x0008Klient może zapisywać z potwierdzoną odpowiedzią.
_FLAG_NOTIFY0x0010Serwer może wysyłać powiadomienia (niepotwierdzone).
_FLAG_INDICATE0x0020Serwer może wysyłać wskazania (potwierdzone).
_FLAG_AUTHENTICATED_SIGNED_WRITE0x0040Klient może wysyłać podpisane zapisy.
_FLAG_AUX_WRITE0x0100Rozszerzone właściwości: dozwolone są zapisy kolejkowane/niezawodne.
_FLAG_READ_ENCRYPTED0x0200Odczyt wymaga szyfrowanego łącza.
_FLAG_READ_AUTHENTICATED0x0400Odczyt wymaga uwierzytelnionego (chronionego MITM) łącza.
_FLAG_READ_AUTHORIZED0x0800Odczyt wymaga autoryzacji na poziomie aplikacji.
_FLAG_WRITE_ENCRYPTED0x1000Zapis wymaga szyfrowanego łącza.
_FLAG_WRITE_AUTHENTICATED0x2000Zapis wymaga uwierzytelnionego (chronionego MITM) łącza.
_FLAG_WRITE_AUTHORIZED0x4000Zapis wymaga autoryzacji na poziomie aplikacji.
Podobnie jak w przypadku powyższych stałych zdarzeń, flagi te nie są dostarczane przez moduł
bluetooth; skopiuj do swojego programu te, których potrzebujesz.
- gatts_read(value_handle: int, /) bytes¶
Odczytuje lokalną wartość dla tego uchwytu (która została zapisana albo przez
gatts_write, albo przez zdalnego klienta).
- gatts_write(value_handle: int, data: bytes, send_update: bool = False, /) None¶
Zapisuje lokalną wartość dla tego uchwytu, którą może odczytać klient.
Jeśli send_update ma wartość
True, to wszyscy subskrybujący klienci zostaną powiadomieni (lub otrzymają wskazanie, w zależności od tego, co subskrybują i które operacje obsługuje charakterystyka) o tym zapisie.
- gatts_notify(conn_handle: int, value_handle: int, data: bytes | None = None, /) None¶
Wysyła żądanie powiadomienia do połączonego klienta.
Jeśli data ma wartość
None(domyślnie), to wysłana zostanie bieżąca lokalna wartość (ustawiona za pomocągatts_write).W przeciwnym razie, jeśli data nie ma wartości
None, to wartość ta zostanie wysłana do klienta jako część powiadomienia. Lokalna wartość nie zostanie zmodyfikowana.Uwaga: Powiadomienie zostanie wysłane niezależnie od statusu subskrypcji klienta dla tej charakterystyki.
- gatts_indicate(conn_handle: int, value_handle: int, data: bytes | None = None, /) None¶
Wysyła żądanie wskazania do połączonego klienta.
Jeśli data ma wartość
None(domyślnie), to wysłana zostanie bieżąca lokalna wartość (ustawiona za pomocągatts_write).W przeciwnym razie, jeśli data nie ma wartości
None, to wartość ta zostanie wysłana do klienta jako część wskazania. Lokalna wartość nie zostanie zmodyfikowana.Po potwierdzeniu (lub niepowodzeniu, np. przekroczeniu limitu czasu) zgłoszone zostanie zdarzenie
_IRQ_GATTS_INDICATE_DONE.Uwaga: Wskazanie zostanie wysłane niezależnie od statusu subskrypcji klienta dla tej charakterystyki.
- gatts_set_buffer(value_handle: int, len: int, append: bool = False, /) None¶
Ustawia rozmiar wewnętrznego bufora dla wartości w bajtach. Ograniczy to największy możliwy zapis, który może zostać odebrany. Domyślnie jest to 20 bajtów (domyślne ATT MTU wynoszące 23 minus 3-bajtowy nagłówek ATT).
Ustawienie append na
Truespowoduje, że wszystkie zdalne zapisy będą dołączane do bieżącej wartości, a nie ją zastępować. W ten sposób można zbuforować maksymalnie len bajtów. Gdy użyjeszgatts_read, wartość zostanie wyczyszczona po odczycie. Funkcja ta jest przydatna przy implementowaniu czegoś takiego jak Nordic UART Service.
Klient GATT
Klient GATT może wykrywać oraz odczytywać/zapisywać charakterystyki na zdalnym serwerze GATT.
Częściej to urządzenie w roli central działa jako klient GATT, jednak możliwe jest również, aby urządzenie peripheral działało jako klient w celu wykrycia informacji o urządzeniu central, które się z nim połączyło (np. aby odczytać nazwę urządzenia z usługi informacji o urządzeniu).
- gattc_discover_services(conn_handle: int, uuid: UUID | None = None, /) None¶
Odpytuje połączony serwer o jego usługi.
Opcjonalnie podaj uuid usługi, aby odpytać tylko o tę usługę.
Dla każdej wykrytej usługi zgłoszone zostanie zdarzenie
_IRQ_GATTC_SERVICE_RESULT, a po zakończeniu zdarzenie_IRQ_GATTC_SERVICE_DONE.
- gattc_discover_characteristics(conn_handle: int, start_handle: int, end_handle: int, uuid: UUID | None = None, /) None¶
Odpytuje połączony serwer o charakterystyki w określonym zakresie.
Opcjonalnie podaj uuid charakterystyki, aby odpytać tylko o tę charakterystykę.
Przekazanie
start_handle=1orazend_handle=0xffffobejmuje pełny zakres uchwytów atrybutów GATT, więc ta kombinacja skutecznie przeszukuje każdą usługę na urządzeniu zdalnym.Dla każdej wykrytej charakterystyki zgłoszone zostanie zdarzenie
_IRQ_GATTC_CHARACTERISTIC_RESULT, a po zakończeniu zdarzenie_IRQ_GATTC_CHARACTERISTIC_DONE.
- gattc_discover_descriptors(conn_handle: int, start_handle: int, end_handle: int, /) None¶
Odpytuje połączony serwer o deskryptory w określonym zakresie.
Dla każdego wykrytego deskryptora zgłoszone zostanie zdarzenie
_IRQ_GATTC_DESCRIPTOR_RESULT, a po zakończeniu zdarzenie_IRQ_GATTC_DESCRIPTOR_DONE.
- gattc_read(conn_handle: int, value_handle: int, /) None¶
Wysyła zdalny odczyt do połączonego serwera dla określonego uchwytu charakterystyki lub deskryptora.
Gdy wartość będzie dostępna, zgłoszone zostanie zdarzenie
_IRQ_GATTC_READ_RESULT, a po zakończeniu zdarzenie_IRQ_GATTC_READ_DONE.
- gattc_write(conn_handle: int, value_handle: int, data: bytes, mode: int = 0, /) None¶
Wysyła zdalny zapis do połączonego serwera dla określonego uchwytu charakterystyki lub deskryptora.
Argument mode określa zachowanie zapisu, a obecnie obsługiwane wartości to:
mode=0(domyślnie) to zapis bez odpowiedzi: zapis zostanie wysłany do zdalnego serwera, ale nie zostanie zwrócone żadne potwierdzenie ani zgłoszone żadne zdarzenie.mode=1to zapis z odpowiedzią: zdalny serwer jest proszony o wysłanie odpowiedzi/potwierdzenia, że otrzymał dane.
Jeśli od zdalnego serwera zostanie odebrana odpowiedź, zgłoszone zostanie zdarzenie
_IRQ_GATTC_WRITE_DONE.
- gattc_exchange_mtu(conn_handle: int, /) None¶
Inicjuje wymianę MTU z połączonym serwerem, używając preferowanego MTU ustawionego za pomocą
BLE.config(mtu=value).Zdarzenie
_IRQ_MTU_EXCHANGEDzostanie zgłoszone po zakończeniu wymiany MTU.Wymiana MTU jest zazwyczaj inicjowana przez urządzenie central; NimBLE obsługuje obie role.
Kanały L2CAP zorientowane na połączenie
Funkcja ta umożliwia wymianę danych podobną do gniazd (socket) między dwoma urządzeniami BLE. Po połączeniu urządzeń przez GAP każde z nich może nasłuchiwać, aż drugie połączy się na numerycznym PSM (Protocol/Service Multiplexer).
W danej chwili aktywny może być tylko jeden kanał L2CAP (tzn. nie można się połączyć podczas nasłuchiwania).
Aktywne kanały L2CAP są identyfikowane przez uchwyt połączenia, na którym zostały ustanowione, oraz przez CID (channel ID).
Kanały zorientowane na połączenie mają wbudowaną kontrolę przepływu opartą na kredytach. W przeciwieństwie do ATT, gdzie urządzenia negocjują wspólne MTU, zarówno urządzenie nasłuchujące, jak i łączące się ustawiają niezależne MTU, które ogranicza maksymalną ilość zaległych danych, jakie urządzenie zdalne może wysłać, zanim zostaną one w pełni odebrane w
l2cap_recvinto.- l2cap_listen(psm: int, mtu: int, /) None¶
Rozpoczyna nasłuchiwanie przychodzących żądań kanału L2CAP na określonym psm z lokalnym MTU ustawionym na mtu.
Gdy urządzenie zdalne zainicjuje połączenie, zgłoszone zostanie zdarzenie
_IRQ_L2CAP_ACCEPT, które daje nasłuchującemu serwerowi szansę na odrzucenie przychodzącego połączenia (poprzez zwrócenie niezerowej liczby całkowitej).Po zaakceptowaniu połączenia zgłoszone zostanie zdarzenie
_IRQ_L2CAP_CONNECT, umożliwiające serwerowi uzyskanie channel ID (CID) oraz lokalnego i zdalnego MTU.Uwaga: Obecnie nie jest możliwe zatrzymanie nasłuchiwania.
- l2cap_connect(conn_handle: int, psm: int, mtu: int, /) None¶
Łączy się z nasłuchującym partnerem na określonym psm z lokalnym MTU ustawionym na mtu.
Po pomyślnym połączeniu zgłoszone zostanie zdarzenie
_IRQ_L2CAP_CONNECT, umożliwiające klientowi uzyskanie CID oraz lokalnego i zdalnego (peer) MTU.Nieudane połączenie zgłosi zdarzenie
_IRQ_L2CAP_DISCONNECTz niezerowym statusem.
- l2cap_disconnect(conn_handle: int, cid: int, /) None¶
Rozłącza aktywny kanał L2CAP o określonym conn_handle i cid.
- l2cap_send(conn_handle: int, cid: int, buf: bytes, /) bool¶
Wysyła określony buf (który musi obsługiwać protokół buforowy) na kanale L2CAP identyfikowanym przez conn_handle i cid.
Bufor musi spełniać oba ograniczenia: nie może przekraczać zdalnego (peer) MTU ani nie może przekraczać dwukrotności lokalnego MTU.
Zwróci to
False, jeśli kanał jest teraz „zatrzymany”, co oznacza, żel2cap_sendnie może zostać ponownie wywołane, dopóki nie zostanie odebrane zdarzenie_IRQ_L2CAP_SEND_READY(co nastąpi, gdy urządzenie zdalne przyzna więcej kredytów, zazwyczaj po odebraniu i przetworzeniu danych).
- l2cap_recvinto(conn_handle: int, cid: int, buf: Any | None, /) int¶
Odbiera dane z określonego conn_handle i cid do podanego buf (który musi obsługiwać protokół buforowy, np. bytearray lub memoryview).
Zwraca liczbę bajtów odczytanych z kanału.
Jeśli buf ma wartość
None, to zwraca liczbę dostępnych bajtów.Uwaga: Po odebraniu zdarzenia
_IRQ_L2CAP_RECVaplikacja powinna kontynuować wywoływaniel2cap_recvinto, dopóki w buforze odbiorczym nie będzie już dostępnych żadnych bajtów (zazwyczaj do rozmiaru zdalnego (peer) MTU).Dopóki bufor odbiorczy nie zostanie opróżniony, urządzeniu zdalnemu nie zostaną przyznane kolejne kredyty kanału i nie będzie ono mogło wysłać już żadnych danych.
Parowanie i wiązanie (Bonding)
Parowanie pozwala na szyfrowanie i uwierzytelnianie połączenia poprzez wymianę sekretów (z opcjonalną ochroną MITM za pomocą uwierzytelniania passkey).
Wiązanie to proces zapisywania tych sekretów w pamięci nieulotnej. Po związaniu urządzenie jest w stanie rozwiązać rozwiązywalny adres prywatny (RPA) innego urządzenia na podstawie przechowywanego klucza rozwiązywania tożsamości (IRK). Aby obsługiwać wiązanie, aplikacja musi zaimplementować zdarzenia
_IRQ_GET_SECREToraz_IRQ_SET_SECRET.- gap_pair(conn_handle: int, /) None¶
Inicjuje parowanie z urządzeniem zdalnym.
Przed wywołaniem tej metody upewnij się, że opcje konfiguracyjne
io,mitm,le_secureorazbondsą ustawione (za pomocąconfig).Po pomyślnym parowaniu zgłoszone zostanie zdarzenie
_IRQ_ENCRYPTION_UPDATE.
- gap_passkey(conn_handle: int, action: int, passkey: int, /) None¶
Odpowiada na zdarzenie
_IRQ_PASSKEY_ACTIONdla określonego conn_handle i action. Znaczenie passkey zależy od action (które z kolei zależy od skonfigurowanej możliwości wejścia/wyjścia):Akcja
Wymagana odpowiedź passkey
_PASSKEY_ACTION_INPUTPasskey, który użytkownik odczytuje z urządzenia zdalnego.
_PASSKEY_ACTION_DISPLAYWygenerowany lokalnie losowy 6-cyfrowy passkey pokazany użytkownikowi.
_PASSKEY_ACTION_NUMERIC_COMPARISON1, aby zaakceptować passkey pokazany w zdarzeniu_IRQ_PASSKEY_ACTION, lub0, aby anulować parowanie.
class UUID¶
- class bluetooth.UUID(value: int | bytes | str, /)¶
Tworzy instancję UUID o określonej wartości
value. Bluetooth używa trzech szerokości UUID;UUIDakceptuje każdą z nich:Szerokość UUID
Akceptowane typy
valuePrzykład
16-bitowy
intlub 2-bajtowy bufor (little-endian)UUID(0x2908)lubUUID(b'\x08\x29')32-bitowy
4-bajtowy bufor (little-endian)
UUID(b'\x08\x29\x00\x00')128-bitowy
16-bajtowy bufor lub łańcuch znaków z myślnikami
UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E')16- i 32-bitowe UUID są zazwyczaj identyfikatorami przydzielonymi przez SIG (zobacz przydzielone numery Bluetooth); 128-bitowe UUID są zwykle definiowane przez dostawcę.