12.4. Negociación de protocolo de enlace y capacidades¶
La cámara y el anfitrión llegan ambos al transporte con sus propias ideas sobre cómo debe ejecutarse el protocolo: qué modos de CRC, si se requieren ACK, cuál es la carga máxima que pueden almacenar en búfer. Antes de que comience el tráfico real, intercambian un protocolo de enlace que fija esos parámetros para el resto de la sesión.
12.4.1. El anfitrión abre la conexión¶
El lado de la cámara arranca la pila del protocolo al inicio (o la aplicación la reinicia con protocol.init() para cambiar parámetros), y luego espera tranquilamente a un anfitrión. Desde el punto de vista de la cámara, no hay nada que hacer hasta que llega un paquete.
El lado del anfitrión abre el transporte – puerto USB o UART – e inmediatamente envía un paquete PROTO_SYNC (código de operación 0x00). Este paquete tiene una carga mágica que permite a la cámara reconocerlo incluso si ambos lados se desincronizaron, y es el único paquete al que la cámara responde antes de que se negocien las capacidades.
Si la cámara no responde dentro del tiempo de espera de retransmisión, el anfitrión envía PROTO_SYNC de nuevo, hasta rtx_retries veces. Tras eso, se rinde e informa de un fallo de conexión. El reintento es lo que hace que «desconectar, reconectar, reiniciar el script del anfitrión» funcione sin que la cámara necesite saber que el anfitrión se marchó.
12.4.2. Intercambio de capacidades¶
Una vez que la cámara confirma la sincronización, el anfitrión envía PROTO_GET_CAPS (código de operación 0x01) para preguntar qué admite la cámara. La carga de respuesta informa de:
Validación de CRC activada o desactivada
Seguimiento de números de secuencia activado o desactivado
ACK activados o desactivados
Notificaciones de eventos activadas o desactivadas
El tamaño máximo de carga de la cámara en bytes
El recuento actual de reintentos de retransmisión, el tiempo de espera y los parámetros de sondeo
El anfitrión los compara con su propia configuración. Si el anfitrión necesita cambiar alguno de ellos – por ejemplo, para negociar una carga máxima menor porque su búfer de recepción es más pequeño que el de la cámara – envía PROTO_SET_CAPS (código de operación 0x02) con los nuevos valores. La cámara reconfigura su pila y confirma. A partir de aquí, cada paquete que cruza el cable sigue ese contrato compartido.
Si el anfitrión no anula nada, los valores por defecto están todos activados: validación de CRC, seguimiento de números de secuencia, ACK y notificaciones de eventos. La carga máxima por defecto es el búfer por placa de la cámara menos 14 bytes de sobrecarga de encuadre (el encabezado de 10 bytes más el CRC de carga final de 4 bytes). Para la mayoría del trabajo de cámara a portátil los valores por defecto son el punto de partida correcto; la página de fiabilidad explica cuándo y por qué una aplicación desactiva algunos de ellos.
12.4.3. Descubrimiento de canales¶
Tras las capacidades, el anfitrión envía CHANNEL_LIST (código de operación 0x20). La cámara responde con una lista de canales registrados – los cuatro integrados (stdin, stdout, stream, profile) más cualquiera que la aplicación haya registrado con protocol.register(). Cada entrada lleva el ID del canal, su nombre y sus indicadores de capacidad (solo lectura, solo escritura, bloqueable).
El anfitrión guarda la lista y la usa más tarde cuando el código de aplicación solicita channel_read("frame") o channel_write("config", ...) – el nombre se busca para obtener un ID de canal una vez, y luego cada paquete posterior en ese canal usa el ID directamente.
Si la cámara registra un nuevo canal después de la lista inicial – algo común cuando una aplicación empieza a ejecutarse tras el protocolo de enlace – la cámara emite un paquete de evento CHANNEL_REGISTERED. El anfitrión escucha esos eventos y actualiza su lista interna de canales, de modo que un script de anfitrión que se conectó pronto ve aparecer los canales recién registrados sin reiniciarse.
El protocolo de enlace consume unas pocas idas y vueltas en la configuración de la conexión y luego nunca se repite. El tráfico en estado estable son solo paquetes: bytes encuadrados que entran, bytes encuadrados que salen, con los IDs de canal ya conocidos en ambos lados.