12.5. Güvenilirlik – sıralar, ACK’ler, yeniden iletimler¶
Çerçeveleme katmanı, CRC’leri ile bozulmayı tespit eder. Güvenilirlik katmanı, bir paket sağlam biçimde ulaşmadığında yeniden iletim için pazarlık yaparak “tespit edilen bozulma”yı “uygulamanın asla bozuk veri görmemesi”ne dönüştürür.
12.5.1. Sıra numaraları¶
Her paket başlığı, her gidiş yönü için ayrı olmak üzere bir baytlık bir sıra numarası taşır. Gönderici, iletimden önce sayacı artırır; alıcı ise her alınan paketin sıra numarasının bir öncekinin bir fazlası olduğunu (modulo 256) denetler.
Temiz ve sıralı bir paket yerine alıcıda üç şey ortaya çıkabilir:
Beklenen sıra numarası, geçerli bir CRC ile birlikte. Paket bir sonraki katmana teslim edilir.
Beklenen sıra numarası, hatalı bir CRC ile birlikte. Alıcı paketi atar ve (ACK’ler pazarlık edilmişse) yeniden iletim isteyen bir NAK gönderir.
Beklenenden bir fazla olan bir sıra numarası, geçerli bir CRC ile birlikte. Alıcı önceki paketin kaybolduğunu anlar; kaçırılan sıraya atıfta bulunan bir NAK gönderir ve yenisini bir kenara koyar.
Yinelenen durum (orijinal paket sonunda ulaştıktan sonra gelen bir yeniden iletim), beklenen sayaca karşı denetlenerek ele alınır: sıra numarası beklenenin gerisindeyse paket bir yinelemedir ve alıcı, göndericinin ilk seferde belli ki almadığı ACK’yi gönderdikten sonra paketi atar.
12.5.2. ACK ve NAK¶
Paket başlığındaki iki bayrak biti, güvenilirlik trafiğinin kendisini taşır:
Giden bir pakette ayarlanan
ACK_REQ“Karşılığında bir onay istiyorum” anlamına gelir. Veri paketleri normalde bunu ayarlar; durum yoklamaları ve tek seferlik olaylar ayarlamayabilir.Bir pakette ayarlanan
ACK“bu paket, başlıktaki sıra numarası için onaydır” anlamına gelir. Kendine ait bir yük taşımaz.Ayarlanan
NAK“bu paket önceki bir paketi reddediyor” anlamına gelir – genellikle hatalı bir CRC veya bir sıra numarası boşluğu nedeniyle. Başlık, göndericiye hangi sıranın yeniden iletileceğini gösterir.
Gönderici bir dur-ve-bekle döngüsü çalıştırır: onay gerektiren bir paket iletir, ardından bir sonrakini göndermeden önce eşleşen ACK’yi (veya NAK’yi) bekler. Tek-uçuşta modeli, gönderici durumunu sınırlı tutar – en küçük kameralarda birkaç yüz bayt – ve protokolün iş hacmi için optimize edilmiş bir boru hattı yerine iki uç nokta arasında bir denetim kanalı olarak rolüyle örtüşür. NAK durumunda gönderici aynı paketi RTX bayrağı ayarlanmış olarak yeniden iletir, böylece alıcı bunun bir yeniden deneme olduğunu bilir.
12.5.3. Yeniden iletim zamanlaması¶
Yeniden iletim zaman aşımı içinde ne ACK ne de NAK gelirse, gönderici uçuştaki paketi kendiliğinden yeniden iletir. Zaman aşımı varsayılan olarak 500 ms değerindedir ve her ardışık yeniden denemede ikiye katlanır (1 sn, 2 sn, …). Yapılandırılan yeniden deneme sayısından sonra – varsayılan üç – gönderici vazgeçer ve uygulamaya bir aktarım hatası bildirir.
Zaman aşımını ikiye katlamak, standart üstel geri çekilme desenidir. Kısa bir ilk zaman aşımı, kaybolan paketleri hızla yakalar; ikiye katlama ise birkaç yüz milisaniye boyunca meşgul olan bir ana bilgisayarın, yükü daha da artıran bir yineleme fırtınasını tetiklememesini sağlar.
12.5.4. Güvenilirliği yapılandırma¶
Uygulama veri kaybını göze alabildiğinde, her iki uç da anlaşarak güvenilirlik katmanının parçalarını kapatabilir:
protocol.init(ack=False)paket başına ACK’leri devre dışı bırakır. Gönderici gönderir ve unutur; alıcı ne gelirse teslim eder. Eski bir örneğin kabul edilebilir olduğu sensör verisi akışı için iyidir.protocol.init(seq=False)sıra numarası takibini kapatır, bu da ACK’lerin de kapalı olduğu anlamına gelir. Yalnızca kusursuz güvenilir aktarımlarda faydalıdır.protocol.init(crc=False)CRC doğrulamasını kapatır ancak çerçevelemenin geri kalanını sağlam bırakır. Yalnızca aktarımın kendisi CRC hatalarının olmayacağı kadar sağlam olduğunda yapmaya değer.
Varsayılanlar – her şey açık – her ana bilgisayardan kameraya hata ayıklama oturumu için doğru başlangıç noktasıdır. Uygulama üretime geçtikten sonra ödünleşimler, verisine ve aktarımına özgü hale gelir.
12.5.5. Durum kodları¶
Bir aktarım hatası uygulama koduna kadar yayıldığında, bir durum kodu olarak gelir. Protokol kütüphanesi on tane tanımlar:
SUCCESS– işlem tamamlandı.FAILED– komut belirtilmeyen bir nedenle başarısız oldu.INVALID– alıcı komutu veya argümanlarından birini reddetti.TIMEOUT– bir yeniden deneme zamanlayıcısı doldu.BUSY– kamera meşgul (genellikle kilitli bir kanal).CHECKSUM– başlık veya yük CRC’si eşleşmedi.SEQUENCE– sıra numarası, katmanın kurtarabileceğinin ötesinde sırasızdı.OVERFLOW– bir yük, pazarlık edilen maksimumu aştı.FRAGMENT– çok parçalı bir mesaj, eksik parçalarla geldi.UNKNOWN– gerçekten beklenmedik koşullar için savunmacı bir genel yakalayıcı.
channel_read() çağıran ana bilgisayar kodu bunları Python istisnaları olarak görür; özel hata işlemeyi tercih etmiş kamera tarafı uygulama kodu ise bunları arka uç geri çağırmalarından dönen değerler olarak görür. Çoğu kamera uygulamasının durum kodlarına bakmasına hiç gerek yoktur – kütüphane yeniden denemeyi halleder ve uygulamaya yalnızca gerçekten kurtarılamaz hatalar (örn. aktarımın kendisi yok olmuştur) ulaşır.
Bozulmayı tespit etmek için çerçeveleme ve ondan kurtulmak için güvenilirlik yerinde olunca, kablo düzeyindeki iş tamamlanmıştır. Uygulama kodu çerçevelenmiş, sıralı, sağlam paketler görür; içlerindeki baytlar, üstteki kanalın istediği her anlama gelmekte serbesttir.