12.2. الطبقات الأربع¶
مكتبة البروتوكول مبنية كمكدّس من أربع طبقات، تحل كل واحدة منها مشكلة واحدة وتبني على الطبقة التي تحتها. ويستعرض بقية الفصل المكدّس من الأسفل إلى الأعلى.
12.2.1. الناقل¶
في الأسفل يوجد أنبوب البايتات بين الكاميرا والمضيف. لا تهتم مكتبة البروتوكول بأيٍّ منهما يحمل البايتات:
USB-CDC عبر منفذ USB الذي توصَّل به الكاميرا. وهو الخيار الافتراضي والأعلى عرض نطاق ترددي لكل كاميرا.
UART عبر زوج من دبابيس GPIO على الكاميرا متصلة بمحوّل تسلسلي على المضيف. مفيد للنشر بلا رأس (headless) حيث يكون منفذ USB مشغولًا أو غير قابل للوصول فيزيائيًا.
وظيفة الناقل الوحيدة هي "البايتات تدخل، والبايتات تخرج، بالترتيب". كل ما فوق هذه الطبقة يفترض أن الناقل يسلّم البايتات بالترتيب الذي كُتبت به، لكنه يسمح بأن تتلف البايتات نفسها أو بأن تنقطع الوصلة كليًا. والدفعات المفقودة جزئيًا (بضعة بايتات مفقودة) والانقطاعات النظيفة (الوصلة كلها مفقودة لفترة ثم تعود) كلاهما يُعالَج في طبقة أعلى.
12.2.2. التأطير¶
تفرض الطبقة التالية إلى الأعلى بنية على تدفق البايتات. يصبح كل رسالة حزمة -- ترويسة من 10 بايتات يتبعها حمولة يتبعها ذيل من 4 بايتات. وتحمل الترويسة:
كلمة مزامنة من بايتين (
0xD5AA) تتيح للمستقبِل أن يعيد إيجاد بداية الحزمة بعد فقدان المزامنة.رقم تسلسلي من بايت واحد تستخدمه طبقة الموثوقية.
معرّف قناة من بايت واحد يبيّن إلى أي تدفق منطقي تنتمي الحزمة.
حقل رايات من بايت واحد لبتات ACK / NAK / fragment / event.
رمز عملية من بايت واحد يميّز بين أوامر البروتوكول وأوامر النظام وأوامر القنوات.
طول حمولة من بايتين.
تحقق CRC من بايتين على بايتات الترويسة الثمانية السابقة.
تتبع الحمولة، ثم تحقق CRC من 4 بايتات على الحمولة نفسها. ويلتقط تحقّقا CRC التلفَ بشكل مستقل: بتّة مقلوبة في الترويسة تُبطل تحقق CRC للترويسة، ويستطيع المستقبِل إسقاط الحزمة دون الحاجة إطلاقًا إلى قراءة الحمولة.
12.2.3. الموثوقية¶
تحوّل طبقة الموثوقية "الحزم التي قد تصل" إلى "الحزم التي قد وصلت." فهي تتتبّع الأرقام التسلسلية في الترويسة، وتطلب من الطرف الآخر إرسال إقرارات (acknowledgements) لكل حزمة تتطلب ذلك، وتعيد الإرسال عندما لا يصل الإقرار خلال مهلة زمنية. وافتراضيًا تبدأ مهلة إعادة الإرسال عند 500 مللي ثانية وتتضاعف مع كل محاولة، مع ثلاث محاولات قبل الاستسلام.
كل سلوك من تلك السلوكيات قابل للضبط في استدعاء protocol.init(): يمكن إيقاف ACK للتدفقات أحادية الاتجاه، ويمكن تخطّي التحقق من CRC على الناقلات النظيفة تمامًا، ويمكن ضبط معاملات إعادة الإرسال للوصلات البطيئة أو عالية زمن الاستجابة.
12.2.4. القنوات¶
الطبقة العليا هي ما يراه كود التطبيق. القناة هي تدفق منطقي مسمّى يُعرَّف بمعرّف قناة من 0 إلى 31. ويمكن لما يصل إلى 32 قناة أن تتعايش على ناقل واحد؛ كل واحدة مستقلة عن الأخريات، ومُعنوَنة بمعرّفها في ترويسة كل حزمة. تُقلع الكاميرا بأربع قنوات مدمجة -- stdin و stdout و stream و profile -- ويسجّل كود التطبيق المزيد فوقها باستدعاء protocol.register() مع صنف Python.
الطبقات الأربع لا تخلط الاهتمامات. فالتأطير لا يعرف شيئًا عن القنوات؛ والموثوقية لا تعرف شيئًا عن محتويات الحزم؛ وطبقة القنوات لا تعرف كيف تصل البايتات. هذا الفصل هو السبب في أن تبديل الناقل (من USB إلى UART مثلًا) لا يتموّج صعودًا إلى كود القنوات، وهو ما يجعل بقية الفصل قابلة للسير فيها طبقةً تلو الأخرى.