bluetooth — Bluetooth de bajo nivel¶
Este módulo proporciona una interfaz con el controlador Bluetooth integrado. Admite Bluetooth Low Energy (BLE) en los roles Central, Periférico, Difusor (Broadcaster) y Observador, así como servidor y cliente GATT y canales L2CAP orientados a conexión. Un dispositivo puede operar en varios roles simultáneamente. También se admiten el emparejamiento y el vinculado (bonding).
Esta API está pensada para coincidir con el protocolo Bluetooth de bajo nivel y proporcionar bloques de construcción para abstracciones de más alto nivel, como tipos de dispositivos específicos.
Truco
Para la mayoría de las aplicaciones, es preferible usar la biblioteca de más alto nivel aioble, que proporciona un envoltorio basado en asyncio alrededor de este módulo. Consulte aioble — BLE asíncrono.
class BLE¶
- class bluetooth.BLE¶
Devuelve el objeto singleton BLE.
Configuración
- active(active: bool | None = None, /) bool¶
Opcionalmente cambia el estado activo de la radio BLE y devuelve el estado actual.
La radio debe activarse antes de usar cualquier otro método de esta clase.
- config(param: str, /) Any¶
- config(*, **kwargs: Any) None
Obtiene o establece valores de configuración de la interfaz BLE. Para obtener un valor, el nombre del parámetro debe indicarse entre comillas como una cadena, y solo se consulta un parámetro a la vez. Para establecer valores, use la sintaxis de palabras clave, y se pueden establecer uno o más parámetros a la vez.
Los valores actualmente admitidos son:
'mac': La dirección actual en uso, según el modo de dirección actual. Esto devuelve una tupla de(addr_type, addr).Consulte
gap_scanpara más detalles sobre el tipo de dirección.Esto solo puede consultarse mientras la interfaz está actualmente activa.
'addr_mode': Establece el modo de dirección. Los valores son:Valor
Nombre
Comportamiento
0x00PUBLIC
Usa la dirección pública del controlador.
0x01RANDOM
Usa una dirección estática generada.
0x02RPA
Usa direcciones privadas resolubles.
0x03NRPA
Usa direcciones privadas no resolubles.
De forma predeterminada, la interfaz usará una dirección PUBLIC si está disponible; en caso contrario, usará una dirección RANDOM.
'gap_name': Obtiene/establece el nombre del dispositivo GAP usado por el servicio Generic Access (UUID0x1800), característica Device Name (UUID0x2a00). Esto se puede establecer en cualquier momento y cambiar varias veces.'rxbuf': Obtiene/establece el tamaño en bytes del búfer interno usado para almacenar los eventos entrantes. Este búfer es global para todo el controlador BLE y, por tanto, gestiona los datos entrantes de todos los eventos, incluidas todas las características. Aumentarlo permite gestionar mejor los datos entrantes en ráfagas (por ejemplo, resultados de escaneo) y recibir valores de característica más grandes.'mtu': Obtiene/establece la MTU que se usará durante un intercambio de MTU de ATT. La MTU resultante será el mínimo entre esta y la MTU del dispositivo remoto. El intercambio de MTU de ATT no se realizará automáticamente (a menos que el dispositivo remoto lo inicie) y debe iniciarse manualmente congattc_exchange_mtu. Use el evento_IRQ_MTU_EXCHANGEDpara descubrir la MTU de una conexión determinada.'bond': Establece si se habilitará el vinculado (bonding) durante el emparejamiento. Cuando está habilitado, las solicitudes de emparejamiento establecerán el indicador «bond» y las claves serán almacenadas por ambos dispositivos.'mitm': Establece si se requiere protección MITM para el emparejamiento.'io': Establece las capacidades de E/S de este dispositivo.Las opciones disponibles son:
Constante
Valor
Capacidad
_IO_CAPABILITY_DISPLAY_ONLY0
Solo pantalla
_IO_CAPABILITY_DISPLAY_YESNO1
Pantalla con entrada sí/no
_IO_CAPABILITY_KEYBOARD_ONLY2
Solo teclado
_IO_CAPABILITY_NO_INPUT_OUTPUT3
Sin entrada ni salida
_IO_CAPABILITY_KEYBOARD_DISPLAY4
Teclado y pantalla
'le_secure': Establece si se requiere el emparejamiento «LE Secure». El valor predeterminado es falso (es decir, permite el «Legacy Pairing»).
Gestión de eventos
- irq(handler: Callable[[int, Tuple], Any | None], /) None¶
Registra una función de retorno (callback) para los eventos de la pila BLE. El handler recibe dos argumentos:
event(que será uno de los códigos siguientes) ydata(que es una tupla de valores específica del evento).Nota: Como optimización para evitar asignaciones de memoria innecesarias, las entradas
addr,adv_data,char_data,notify_datayuuidde las tuplas son instancias de memoryview de solo lectura que apuntan al búfer circular interno debluetooth, y solo son válidas durante la invocación de la función gestora del IRQ. Si su programa necesita guardar uno de estos valores para acceder a él después de que la función gestora del IRQ haya retornado (por ejemplo, guardándolo en una instancia de clase o en una variable global), entonces necesita tomar una copia de los datos, ya sea usandobytes()obluetooth.UUID(), de esta manera:connected_addr = bytes(addr) # equivalently: adv_data, char_data, or notify_data matched_uuid = bluetooth.UUID(uuid)
Por ejemplo, la función gestora del IRQ para un resultado de escaneo podría inspeccionar
adv_datapara decidir si es el dispositivo correcto, y solo entonces copiar los datos de la dirección para usarlos en otra parte del programa. Y para imprimir datos desde dentro de la función gestora del IRQ, será necesarioprint(bytes(addr)).Una función gestora normalmente actúa según el código del evento y desempaqueta la tupla de carga útil específica del 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 ...
A continuación se listan todos los códigos de evento, la carga útil que entregan y una breve descripción. Para los eventos cuyo campo
statusse menciona,statuses0en caso de éxito y un valor distinto de cero específico de la implementación en caso de fallo.Constante
Valor
Evento
Tupla de carga útil
_IRQ_CENTRAL_CONNECT1
Un central se ha conectado a este periférico.
(conn_handle, addr_type, addr)_IRQ_CENTRAL_DISCONNECT2
Un central se ha desconectado de este periférico.
(conn_handle, addr_type, addr)_IRQ_GATTS_WRITE3
Un cliente conectado ha escrito en una característica o descriptor local. Use
gatts_readpara obtener el nuevo valor.(conn_handle, attr_handle)_IRQ_GATTS_READ_REQUEST4
Un cliente conectado ha emitido una lectura. Devuelva un código de error distinto de cero de la tabla siguiente para denegar la lectura, o
0/Nonepara aceptarla.(conn_handle, attr_handle)_IRQ_SCAN_RESULT5
Se recibió un único paquete de publicidad durante un escaneo activo.
(addr_type, addr, adv_type, rssi, adv_data)_IRQ_SCAN_DONE6
El escaneo actual ha finalizado, ya sea porque transcurrió la duración configurada o porque se llamó a
gap_scan(None).()_IRQ_PERIPHERAL_CONNECT7
Una llamada previa a
gap_connectha tenido éxito.(conn_handle, addr_type, addr)_IRQ_PERIPHERAL_DISCONNECT8
Un periférico conectado se ha desconectado.
(conn_handle, addr_type, addr)_IRQ_GATTC_SERVICE_RESULT9
Se encontró un servicio mediante
gattc_discover_services.(conn_handle, start_handle, end_handle, uuid)_IRQ_GATTC_SERVICE_DONE10
El descubrimiento de servicios ha finalizado.
(conn_handle, status)_IRQ_GATTC_CHARACTERISTIC_RESULT11
Se encontró una característica mediante
gattc_discover_characteristics.(conn_handle, end_handle, value_handle, properties, uuid)_IRQ_GATTC_CHARACTERISTIC_DONE12
El descubrimiento de características ha finalizado.
(conn_handle, status)_IRQ_GATTC_DESCRIPTOR_RESULT13
Se encontró un descriptor mediante
gattc_discover_descriptors.(conn_handle, dsc_handle, uuid)_IRQ_GATTC_DESCRIPTOR_DONE14
El descubrimiento de descriptores ha finalizado.
(conn_handle, status)_IRQ_GATTC_READ_RESULT15
Una llamada previa a
gattc_readha devuelto datos.(conn_handle, value_handle, char_data)_IRQ_GATTC_READ_DONE16
Una llamada previa a
gattc_readha finalizado.(conn_handle, value_handle, status)_IRQ_GATTC_WRITE_DONE17
Una llamada previa a
gattc_writeha sido confirmada.(conn_handle, value_handle, status)_IRQ_GATTC_NOTIFY18
Un servidor remoto ha enviado una notificación (sin confirmación).
(conn_handle, value_handle, notify_data)_IRQ_GATTC_INDICATE19
Un servidor remoto ha enviado una indicación (con confirmación).
(conn_handle, value_handle, notify_data)_IRQ_GATTS_INDICATE_DONE20
Una indicación enviada previamente ha sido confirmada por el cliente (o ha expirado).
(conn_handle, value_handle, status)_IRQ_MTU_EXCHANGED21
Se ha completado un intercambio de MTU de ATT (iniciado por cualquiera de los dos lados).
(conn_handle, mtu)_IRQ_L2CAP_ACCEPT22
Un dispositivo remoto ha solicitado una conexión L2CAP en un PSM en el que este dispositivo está escuchando. Devuelva un entero distinto de cero para rechazar, o
0/Nonepara aceptar.(conn_handle, cid, psm, our_mtu, peer_mtu)_IRQ_L2CAP_CONNECT23
Un canal L2CAP está ahora establecido, ya sea aceptando una solicitud entrante o completando una llamada saliente a
l2cap_connect.(conn_handle, cid, psm, our_mtu, peer_mtu)_IRQ_L2CAP_DISCONNECT24
Un canal L2CAP se ha desconectado.
statuses0para una desconexión limpia, o distinto de cero si un intento de conexión saliente falló.(conn_handle, cid, psm, status)_IRQ_L2CAP_RECV25
Han llegado datos a un canal L2CAP. Llame a
l2cap_recvintopara leerlos.(conn_handle, cid)_IRQ_L2CAP_SEND_READY26
Una llamada previa a
l2cap_sendque devolvióFalsese ha vaciado y el canal está listo de nuevo. Unstatusdistinto de cero significa que el búfer de transmisión se desbordó y la aplicación debe reenviar los datos.(conn_handle, cid, status)_IRQ_CONNECTION_UPDATE27
El dispositivo remoto ha actualizado los parámetros de conexión (intervalo, latencia, tiempo de espera de supervisión).
(conn_handle, conn_interval, conn_latency, supervision_timeout, status)_IRQ_ENCRYPTION_UPDATE28
El estado de cifrado de una conexión ha cambiado, normalmente después de que se completa el emparejamiento o el vinculado.
(conn_handle, encrypted, authenticated, bonded, key_size)_IRQ_GET_SECRET29
La pila está solicitando un secreto de vinculado almacenado. Si
keyesNone, devuelva elindex-ésimo valor almacenado desec_type; en caso contrario, devuelva el valor asociado al par(sec_type, key)dado. DevuelvaNonesi no hay nada almacenado.(sec_type, index, key)_IRQ_SET_SECRET30
La pila pide a la aplicación que persista un secreto de vinculado. Devuelva
Trueuna vez almacenado.(sec_type, key, value)_IRQ_PASSKEY_ACTION31
Se requiere una acción de clave de acceso (passkey) como parte del emparejamiento. Responda usando
gap_passkey; consulte la tabla de acciones de clave de acceso más abajo para conocer las posibles acciones.(conn_handle, action, passkey)Para el evento
_IRQ_GATTS_READ_REQUEST, los códigos de retorno disponibles son:Constante
Valor
Significado
_GATTS_NO_ERROR0x00Acepta la lectura.
_GATTS_ERROR_READ_NOT_PERMITTED0x02Lectura no permitida.
_GATTS_ERROR_WRITE_NOT_PERMITTED0x03Escritura no permitida.
_GATTS_ERROR_INSUFFICIENT_AUTHENTICATION0x05El cliente no está autenticado.
_GATTS_ERROR_INSUFFICIENT_AUTHORIZATION0x08El cliente no está autorizado.
_GATTS_ERROR_INSUFFICIENT_ENCRYPTION0x0fEl enlace no está cifrado.
Para el evento
_IRQ_PASSKEY_ACTION, las acciones disponibles son:Constante
Valor
Significado
_PASSKEY_ACTION_NONE0
No se requiere ninguna acción.
_PASSKEY_ACTION_INPUT2
Pide al usuario que introduzca la clave de acceso mostrada en el dispositivo remoto.
_PASSKEY_ACTION_DISPLAY3
Muestra una clave de acceso de 6 dígitos para que la introduzca el dispositivo remoto.
_PASSKEY_ACTION_NUMERIC_COMPARISON4
Confirma que la clave de acceso coincide con la mostrada en el dispositivo remoto.
Para ahorrar espacio en el firmware, estas constantes no están incluidas en el módulo
bluetooth. Añada las que necesite, tomándolas de las listas anteriores, a su programa.
Rol de difusor (Advertiser)
- gap_advertise(interval_us: int | None, adv_data: bytes | None = None, *, resp_data: bytes | None = None, connectable: bool = True) None¶
Inicia la publicidad al intervalo especificado (en microsegundos). Este intervalo se redondeará hacia abajo al múltiplo de 625us más cercano. Para detener la publicidad, establezca interval_us en
None.adv_data y resp_data pueden ser de cualquier tipo que implemente el protocolo de búfer (p. ej.,
bytes,bytearray,str). adv_data se incluye en todas las difusiones, y resp_data se envía como respuesta a un escaneo activo.Nota: si adv_data (o resp_data) es
None, entonces se reutilizarán los datos pasados a la llamada anterior agap_advertise. Esto permite que un difusor reanude la publicidad simplemente congap_advertise(interval_us). Para borrar la carga útil de la publicidad, pase unbytesvacío, es decir,b''.
Rol de observador (Scanner)
- gap_scan(duration_ms: int | None, interval_us: int = 1280000, window_us: int = 11250, active: bool = False, /) None¶
Ejecuta una operación de escaneo que dura el tiempo especificado (en milisegundos).
Para escanear indefinidamente, establezca duration_ms en
0.Para detener el escaneo, establezca duration_ms en
None.Use interval_us y window_us para configurar opcionalmente el ciclo de trabajo. El escáner se ejecutará durante window_us microsegundos cada interval_us microsegundos durante un total de duration_ms milisegundos. El intervalo y la ventana predeterminados son 1,28 segundos y 11,25 milisegundos respectivamente (escaneo en segundo plano).
Para cada resultado de escaneo se generará el evento
_IRQ_SCAN_RESULT, con los datos de evento(addr_type, addr, adv_type, rssi, adv_data).Los valores de
addr_typeindican direcciones públicas o aleatorias:Valor
Nombre
Significado
0x00PUBLIC
Dirección pública del dispositivo.
0x01RANDOM
Dirección aleatoria (estática, RPA o NRPA; el tipo está codificado en la propia dirección).
Los valores de
adv_typecorresponden a la especificación Bluetooth:Valor
Nombre
Significado
0x00ADV_IND
Publicidad no dirigida conectable y escaneable.
0x01ADV_DIRECT_IND
Publicidad dirigida conectable.
0x02ADV_SCAN_IND
Publicidad no dirigida escaneable.
0x03ADV_NONCONN_IND
Publicidad no dirigida no conectable.
0x04SCAN_RSP
Respuesta de escaneo.
activese puede establecer enTruesi desea recibir respuestas de escaneo en los resultados.Cuando el escaneo se detiene (ya sea porque finaliza la duración o cuando se detiene explícitamente), se generará el evento
_IRQ_SCAN_DONE.
Rol central
Un dispositivo central puede conectarse a los periféricos que ha descubierto usando el rol de observador (consulte
gap_scan) o con una dirección conocida.- 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 a un periférico.
Consulte
gap_scanpara más detalles sobre los tipos de dirección.Para cancelar anticipadamente un intento de conexión pendiente, llame a
gap_connect(None).En caso de éxito, se generará el evento
_IRQ_PERIPHERAL_CONNECT. Si se cancela un intento de conexión, se generará el evento_IRQ_PERIPHERAL_DISCONNECT.El dispositivo esperará hasta scan_duration_ms para recibir una carga útil de publicidad del dispositivo.
El intervalo de conexión se puede configurar en microsegundos usando uno o ambos de min_conn_interval_us y max_conn_interval_us. En caso contrario, se elegirá un intervalo predeterminado, normalmente entre 30000 y 50000 microsegundos. Un intervalo más corto aumentará el rendimiento, a expensas del consumo de energía.
Rol periférico
Se espera que un dispositivo periférico envíe publicidad conectable (consulte
gap_advertise). Normalmente actuará como servidor GATT, habiendo registrado primero servicios y características usandogatts_register_services.Cuando un central se conecta, se generará el evento
_IRQ_CENTRAL_CONNECT.Roles central y periférico
- gap_disconnect(conn_handle: int, /) bool¶
Desconecta el identificador de conexión especificado. Este puede ser un central que se ha conectado a este dispositivo (si actúa como periférico) o un periférico al que este dispositivo se conectó previamente (si actúa como central).
En caso de éxito, se generará el evento
_IRQ_PERIPHERAL_DISCONNECTo_IRQ_CENTRAL_DISCONNECT.Devuelve
Falsesi el identificador de conexión no estaba conectado, yTrueen caso contrario.
Servidor GATT
Un servidor GATT tiene un conjunto de servicios registrados. Cada servicio puede contener características, cada una de las cuales tiene un valor. Las características también pueden contener descriptores, que a su vez tienen valores.
Estos valores se almacenan localmente y se acceden mediante su «value handle» que se genera durante el registro del servicio. También pueden ser leídos o escritos por un dispositivo cliente remoto. Además, un servidor puede «notificar» una característica a un cliente conectado mediante un identificador de conexión.
Un dispositivo en rol central o periférico puede funcionar como servidor GATT; sin embargo, en la mayoría de los casos será más común que un dispositivo periférico actúe como servidor.
Las características y los descriptores tienen un tamaño máximo predeterminado de 20 bytes (la MTU de ATT predeterminada de 23 bytes menos una cabecera ATT de 3 bytes; una MTU negociada más grande no eleva por sí sola este límite). Cualquier cosa que un cliente les escriba se truncará a esta longitud. Sin embargo, cualquier escritura local aumentará el tamaño máximo, así que si desea permitir escrituras más grandes desde un cliente a una característica dada, use
gatts_writedespués del registro. P. ej.,gatts_write(char_handle, bytes(100)).- gatts_register_services(services_definition: Sequence[Sequence], /) Sequence[Sequence[int]]¶
Configura el servidor con los servicios especificados, reemplazando cualquier servicio existente.
services_definition es una lista de servicios, donde cada servicio es una tupla de dos elementos que contiene un UUID y una lista de características.
Cada característica es una tupla de dos o tres elementos que contiene un UUID, un valor de flags y, opcionalmente, una lista de descriptores.
Cada descriptor es una tupla de dos elementos que contiene un UUID y un valor de flags.
Los flags son una combinación con OR a nivel de bits de los flags definidos a continuación. Estos establecen tanto el comportamiento de la característica (o descriptor) como los requisitos de seguridad y privacidad.
El valor de retorno es una lista (un elemento por servicio) de tuplas (cada elemento es un value handle). Los identificadores de características y descriptores se aplanan en la misma tupla, en el orden en que están definidos.
El siguiente ejemplo registra dos servicios (Heart Rate y 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), )
Los tres value handles (
hr,tx,rx) se pueden usar congatts_read,gatts_write,gatts_notifyegatts_indicate.Nota: La publicidad debe detenerse antes de registrar servicios.
Los flags disponibles para características y descriptores son:
Constante
Valor
Significado
_FLAG_BROADCAST0x0001La característica puede difundirse.
_FLAG_READ0x0002El cliente puede leer el valor.
_FLAG_WRITE_NO_RESPONSE0x0004El cliente puede escribir sin esperar una respuesta.
_FLAG_WRITE0x0008El cliente puede escribir con una respuesta confirmada.
_FLAG_NOTIFY0x0010El servidor puede enviar notificaciones (sin confirmación).
_FLAG_INDICATE0x0020El servidor puede enviar indicaciones (con confirmación).
_FLAG_AUTHENTICATED_SIGNED_WRITE0x0040El cliente puede emitir escrituras firmadas.
_FLAG_AUX_WRITE0x0100Propiedades extendidas: se permiten escrituras en cola/fiables.
_FLAG_READ_ENCRYPTED0x0200La lectura requiere un enlace cifrado.
_FLAG_READ_AUTHENTICATED0x0400La lectura requiere un enlace autenticado (con protección MITM).
_FLAG_READ_AUTHORIZED0x0800La lectura requiere autorización a nivel de aplicación.
_FLAG_WRITE_ENCRYPTED0x1000La escritura requiere un enlace cifrado.
_FLAG_WRITE_AUTHENTICATED0x2000La escritura requiere un enlace autenticado (con protección MITM).
_FLAG_WRITE_AUTHORIZED0x4000La escritura requiere autorización a nivel de aplicación.
Al igual que con las constantes de evento anteriores, estos flags no son proporcionados por el módulo
bluetooth; copie los que necesite en su programa.
- gatts_read(value_handle: int, /) bytes¶
Lee el valor local de este handle (que ha sido escrito por
gatts_writeo por un cliente remoto).
- gatts_write(value_handle: int, data: bytes, send_update: bool = False, /) None¶
Escribe el valor local de este handle, que puede ser leído por un cliente.
Si send_update es
True, entonces se notificará (o indicará, según a qué estén suscritos y qué operaciones admita la característica) a los clientes suscritos sobre esta escritura.
- gatts_notify(conn_handle: int, value_handle: int, data: bytes | None = None, /) None¶
Envía una solicitud de notificación a un cliente conectado.
Si data es
None(el valor predeterminado), entonces se enviará el valor local actual (establecido congatts_write).En caso contrario, si data no es
None, entonces ese valor se envía al cliente como parte de la notificación. El valor local no se modificará.Nota: La notificación se enviará independientemente del estado de suscripción del cliente a esta característica.
- gatts_indicate(conn_handle: int, value_handle: int, data: bytes | None = None, /) None¶
Envía una solicitud de indicación a un cliente conectado.
Si data es
None(el valor predeterminado), entonces se enviará el valor local actual (establecido congatts_write).En caso contrario, si data no es
None, entonces ese valor se envía al cliente como parte de la indicación. El valor local no se modificará.Tras la confirmación (o el fallo, p. ej., un tiempo de espera agotado), se generará el evento
_IRQ_GATTS_INDICATE_DONE.Nota: La indicación se enviará independientemente del estado de suscripción del cliente a esta característica.
- gatts_set_buffer(value_handle: int, len: int, append: bool = False, /) None¶
Establece el tamaño del búfer interno para un valor en bytes. Esto limitará la mayor escritura posible que se puede recibir. El valor predeterminado es 20 bytes (MTU de ATT predeterminada de 23 menos la cabecera ATT de 3 bytes).
Establecer append en
Truehará que todas las escrituras remotas se añadan al valor actual, en lugar de reemplazarlo. Como máximo se pueden almacenar en búfer len bytes de esta manera. Cuando usegatts_read, el valor se borrará después de la lectura. Esta característica es útil al implementar algo como el Nordic UART Service.
Cliente GATT
Un cliente GATT puede descubrir y leer/escribir características en un servidor GATT remoto.
Es más común que un dispositivo en rol central actúe como cliente GATT; sin embargo, también es posible que un periférico actúe como cliente para descubrir información sobre el central que se ha conectado a él (p. ej., para leer el nombre del dispositivo del servicio de información del dispositivo).
- gattc_discover_services(conn_handle: int, uuid: UUID | None = None, /) None¶
Consulta a un servidor conectado por sus servicios.
Opcionalmente, especifique un uuid de servicio para consultar solo por ese servicio.
Para cada servicio descubierto, se generará el evento
_IRQ_GATTC_SERVICE_RESULT, seguido de_IRQ_GATTC_SERVICE_DONEal finalizar.
- gattc_discover_characteristics(conn_handle: int, start_handle: int, end_handle: int, uuid: UUID | None = None, /) None¶
Consulta a un servidor conectado por las características en el rango especificado.
Opcionalmente, especifique un uuid de característica para consultar solo por esa característica.
Pasar
start_handle=1yend_handle=0xffffcubre todo el rango de identificadores de atributos GATT, por lo que esta combinación busca efectivamente en todos los servicios del dispositivo remoto.Para cada característica descubierta, se generará el evento
_IRQ_GATTC_CHARACTERISTIC_RESULT, seguido de_IRQ_GATTC_CHARACTERISTIC_DONEal finalizar.
- gattc_discover_descriptors(conn_handle: int, start_handle: int, end_handle: int, /) None¶
Consulta a un servidor conectado por los descriptores en el rango especificado.
Para cada descriptor descubierto, se generará el evento
_IRQ_GATTC_DESCRIPTOR_RESULT, seguido de_IRQ_GATTC_DESCRIPTOR_DONEal finalizar.
- gattc_read(conn_handle: int, value_handle: int, /) None¶
Emite una lectura remota a un servidor conectado para el identificador de característica o descriptor especificado.
Cuando hay un valor disponible, se generará el evento
_IRQ_GATTC_READ_RESULT, seguido de_IRQ_GATTC_READ_DONEal finalizar.
- gattc_write(conn_handle: int, value_handle: int, data: bytes, mode: int = 0, /) None¶
Emite una escritura remota a un servidor conectado para el identificador de característica o descriptor especificado.
El argumento mode especifica el comportamiento de la escritura, siendo los valores actualmente admitidos:
mode=0(predeterminado) es una escritura sin respuesta: la escritura se enviará al servidor remoto pero no se devolverá ninguna confirmación, y no se generará ningún evento.mode=1es una escritura con respuesta: se solicita al servidor remoto que envíe una respuesta/confirmación de que recibió los datos.
Si se recibe una respuesta del servidor remoto, se generará el evento
_IRQ_GATTC_WRITE_DONE.
- gattc_exchange_mtu(conn_handle: int, /) None¶
Inicia el intercambio de MTU con un servidor conectado, usando la MTU preferida establecida mediante
BLE.config(mtu=value).El evento
_IRQ_MTU_EXCHANGEDse generará cuando se complete el intercambio de MTU.El intercambio de MTU normalmente lo inicia el central; NimBLE admite ambos roles.
Canales L2CAP orientados a conexión
Esta característica permite el intercambio de datos similar a sockets entre dos dispositivos BLE. Una vez que los dispositivos están conectados vía GAP, cualquiera de ellos puede escuchar a la espera de que el otro se conecte en un PSM numérico (Protocol/Service Multiplexer).
Solo puede haber un canal L2CAP activo a la vez (es decir, no se puede conectar mientras se está escuchando).
Los canales L2CAP activos se identifican por el identificador de conexión sobre el que se establecieron y por un CID (identificador de canal).
Los canales orientados a conexión tienen un control de flujo basado en créditos incorporado. A diferencia de ATT, donde los dispositivos negocian una MTU compartida, tanto el dispositivo que escucha como el que se conecta establecen cada uno una MTU independiente que limita la cantidad máxima de datos pendientes que el dispositivo remoto puede enviar antes de que se consuman por completo en
l2cap_recvinto.- l2cap_listen(psm: int, mtu: int, /) None¶
Empieza a escuchar a la espera de solicitudes de canal L2CAP entrantes en el psm especificado, con la MTU local establecida en mtu.
Cuando un dispositivo remoto inicia una conexión, se generará el evento
_IRQ_L2CAP_ACCEPT, que da al servidor que escucha la oportunidad de rechazar la conexión entrante (devolviendo un entero distinto de cero).Una vez que se acepta la conexión, se generará el evento
_IRQ_L2CAP_CONNECT, permitiendo al servidor obtener el identificador de canal (CID) y la MTU local y remota.Nota: Actualmente no es posible dejar de escuchar.
- l2cap_connect(conn_handle: int, psm: int, mtu: int, /) None¶
Conecta a un par que está escuchando en el psm especificado, con la MTU local establecida en mtu.
Si la conexión tiene éxito, se generará el evento
_IRQ_L2CAP_CONNECT, permitiendo al cliente obtener el CID y la MTU local y remota (del par).Una conexión fallida generará el evento
_IRQ_L2CAP_DISCONNECTcon un estado distinto de cero.
- l2cap_disconnect(conn_handle: int, cid: int, /) None¶
Desconecta un canal L2CAP activo con el conn_handle y el cid especificados.
- l2cap_send(conn_handle: int, cid: int, buf: bytes, /) bool¶
Envía el buf especificado (que debe admitir el protocolo de búfer) sobre el canal L2CAP identificado por conn_handle y cid.
El búfer debe satisfacer ambos límites: no debe superar la MTU remota (del par) y no debe superar el doble de la MTU local.
Esto devolverá
Falsesi el canal está ahora «detenido» (stalled), lo que significa que no se debe volver a llamar al2cap_sendhasta que se reciba el evento_IRQ_L2CAP_SEND_READY(lo que ocurrirá cuando el dispositivo remoto conceda más créditos, normalmente después de haber recibido y procesado los datos).
- l2cap_recvinto(conn_handle: int, cid: int, buf: Any | None, /) int¶
Recibe datos del conn_handle y cid especificados en el buf proporcionado (que debe admitir el protocolo de búfer, p. ej., bytearray o memoryview).
Devuelve el número de bytes leídos del canal.
Si buf es
None, entonces devuelve el número de bytes disponibles.Nota: Después de recibir el evento
_IRQ_L2CAP_RECV, la aplicación debe seguir llamando al2cap_recvintohasta que no haya más bytes disponibles en el búfer de recepción (normalmente hasta el tamaño de la MTU remota, del par).Hasta que el búfer de recepción esté vacío, no se concederán más créditos de canal al dispositivo remoto y este no podrá enviar más datos.
Emparejamiento y vinculado
El emparejamiento permite que una conexión sea cifrada y autenticada mediante el intercambio de secretos (con protección MITM opcional vía autenticación por clave de acceso).
El vinculado (bonding) es el proceso de almacenar esos secretos en almacenamiento no volátil. Cuando están vinculados, un dispositivo puede resolver una dirección privada resoluble (RPA) de otro dispositivo basándose en la clave de resolución de identidad (IRK) almacenada. Para admitir el vinculado, una aplicación debe implementar los eventos
_IRQ_GET_SECRETy_IRQ_SET_SECRET.- gap_pair(conn_handle: int, /) None¶
Inicia el emparejamiento con el dispositivo remoto.
Antes de llamar a esto, asegúrese de que las opciones de configuración
io,mitm,le_secureybondestén establecidas (víaconfig).Si el emparejamiento tiene éxito, se generará el evento
_IRQ_ENCRYPTION_UPDATE.
- gap_passkey(conn_handle: int, action: int, passkey: int, /) None¶
Responde a un evento
_IRQ_PASSKEY_ACTIONpara el conn_handle y la action especificados. El significado de passkey depende de action (que a su vez depende de la capacidad de E/S configurada):Acción
Respuesta passkey requerida
_PASSKEY_ACTION_INPUTLa clave de acceso que el usuario lee del dispositivo remoto.
_PASSKEY_ACTION_DISPLAYUna clave de acceso aleatoria de 6 dígitos generada localmente y mostrada al usuario.
_PASSKEY_ACTION_NUMERIC_COMPARISON1para aceptar la clave de acceso mostrada en el evento_IRQ_PASSKEY_ACTION, o0para cancelar el emparejamiento.
class UUID¶
- class bluetooth.UUID(value: int | bytes | str, /)¶
Crea una instancia de UUID con el
valueespecificado. Bluetooth usa tres anchos de UUID;UUIDacepta cualquiera de ellos:Ancho de UUID
Tipos de
valueaceptadosEjemplo
16 bits
into un búfer de 2 bytes (little-endian)UUID(0x2908)oUUID(b'\x08\x29')32 bits
búfer de 4 bytes (little-endian)
UUID(b'\x08\x29\x00\x00')128 bits
búfer de 16 bytes o una cadena con guiones
UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E')Los UUID de 16 y 32 bits son normalmente identificadores asignados por el SIG (consulte los números asignados de Bluetooth); los UUID de 128 bits suelen ser definidos por el fabricante.