bluetooth — Bluetooth de baixo nível¶
Este módulo fornece uma interface para o controlador Bluetooth integrado. Ele oferece suporte a Bluetooth Low Energy (BLE) nos papéis Central, Periférico, Broadcaster e Observador, bem como Servidor e Cliente GATT e canais L2CAP orientados a conexão. Um dispositivo pode operar em vários papéis simultaneamente. O pareamento e o vínculo (bonding) também são suportados.
Esta API foi projetada para corresponder ao protocolo Bluetooth de baixo nível e fornecer blocos de construção para abstrações de nível mais alto, como tipos de dispositivos específicos.
Dica
Para a maioria das aplicações, prefira a biblioteca de nível mais alto aioble, que fornece um wrapper baseado em asyncio em torno deste módulo. Consulte aioble — BLE Assíncrono.
class BLE¶
- class bluetooth.BLE¶
Retorna o objeto BLE singleton.
Configuração
- active(active: bool | None = None, /) bool¶
Opcionalmente altera o estado ativo do rádio BLE e retorna o estado atual.
O rádio deve estar ativo antes de usar qualquer outro método desta classe.
- config(param: str, /) Any¶
- config(*, **kwargs: Any) None
Obtém ou define valores de configuração da interface BLE. Para obter um valor, o nome do parâmetro deve ser entre aspas como uma string, e apenas um parâmetro é consultado por vez. Para definir valores use a sintaxe de palavra-chave, e um ou mais parâmetros podem ser definidos por vez.
Os valores atualmente suportados são:
'mac': O endereço atualmente em uso, dependendo do modo de endereço atual. Isso retorna uma tupla de(addr_type, addr).Consulte
gap_scanpara detalhes sobre o tipo de endereço.Isso só pode ser consultado enquanto a interface estiver atualmente ativa.
'addr_mode': Define o modo de endereço. Os valores são:Valor
Nome
Comportamento
0x00PUBLIC
Usa o endereço público do controlador.
0x01RANDOM
Usa um endereço estático gerado.
0x02RPA
Usa endereços privados resolvíveis.
0x03NRPA
Usa endereços privados não resolvíveis.
Por padrão, a interface usará um endereço PUBLIC se disponível; caso contrário, usará um endereço RANDOM.
'gap_name': Obtém/define o nome do dispositivo GAP usado pelo serviço Generic Access (UUID0x1800), característica Device Name (UUID0x2a00). Isso pode ser definido a qualquer momento e alterado várias vezes.'rxbuf': Obtém/define o tamanho em bytes do buffer interno usado para armazenar eventos recebidos. Esse buffer é global para todo o driver BLE e, portanto, lida com os dados recebidos de todos os eventos, incluindo todas as características. Aumentá-lo permite um melhor tratamento de dados recebidos em rajadas (por exemplo, resultados de varredura) e a capacidade de receber valores de características maiores.'mtu': Obtém/define a MTU que será usada durante uma troca de MTU ATT. A MTU resultante será o mínimo entre esta e a MTU do dispositivo remoto. A troca de MTU ATT não acontecerá automaticamente (a menos que o dispositivo remoto a inicie) e deve ser iniciada manualmente comgattc_exchange_mtu. Use o evento_IRQ_MTU_EXCHANGEDpara descobrir a MTU de uma determinada conexão.'bond': Define se o vínculo (bonding) será habilitado durante o pareamento. Quando habilitado, as solicitações de pareamento definirão a flag “bond” e as chaves serão armazenadas por ambos os dispositivos.'mitm': Define se a proteção MITM é necessária para o pareamento.'io': Define as capacidades de E/S deste dispositivo.As opções disponíveis são:
Constante
Valor
Capacidade
_IO_CAPABILITY_DISPLAY_ONLY0
Apenas exibição
_IO_CAPABILITY_DISPLAY_YESNO1
Exibição com entrada sim/não
_IO_CAPABILITY_KEYBOARD_ONLY2
Apenas teclado
_IO_CAPABILITY_NO_INPUT_OUTPUT3
Sem entrada ou saída
_IO_CAPABILITY_KEYBOARD_DISPLAY4
Teclado e exibição
'le_secure': Define se o pareamento “LE Secure” é necessário. O padrão é false (ou seja, permite “Legacy Pairing”).
Tratamento de Eventos
- irq(handler: Callable[[int, Tuple], Any | None], /) None¶
Registra um callback para eventos da pilha BLE. O handler recebe dois argumentos,
event(que será um dos códigos abaixo) edata(que é uma tupla de valores específica do evento).Observação: Como otimização para evitar alocações desnecessárias, as entradas
addr,adv_data,char_data,notify_dataeuuidnas tuplas são instâncias de memoryview somente leitura que apontam para o ringbuffer interno dobluetoothe são válidas apenas durante a invocação da função de tratamento de IRQ. Se o seu programa precisar salvar um desses valores para acessá-lo depois que o tratador de IRQ retornar (por exemplo, salvando-o em uma instância de classe ou variável global), ele precisa fazer uma cópia dos dados, seja usandobytes()oubluetooth.UUID(), assim:connected_addr = bytes(addr) # equivalently: adv_data, char_data, or notify_data matched_uuid = bluetooth.UUID(uuid)
Por exemplo, o tratador de IRQ para um resultado de varredura pode inspecionar o
adv_datapara decidir se é o dispositivo correto e só então copiar os dados de endereço para serem usados em outro lugar do programa. E para imprimir dados de dentro do tratador de IRQ, será necessárioprint(bytes(addr)).Um tratador normalmente despacha com base no código do evento e desempacota a tupla de payload específica do evento:
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 ...
Cada código de evento, o payload que ele entrega e uma breve descrição estão listados abaixo. Para eventos cujo campo
statusé mencionado,statusé0em caso de sucesso e um valor não nulo específico da implementação em caso de falha.Constante
Valor
Evento
Tupla de payload
_IRQ_CENTRAL_CONNECT1
Um central se conectou a este periférico.
(conn_handle, addr_type, addr)_IRQ_CENTRAL_DISCONNECT2
Um central se desconectou deste periférico.
(conn_handle, addr_type, addr)_IRQ_GATTS_WRITE3
Um cliente conectado escreveu em uma característica ou descritor local. Use
gatts_readpara obter o novo valor.(conn_handle, attr_handle)_IRQ_GATTS_READ_REQUEST4
Um cliente conectado emitiu uma leitura. Retorne um código de erro não nulo da tabela abaixo para negar a leitura, ou
0/Nonepara aceitá-la.(conn_handle, attr_handle)_IRQ_SCAN_RESULT5
Um único pacote de anúncio foi recebido durante uma varredura ativa.
(addr_type, addr, adv_type, rssi, adv_data)_IRQ_SCAN_DONE6
A varredura atual foi encerrada, seja porque a duração configurada expirou ou porque
gap_scan(None)foi chamado.()_IRQ_PERIPHERAL_CONNECT7
Um
gap_connectemitido anteriormente teve sucesso.(conn_handle, addr_type, addr)_IRQ_PERIPHERAL_DISCONNECT8
Um periférico conectado se desconectou.
(conn_handle, addr_type, addr)_IRQ_GATTC_SERVICE_RESULT9
Um serviço foi encontrado por
gattc_discover_services.(conn_handle, start_handle, end_handle, uuid)_IRQ_GATTC_SERVICE_DONE10
A descoberta de serviços foi concluída.
(conn_handle, status)_IRQ_GATTC_CHARACTERISTIC_RESULT11
Uma característica foi encontrada por
gattc_discover_characteristics.(conn_handle, end_handle, value_handle, properties, uuid)_IRQ_GATTC_CHARACTERISTIC_DONE12
A descoberta de características foi concluída.
(conn_handle, status)_IRQ_GATTC_DESCRIPTOR_RESULT13
Um descritor foi encontrado por
gattc_discover_descriptors.(conn_handle, dsc_handle, uuid)_IRQ_GATTC_DESCRIPTOR_DONE14
A descoberta de descritores foi concluída.
(conn_handle, status)_IRQ_GATTC_READ_RESULT15
Um
gattc_reademitido anteriormente retornou dados.(conn_handle, value_handle, char_data)_IRQ_GATTC_READ_DONE16
Um
gattc_reademitido anteriormente foi concluído.(conn_handle, value_handle, status)_IRQ_GATTC_WRITE_DONE17
Um
gattc_writeemitido anteriormente foi confirmado.(conn_handle, value_handle, status)_IRQ_GATTC_NOTIFY18
Um servidor remoto enviou uma notificação (não confirmada).
(conn_handle, value_handle, notify_data)_IRQ_GATTC_INDICATE19
Um servidor remoto enviou uma indicação (confirmada).
(conn_handle, value_handle, notify_data)_IRQ_GATTS_INDICATE_DONE20
Uma indicação enviada anteriormente foi confirmada pelo cliente (ou expirou).
(conn_handle, value_handle, status)_IRQ_MTU_EXCHANGED21
Uma troca de MTU ATT foi concluída (iniciada por qualquer um dos lados).
(conn_handle, mtu)_IRQ_L2CAP_ACCEPT22
Um dispositivo remoto solicitou uma conexão L2CAP em um PSM no qual este dispositivo está escutando. Retorne um inteiro não nulo para rejeitar, ou
0/Nonepara aceitar.(conn_handle, cid, psm, our_mtu, peer_mtu)_IRQ_L2CAP_CONNECT23
Um canal L2CAP agora está estabelecido, seja aceitando uma solicitação recebida ou concluindo um
l2cap_connectde saída.(conn_handle, cid, psm, our_mtu, peer_mtu)_IRQ_L2CAP_DISCONNECT24
Um canal L2CAP foi desconectado.
statusé0para uma desconexão limpa, ou não nulo se uma tentativa de conexão de saída falhou.(conn_handle, cid, psm, status)_IRQ_L2CAP_RECV25
Dados chegaram em um canal L2CAP. Chame
l2cap_recvintopara lê-los.(conn_handle, cid)_IRQ_L2CAP_SEND_READY26
Um
l2cap_sendanterior que retornouFalsefoi esvaziado e o canal está pronto novamente. Umstatusnão nulo significa que o buffer de transmissão transbordou e a aplicação deve reenviar os dados.(conn_handle, cid, status)_IRQ_CONNECTION_UPDATE27
O dispositivo remoto atualizou os parâmetros da conexão (intervalo, latência, tempo limite de supervisão).
(conn_handle, conn_interval, conn_latency, supervision_timeout, status)_IRQ_ENCRYPTION_UPDATE28
O estado de criptografia de uma conexão mudou, normalmente após a conclusão do pareamento ou vínculo.
(conn_handle, encrypted, authenticated, bonded, key_size)_IRQ_GET_SECRET29
A pilha está solicitando um segredo de vínculo armazenado. Se
keyforNone, retorne oindex-ésimo valor armazenado desec_type; caso contrário, retorne o valor associado ao(sec_type, key)fornecido. RetorneNonese nada estiver armazenado.(sec_type, index, key)_IRQ_SET_SECRET30
A pilha está pedindo à aplicação para persistir um segredo de vínculo. Retorne
Truequando armazenado.(sec_type, key, value)_IRQ_PASSKEY_ACTION31
Uma ação de passkey é necessária como parte do pareamento. Responda usando
gap_passkey; consulte a tabela de ações de passkey abaixo para as ações possíveis.(conn_handle, action, passkey)Para o evento
_IRQ_GATTS_READ_REQUEST, os códigos de retorno disponíveis são:Constante
Valor
Significado
_GATTS_NO_ERROR0x00Aceita a leitura.
_GATTS_ERROR_READ_NOT_PERMITTED0x02Leitura não permitida.
_GATTS_ERROR_WRITE_NOT_PERMITTED0x03Escrita não permitida.
_GATTS_ERROR_INSUFFICIENT_AUTHENTICATION0x05O cliente não está autenticado.
_GATTS_ERROR_INSUFFICIENT_AUTHORIZATION0x08O cliente não está autorizado.
_GATTS_ERROR_INSUFFICIENT_ENCRYPTION0x0fO enlace não está criptografado.
Para o evento
_IRQ_PASSKEY_ACTION, as ações disponíveis são:Constante
Valor
Significado
_PASSKEY_ACTION_NONE0
Nenhuma ação necessária.
_PASSKEY_ACTION_INPUT2
Solicita ao usuário que digite a passkey mostrada no dispositivo remoto.
_PASSKEY_ACTION_DISPLAY3
Exibe uma passkey de 6 dígitos para o dispositivo remoto digitar.
_PASSKEY_ACTION_NUMERIC_COMPARISON4
Confirma que a passkey corresponde à mostrada no dispositivo remoto.
A fim de economizar espaço no firmware, essas constantes não estão incluídas no módulo
bluetooth. Adicione ao seu programa as que você precisar das listas acima.
Papel de Broadcaster (Anunciante)
- gap_advertise(interval_us: int | None, adv_data: bytes | None = None, *, resp_data: bytes | None = None, connectable: bool = True) None¶
Inicia o anúncio no intervalo especificado (em microssegundos). Esse intervalo será arredondado para baixo até o múltiplo de 625us mais próximo. Para parar de anunciar, defina interval_us como
None.adv_data e resp_data podem ser de qualquer tipo que implemente o protocolo de buffer (por exemplo,
bytes,bytearray,str). adv_data é incluído em todos os anúncios, e resp_data é enviado em resposta a uma varredura ativa.Observação: se adv_data (ou resp_data) for
None, então os dados passados à chamada anterior degap_advertiseserão reutilizados. Isso permite que um broadcaster retome o anúncio apenas comgap_advertise(interval_us). Para limpar o payload de anúncio, passe umbytesvazio, ou seja,b''.
Papel de Observador (Scanner)
- gap_scan(duration_ms: int | None, interval_us: int = 1280000, window_us: int = 11250, active: bool = False, /) None¶
Executa uma operação de varredura com a duração especificada (em milissegundos).
Para varrer indefinidamente, defina duration_ms como
0.Para parar de varrer, defina duration_ms como
None.Use interval_us e window_us para configurar opcionalmente o ciclo de trabalho. O scanner será executado por window_us microssegundos a cada interval_us microssegundos, durante um total de duration_ms milissegundos. O intervalo e a janela padrão são 1,28 segundos e 11,25 milissegundos, respectivamente (varredura em segundo plano).
Para cada resultado de varredura, o evento
_IRQ_SCAN_RESULTserá gerado, com os dados de evento(addr_type, addr, adv_type, rssi, adv_data).Os valores de
addr_typeindicam endereços públicos ou aleatórios:Valor
Nome
Significado
0x00PUBLIC
Endereço de dispositivo público.
0x01RANDOM
Endereço aleatório (estático, RPA ou NRPA; o tipo é codificado no próprio endereço).
Os valores de
adv_typecorrespondem à Especificação Bluetooth:Valor
Nome
Significado
0x00ADV_IND
Anúncio não direcionado conectável e varrível.
0x01ADV_DIRECT_IND
Anúncio direcionado conectável.
0x02ADV_SCAN_IND
Anúncio não direcionado varrível.
0x03ADV_NONCONN_IND
Anúncio não direcionado não conectável.
0x04SCAN_RSP
Resposta de varredura.
activepode ser definido comoTruese você quiser receber respostas de varredura nos resultados.Quando a varredura é interrompida (seja devido ao término da duração ou quando explicitamente interrompida), o evento
_IRQ_SCAN_DONEserá gerado.
Papel Central
Um dispositivo central pode se conectar a periféricos que ele descobriu usando o papel de observador (consulte
gap_scan) ou com um endereço conhecido.- 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¶
Conecta-se a um periférico.
Consulte
gap_scanpara detalhes sobre os tipos de endereço.Para cancelar antecipadamente uma tentativa de conexão pendente, chame
gap_connect(None).Em caso de sucesso, o evento
_IRQ_PERIPHERAL_CONNECTserá gerado. Se uma tentativa de conexão for cancelada, o evento_IRQ_PERIPHERAL_DISCONNECTserá gerado.O dispositivo aguardará até scan_duration_ms para receber um payload de anúncio do dispositivo.
O intervalo de conexão pode ser configurado em microssegundos usando min_conn_interval_us e/ou max_conn_interval_us. Caso contrário, um intervalo padrão será escolhido, normalmente entre 30000 e 50000 microssegundos. Um intervalo mais curto aumentará o throughput, à custa do consumo de energia.
Papel de Periférico
Espera-se que um dispositivo periférico envie anúncios conectáveis (consulte
gap_advertise). Ele geralmente atuará como um servidor GATT, tendo primeiro registrado serviços e características usandogatts_register_services.Quando um central se conecta, o evento
_IRQ_CENTRAL_CONNECTserá gerado.Papéis Central e Periférico
- gap_disconnect(conn_handle: int, /) bool¶
Desconecta o handle de conexão especificado. Este pode ser um central que se conectou a este dispositivo (se atuando como periférico) ou um periférico ao qual este dispositivo se conectou anteriormente (se atuando como central).
Em caso de sucesso, o evento
_IRQ_PERIPHERAL_DISCONNECTou_IRQ_CENTRAL_DISCONNECTserá gerado.Retorna
Falsese o handle de conexão não estava conectado, eTruecaso contrário.
Servidor GATT
Um servidor GATT possui um conjunto de serviços registrados. Cada serviço pode conter características, cada uma das quais tem um valor. As características também podem conter descritores, que por sua vez têm valores.
Esses valores são armazenados localmente e são acessados por seu “value handle”, que é gerado durante o registro do serviço. Eles também podem ser lidos ou escritos por um dispositivo cliente remoto. Além disso, um servidor pode “notificar” uma característica a um cliente conectado por meio de um handle de conexão.
Um dispositivo nos papéis central ou periférico pode funcionar como um servidor GATT; no entanto, na maioria dos casos será mais comum que um dispositivo periférico atue como o servidor.
Características e descritores têm um tamanho máximo padrão de 20 bytes (a MTU ATT padrão de 23 bytes menos um cabeçalho ATT de 3 bytes; uma MTU negociada maior não eleva por si só esse limite). Qualquer coisa escrita neles por um cliente será truncada para esse tamanho. No entanto, qualquer escrita local aumentará o tamanho máximo, então se você quiser permitir escritas maiores de um cliente em uma determinada característica, use
gatts_writeapós o registro. Por exemplo,gatts_write(char_handle, bytes(100)).- gatts_register_services(services_definition: Sequence[Sequence], /) Sequence[Sequence[int]]¶
Configura o servidor com os serviços especificados, substituindo quaisquer serviços existentes.
services_definition é uma lista de serviços, onde cada serviço é uma tupla de dois elementos contendo um UUID e uma lista de características.
Cada característica é uma tupla de dois ou três elementos contendo um UUID, um valor de flags e, opcionalmente, uma lista de descritores.
Cada descritor é uma tupla de dois elementos contendo um UUID e um valor de flags.
As flags são uma combinação OR bit a bit das flags definidas abaixo. Elas definem tanto o comportamento da característica (ou descritor) quanto os requisitos de segurança e privacidade.
O valor de retorno é uma lista (um elemento por serviço) de tuplas (cada elemento é um value handle). Os handles de características e descritores são achatados na mesma tupla, na ordem em que são definidos.
O exemplo a seguir registra dois serviços (Heart Rate e 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), )
Os três value handles (
hr,tx,rx) podem ser usados comgatts_read,gatts_write,gatts_notifyegatts_indicate.Observação: O anúncio deve ser interrompido antes de registrar serviços.
As flags disponíveis para características e descritores são:
Constante
Valor
Significado
_FLAG_BROADCAST0x0001A característica pode ser transmitida.
_FLAG_READ0x0002O cliente pode ler o valor.
_FLAG_WRITE_NO_RESPONSE0x0004O cliente pode escrever sem esperar uma resposta.
_FLAG_WRITE0x0008O cliente pode escrever com uma resposta confirmada.
_FLAG_NOTIFY0x0010O servidor pode enviar notificações (não confirmadas).
_FLAG_INDICATE0x0020O servidor pode enviar indicações (confirmadas).
_FLAG_AUTHENTICATED_SIGNED_WRITE0x0040O cliente pode emitir escritas assinadas.
_FLAG_AUX_WRITE0x0100Propriedades estendidas: escritas enfileiradas/confiáveis são permitidas.
_FLAG_READ_ENCRYPTED0x0200A leitura requer um enlace criptografado.
_FLAG_READ_AUTHENTICATED0x0400A leitura requer um enlace autenticado (com proteção MITM).
_FLAG_READ_AUTHORIZED0x0800A leitura requer autorização em nível de aplicação.
_FLAG_WRITE_ENCRYPTED0x1000A escrita requer um enlace criptografado.
_FLAG_WRITE_AUTHENTICATED0x2000A escrita requer um enlace autenticado (com proteção MITM).
_FLAG_WRITE_AUTHORIZED0x4000A escrita requer autorização em nível de aplicação.
Assim como as constantes de evento acima, essas flags não são fornecidas pelo módulo
bluetooth; copie as que você precisar para o seu programa.
- gatts_read(value_handle: int, /) bytes¶
Lê o valor local deste handle (que foi escrito por
gatts_writeou por um cliente remoto).
- gatts_write(value_handle: int, data: bytes, send_update: bool = False, /) None¶
Escreve o valor local deste handle, que pode ser lido por um cliente.
Se send_update for
True, então quaisquer clientes inscritos serão notificados (ou indicados, dependendo do que eles assinaram e de quais operações a característica suporta) sobre essa escrita.
- gatts_notify(conn_handle: int, value_handle: int, data: bytes | None = None, /) None¶
Envia uma solicitação de notificação a um cliente conectado.
Se data for
None(o padrão), então o valor local atual (conforme definido comgatts_write) será enviado.Caso contrário, se data não for
None, então esse valor é enviado ao cliente como parte da notificação. O valor local não será modificado.Observação: A notificação será enviada independentemente do status de inscrição do cliente nesta característica.
- gatts_indicate(conn_handle: int, value_handle: int, data: bytes | None = None, /) None¶
Envia uma solicitação de indicação a um cliente conectado.
Se data for
None(o padrão), então o valor local atual (conforme definido comgatts_write) será enviado.Caso contrário, se data não for
None, então esse valor é enviado ao cliente como parte da indicação. O valor local não será modificado.Na confirmação (ou falha, por exemplo, tempo limite), o evento
_IRQ_GATTS_INDICATE_DONEserá gerado.Observação: A indicação será enviada independentemente do status de inscrição do cliente nesta característica.
- gatts_set_buffer(value_handle: int, len: int, append: bool = False, /) None¶
Define o tamanho do buffer interno para um valor em bytes. Isso limitará a maior escrita possível que pode ser recebida. O padrão é 20 bytes (MTU ATT padrão de 23 menos o cabeçalho ATT de 3 bytes).
Definir append como
Truefará com que todas as escritas remotas sejam anexadas ao valor atual, em vez de substituí-lo. No máximo len bytes podem ser armazenados em buffer dessa forma. Quando você usagatts_read, o valor será limpo após a leitura. Esse recurso é útil ao implementar algo como o Nordic UART Service.
Cliente GATT
Um cliente GATT pode descobrir e ler/escrever características em um servidor GATT remoto.
É mais comum que um dispositivo no papel central atue como o cliente GATT; no entanto, também é possível que um periférico atue como cliente a fim de descobrir informações sobre o central que se conectou a ele (por exemplo, para ler o nome do dispositivo a partir do serviço de informações do dispositivo).
- gattc_discover_services(conn_handle: int, uuid: UUID | None = None, /) None¶
Consulta um servidor conectado por seus serviços.
Opcionalmente, especifique um uuid de serviço para consultar apenas esse serviço.
Para cada serviço descoberto, o evento
_IRQ_GATTC_SERVICE_RESULTserá gerado, seguido de_IRQ_GATTC_SERVICE_DONEna conclusão.
- gattc_discover_characteristics(conn_handle: int, start_handle: int, end_handle: int, uuid: UUID | None = None, /) None¶
Consulta um servidor conectado por características no intervalo especificado.
Opcionalmente, especifique um uuid de característica para consultar apenas essa característica.
Passar
start_handle=1eend_handle=0xffffcobre todo o intervalo de handles de atributos GATT, então essa combinação pesquisa efetivamente todos os serviços no dispositivo remoto.Para cada característica descoberta, o evento
_IRQ_GATTC_CHARACTERISTIC_RESULTserá gerado, seguido de_IRQ_GATTC_CHARACTERISTIC_DONEna conclusão.
- gattc_discover_descriptors(conn_handle: int, start_handle: int, end_handle: int, /) None¶
Consulta um servidor conectado por descritores no intervalo especificado.
Para cada descritor descoberto, o evento
_IRQ_GATTC_DESCRIPTOR_RESULTserá gerado, seguido de_IRQ_GATTC_DESCRIPTOR_DONEna conclusão.
- gattc_read(conn_handle: int, value_handle: int, /) None¶
Emite uma leitura remota a um servidor conectado para o handle de característica ou descritor especificado.
Quando um valor estiver disponível, o evento
_IRQ_GATTC_READ_RESULTserá gerado, seguido de_IRQ_GATTC_READ_DONEna conclusão.
- gattc_write(conn_handle: int, value_handle: int, data: bytes, mode: int = 0, /) None¶
Emite uma escrita remota a um servidor conectado para o handle de característica ou descritor especificado.
O argumento mode especifica o comportamento de escrita, sendo os valores atualmente suportados:
mode=0(padrão) é uma escrita-sem-resposta: a escrita será enviada ao servidor remoto, mas nenhuma confirmação será retornada, e nenhum evento será gerado.mode=1é uma escrita-com-resposta: o servidor remoto é solicitado a enviar uma resposta/confirmação de que recebeu os dados.
Se uma resposta for recebida do servidor remoto, o evento
_IRQ_GATTC_WRITE_DONEserá gerado.
- gattc_exchange_mtu(conn_handle: int, /) None¶
Inicia a troca de MTU com um servidor conectado, usando a MTU preferida definida com
BLE.config(mtu=value).O evento
_IRQ_MTU_EXCHANGEDserá gerado quando a troca de MTU for concluída.A troca de MTU é normalmente iniciada pelo central; o NimBLE suporta ambos os papéis.
Canais L2CAP Orientados a Conexão
Esse recurso permite a troca de dados semelhante a sockets entre dois dispositivos BLE. Uma vez que os dispositivos estejam conectados via GAP, qualquer um deles pode escutar para que o outro se conecte em um PSM numérico (Protocol/Service Multiplexer).
Apenas um canal L2CAP pode estar ativo por vez (ou seja, você não pode conectar enquanto está escutando).
Os canais L2CAP ativos são identificados pelo handle de conexão no qual foram estabelecidos e por um CID (channel ID).
Os canais orientados a conexão possuem controle de fluxo baseado em crédito integrado. Diferente do ATT, onde os dispositivos negociam uma MTU compartilhada, tanto o dispositivo que escuta quanto o que se conecta definem cada um uma MTU independente, que limita a quantidade máxima de dados pendentes que o dispositivo remoto pode enviar antes de serem totalmente consumidos em
l2cap_recvinto.- l2cap_listen(psm: int, mtu: int, /) None¶
Começa a escutar solicitações de canal L2CAP recebidas no psm especificado com a MTU local definida como mtu.
Quando um dispositivo remoto inicia uma conexão, o evento
_IRQ_L2CAP_ACCEPTserá gerado, o que dá ao servidor que escuta a chance de rejeitar a conexão recebida (retornando um inteiro não nulo).Uma vez aceita a conexão, o evento
_IRQ_L2CAP_CONNECTserá gerado, permitindo que o servidor obtenha o channel ID (CID) e as MTUs local e remota.Observação: Atualmente não é possível parar de escutar.
- l2cap_connect(conn_handle: int, psm: int, mtu: int, /) None¶
Conecta-se a um par que está escutando no psm especificado com a MTU local definida como mtu.
Em uma conexão bem-sucedida, o evento
_IRQ_L2CAP_CONNECTserá gerado, permitindo que o cliente obtenha o CID e as MTUs local e remota (do par).Uma conexão malsucedida gerará o evento
_IRQ_L2CAP_DISCONNECTcom um status não nulo.
- l2cap_disconnect(conn_handle: int, cid: int, /) None¶
Desconecta um canal L2CAP ativo com o conn_handle e o cid especificados.
- l2cap_send(conn_handle: int, cid: int, buf: bytes, /) bool¶
Envia o buf especificado (que deve suportar o protocolo de buffer) no canal L2CAP identificado por conn_handle e cid.
O buffer deve satisfazer ambos os limites: não deve exceder a MTU remota (do par) e não deve exceder o dobro da MTU local.
Isso retornará
Falsese o canal estiver agora “travado” (stalled), o que significa quel2cap_sendnão deve ser chamado novamente até que o evento_IRQ_L2CAP_SEND_READYseja recebido (o que acontecerá quando o dispositivo remoto conceder mais créditos, normalmente depois de ter recebido e processado os dados).
- l2cap_recvinto(conn_handle: int, cid: int, buf: Any | None, /) int¶
Recebe dados do conn_handle e cid especificados no buf fornecido (que deve suportar o protocolo de buffer, por exemplo, bytearray ou memoryview).
Retorna o número de bytes lidos do canal.
Se buf for
None, então retorna o número de bytes disponíveis.Observação: Após receber o evento
_IRQ_L2CAP_RECV, a aplicação deve continuar chamandol2cap_recvintoaté que não haja mais bytes disponíveis no buffer de recepção (normalmente até o tamanho da MTU remota (do par)).Até que o buffer de recepção esteja vazio, o dispositivo remoto não receberá mais créditos de canal e não poderá enviar mais dados.
Pareamento e Vínculo (Bonding)
O pareamento permite que uma conexão seja criptografada e autenticada por meio da troca de segredos (com proteção MITM opcional via autenticação por passkey).
O vínculo (bonding) é o processo de armazenar esses segredos em armazenamento não volátil. Quando vinculado, um dispositivo é capaz de resolver um endereço privado resolvível (RPA) de outro dispositivo com base na chave de resolução de identidade (IRK) armazenada. Para suportar o vínculo, uma aplicação deve implementar os eventos
_IRQ_GET_SECRETe_IRQ_SET_SECRET.- gap_pair(conn_handle: int, /) None¶
Inicia o pareamento com o dispositivo remoto.
Antes de chamar isso, certifique-se de que as opções de configuração
io,mitm,le_secureebondestejam definidas (viaconfig).Em um pareamento bem-sucedido, o evento
_IRQ_ENCRYPTION_UPDATEserá gerado.
- gap_passkey(conn_handle: int, action: int, passkey: int, /) None¶
Responde a um evento
_IRQ_PASSKEY_ACTIONpara o conn_handle e a action especificados. O significado de passkey depende de action (que, por sua vez, depende da capacidade de E/S configurada):Ação
Resposta passkey necessária
_PASSKEY_ACTION_INPUTA passkey que o usuário lê do dispositivo remoto.
_PASSKEY_ACTION_DISPLAYUma passkey aleatória de 6 dígitos gerada localmente e mostrada ao usuário.
_PASSKEY_ACTION_NUMERIC_COMPARISON1para aceitar a passkey mostrada no evento_IRQ_PASSKEY_ACTION, ou0para cancelar o pareamento.
class UUID¶
- class bluetooth.UUID(value: int | bytes | str, /)¶
Cria uma instância de UUID com o
valueespecificado. O Bluetooth usa três larguras de UUID;UUIDaceita qualquer uma delas:Largura do UUID
Tipos de
valueaceitosExemplo
16 bits
intou um buffer de 2 bytes (little-endian)UUID(0x2908)ouUUID(b'\x08\x29')32 bits
buffer de 4 bytes (little-endian)
UUID(b'\x08\x29\x00\x00')128 bits
buffer de 16 bytes ou uma string com hifens
UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E')UUIDs de 16 e 32 bits são normalmente identificadores alocados pelo SIG (consulte os números atribuídos do Bluetooth); UUIDs de 128 bits são normalmente definidos pelo fornecedor.