12.2. As quatro camadas¶
A biblioteca de protocolo é construída como uma pilha de quatro camadas, cada uma resolvendo um único problema e se apoiando na camada abaixo. O restante do capítulo percorre a pilha de baixo para cima.
12.2.1. Transporte¶
Na base está o canal de bytes entre a câmera e o host. A biblioteca de protocolo não se importa com qual deles carrega os bytes:
USB-CDC pela porta USB na qual a câmera está conectada. A opção padrão e de maior largura de banda para toda câmera.
UART por um par de pinos GPIO na câmera conectados a um adaptador serial no host. Útil para implantações headless onde a porta USB está ocupada ou não está fisicamente acessível.
A única função do transporte é “bytes entram, bytes saem, em ordem”. Tudo acima desta camada assume que o transporte entrega os bytes na ordem em que foram escritos, mas admite que os próprios bytes sejam corrompidos ou que o enlace caia por completo. Rajadas com perdas (alguns bytes faltando) e quedas limpas (o enlace inteiro fora por um tempo e depois de volta) são ambas tratadas em níveis superiores.
12.2.2. Framing¶
A camada seguinte impõe estrutura ao fluxo de bytes. Cada mensagem se torna um pacote – um cabeçalho de 10 bytes seguido de um payload seguido de um trailer de 4 bytes. O cabeçalho carrega:
Uma palavra de sincronização de 2 bytes (
0xD5AA) que permite a um receptor reencontrar o início de um pacote após uma dessincronização.Um número de sequência de 1 byte usado pela camada de confiabilidade.
Um ID de canal de 1 byte que indica a qual fluxo lógico o pacote pertence.
Um campo de flags de 1 byte para os bits ACK / NAK / fragmento / evento.
Um opcode de 1 byte que distingue comandos de protocolo, comandos de sistema e comandos de canal.
Um comprimento de payload de 2 bytes.
Um CRC de 2 bytes sobre os oito bytes de cabeçalho anteriores.
O payload vem em seguida, depois um CRC de 4 bytes sobre o próprio payload. Os dois CRCs detectam corrupção de forma independente: um bit invertido no cabeçalho invalida o CRC do cabeçalho, e o receptor pode descartar o pacote sem nunca precisar ler o payload.
12.2.3. Confiabilidade¶
A camada de confiabilidade transforma “pacotes que podem chegar” em “pacotes que chegaram“. Ela rastreia os números de sequência no cabeçalho, pede ao outro lado que envie confirmações para cada pacote que requer uma e retransmite quando uma confirmação não chega dentro de um tempo limite. Por padrão, o tempo limite de retransmissão começa em 500 ms e dobra a cada nova tentativa, com três tentativas antes de desistir.
Cada um desses comportamentos é configurável na chamada protocol.init(): o ACK pode ser desligado para fluxos unidirecionais, a validação de CRC pode ser ignorada em transportes perfeitamente limpos, e os parâmetros de retransmissão podem ser ajustados para enlaces lentos ou de alta latência.
12.2.4. Canais¶
A camada superior é o que o código de aplicação enxerga. Um canal é um fluxo lógico nomeado, identificado por um ID de canal de 0 a 31. Até 32 canais podem coexistir em um transporte; cada um é independente dos outros, endereçado por seu ID no cabeçalho de cada pacote. A câmera inicializa com quatro canais integrados – stdin, stdout, stream e profile – e o código de aplicação registra mais por cima chamando protocol.register() com uma classe Python.
As quatro camadas não misturam responsabilidades. O framing não conhece os canais; a confiabilidade não conhece o conteúdo dos pacotes; a camada de canais não sabe como os bytes chegam. Essa separação é a razão pela qual uma troca de transporte (de USB para UART, por exemplo) não se propaga até o código de canais, e é o que torna o restante do capítulo percorrível uma camada de cada vez.