12.4. การจับมือและการเจรจาความสามารถ

กล้องและโฮสต์ต่างมาถึงทรานสปอร์ตพร้อมแนวคิดของตัวเองเกี่ยวกับวิธีการทำงานของโปรโตคอล: โหมด CRC ใด จำเป็นต้องมี ACK หรือไม่ เพย์โหลดขนาดใหญ่ที่สุดที่บัฟเฟอร์ได้คือเท่าใด ก่อนที่จะมีการรับส่งข้อมูลจริง ทั้งสองฝ่ายจะแลกเปลี่ยนการจับมือที่กำหนดพารามิเตอร์เหล่านั้นสำหรับเซสชันที่เหลือ

12.4.1. โฮสต์เปิดการเชื่อมต่อ

ฝั่งกล้องเริ่มต้น protocol stack ตอนบูต (หรือแอปพลิเคชันรีสตาร์ทด้วย protocol.init() เพื่อเปลี่ยนพารามิเตอร์) จากนั้นรอเงียบๆ สำหรับโฮสต์ จากมุมมองของกล้องไม่มีอะไรต้องทำจนกว่าจะมีแพ็กเก็ตมาถึง

ฝั่งโฮสต์เปิดทรานสปอร์ต ไม่ว่าจะเป็นพอร์ต USB หรือ UART และส่ง PROTO_SYNC packet (opcode 0x00) ทันที แพ็กเก็ตนี้มีเพย์โหลดแบบ magic ที่ช่วยให้กล้องจดจำได้แม้ทั้งสองฝ่ายจะไม่ซิงค์กัน และเป็นแพ็กเก็ตเดียวที่กล้องตอบสนองก่อนที่จะมีการเจรจาความสามารถ

หากกล้องไม่ตอบกลับภายใน retransmit timeout โฮสต์จะส่ง PROTO_SYNC ซ้ำอีกครั้งได้สูงสุด rtx_retries ครั้ง หลังจากนั้นจะยอมแพ้และรายงานความล้มเหลวในการเชื่อมต่อ การลองซ้ำนี้ทำให้ "ถอดปลั๊ก เสียบใหม่ รีสตาร์ทสคริปต์โฮสต์" ทำงานได้โดยไม่จำเป็นให้กล้องรู้ว่าโฮสต์ออกไปแล้ว

12.4.2. การแลกเปลี่ยนความสามารถ

เมื่อกล้องยืนยัน sync แล้ว โฮสต์จะส่ง PROTO_GET_CAPS (opcode 0x01) เพื่อถามว่ากล้องรองรับอะไรบ้าง เพย์โหลดการตอบกลับรายงาน:

  • การตรวจสอบ CRC เปิดหรือปิดใช้งาน

  • การติดตาม sequence number เปิดหรือปิดใช้งาน

  • ACK เปิดหรือปิดใช้งาน

  • การแจ้งเตือนเหตุการณ์เปิดหรือปิดใช้งาน

  • ขนาดเพย์โหลดสูงสุดของกล้องในหน่วยไบต์

  • จำนวนครั้ง timeout และพารามิเตอร์การโพลล์ของการลองส่งซ้ำในปัจจุบัน

โฮสต์เปรียบเทียบค่าเหล่านั้นกับการกำหนดค่าของตัวเอง หากโฮสต์ต้องการ เปลี่ยน ค่าใดๆ เช่น เจรจาขนาดเพย์โหลดสูงสุดที่เล็กกว่าเพราะบัฟเฟอร์รับของมันเล็กกว่ากล้อง โฮสต์จะส่ง PROTO_SET_CAPS (opcode 0x02) พร้อมค่าใหม่ กล้องจะกำหนดค่า stack ใหม่และยืนยัน จากนี้ไปทุกแพ็กเก็ตที่ข้ามสายสัญญาณจะปฏิบัติตามสัญญาร่วมนั้น

หากโฮสต์ไม่แทนที่สิ่งใด ค่าเริ่มต้นจะเปิดทั้งหมด: การตรวจสอบ CRC การติดตาม sequence number ACK และการแจ้งเตือนเหตุการณ์ ขนาดเพย์โหลดเริ่มต้นคือบัฟเฟอร์ต่อบอร์ดของกล้องลบ 14 ไบต์ของ framing overhead (เฮดเดอร์ 10 ไบต์บวก payload CRC ท้าย 4 ไบต์) สำหรับงานกล้องถึงแล็ปท็อปส่วนใหญ่ค่าเริ่มต้นเป็นจุดเริ่มต้นที่ถูกต้อง หน้าความน่าเชื่อถือจะอธิบายว่าเมื่อใดและทำไมแอปพลิเคชันจึงปิดบางส่วน

12.4.3. การค้นพบช่องสัญญาณ

หลังจากความสามารถแล้ว โฮสต์ส่ง CHANNEL_LIST (opcode 0x20) กล้องตอบกลับพร้อมรายการช่องสัญญาณที่ลงทะเบียน ซึ่งรวมถึงช่องในตัวสี่ช่อง (stdin, stdout, stream, profile) บวกกับช่องที่แอปพลิเคชันลงทะเบียนด้วย protocol.register() แต่ละรายการมี ID ของช่อง ชื่อ และ capability flags (read-only, write-only, lockable)

โฮสต์บันทึกรายการและใช้งานในภายหลังเมื่อโค้ดแอปพลิเคชันขอ channel_read("frame") หรือ channel_write("config", ...) โดยชื่อจะถูกค้นหาเป็น channel ID เพียงครั้งเดียว แล้วทุกแพ็กเก็ตถัดไปบนช่องนั้นจะใช้ ID โดยตรง

หากกล้องลงทะเบียนช่องใหม่หลังจากรายการเริ่มต้น ซึ่งเป็นเรื่องปกติเมื่อแอปพลิเคชันเริ่มทำงานหลังจากการจับมือ กล้องจะส่งแพ็กเก็ตเหตุการณ์ CHANNEL_REGISTERED โฮสต์รับฟังเหล่านั้นและรีเฟรชรายการช่องสัญญาณภายใน ดังนั้นสคริปต์โฮสต์ที่เชื่อมต่อก่อนหน้าจะเห็นช่องสัญญาณที่ลงทะเบียนใหม่ปรากฏขึ้นโดยไม่ต้องรีสตาร์ท

การจับมือใช้เวลารับส่งข้อมูลไปกลับสองสามรอบในการตั้งค่าการเชื่อมต่อและจะไม่ซ้ำอีก การรับส่งข้อมูลในสภาวะปกติเป็นเพียงแพ็กเก็ต: ไบต์ที่แบ่งเฟรมเข้ามา ไบต์ที่แบ่งเฟรมออกไป โดย channel ID รู้จักอยู่แล้วทั้งสองฝ่าย