FiRa 세션: 라운드·슬롯·역할
6장의 핑퐁은 두 기기가 “언제, 어느 채널에서, 어떤 코드로, 누가 먼저” 보낼지 이미 안다고 가정했다. 실제로는 그 약속부터 정해야 한다. iPhone과 갤럭시가 서로를, 또 다른 회사의 태그를 잴 수 있으려면 약속의 형식이 같아야 한다. FiRa Consortium이 정하고 Android UWB 스택이 구현한 그 약속, 세션을 들여다본다.
- 컨트롤러·컨트롤리와 시작자·응답자, 두 쌍의 역할을 구분한다.
- RSTU, 슬롯, 라운드, 측정 간격의 관계를 Android 기본값으로 계산한다.
- 일대다 측정에서 라운드 하나에 몇 대까지 잴 수 있는지 시뮬레이션한다.
- 앱 → UWB 서비스 → 칩(UCI)으로 세션이 열리는 순서와, 세션들이 부딪히지 않게 하는 라운드 도약을 안다.
두 쌍의 역할
- 컨트롤러 / 컨트롤리(controller / controlee): 누가 세션의 설정(채널, 코드, 간격, 슬롯)을 정하고 시간표를 내는가. 컨트롤러가 라운드마다 제어 메시지로 시간표를 알린다.
- 시작자 / 응답자(initiator / responder): 6장의 핑퐁에서 누가 Poll을 보내는가. 보통 컨트롤러가 시작자지만, 둘은 별개의 설정이다.
휴대폰과 분실물 태그라면 휴대폰이 컨트롤러·시작자, 태그가 컨트롤리·응답자다. Android는 TDoA용으로 광고자·관찰자 역할도 둔다(9장).
역할 값: Android FiraParams.java의 RANGING_DEVICE_ROLE_RESPONDER = 0, _INITIATOR = 1, _ADVERTISER = 5, _OBSERVER = 6 · 일대다: MULTI_NODE_MODE_UNICAST = 0, _ONE_TO_MANY = 1, _MANY_TO_MANY = 2
RSTU, 슬롯, 라운드, 간격
FiRa의 시간은 네 층이다.
- RSTU(Ranging Scheduling Time Unit): 1/1.2 µs ≈ 833.3 ns. 499.2 MHz 칩 416개 길이다. 자동차 키(CCC)는 400 RSTU = 1/3 ms를 “chap”이라 부른다.
- 슬롯: 프레임 하나를 보내는 칸. Android 기본 2,400 RSTU = 2 ms. 4장의 거리 측정 프레임(약 140 µs)이 넉넉히 들어간다.
- 라운드: 한 번의 거리 측정에 필요한 메시지들이 차례로 들어가는 슬롯 묶음. 기본 25슬롯 = 50 ms.
- 측정 간격(ranging interval): 라운드가 다시 돌아오는 주기. 기본 200 ms, 즉 초당 5번. 라운드 사이에는 칩이 잔다(12장).
기본값: Android external/uwb fira_app_config_params.rs의 DEFAULT_SLOT_DURATION_RSTU = 2400, DEFAULT_RANGING_DURATION_MS = 200 · FiraParams.java의 SLOTS_PER_RR = 25 · 1 chap = 400 RSTU: aliro_app_config_params.rs의 CHAP_IN_RSTU · RSTU 길이 1/1.2 µs는 chap = 1/3 ms와 400 RSTU의 관계에서 나온 값(= 416 칩 ÷ 499.2 MHz)
여러 사람이 한 마이크를 쓰는 회의에서는 순서표를 미리 나눠 준다. “1번 자리는 사회자, 2~5번은 각 팀, 마지막은 정리”. 각자 자기 차례에만 말하니 부딪히지 않는다. FiRa의 라운드가 순서표, 슬롯이 발언 칸이다. 사람이 많아지면 순서표가 길어지고, 회의(측정) 간격도 길어진다.
DS-TWR 일대다, 라운드가 25슬롯이다. 응답자는 최대 몇 개까지 넣을 수 있을까?
DS-TWR 일대다에 필요한 슬롯 = 4 + 2 × 응답자 수.
라운드 시간표 만들기
슬롯 부족·간격 오류: uci_packets.pdl의 ERROR_INSUFFICIENT_SLOTS_PER_RR = 0x21, ERROR_INVALID_RANGING_DURATION = 0x23 · 측정 방식 이름: RANGING_ROUND_USAGE_SS_TWR_DEFERRED_MODE, _DS_TWR_DEFERRED_MODE, _NON_DEFERRED_MODE
앱에서 칩까지: 세션이 열리는 순서
앱은 UWB 칩을 직접 다루지 않는다. Android에서는 앱 → UWB 시스템 서비스 → UWB 칩(UWBS) 순으로 내려가고, 서비스와 칩은 UCI(UWB Command Interface)라는 명령 형식으로 이야기한다. 그 전에 두 기기는 UWB 밖의 통로(대개 BLE, 12장)로 상대의 주소와 세션 설정, 보안 키를 주고받는다. 이것을 대역 외(OOB) 설정이라 한다.
세션 하나의 일생
external/uwb의 uci_packets.pdl에 정의된 이름이다(SESSION_INIT, SESSION_SET_APP_CONFIG, SESSION_START(RANGE_START), SESSION_STOP, SESSION_DEINIT). 앱 쪽 이름(RangingSession 등)은 Android 버전마다 조금 다르다.세션끼리 부딪히지 않게: 라운드 도약
같은 방에서 여러 휴대폰이 각자 세션을 돌리면, 같은 채널·같은 간격인 두 세션의 라운드가 겹칠 수 있다. 시계가 거의 같은 속도로 가므로, 한 번 겹치면 계속 겹친다. 그래서 FiRa는 간격 몇 개를 블록으로 묶고, 블록마다 라운드를 놓는 자리를 무작위로 바꾼다(라운드 도약, hopping). 겹쳐도 다음 블록에서는 대개 비켜 간다.
두 세션의 충돌
도약·블록 설정: uci_packets.pdl의 HOPPING_MODE = 0x2C, BLOCK_STRIDE_LENGTH = 0x2D · CCC 디지털 키의 도약 방식: CccParams.java의 HOPPING_CONFIG_MODE_CONTINUOUS·_ADAPTIVE, HOPPING_SEQUENCE_AES
핵심 정리
- 컨트롤러·컨트롤리 = 누가 설정·시간표를 정하나, 시작자·응답자 = 누가 Poll을 보내나.
- RSTU ≈ 833 ns(1 chap = 400 RSTU = 1/3 ms). Android 기본: 슬롯 2,400 RSTU(2 ms), 라운드 25슬롯(50 ms), 간격 200 ms(초당 5번).
- 일대다에서 응답자가 늘면 라운드에 필요한 슬롯이 늘고, 넘치면 “슬롯 부족”으로 멈춘다.
- 앱 → UWB 서비스 → UCI(SESSION_INIT → SET_APP_CONFIG → START) → 칩. 그 전에 BLE 등으로 OOB 설정.
- 라운드 도약은 블록마다 라운드 자리를 바꿔, 세션끼리 계속 부딪히는 것을 막는다.
확인 퀴즈
Android 기본 슬롯 2,400 RSTU는 몇 ms인가?
측정 간격 200 ms면 초당 측정은?
라운드 도약이 막는 것은?
Android UWB 서비스가 칩에 세션 설정 값을 넣는 UCI 명령은?