12.3. A csomagformátum

A kamera és a gazda között a vezetéken áthaladó minden bájt egy csomag része. Egy csomag egy 10 bájtos fejléccel kezdődik, egy változó hosszúságú hasznos teherrel folytatódik, és egy 4 bájtos záró CRC-vel ér véget. Más bájt nem jelenik meg a vezetéken – amint a gazda meglátta a 2 bájtos szinkronszót, a következő bájtok pontosan ebben a sorrendben egy fejlécet alkotnak.

Egy protokollcsomag vízszintes elrendezése, amely a 10 bájtos fejlécet (szinkronszó, sorszám, csatornaazonosító, jelzők, műveletkód, hasznos teher hossza, fejléc CRC) mutatja, amelyet a változó hosszúságú hasznos teher és egy 4 bájtos hasznos teher CRC követ.

12.3.1. A fejléc

Tíz bájt, kitöltés nélkül csomagolva. Az egyes mezők:

  • sync – a 16 bites 0xD5AA szó little-endian sorrendben. A vezetéken a 0. bájt 0xAA, az 1. bájt 0xD5. A bájtokat letapogató fogadó az AA D5 pár keresésével találja meg egy csomag kezdetét; az előtte lévő bármi szemétként kezelendő. Az érték megválasztása szándékos: a 0xAA és a 0xD5 ritkán fordul elő nyomtatható szövegben, és a pár valószínűtlenül jelenik meg véletlenül egy hasznos teher közepén.

  • seq – egy bájt. Egy számláló, amely adott irányban minden elküldött csomagra eggyel növekszik. A fogadó ellenőrzi, hogy a következő csomag sorszáma a várt-e; ha nem, a megbízhatósági réteg újraküldést kér.

  • chan – egy bájt. A csatornaazonosító, amelyhez ez a csomag tartozik. A 0..31 csatornák használhatók; a beépített stdin, stdout, stream és (opcionálisan) profile csatornák rögzített azonosítókat foglalnak le a kamerán.

  • flags – egy bájt. Egy bitmező, amely megmondja a fogadónak, hogyan értelmezze a csomagot:

    • bit 0 ACK – this packet is an acknowledgement of a previous one.

    • bit 1 NAK – this packet rejects a previous one.

    • bit 2 RTX – this packet is a retransmit.

    • bit 3 ACK_REQ – the sender wants this packet acknowledged.

    • bit 4 FRAGMENT – more fragments follow this one in a larger message.

    • bit 5 EVENT – this packet carries a channel event rather than data.

    • a 6. és 7. bit fenntartott.

  • opcode – egy bájt. A parancs- vagy válaszkód. A protokollkönyvtár cél szerint foglal le műveletkód-tartományokat:

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

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

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

  • len – két bájt, little-endian. A fejlécet követő hasznos teher bájtjainak száma. A nulla hossz megengedett – sok nyugtázás és kis parancs nem hordoz hasznos terhet.

  • crc – két bájt. Egy CRC-16 az előző nyolc fejlécbájton. Az a fogadó, amely rossz CRC-jű fejlécet kap, eldobja az egész csomagot anélkül, hogy egyáltalán ránézne a hasznos teherre.

12.3.2. A hasznos teher

Nulla vagy több bájt, amelyet a keretezési réteg átlátszatlanként kezel. A hasznos teher tartalma a műveletkódtól függ: egy CHANNEL_READ válasznál a tényleges csatornaadat; egy GET_CAPS válasznál egy kis, rögzített struktúra; egy csatornaírásnál pedig az, amit a gazda küldött.

A maximális hasznos teher mérete a kamera protokollpufferének méretétől függ (lásd a kártyánkénti táblázatot a protocol.init() alatt). A korlátnál hosszabb üzenetek töredékekre bomlanak úgy, hogy a FRAGMENT jelző az utolsó kivételével mindegyiken be van állítva.

12.3.3. A záró CRC

Négy bájt, egy CRC-32 a hasznos teheren. Elkapja azt a sérülést, amelyet a fejléc CRC nem lát, különösen hosszú hasznos terheknél, ahol egy keret közepén bekövetkező egybites hiba egyébként átcsúszna.

Az integritás-ellenőrzés két CRC közötti szétosztása szándékos. A fejléc CRC magukat a keretezési mezőket védi – különösen a hasznos teher hosszát. Egy külön fejléc CRC nélkül a hosszbájtban bekövetkező egyetlen bitfordulás azt eredményezné, hogy a fogadó rossz számú bájtot olvasna be a hasznos teherhez, és teljesen kiesne a bájtfolyam szinkronjából; ennek meglétével viszont a sérült fejléc azonnal elutasításra kerül, és a fogadó újra megkeresi a következő szinkronszót. A hasznos teher CRC ezután külön szempontként védi az üzenet törzsét, így az adatban bekövetkező bitfordulás sérült hasznos teherként jelentődik, nem pedig keretezési hibának tévesztik.

A formátum elég kicsi ahhoz, hogy bájtról bájtra végig lehessen járni, és az, hogy minden csomag azonos elrendezésű – szinkron, majd fejléc, majd hasznos teher, majd CRC –, azt jelenti, hogy egy kézzel írt elemző elfér egy képernyőnyi kódban. Ezért egy apró gazda implementáció C-ben, Pythonban vagy Rustban egy hétvégi projekt; a protokollkönyvtár a karbantartott Python változat mindkét oldalon.