11.5. Conexões¶
Uma vez que um central escolhe um periférico no fluxo de anúncios e lhe envia uma connect request, ambos os lados saem do modo de anúncio / varredura e entram em uma conexão. O rádio agora agenda sua atividade nos canais de dados da camada de enlace, saltando pseudoaleatoriamente entre eles na sequência acordada no momento da conexão. Tudo acima da camada de enlace – GATT, segurança, L2CAP – roda sobre a conexão que é estabelecida aqui.
11.5.1. O evento de conexão¶
Dois dispositivos em uma conexão BLE não transmitem continuamente. Eles concordam com um connection interval e, a cada intervalo, ambos os lados acordam o rádio, trocam quaisquer pacotes enfileirados, confirmam o que receberam e voltam a dormir. Cada uma dessas trocas é chamada de connection event.
O rádio de cada lado fica acordado apenas durante os breves eventos de conexão, com todo o resto dormindo. O periférico pode pular eventos sob peripheral latency.¶
Os números que governam isso são negociados no momento da conexão e a camada de enlace os impõe. Eles ficam visíveis para a aplicação tanto como controles do lado da solicitação quanto como os valores resultantes reportados de volta.
Connection interval. De 7,5 ms a 4 s, em passos de 1,25 ms. O central escolhe o valor que o periférico solicita, a menos que a solicitação seja inviável. Intervalos mais curtos entregam dados com menor latência ao custo de mais atividade de rádio; intervalos mais longos economizam energia, mas tornam cada ida e volta mais lenta.
Peripheral latency. Um inteiro não negativo N. O periférico tem permissão para pular até N eventos de conexão sem nada a enviar, voltando a dormir em vez de acordar o rádio para uma troca vazia. Útil para sensores que acordam para reportar uma vez por segundo, mas que querem um connection interval baixo e responsivo para a rara mensagem imediata.
Supervision timeout. De 100 ms a 32 s. Se qualquer um dos lados não ouvir nada do outro por esse tempo, o enlace é declarado perdido e ambos os lados voltam ao anúncio / varredura. O timeout deve ser maior que
connection_interval * (1 + peripheral_latency)– a camada de enlace rejeita valores que violem isso.
aioble.Device.connect() recebe min_conn_interval_us e max_conn_interval_us para que o central possa solicitar um intervalo específico; o valor real que o rádio definiu pode ser lido de volta através da configuração da camada de enlace depois que a conexão estiver no ar.
11.5.2. O que “central” e “periférico” significam dentro de uma conexão¶
Os papéis definidos no momento do anúncio permanecem após a conexão ser estabelecida:
O central controla a temporização – ele detém o lado mestre da sequência de saltos e dos eventos de conexão.
O periférico é reativo. Ele pode solicitar uma mudança nos parâmetros de conexão (um intervalo mais lento para economizar energia, por exemplo), mas o central decide se aceita.
Os papéis são independentes de quem hospeda o banco de dados GATT, que é um eixo separado. Por convenção, o periférico também é o servidor GATT e o central é o cliente GATT, mas o BLE permite que qualquer um dos lados hospede serviços GATT. As câmeras quase sempre seguem a convenção: periférico + servidor para aplicações do tipo “a câmera publica dados”, central + cliente para aplicações do tipo “a câmera lê de um sensor”.
11.5.3. A unidade máxima de transmissão (MTU)¶
A camada de enlace transporta pacotes que são curtos por padrão – 27 bytes de payload, dos quais apenas 23 estão disponíveis para o GATT. Isso é suficiente para uma pequena leitura ou um comando curto, mas é minúsculo ao lado de qualquer coisa com múltiplos bytes. Ambos os lados podem negociar esse valor para cima, até o limite que o firmware do rádio suporta (tipicamente algumas centenas de bytes em controladores modernos).
A API aioble conduz a negociação através de aioble.DeviceConnection.exchange_mtu() e o resultado fica disponível no atributo mtu. MTUs maiores significam menos idas e voltas para qualquer valor maior que ~20 bytes, a um pequeno custo de memória de buffer.
11.5.4. Tempo de vida¶
Uma conexão dura até que ocorra um destes:
qualquer um dos lados chame
disconnect(),o supervision timeout dispare (fora de alcance, rádio desligado, o par travou), ou
uma falha explícita na camada de enlace (incompatibilidade de criptografia, rejeição de pareamento).
Quando a conexão cai, toda operação GATT enfileirada ou em trânsito nela levanta aioble.DeviceDisconnectedError, e quaisquer blocos async with connection em que a aplicação esteja são encerrados de forma limpa. Um periférico tipicamente responde voltando a aioble.advertise() e aguardando o próximo central; um central responde tanto fazendo varredura novamente quanto expondo a desconexão à aplicação.
O tempo de vida é uma das razões pelas quais aioble é útil. Uma API BLE síncrona teria que expor callbacks de desconexão e máscaras de eventos; a versão asyncio transforma desconexões em exceções dentro da corrotina que estava aguardando a operação, que é exatamente para o que a limpeza do async with foi construída.