12.4. Підтискання руки (handshake) та узгодження можливостей¶
Камера та хост прибувають до транспортного рівня зі своїми уявленнями про те, як має працювати протокол: які режими CRC, чи потрібні ACK, який максимальний розмір корисного навантаження, який вони можуть буферизувати. Перш ніж починається реальний трафік, вони обмінюються підтисканням руки (handshake), яке фіксує ці параметри для решти сесії.
12.4.1. Хост відкриває з’єднання¶
Сторона камери запускає стек протоколу під час завантаження (або застосунок перезапускає його за допомогою protocol.init() для зміни параметрів), після чого тихо чекає на хост. З погляду камери немає нічого робити, доки не надійде пакет.
Сторона хоста відкриває транспорт – порт USB або UART – і негайно надсилає пакет PROTO_SYNC (опкод 0x00). Цей пакет має магічне корисне навантаження, яке дозволяє камері розпізнати його, навіть якщо обидві сторони вийшли з синхронізації, і це єдиний пакет, на який камера відповідає до узгодження можливостей.
Якщо камера не відповідає протягом таймауту повторної передачі, хост знову надсилає PROTO_SYNC, до rtx_retries разів. Після цього він здається і повідомляє про помилку з’єднання. Повторна спроба – це те, що дозволяє «від’єднати, підключити знову, перезапустити скрипт хоста» без необхідності камері знати, що хост відключився.
12.4.2. Обмін можливостями¶
Після того як камера підтверджує синхронізацію, хост надсилає PROTO_GET_CAPS (опкод 0x01), щоб дізнатися, що підтримує камера. Відповідне корисне навантаження повідомляє:
Перевірку CRC увімкнено або вимкнено
Відстеження порядкових номерів увімкнено або вимкнено
ACK увімкнено або вимкнено
Сповіщення про події увімкнено або вимкнено
Максимальний розмір корисного навантаження камери в байтах
Поточну кількість повторних спроб, таймаут і параметри опитування
Хост порівнює їх зі своєю конфігурацією. Якщо хосту потрібно змінити будь-який із них – наприклад, узгодити менший максимальний розмір корисного навантаження, оскільки його буфер прийому менший за буфер камери – він надсилає PROTO_SET_CAPS (опкод 0x02) з новими значеннями. Камера переналаштовує свій стек і підтверджує. Відтепер кожен пакет, що перетинає дріт, дотримується цього спільного контракту.
Якщо хост нічого не перевизначає, усі параметри за замовчуванням увімкнені: перевірка CRC, відстеження порядкових номерів, ACK та сповіщення про події. Максимальний розмір корисного навантаження за замовчуванням – це буфер плати камери мінус 14 байт накладних витрат на обрамлення (10-байтний заголовок плюс 4-байтний кінцевий CRC корисного навантаження). Для більшості завдань між камерою та ноутбуком значення за замовчуванням є правильною відправною точкою; сторінка про надійність описує, коли та чому застосунок відключає їх частково.
12.4.3. Виявлення каналів¶
Після узгодження можливостей хост надсилає CHANNEL_LIST (опкод 0x20). Камера відповідає списком зареєстрованих каналів – чотирьох вбудованих (stdin, stdout, stream, profile) плюс будь-яких, зареєстрованих застосунком за допомогою protocol.register(). Кожен запис містить ID каналу, його назву та прапорці можливостей (лише читання, лише запис, блокований).
Хост зберігає список і використовує його пізніше, коли код застосунку запитує channel_read("frame") або channel_write("config", ...) – ім’я один раз перетворюється на ID каналу, після чого кожен наступний пакет на цьому каналі використовує ID безпосередньо.
Якщо камера реєструє новий канал після початкового списку – що зазвичай відбувається, коли застосунок починає роботу після підтискання руки – камера випускає пакет події CHANNEL_REGISTERED. Хост прослуховує їх і оновлює свій внутрішній список каналів, тому скрипт хоста, підключений завчасно, бачить нові канали, що з’являються, без перезапуску.
Підтискання руки займає кілька обмінів під час налаштування з’єднання і більше ніколи не повторюється. Трафік у стабільному стані – це просто пакети: обрамлені байти в одному напрямку і в іншому, а ID каналів вже відомі з обох сторін.