초광대역 통신은 정확한 범위에 초점을 맞춘 무선 기술입니다. 10cm의 정확도로 위치 측정) 이 무선 기술은 단거리 측정을 위해 저에너지 밀도를 사용하여 무선 스펙트럼의 상당 부분에 걸쳐 고대역폭 신호를 수행합니다. UWB의 대역폭이 500MHz 보다 크거나 20% 를 초과하는 경우 있습니다.
컨트롤러/개시자와 통제자/대응자 비교
UWB 통신은 두 기기 사이에서 발생하는데, 그 중 하나는 컨트롤러이고
다른 하나는 Controlee입니다 컨트롤러는 복잡한 채널 결정
(UwbComplexChannel
)
두 장치가 공유 및 시작자이고 제어 대상자는
있습니다.
컨트롤러는 여러 Controlee를 처리할 수 있지만 Controlee는 구독만 할 수 있음 전달할 수 있습니다 컨트롤러/시작자와 통제자/대응자 모두 구성이 지원됩니다
매개변수 범위 지정
컨트롤러와 통제자는 서로를 식별하고 소통해야 함 범위 설정 매개변수를 사용하여 범위 지정을 시작합니다. 이 교환은 애플리케이션이 OOB(보안 대역 외) 메커니즘(예: 저전력 블루투스 (BLE)
범위 지정 매개변수는 지역 주소, 복잡한 채널, 세션 키 등이 포함됩니다. 참고 범위 설정 세션 후에 이러한 매개변수가 회전하거나 변경될 수 있음 종료되고 범위 지정을 다시 시작하기 위해 재통신해야 합니다.
배경 범위 설정
백그라운드에서 실행되는 앱은 기기가 다음과 같은 경우 UWB 범위 세션을 시작할 수 있습니다.
지원합니다 기기 기능을 확인하려면 RangingCapabilities
를 참고하세요.
앱이 백그라운드에서 실행될 때 범위 보고서를 수신하지 않습니다. 앱 포그라운드로 이동할 때 범위 보고서를 수신합니다.
STS 구성
앱 또는 서비스가 Scrambled를 사용하여 각 세션의 세션 키를 프로비저닝합니다. 타임스탬프 시퀀스 (STS) 프로비저닝된 STS가 정적 STS보다 안전합니다. 구성할 수 있습니다 프로비저닝된 STS는 다음을 실행하는 모든 UWB 지원 기기에서 지원됩니다. Android 14 이상
위협 카테고리 | 정적 STS | 프로비저닝된 STS |
---|---|---|
에어: 수동 관찰자 | 완화됨 | 완화됨 |
공기: 신호 증폭 | 완화됨 | 완화됨 |
Air: 리플레이/릴레이 공격 | 취약성 | 완화됨 |
프로비저닝된 STS의 경우:
프로비저닝된 STS를 지원하는
RangingParameters
에서uwbConfigType
를 사용합니다.sessionKeyInfo
필드에 16바이트 키를 제공합니다.
정적 STS:
정적 STS를 지원하는
RangingParameters
에서uwbConfigType
를 사용합니다.sessionKeyInfo
필드에 8바이트 키를 입력합니다.
단계
UWB API를 사용하려면 다음 단계를 따르세요.
- Android 기기가 Android 12 이상에서 실행되고
사용하여 UWB 지원
PackageManager#hasSystemFeature("android.hardware.uwb")
- IoT 기기에 범위를 지정하는 경우 FiRa MAC 1.3인지 확인합니다. .
- 원하는 OOB 메커니즘을 사용하여 UWB 지원 피어 기기를 찾습니다.
예:
BluetoothLeScanner
- 원하는 보안 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 지원
이제 Java와의 상호 운용성을 달성하는 데 도움이 되는 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, 태블릿 | |
삼성 | Galaxy Note 20, S21+, S22+, S23+, S24+ Z Fold 2, 3, 4, 5 |
서드 파티 SDK
2023년 4월부터 다음 파트너 솔루션은 현재 Jetpack 라이브러리를 참조하세요.
- Estimote UWB 개발 키트.
- Mobile Knowledge MK UWB Kit Mobile Edition 2.0
알려진 문제: MAC 주소 및 정적 STS 공급업체 ID 필드의 바이트 순서가 뒤바뀜
Android 13 이하에서 Android UWB 스택이 바이트를 잘못 역전함 다음 필드에 대한 올바른 순서를 지정합니다.
- 기기 MAC 주소
- 목적지 MAC 주소
- 정적 STS 공급업체 ID
바이트 순서 반전이 발생하는 이유는 Android 스택이 이러한 필드를 처리하기 때문입니다. 값을 제공해야 합니다. UCI 사양을 업데이트하기 위해 FiRa와 협력하고 있습니다. (CR-1112) 해당 필드가 배열로 취급되어야 함을 명시적으로 명시합니다.
이 문제는 2320XXXX
버전의 GMS 코어 업데이트를 통해 해결될 예정입니다.
IOT 공급업체는 그 시점부터 Android 기기와 호환되려면
이러한 필드의 바이트 순서를 역전하지 않도록 구현하세요.