12.3. รูปแบบแพ็กเก็ต¶
ทุกไบต์ที่ข้ามสายสัญญาณระหว่างกล้องและโฮสต์เป็นส่วนหนึ่งของแพ็กเก็ต แพ็กเก็ตเริ่มต้นด้วยเฮดเดอร์ 10 ไบต์ ตามด้วยเพย์โหลดที่มีความยาวผันแปร และสิ้นสุดด้วย CRC ท้าย 4 ไบต์ ไม่มีไบต์อื่นปรากฏบนสายสัญญาณ เมื่อโฮสต์เห็น sync word 2 ไบต์แล้ว ไบต์ถัดไปคือเฮดเดอร์ตามลำดับที่แน่นอนนี้
12.3.1. เฮดเดอร์¶
สิบไบต์ บรรจุโดยไม่มีการเติมช่องว่าง แต่ละฟิลด์:
sync-- คำ 16 บิต0xD5AAในลำดับ little-endian ไบต์ที่ 0 บนสายสัญญาณคือ0xAAไบต์ที่ 1 คือ0xD5ตัวรับที่สแกนไบต์สามารถหาจุดเริ่มต้นของแพ็กเก็ตโดยค้นหาคู่AA D5ทุกสิ่งก่อนหน้าจะถูกถือว่าเป็นขยะ การเลือกค่านี้เป็นเจตนา:0xAAและ0xD5แทบไม่ปรากฏในข้อความที่พิมพ์ได้ และคู่นี้ไม่น่าจะเกิดขึ้นโดยบังเอิญในกลางเพย์โหลดseq-- หนึ่งไบต์ ตัวนับที่เพิ่มขึ้นทีละหนึ่งสำหรับแต่ละแพ็กเก็ตที่ส่งในทิศทางที่กำหนด ตัวรับตรวจสอบว่า sequence number ของแพ็กเก็ตถัดไปเป็นไปตามที่คาดหวัง หากไม่ใช่ reliability layer จะขอให้ส่งซ้ำchan-- หนึ่งไบต์ channel ID ที่แพ็กเก็ตนี้属于 ช่องสัญญาณ 0..31 สามารถใช้งานได้ ช่องในตัวstdin,stdout,streamและprofile(ตามตัวเลือก) ใช้ ID คงที่ที่กล้องสงวนไว้flags-- หนึ่งไบต์ บิตฟิลด์ที่บอกตัวรับวิธีตีความแพ็กเก็ต:บิต 0
ACK-- แพ็กเก็ตนี้เป็นการยืนยันรับรองของแพ็กเก็ตก่อนหน้าบิต 1
NAK-- แพ็กเก็ตนี้ปฏิเสธแพ็กเก็ตก่อนหน้าบิต 2
RTX-- แพ็กเก็ตนี้เป็นการส่งซ้ำบิต 3
ACK_REQ-- ผู้ส่งต้องการให้แพ็กเก็ตนี้ได้รับการยืนยันบิต 4
FRAGMENT-- มีชิ้นส่วนเพิ่มเติมตามมาในข้อความที่ใหญ่กว่าบิต 5
EVENT-- แพ็กเก็ตนี้บรรจุเหตุการณ์ช่องสัญญาณแทนข้อมูลบิต 6 และ 7 สงวนไว้
opcode-- หนึ่งไบต์ รหัสคำสั่งหรือการตอบกลับ ไลบรารีโปรโตคอลสงวนช่วง opcode ตามวัตถุประสงค์:0x00..0x0F-- คำสั่งโปรโตคอล (SYNC, GET_CAPS, SET_CAPS, STATS, VERSION)0x10..0x1F-- คำสั่งระบบ (RESET, BOOT, INFO, EVENT, MEMORY)0x20..0x2F-- คำสั่งช่องสัญญาณ (LIST, POLL, LOCK, UNLOCK, SHAPE, SIZE, READ, WRITE, IOCTL, EVENT)
len-- สองไบต์ little-endian จำนวนไบต์เพย์โหลดที่ตามหลังเฮดเดอร์ ความยาวศูนย์ถูกต้องตามกฎ การยืนยันรับรองและคำสั่งขนาดเล็กหลายรายการไม่มีเพย์โหลดcrc-- สองไบต์ CRC-16 เหนือแปดไบต์เฮดเดอร์ก่อนหน้า ตัวรับที่ได้รับเฮดเดอร์ที่มี CRC ไม่ถูกต้องจะทิ้งแพ็กเก็ตทั้งหมดโดยไม่ดูเพย์โหลดด้วยซ้ำ
12.3.2. เพย์โหลด¶
ศูนย์ไบต์หรือมากกว่า ถือเป็นข้อมูลทึบแสงโดย framing layer สิ่งที่อยู่ในเพย์โหลดขึ้นอยู่กับ opcode: สำหรับการตอบกลับ CHANNEL_READ คือข้อมูลช่องสัญญาณจริง สำหรับการตอบกลับ GET_CAPS คือโครงสร้างคงที่ขนาดเล็ก สำหรับการเขียนช่องสัญญาณคือสิ่งที่โฮสต์ส่ง
ขนาดเพย์โหลดสูงสุดขึ้นอยู่กับขนาดบัฟเฟอร์โปรโตคอลของกล้อง (ดูตารางต่อบอร์ดใน protocol.init()) ข้อความที่ยาวเกินขีดจำกัดจะถูกแบ่งออกเป็นชิ้นส่วนโดยตั้ง flag FRAGMENT บนทุกชิ้นยกเว้นชิ้นสุดท้าย
12.3.3. CRC ท้าย¶
สี่ไบต์ CRC-32 เหนือเพย์โหลด ตรวจจับความเสียหายที่ header CRC ไม่สามารถมองเห็นได้ โดยเฉพาะบนเพย์โหลดยาวที่ข้อผิดพลาดหนึ่งบิตกลางเฟรมจะผ่านไปได้อย่างอื่น
การแบ่งการตรวจสอบความสมบูรณ์ออกเป็น CRC สองตัวเป็นเจตนา Header CRC ปกป้องฟิลด์ framing เอง โดยเฉพาะความยาวเพย์โหลด หากไม่มี header CRC แยกต่างหาก การกลับบิตเดียวในไบต์ความยาวจะทำให้ตัวรับอ่านจำนวนไบต์เพย์โหลดผิดและหลุดซิงค์จากสตรีมไบต์โดยสิ้นเชิง เมื่อมี header CRC เฮดเดอร์ที่เสียหายจะถูกปฏิเสธทันทีและตัวรับจะสแกนหา sync word ถัดไปใหม่ จากนั้น payload CRC ปกป้องเนื้อหาข้อความเป็นข้อกังวลแยกต่างหาก ดังนั้นการกลับบิตในข้อมูลจะถูกรายงานว่าเป็นเพย์โหลดเสียหายแทนที่จะเข้าใจผิดว่าเป็นข้อผิดพลาด framing
รูปแบบนี้เล็กพอที่จะเดินผ่านทีละไบต์ และความจริงที่ว่าทุกแพ็กเก็ตมีเลย์เอาต์เดียวกัน ได้แก่ sync แล้วเฮดเดอร์ แล้วเพย์โหลด แล้ว CRC หมายความว่าตัวแยกวิเคราะห์ที่เขียนด้วยมือพอดีหน้าจอหนึ่ง นั่นคือเหตุผลที่การใช้งานโฮสต์ขนาดเล็กใน C, Python หรือ Rust เป็นโปรเจ็กต์สุดสัปดาห์ ส่วนไลบรารีโปรโตคอลคือเวอร์ชัน Python ที่ดูแลรักษาในแต่ละฝ่าย