12.3. Format paketa

Svaki bajt koji prijeđe žicu između kamere i domaćina dio je paketa. Paket počinje 10-bajtnim zaglavljem, nastavlja se sadržajem promjenjive duljine i završava 4-bajtnim završnim CRC-om. Nikakvi drugi bajtovi se ne pojavljuju na žici – jednom kada domaćin vidi 2-bajtnu sinkronizacijsku riječ, sljedeći bajtovi su zaglavlje točno u ovom slijedu.

Vodoravni prikaz protokolnog paketa koji pokazuje 10-bajtno zaglavlje (sinkronizacijska riječ, redni broj, ID kanala, zastavice, opcode, duljina sadržaja, CRC zaglavlja) nakon kojeg slijedi sadržaj promjenjive duljine i 4-bajtni CRC sadržaja.

12.3.1. Zaglavlje

Deset bajtova, zapakirano bez dopune. Svako polje:

  • sync – 16-bitna riječ 0xD5AA u little-endian poretku. Bajt 0 na žici je 0xAA, bajt 1 je 0xD5. Primatelj koji skenira bajtove može pronaći početak paketa tražeći par AA D5; sve prije toga tretira se kao smeće. Izbor vrijednosti je namjeran: 0xAA i 0xD5 rijetko se pojavljuju u tekstu koji se može ispisati, a par se vjerojatno neće slučajno pojaviti usred sadržaja.

  • seq – jedan bajt. Brojač koji se povećava za jedan za svaki paket poslan u danom smjeru. Primatelj provjerava je li redni broj sljedećeg paketa očekivani; ako nije, sloj pouzdanosti traži ponovni prijenos.

  • chan – jedan bajt. ID kanala kojem ovaj paket pripada. Kanali 0..31 su upotrebljivi; ugrađeni kanali stdin, stdout, stream i (po izboru) profile zauzimaju fiksne ID-eve koje kamera rezervira.

  • flags – jedan bajt. Bitovno polje koje primatelju govori kako protumačiti paket:

    • bit 0 ACK – ovaj paket je potvrda prethodnog.

    • bit 1 NAK – ovaj paket odbacuje prethodni.

    • bit 2 RTX – ovaj paket je ponovni prijenos.

    • bit 3 ACK_REQ – pošiljatelj želi da se ovaj paket potvrdi.

    • bit 4 FRAGMENT – nakon ovog slijede dodatni fragmenti u većoj poruci.

    • bit 5 EVENT – ovaj paket nosi događaj kanala umjesto podataka.

    • bitovi 6 i 7 su rezervirani.

  • opcode – jedan bajt. Kod naredbe ili odgovora. Biblioteka za protokol rezervira raspone opcode-a prema namjeni:

    • 0x00..0x0F – protokolne naredbe (SYNC, GET_CAPS, SET_CAPS, STATS, VERSION).

    • 0x10..0x1F – sistemske naredbe (RESET, BOOT, INFO, EVENT, MEMORY).

    • 0x20..0x2F – naredbe kanala (LIST, POLL, LOCK, UNLOCK, SHAPE, SIZE, READ, WRITE, IOCTL, EVENT).

  • len – dva bajta, little-endian. Broj bajtova sadržaja koji slijede nakon zaglavlja. Duljina nula je dopuštena – mnoge potvrde i male naredbe ne nose nikakav sadržaj.

  • crc – dva bajta. CRC-16 preko prethodnih osam bajtova zaglavlja. Primatelj koji dobije zaglavlje s lošim CRC-om odbacuje cijeli paket bez da uopće pogleda sadržaj.

12.3.2. Sadržaj

Nula ili više bajtova, koje sloj uokvirivanja tretira kao neproziran. Što je u sadržaju ovisi o opcode-u: za odgovor CHANNEL_READ to su stvarni podaci kanala; za odgovor GET_CAPS to je mala fiksna struktura; za pisanje na kanal to je što god je domaćin poslao.

Maksimalna veličina sadržaja ovisi o veličini protokolnog međuspremnika kamere (pogledajte tablicu po pojedinoj ploči u protocol.init()). Poruke dulje od ograničenja dijele se u fragmente s postavljenom zastavicom FRAGMENT na svima osim na posljednjem.

12.3.3. Završni CRC

Četiri bajta, CRC-32 preko sadržaja. Hvata oštećenja koja CRC zaglavlja ne može vidjeti, osobito na dugim sadržajima gdje bi se jednobitna pogreška usred okvira inače provukla.

Podjela provjere integriteta na dva CRC-a je namjerna. CRC zaglavlja štiti sama polja uokvirivanja – osobito duljinu sadržaja. Bez zasebnog CRC-a zaglavlja, jedan preokrenuti bit u bajtu duljine uzrokovao bi da primatelj pročita pogrešan broj bajtova za sadržaj i potpuno izgubi sinkronizaciju s tokom bajtova; s njim, oštećeno zaglavlje se izravno odbacuje, a primatelj ponovno skenira sljedeću sinkronizacijsku riječ. CRC sadržaja zatim štiti tijelo poruke kao zasebno pitanje, pa se preokrenuti bit u podacima prijavljuje kao oštećeni sadržaj umjesto da se zamijeni za pogrešku uokvirivanja.

Format je dovoljno malen da se prođe bajt po bajt, a činjenica da svaki paket ima isti raspored – sinkronizacija, zatim zaglavlje, zatim sadržaj, zatim CRC – znači da ručno napisan parser stane na jedan zaslon koda. Zato je sićušna implementacija domaćina u jeziku C, Python ili Rust projekt za vikend; biblioteka za protokol je održavana Python verzija na svakoj strani.