12.3. Formát paketu

Každý bajt, který projde přes vedení mezi kamerou a hostitelem, je součástí paketu. Paket začíná 10bajtovou hlavičkou, pokračuje užitečným obsahem (payload) proměnné délky a končí 4bajtovým koncovým CRC. Na vedení se neobjevují žádné jiné bajty – jakmile hostitel uvidí 2bajtové synchronizační slovo, následující bajty jsou hlavička v přesně tomto pořadí.

Horizontální rozvržení paketu protokolu zobrazující 10bajtovou hlavičku (synchronizační slovo, pořadové číslo, ID kanálu, příznaky, opcode, délka užitečného obsahu, CRC hlavičky), za níž následuje užitečný obsah proměnné délky a 4bajtové CRC užitečného obsahu.

12.3.1. Hlavička

Deset bajtů, sbalených bez vycpávky (padding). Každé pole:

  • sync – 16bitové slovo 0xD5AA v pořadí little-endian. Bajt 0 na vedení je 0xAA, bajt 1 je 0xD5. Příjemce procházející bajty může najít začátek paketu vyhledáním dvojice AA D5; vše před ní je považováno za smetí. Volba hodnoty je záměrná: 0xAA a 0xD5 se v tisknutelném textu vyskytují zřídka a je nepravděpodobné, že by se dvojice náhodně objevila uprostřed užitečného obsahu (payload).

  • seq – jeden bajt. Čítač, který se zvyšuje o jedna pro každý paket odeslaný v daném směru. Příjemce kontroluje, že pořadové číslo dalšího paketu je očekávané; pokud ne, vrstva spolehlivosti požádá o opětovné odeslání.

  • chan – jeden bajt. ID kanálu, kterému tento paket patří. Použitelné jsou kanály 0..31; vestavěné kanály stdin, stdout, stream a (volitelně) profile zabírají pevná ID, která si kamera rezervuje.

  • flags – jeden bajt. Bitové pole, které příjemci říká, jak paket interpretovat:

    • bit 0 ACK – tento paket je potvrzení (acknowledgement) předchozího.

    • bit 1 NAK – tento paket odmítá předchozí.

    • bit 2 RTX – tento paket je opětovné odeslání.

    • bit 3 ACK_REQ – odesílatel chce, aby byl tento paket potvrzen.

    • bit 4 FRAGMENT – po tomto následují další fragmenty větší zprávy.

    • bit 5 EVENT – tento paket nese událost kanálu, nikoli data.

    • bity 6 a 7 jsou rezervované.

  • opcode – jeden bajt. Kód příkazu nebo odpovědi. Knihovna protokolu rezervuje rozsahy opcode podle účelu:

    • 0x00..0x0F – příkazy protokolu (SYNC, GET_CAPS, SET_CAPS, STATS, VERSION).

    • 0x10..0x1F – systémové příkazy (RESET, BOOT, INFO, EVENT, MEMORY).

    • 0x20..0x2F – příkazy kanálu (LIST, POLL, LOCK, UNLOCK, SHAPE, SIZE, READ, WRITE, IOCTL, EVENT).

  • len – dva bajty, little-endian. Počet bajtů užitečného obsahu, které následují po hlavičce. Délka nula je legální – mnoho potvrzení a malých příkazů nenese žádný užitečný obsah (payload).

  • crc – dva bajty. CRC-16 přes předchozích osm bajtů hlavičky. Příjemce, který dostane hlavičku se špatným CRC, zahodí celý paket, aniž by se vůbec podíval na užitečný obsah (payload).

12.3.2. Užitečný obsah (payload)

Nula nebo více bajtů, vrstvou rámcování považovaných za neprůhledné. Co je v užitečném obsahu, závisí na opcode: pro odpověď CHANNEL_READ jsou to skutečná data kanálu; pro odpověď GET_CAPS je to malá pevná struktura; pro zápis na kanál je to cokoli, co hostitel poslal.

Maximální velikost užitečného obsahu (payload) závisí na velikosti bufferu protokolu kamery (viz tabulka podle desky v protocol.init()). Zprávy delší než limit jsou rozděleny na fragmenty s nastaveným příznakem FRAGMENT u všech kromě posledního.

12.3.3. Koncové CRC

Čtyři bajty, CRC-32 přes užitečný obsah (payload). Zachytí poškození, které CRC hlavičky nedokáže vidět, zejména u dlouhých užitečných obsahů, kde by jinak jednobitová chyba uprostřed rámce proklouzla.

Rozdělení kontroly integrity mezi dvě CRC je záměrné. CRC hlavičky chrání samotná pole rámcování – zejména délku užitečného obsahu. Bez samostatného CRC hlavičky by jediný překlopený bit v bajtu délky způsobil, že by příjemce přečetl nesprávný počet bajtů užitečného obsahu a zcela se rozsynchronizoval s bajtovým proudem; s ním je poškozená hlavička rovnou odmítnuta a příjemce znovu hledá další synchronizační slovo. CRC užitečného obsahu pak chrání tělo zprávy jako samostatnou záležitost, takže překlopený bit v datech je hlášen jako poškozený užitečný obsah, nikoli zaměněn za chybu rámcování.

Formát je dost malý na to, aby se dal projít bajt po bajtu, a fakt, že každý paket má stejné rozvržení – synchronizace, pak hlavička, pak užitečný obsah, pak CRC – znamená, že ručně napsaný parser se vejde na jednu obrazovku kódu. Proto je drobná hostitelská implementace v C, Pythonu nebo Rustu víkendový projekt; knihovna protokolu je udržovaná verze v Pythonu na každé straně.