12.4. 핸드셰이크 및 기능 협상¶
카메라와 호스트는 모두 프로토콜이 어떻게 동작해야 하는지에 대한 각자의 생각을 가지고 트랜스포트에 도달합니다: 어떤 CRC 모드를 쓸지, ACK가 필요한지, 버퍼링할 수 있는 최대 페이로드가 얼마인지 등입니다. 실제 트래픽이 시작되기 전에 양측은 세션의 나머지 기간 동안 이러한 매개변수를 고정하는 핸드셰이크를 교환합니다.
12.4.1. 호스트가 연결을 엽니다¶
카메라 측은 부팅 시 프로토콜 스택을 시작하며(또는 애플리케이션이 매개변수를 변경하기 위해 protocol.init() 으로 재시작), 그 후 호스트를 조용히 기다립니다. 카메라 관점에서는 패킷이 도착할 때까지 할 일이 없습니다.
호스트 측은 트랜스포트 – USB 포트 또는 UART – 를 열고 즉시 PROTO_SYNC 패킷(opcode 0x00)을 보냅니다. 이 패킷에는 양측의 동기가 어긋났더라도 카메라가 이를 인식할 수 있게 해 주는 매직 페이로드가 있으며, 기능이 협상되기 전에 카메라가 응답하는 유일한 패킷입니다.
카메라가 재전송 타임아웃 내에 응답하지 않으면 호스트는 rtx_retries 횟수까지 PROTO_SYNC 를 다시 보냅니다. 그 후에는 포기하고 연결 실패를 보고합니다. 이 재시도 덕분에 “뽑았다 다시 꽂고, 호스트 스크립트 재시작” 이 카메라가 호스트가 사라졌음을 알 필요 없이 동작합니다.
12.4.2. 기능 교환¶
카메라가 동기화를 확인하고 나면, 호스트는 카메라가 무엇을 지원하는지 묻기 위해 PROTO_GET_CAPS (opcode 0x01)를 보냅니다. 응답 페이로드는 다음을 보고합니다:
CRC 검증 활성화 또는 비활성화
시퀀스 번호 추적 활성화 또는 비활성화
ACK 활성화 또는 비활성화
이벤트 알림 활성화 또는 비활성화
카메라의 최대 페이로드 크기(바이트 단위)
현재 재전송 재시도 횟수, 타임아웃, 폴링 매개변수
호스트는 이를 자신의 설정과 비교합니다. 호스트가 그중 어느 하나라도 변경 해야 한다면 – 예를 들어 수신 버퍼가 카메라보다 작아서 더 작은 최대 페이로드를 협상해야 하는 경우 – 새 값과 함께 PROTO_SET_CAPS (opcode 0x02)를 보냅니다. 카메라는 스택을 재구성하고 이를 확인합니다. 이후로는 와이어를 건너는 모든 패킷이 그 공유된 계약을 따릅니다.
호스트가 아무것도 재정의하지 않으면 기본값은 모두 켜져 있습니다: CRC 검증, 시퀀스 번호 추적, ACK, 이벤트 알림입니다. 기본 최대 페이로드는 카메라의 보드별 버퍼에서 프레이밍 오버헤드 14바이트(10바이트 헤더에 4바이트 후행 페이로드 CRC를 더한 것)를 뺀 값입니다. 대부분의 카메라-노트북 작업에서는 기본값이 올바른 출발점이며, 애플리케이션이 그중 일부를 언제 왜 끄는지는 신뢰성 페이지에서 다룹니다.
12.4.3. 채널 검색¶
기능 교환 후 호스트는 CHANNEL_LIST (opcode 0x20)를 보냅니다. 카메라는 등록된 채널 목록으로 응답합니다 – 네 개의 내장 채널(stdin, stdout, stream, profile)과 애플리케이션이 protocol.register() 로 등록한 채널들입니다. 각 항목에는 채널의 ID, 이름, 그리고 기능 플래그(읽기 전용, 쓰기 전용, 잠금 가능)가 담겨 있습니다.
호스트는 이 목록을 보관해 두었다가, 나중에 애플리케이션 코드가 channel_read("frame") 또는 channel_write("config", ...) 를 요청할 때 사용합니다 – 이름은 한 번 채널 ID로 조회되고, 그 후 해당 채널의 모든 후속 패킷은 ID를 직접 사용합니다.
카메라가 초기 목록 이후에 새 채널을 등록하면 – 핸드셰이크 후에 애플리케이션이 실행되기 시작할 때 흔한 일입니다 – 카메라는 CHANNEL_REGISTERED 이벤트 패킷을 발생시킵니다. 호스트는 이를 수신 대기하다가 내부 채널 목록을 갱신하므로, 일찍 연결된 호스트 스크립트도 재시작 없이 새로 등록된 채널이 나타나는 것을 볼 수 있습니다.
핸드셰이크는 연결 설정 시 몇 차례의 왕복을 거치고 나면 다시는 반복되지 않습니다. 정상 상태 트래픽은 그저 패킷일 뿐입니다: 프레임화된 바이트가 들어오고 나가며, 채널 ID는 양측에서 이미 알고 있습니다.