12.3. Paket biçimi

Kamera ile ana bilgisayar arasında kabloyu geçen her bayt bir paketin parçasıdır. Bir paket 10 baytlık bir başlıkla başlar, değişken uzunlukta bir yük içerir ve 4 baytlık sondaki bir CRC ile biter. Kabloda başka bayt görünmez – ana bilgisayar 2 baytlık senkronizasyon sözcüğünü gördükten sonra, sonraki baytlar tam olarak bu sırada bir başlıktır.

10 baytlık başlığı (senkronizasyon sözcüğü, sıra numarası, kanal kimliği, bayraklar, işlem kodu, yük uzunluğu, başlık CRC'si) ardından değişken uzunluklu yükü ve 4 baytlık yük CRC'sini gösteren bir protokol paketinin yatay düzeni.

12.3.1. Başlık

On bayt, dolgu olmadan paketlenmiş. Her alan:

  • sync – little-endian sırada 16 bitlik 0xD5AA sözcüğü. Kablodaki bayt 0 0xAA, bayt 1 0xD5‘tir. Baytları tarayan bir alıcı, AA D5 çiftini arayarak bir paketin başlangıcını bulabilir; ondan öncekiler çöp olarak ele alınır. Değerin seçimi kasıtlıdır: 0xAA ve 0xD5 yazdırılabilir metinde nadiren görünür ve çiftin bir yükün ortasında tesadüfen oluşması olası değildir.

  • seq – bir bayt. Belirli bir yönde gönderilen her paket için birer artan bir sayaç. Alıcı, sonraki paketin sıra numarasının beklenen olup olmadığını kontrol eder; değilse, güvenilirlik katmanı bir yeniden iletim ister.

  • chan – bir bayt. Bu paketin ait olduğu kanal kimliği. Kanal 0..31 kullanılabilir; yerleşik stdin, stdout, stream ve (isteğe bağlı olarak) profile kanalları kameranın ayırdığı sabit kimlikleri alır.

  • flags – bir bayt. Alıcıya paketi nasıl yorumlayacağını söyleyen bir bit alanı:

    • bit 0 ACK – bu paket önceki bir paketin onayıdır.

    • bit 1 NAK – bu paket önceki bir paketi reddeder.

    • bit 2 RTX – bu paket bir yeniden iletimdir.

    • bit 3 ACK_REQ – gönderen bu paketin onaylanmasını ister.

    • bit 4 FRAGMENT – daha büyük bir mesajda bunu izleyen daha fazla parça var.

    • bit 5 EVENT – bu paket veri yerine bir kanal olayı taşır.

    • bit 6 ve 7 ayrılmıştır.

  • opcode – bir bayt. Komut veya yanıt kodu. Protokol kütüphanesi işlem kodu aralıklarını amaca göre ayırır:

    • 0x00..0x0F – protokol komutları (SYNC, GET_CAPS, SET_CAPS, STATS, VERSION).

    • 0x10..0x1F – sistem komutları (RESET, BOOT, INFO, EVENT, MEMORY).

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

  • len – iki bayt, little-endian. Başlığı izleyen yük baytlarının sayısı. Sıfır uzunluk yasaldır – birçok onay ve küçük komut yük taşımaz.

  • crc – iki bayt. Önceki sekiz başlık baytı üzerinde bir CRC-16. Hatalı CRC’li bir başlık alan bir alıcı, yüke bakmadan bile tüm paketi düşürür.

12.3.2. Yük

Sıfır veya daha fazla bayt, çerçeveleme katmanı tarafından opak olarak ele alınır. Yükte ne olduğu işlem koduna bağlıdır: bir CHANNEL_READ yanıtı için gerçek kanal verisidir; bir GET_CAPS yanıtı için küçük sabit bir yapıdır; bir kanal yazması için ana bilgisayarın gönderdiği her neyse odur.

Maksimum yük boyutu kameranın protokol arabellek boyutuna bağlıdır (protocol.init() içindeki kart başına tabloya bakın). Üst sınırdan daha uzun mesajlar, sonuncu hariç tümünde FRAGMENT bayrağı ayarlanmış parçalara bölünür.

12.3.3. Sondaki CRC

Dört bayt, yük üzerinde bir CRC-32. Başlık CRC’sinin göremediği bozulmaları, özellikle bir çerçeve ortasındaki tek bitlik bir hatanın aksi takdirde gözden kaçacağı uzun yüklerde yakalar.

Bütünlük kontrolünü iki CRC arasında bölmek kasıtlıdır. Başlık CRC’si çerçeveleme alanlarının kendisini – özellikle yük uzunluğunu – korur. Ayrı bir başlık CRC’si olmadan, uzunluk baytındaki tek bir bit çevrilmesi alıcının yük için yanlış sayıda bayt okumasına ve bayt akışından tamamen senkronizasyondan çıkmasına neden olur; bununla birlikte, hasarlı bir başlık doğrudan reddedilir ve alıcı bir sonraki senkronizasyon sözcüğü için yeniden tarama yapar. Yük CRC’si ise mesaj gövdesini ayrı bir mesele olarak korur, böylece verideki bir bit çevrilmesi bir çerçeveleme hatasıyla karıştırılmak yerine bozuk bir yük olarak bildirilir.

Biçim, bayt bayt incelenebilecek kadar küçüktür ve her paketin aynı düzene sahip olması – senkronizasyon, sonra başlık, sonra yük, sonra CRC – elle yazılmış bir ayrıştırıcının bir ekran kadar koda sığması anlamına gelir. C, Python veya Rust’ta küçük bir ana bilgisayar uygulamasının bir hafta sonu projesi olmasının nedeni budur; protokol kütüphanesi her iki taraftaki bakımı yapılan Python sürümüdür.