초광대역 (UWB) 통신

초광대역 통신은 정확한 범위에 초점을 맞춘 무선 기술입니다. 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의 경우:

  1. 프로비저닝된 STS를 지원하는 RangingParameters에서 uwbConfigType를 사용합니다.

  2. sessionKeyInfo 필드에 16바이트 키를 제공합니다.

정적 STS:

  1. 정적 STS를 지원하는 RangingParameters에서 uwbConfigType를 사용합니다.

  2. sessionKeyInfo 필드에 8바이트 키를 입력합니다.

단계

UWB API를 사용하려면 다음 단계를 따르세요.

  1. Android 기기가 Android 12 이상에서 실행되고 사용하여 UWB 지원 PackageManager#hasSystemFeature("android.hardware.uwb")
  2. IoT 기기에 범위를 지정하는 경우 FiRa MAC 1.3인지 확인합니다. .
  3. 원하는 OOB 메커니즘을 사용하여 UWB 지원 피어 기기를 찾습니다. 예: BluetoothLeScanner
  4. 원하는 보안 OOB 메커니즘을 사용하여 범위 지정 매개변수를 교환합니다. (예: BluetoothGatt)
  5. 사용자가 세션을 중지하려는 경우 세션 범위를 취소합니다.

사용 제한

UWB API 사용 시 다음 제한사항이 적용됩니다.

  1. 새 UWB 범위 세션을 시작하는 앱이 포그라운드 상태여야 합니다. 앱 또는 서비스(단, 그림과 같이 백그라운드 범위 지정은 지원되지 않음) 살펴봤습니다
  2. 세션이 진행되는 동안 앱이 백그라운드로 이동하면 범위 보고서를 더 이상 수신하지 않을 수 있습니다. 하지만 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 라이브러리를 지원합니다.

공급업체 기기 모델
Google 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 라이브러리를 참조하세요.

알려진 문제: MAC 주소 및 정적 STS 공급업체 ID 필드의 바이트 순서가 뒤바뀜

Android 13 이하에서 Android UWB 스택이 바이트를 잘못 역전함 다음 필드에 대한 올바른 순서를 지정합니다.

  • 기기 MAC 주소
  • 목적지 MAC 주소
  • 정적 STS 공급업체 ID

바이트 순서 반전이 발생하는 이유는 Android 스택이 이러한 필드를 처리하기 때문입니다. 값을 제공해야 합니다. UCI 사양을 업데이트하기 위해 FiRa와 협력하고 있습니다. (CR-1112) 해당 필드가 배열로 취급되어야 함을 명시적으로 명시합니다.

이 문제는 2320XXXX 버전의 GMS 코어 업데이트를 통해 해결될 예정입니다. IOT 공급업체는 그 시점부터 Android 기기와 호환되려면 이러한 필드의 바이트 순서를 역전하지 않도록 구현하세요.