초광대역 통신은 기기 간의 정확한 범위(위치 10cm 정확도 측정)에 중점을 둔 무선 기술입니다. 이 무선 기술은 단거리 측정에 저에너지 밀도를 사용하고 무선 스펙트럼의 상당 부분에서 고대역폭 신호를 실행할 수 있습니다. UWB의 대역폭이 500MHz를 초과 (또는 부분 대역폭의 20% 초과)합니다.
컨트롤러/시작자 vs. 관리자/응답자
UWB 통신은 두 기기 간에 발생합니다. 여기서 하나는 컨트롤러이고 다른 하나는 Controlee입니다. 컨트롤러는 두 기기가 공유할 복잡한 채널(UwbComplexChannel
)을 결정하고 시작자이고 피제어자는 응답자입니다.
컨트롤러는 여러 Controlee를 처리할 수 있지만 Controlee는 단일 컨트롤러만 구독할 수 있습니다. 컨트롤러/시작자와 제어 대상/응답자 구성이 모두 지원됩니다.
범위 지정 매개변수
컨트롤러와 제어자는 서로를 식별하고 범위 설정 매개변수를 통신하여 범위 설정을 시작해야 합니다. 이러한 교환은 애플리케이션이 저전력 블루투스 (BLE)와 같이 사용자가 선택한 안전한 대역 외 (OOB) 메커니즘을 사용하여 구현해야 합니다.
범위 설정 매개변수에는 로컬 주소, 복합 채널, 세션 키 등이 포함됩니다. 이러한 매개변수는 범위 설정 세션이 종료된 후 순환되거나 변경될 수 있으며 범위 지정을 다시 시작하려면 다시 전달해야 합니다.
백그라운드 범위 설정
백그라운드에서 실행되는 앱은 UWB 범위 세션을 시작할 수 있습니다(기기에서 지원하는 경우). 기기 기능을 확인하려면 RangingCapabilities
를 참고하세요.
앱은 백그라운드에서 실행될 때 범위 보고서를 수신하지 않으며, 앱이 포그라운드로 이동할 때 범위 보고서를 수신합니다.
STS 구성
앱 또는 서비스가 스크램블된 타임스탬프 시퀀스 (STS)를 사용하여 각 세션의 세션 키를 프로비저닝합니다. 프로비저닝된 STS는 정적 STS 구성보다 안전합니다. 프로비저닝된 STS는 Android 14 이상을 실행하는 모든 UWB 지원 기기에서 지원됩니다.
위협 카테고리 | 정적 STS | 프로비저닝된 STS |
---|---|---|
공기: 수동 관찰자 | 완화됨 | 완화됨 |
공기: 신호 증폭 | 완화됨 | 완화됨 |
공기: 리플레이/중계 공격 | 민감성 | 완화됨 |
프로비저닝된 STS의 경우:
프로비저닝된 STS를 지원하는
RangingParameters
의uwbConfigType
를 사용합니다.sessionKeyInfo
필드에 16바이트 키를 입력합니다.
정적 STS:
정적 STS를 지원하는
RangingParameters
의uwbConfigType
를 사용합니다.sessionKeyInfo
필드에 8바이트 키를 제공합니다.
걸음수
UWB API를 사용하려면 다음 단계를 따르세요.
- Android 기기가 Android 12 이상을 실행하고
PackageManager#hasSystemFeature("android.hardware.uwb")
를 사용하여 UWB를 지원하는지 확인합니다. - IoT 기기의 범위를 지정하는 경우 FiRa MAC 1.3을 준수하는지 확인합니다.
BluetoothLeScanner
와 같은 원하는 OOB 메커니즘을 사용하여 UWB 지원 동종 기기를 탐색합니다.- 선택한 보안 OOB 메커니즘(예:
BluetoothGatt
)을 사용하여 범위 설정 매개변수를 교환합니다. - 사용자가 세션을 중지하고자 한다면 세션 범위를 취소합니다.
사용 제한
UWB API 사용에는 다음 제한사항이 적용됩니다.
- 새 UWB 범위 지정 세션을 시작하는 앱은 앞에서 설명한 것처럼 백그라운드 범위 설정이 지원되지 않는 한 포그라운드 앱 또는 서비스여야 합니다.
- 앱이 백그라운드로 이동하면 (세션이 진행되는 동안) 앱이 더 이상 범위 보고서를 수신하지 않을 수 있습니다. 하지만 UWB 세션은 하위 레이어에서 계속 유지됩니다. 앱이 포그라운드로 다시 이동하면 범위 설정 보고서가 재개됩니다.
코드 샘플
샘플 앱
UWB Jetpack 라이브러리를 사용하는 방법에 관한 전체 예는 GitHub의 샘플 애플리케이션을 참고하세요. 이 샘플 앱에서는 Android 기기에서 UWB 호환성을 검증하고, OOB 메커니즘을 사용하여 검색 프로세스를 사용 설정하고, 두 UWB 지원 기기 간의 UWB 범위를 설정하는 방법을 다룹니다. 이 샘플은 기기 제어 및 미디어 공유 사용 사례도 다룹니다.
UWB 범위
다음 코드 샘플은 Controlee의 UWB 범위 설정을 시작하고 종료합니다.
// The coroutineScope responsible for handling uwb ranging.
// This will be initialized when startRanging is called.
var job: Job?
// A code snippet that initiates uwb ranging for a Controlee.
suspend fun startRanging() {
// Get the ranging parameter of a partnering Controller using an OOB mechanism of choice.
val partnerAddress : Pair<UwbAddress, UwbComplexChannel> = listenForPartnersAddress()
// Create the ranging parameters.
val partnerParameters = RangingParameters(
uwbConfigType = UwbRangingParameters.UWB_CONFIG_ID_1,
// SessionKeyInfo is used to encrypt the ranging session.
sessionKeyInfo = null,
complexChannel = partnerAddress.second,
peerDevices = listOf(UwbDevice.createForAddress(partnerAddress.first)),
updateRateType = UwbRangingParameters.RANGING_UPDATE_RATE_AUTOMATIC
)
// Initiate a session that will be valid for a single ranging session.
val clientSession = uwbManager.clientSessionScope()
// Share the localAddress of the current session to the partner device.
broadcastMyParameters(clientSession.localAddress)
val sessionFlow = clientSession.prepareSession(partnerParameters)
// Start a coroutine scope that initiates ranging.
CoroutineScope(Dispatchers.Main.immediate).launch {
sessionFlow.collect {
when(it) {
is RangingResultPosition -> doSomethingWithPosition(it.position)
is RangingResultPeerDisconnected -> peerDisconnected(it)
}
}
}
}
// A code snippet that cancels uwb ranging.
fun cancelRanging() {
// Canceling the CoroutineScope will stop the ranging.
job?.let {
it.cancel()
}
}
RxJava3 지원
이제 자바 클라이언트와의 상호 운용성을 실현하는 데 도움이 되도록 Rxjava3 지원을 사용할 수 있습니다. 이 라이브러리는 범위 설정 결과를 Observable 또는 Flowable 스트림으로 가져오고 UwbClientSessionScope를 단일 객체로 검색하는 방법을 제공합니다.
private final UwbManager uwbManager;
// Retrieve uwbManager.clientSessionScope as a Single object
Single<UwbClientSessionScope> clientSessionScopeSingle =
UwbManagerRx.clientSessionScopeSingle(uwbManager);
UwbClientSessionScope uwbClientSessionScope = clientSessionScopeSingle.blockingGet();
// Retrieve uwbClientSessionScope.prepareSession Flow as an Observable object
Observable<RangingResult> rangingResultObservable =
UwbClientSessionScopeRx.rangingResultsObservable(clientSessionScope,
rangingParameters);
// Consume ranging results from Observable
rangingResultObservable.subscribe(
rangingResult -> doSomethingWithRangingResult(result), // onNext
(error) -> doSomethingWithError(error), // onError
() -> doSomethingOnResultEventsCompleted(), //onCompleted
);
// Unsubscribe
rangingResultObservable.unsubscribe();
// Retrieve uwbClientSessionScope.prepareSession Flow as a Flowable object
Flowable<RangingResult> rangingResultFlowable =
UwbClientSessionScopeRx.rangingResultsFlowable(clientSessionScope,
rangingParameters);
// Consume ranging results from Flowable using Disposable
Disposable disposable = rangingResultFlowable
.delay(1, TimeUnit.SECONDS)
.subscribeWith(new DisposableSubscriber<RangingResult> () {
@Override public void onStart() {
request(1);
}
@Override public void onNext(RangingResult rangingResult) {
doSomethingWithRangingResult(rangingResult);
request(1);
}
@Override public void onError(Throwable t) {
t.printStackTrace();
}
@Override public void onComplete() {
doSomethingOnEventsCompleted();
}
});
// Stop subscription
disposable.dispose();
생태계 지원
지원되는 파트너 기기 및 서드 파티 SDK는 다음과 같습니다.
UWB 지원 휴대기기
2024년 3월부터 다음 기기에서 Android UWB Jetpack 라이브러리를 지원합니다.
공급업체 | 기기 모델 |
---|---|
Pixel 6 Pro, 7 Pro, 8 Pro, Fold, 태블릿 | |
Samsung | Galaxy Note 20, S21+, S22+, S23+, S24+ Z Fold 2, 3, 4, 5 |
서드 파티 SDK
2023년 4월부터 이러한 파트너 솔루션은 현재 Jetpack 라이브러리와 호환됩니다.
- UWB 개발 키트를 사용합니다.
- Mobile Knowledge MK UWB Kit Mobile Edition 2.0.
알려진 문제: MAC 주소 및 정적 STS 공급업체 ID 필드의 바이트 순서가 바뀜
Android 13 이하에서 Android UWB 스택은 다음 필드의 바이트 순서를 잘못 바꿉니다.
- 기기 MAC 주소
- 대상 MAC 주소
- 정적 STS 공급업체 ID
바이트 순서 반전이 발생하는 이유는 Android 스택이 이러한 필드를 배열이 아닌 값으로 취급하기 때문입니다. Google은 이러한 필드가 배열로 취급되어야 한다고 명시적으로 명시하기 위해 FiRa와 협력하여 UCI 사양(CR-1112)을 업데이트하고 있습니다.
이 문제는 2320XXXX
버전의 GMS 코어 업데이트를 통해 해결될 예정입니다.
이 시점부터 Android 기기를 준수하려면 IoT 공급업체는 이러한 필드의 바이트 순서를 반대로 되돌리지 않도록 구현을 수정해야 합니다.