11.2. A pilha BLE

Tal como as redes, o Bluetooth Low Energy é construído como uma pilha de camadas, cada uma resolvendo um único problema e expondo uma abstração limpa à camada acima. Os nomes abaixo vêm diretamente da especificação Bluetooth Core e aparecem nas APIs aioble e bluetooth.

A vertical stack of five labelled boxes. From bottom to top: Physical (radio), Link Layer, GAP, GATT, Application. An arrow on the right points up the stack labelled "what we build". An arrow on the left points down the stack labelled "what is provided".

A pilha Bluetooth Low Energy. Cada camada entrega uma abstração mais limpa à seguinte, o mesmo padrão que a pilha de rede utiliza.

Camada física. Move bits entre dois dispositivos pelo rádio de 2,4 GHz. Seleção de canal, modulação, potência de transmissão. O trabalho da câmara é estar ligada; o silício trata do resto.

Camada de ligação. Move pacotes entre dois dispositivos que concordam em comunicar. Adiciona endereços de dispositivo para que cada pacote possa ser direcionado a um vizinho, agenda os eventos de rádio periódicos que constituem uma ligação, e trata da retransmissão de qualquer pacote que o recetor não tenha confirmado.

Generic Access Profile (GAP). A camada de descoberta e ligação. Define quatro papéis – broadcaster, observer, peripheral, central – e o protocolo de advertising / scanning que permite a dois dispositivos encontrarem-se em primeiro lugar, mais o procedimento para abrir e fechar uma ligação entre eles. É aqui que vivem os endereços, os payloads de publicidade, os parâmetros de ligação e o emparelhamento.

Generic Attribute Profile (GATT). A camada de dados. Situa-se por cima de uma ligação GAP aberta e expõe uma pequena base de dados chave/valor: um lado aloja uma árvore de valores nomeados chamados características, o outro lado lê, escreve ou subscreve-os. É aqui que fluem os bytes reais da aplicação.

Aplicação. O que quer que a câmara e o par concordem que os bytes significam. O Bluetooth SIG publica perfis standard – frequência cardíaca, nível da bateria, deteção ambiental – que definem características de uso comum para que dispositivos não relacionados possam interoperar, mas qualquer aplicação é livre de definir os seus próprios.

11.2.1. Como as camadas se empilham em tempo de execução

O padrão corresponde à pilha de rede:

  • Os bytes da aplicação vão para um valor de característica.

  • O GATT envolve-os com um cabeçalho a identificar a que característica os bytes pertencem.

  • O GAP mantém uma ligação aberta para que o GATT tenha para onde enviar.

  • A camada de ligação envolve o conjunto num pacote, endereçado ao endereço de dispositivo do par, e agenda um evento de rádio para o transmitir.

  • A camada física transforma o pacote numa breve rajada de rádio de 2,4 GHz.

A camada física e a camada de ligação são quase invisíveis a partir do Python – o silício e o firmware de rádio tratam delas. A partir do GAP para cima, o código Python da câmara tem mais a dizer.

11.2.2. Duas camadas que a API visível ao utilizador ignora silenciosamente

A especificação Bluetooth nomeia mais duas camadas que se situam entre a camada de ligação e o GAP/GATT: a Host Controller Interface (HCI) – o protocolo que a CPU anfitriã utiliza para controlar um chip de rádio separado – e o L2CAP – o multiplexador que divide uma ligação de camada de ligação em vários canais lógicos.

Nenhuma delas é visível na API aioble, mas nenhuma desaparece. O HCI fica dentro do porto BLE e é invisível a menos que uma compilação personalizada do MicroPython esteja em jogo, e o L2CAP é o portador sobre o qual o GATT corre. Uma aplicação que queira fluxos de bytes em bruto pode reclamar o seu próprio canal L2CAP (Canais L2CAP).